From 33012d9530c40817e1fc5230b3e663f7690b2e94 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 4 Sep 2005 08:01:00 -0700 Subject: Version abc50904 --- Makefile | 10 +- abc.dsp | 332 ++-- abc.opt | Bin 51712 -> 51712 bytes abc.plg | 863 +++++++-- abc.rc | 1 + src/base/abc/abc.c | 3974 ---------------------------------------- src/base/abc/abc.h | 76 +- src/base/abc/abcAttach.c | 405 ---- src/base/abc/abcBalance.c | 236 --- src/base/abc/abcCollapse.c | 147 -- src/base/abc/abcCreate.c | 1407 -------------- src/base/abc/abcCut.c | 190 -- src/base/abc/abcDsd.c | 539 ------ src/base/abc/abcFpga.c | 246 --- src/base/abc/abcFraig.c | 583 ------ src/base/abc/abcFxu.c | 259 --- src/base/abc/abcMap.c | 668 ------- src/base/abc/abcMiter.c | 600 ------ src/base/abc/abcNtbdd.c | 402 ---- src/base/abc/abcNtk.c | 592 ++++++ src/base/abc/abcObj.c | 871 +++++++++ src/base/abc/abcPrint.c | 505 ----- src/base/abc/abcReconv.c | 742 -------- src/base/abc/abcRefactor.c | 354 ---- src/base/abc/abcRenode.c | 609 ------- src/base/abc/abcRewrite.c | 184 -- src/base/abc/abcSat.c | 252 --- src/base/abc/abcSeq.c | 644 ------- src/base/abc/abcSeqRetime.c | 203 --- src/base/abc/abcStrash.c | 287 --- src/base/abc/abcSweep.c | 607 ------ src/base/abc/abcSymm.c | 202 -- src/base/abc/abcTiming.c | 755 -------- src/base/abc/abcUnreach.c | 336 ---- src/base/abc/abcVerify.c | 311 ---- src/base/abc/module.make | 33 +- src/base/abci/abc.c | 4058 +++++++++++++++++++++++++++++++++++++++++ src/base/abci/abcAttach.c | 405 ++++ src/base/abci/abcBalance.c | 239 +++ src/base/abci/abcCollapse.c | 147 ++ src/base/abci/abcCut.c | 190 ++ src/base/abci/abcDsd.c | 539 ++++++ src/base/abci/abcFpga.c | 267 +++ src/base/abci/abcFraig.c | 586 ++++++ src/base/abci/abcFxu.c | 259 +++ src/base/abci/abcMap.c | 689 +++++++ src/base/abci/abcMiter.c | 600 ++++++ src/base/abci/abcNtbdd.c | 402 ++++ src/base/abci/abcPrint.c | 505 +++++ src/base/abci/abcReconv.c | 742 ++++++++ src/base/abci/abcRefactor.c | 354 ++++ src/base/abci/abcRenode.c | 609 +++++++ src/base/abci/abcRewrite.c | 184 ++ src/base/abci/abcSat.c | 252 +++ src/base/abci/abcStrash.c | 287 +++ src/base/abci/abcSweep.c | 607 ++++++ src/base/abci/abcSymm.c | 221 +++ src/base/abci/abcTiming.c | 755 ++++++++ src/base/abci/abcUnreach.c | 336 ++++ src/base/abci/abcVerify.c | 311 ++++ src/base/abci/abc_.c | 47 + src/base/abci/module.make | 24 + src/base/abcs/abcRetime.c | 203 +++ src/base/abcs/abcSeq.c | 644 +++++++ src/base/abcs/abc_.c | 47 + src/base/abcs/module.make | 2 + src/base/io/ioWriteDot_old.c | 325 ---- src/map/fpga/fpga.h | 2 + src/map/fpga/fpgaCore.c | 41 +- src/map/fpga/fpgaCreate.c | 2 + src/map/fpga/fpgaCutUtils.c | 103 -- src/map/fpga/fpgaInt.h | 17 +- src/map/fpga/fpgaMatch.c | 2 +- src/map/fpga/fpgaSwitch.c | 176 ++ src/map/fpga/fpgaUtils.c | 37 - src/map/fpga/module.make | 1 + src/map/mapper/mapper.h | 2 + src/map/mapper/mapperCore.c | 83 +- src/map/mapper/mapperCreate.c | 6 +- src/map/mapper/mapperInt.h | 8 + src/map/mapper/mapperLib.c | 1 + src/map/mapper/mapperMatch.c | 34 +- src/map/mapper/mapperRefs.c | 9 +- src/map/mapper/mapperSwitch.c | 243 +++ src/map/mapper/module.make | 1 + src/map/mio/mio.h | 1 + src/map/mio/mioApi.c | 17 +- src/misc/mvc/module.make | 16 + src/misc/mvc/mvc.c | 46 + src/misc/mvc/mvc.h | 733 ++++++++ src/misc/mvc/mvcApi.c | 233 +++ src/misc/mvc/mvcCompare.c | 369 ++++ src/misc/mvc/mvcContain.c | 173 ++ src/misc/mvc/mvcCover.c | 251 +++ src/misc/mvc/mvcCube.c | 175 ++ src/misc/mvc/mvcDivide.c | 436 +++++ src/misc/mvc/mvcDivisor.c | 90 + src/misc/mvc/mvcList.c | 362 ++++ src/misc/mvc/mvcLits.c | 345 ++++ src/misc/mvc/mvcMan.c | 77 + src/misc/mvc/mvcOpAlg.c | 163 ++ src/misc/mvc/mvcOpBool.c | 151 ++ src/misc/mvc/mvcPrint.c | 220 +++ src/misc/mvc/mvcSort.c | 141 ++ src/misc/mvc/mvcUtils.c | 868 +++++++++ src/misc/vec/vecInt.h | 41 + src/misc/vec/vecPtr.h | 62 +- src/misc/vec/vecStr.h | 20 + src/misc/vec/vecVec.h | 3 + src/opt/sim/module.make | 9 + src/opt/sim/sim.h | 190 ++ src/opt/sim/simMan.c | 278 +++ src/opt/sim/simSat.c | 48 + src/opt/sim/simSupp.c | 594 ++++++ src/opt/sim/simSwitch.c | 107 ++ src/opt/sim/simSym.c | 93 + src/opt/sim/simSymSat.c | 202 ++ src/opt/sim/simSymSim.c | 159 ++ src/opt/sim/simSymStr.c | 481 +++++ src/opt/sim/simUtils.c | 457 +++++ src/sat/fraig/fraig.h | 1 + src/sat/fraig/fraigApi.c | 8 +- src/sat/fraig/fraigFeed.c | 116 +- src/sat/fraig/fraigInt.h | 14 +- src/sat/fraig/fraigMan.c | 1 + src/sat/fraig/fraigSat.c | 18 +- src/sat/fraig/fraigTable.c | 52 +- src/sat/fraig/fraigUtil.c | 65 + src/sat/sim/module.make | 6 - src/sat/sim/sim.h | 136 -- src/sat/sim/simMan.c | 166 -- src/sat/sim/simSat.c | 48 - src/sat/sim/simSupp.c | 273 --- src/sat/sim/simSym.c | 48 - src/sat/sim/simUnate.c | 48 - src/sat/sim/simUtils.c | 379 ---- src/seq/module.make | 1 - src/sop/mvc/module.make | 16 - src/sop/mvc/mvc.c | 46 - src/sop/mvc/mvc.h | 733 -------- src/sop/mvc/mvcApi.c | 233 --- src/sop/mvc/mvcCompare.c | 369 ---- src/sop/mvc/mvcContain.c | 173 -- src/sop/mvc/mvcCover.c | 251 --- src/sop/mvc/mvcCube.c | 175 -- src/sop/mvc/mvcDivide.c | 436 ----- src/sop/mvc/mvcDivisor.c | 90 - src/sop/mvc/mvcList.c | 362 ---- src/sop/mvc/mvcLits.c | 345 ---- src/sop/mvc/mvcMan.c | 77 - src/sop/mvc/mvcOpAlg.c | 163 -- src/sop/mvc/mvcOpBool.c | 151 -- src/sop/mvc/mvcPrint.c | 220 --- src/sop/mvc/mvcSort.c | 141 -- src/sop/mvc/mvcUtils.c | 868 --------- 155 files changed, 25299 insertions(+), 22570 deletions(-) delete mode 100644 src/base/abc/abc.c delete mode 100644 src/base/abc/abcAttach.c delete mode 100644 src/base/abc/abcBalance.c delete mode 100644 src/base/abc/abcCollapse.c delete mode 100644 src/base/abc/abcCreate.c delete mode 100644 src/base/abc/abcCut.c delete mode 100644 src/base/abc/abcDsd.c delete mode 100644 src/base/abc/abcFpga.c delete mode 100644 src/base/abc/abcFraig.c delete mode 100644 src/base/abc/abcFxu.c delete mode 100644 src/base/abc/abcMap.c delete mode 100644 src/base/abc/abcMiter.c delete mode 100644 src/base/abc/abcNtbdd.c create mode 100644 src/base/abc/abcNtk.c create mode 100644 src/base/abc/abcObj.c delete mode 100644 src/base/abc/abcPrint.c delete mode 100644 src/base/abc/abcReconv.c delete mode 100644 src/base/abc/abcRefactor.c delete mode 100644 src/base/abc/abcRenode.c delete mode 100644 src/base/abc/abcRewrite.c delete mode 100644 src/base/abc/abcSat.c delete mode 100644 src/base/abc/abcSeq.c delete mode 100644 src/base/abc/abcSeqRetime.c delete mode 100644 src/base/abc/abcStrash.c delete mode 100644 src/base/abc/abcSweep.c delete mode 100644 src/base/abc/abcSymm.c delete mode 100644 src/base/abc/abcTiming.c delete mode 100644 src/base/abc/abcUnreach.c delete mode 100644 src/base/abc/abcVerify.c create mode 100644 src/base/abci/abc.c create mode 100644 src/base/abci/abcAttach.c create mode 100644 src/base/abci/abcBalance.c create mode 100644 src/base/abci/abcCollapse.c create mode 100644 src/base/abci/abcCut.c create mode 100644 src/base/abci/abcDsd.c create mode 100644 src/base/abci/abcFpga.c create mode 100644 src/base/abci/abcFraig.c create mode 100644 src/base/abci/abcFxu.c create mode 100644 src/base/abci/abcMap.c create mode 100644 src/base/abci/abcMiter.c create mode 100644 src/base/abci/abcNtbdd.c create mode 100644 src/base/abci/abcPrint.c create mode 100644 src/base/abci/abcReconv.c create mode 100644 src/base/abci/abcRefactor.c create mode 100644 src/base/abci/abcRenode.c create mode 100644 src/base/abci/abcRewrite.c create mode 100644 src/base/abci/abcSat.c create mode 100644 src/base/abci/abcStrash.c create mode 100644 src/base/abci/abcSweep.c create mode 100644 src/base/abci/abcSymm.c create mode 100644 src/base/abci/abcTiming.c create mode 100644 src/base/abci/abcUnreach.c create mode 100644 src/base/abci/abcVerify.c create mode 100644 src/base/abci/abc_.c create mode 100644 src/base/abci/module.make create mode 100644 src/base/abcs/abcRetime.c create mode 100644 src/base/abcs/abcSeq.c create mode 100644 src/base/abcs/abc_.c create mode 100644 src/base/abcs/module.make delete mode 100644 src/base/io/ioWriteDot_old.c create mode 100644 src/map/fpga/fpgaSwitch.c create mode 100644 src/map/mapper/mapperSwitch.c create mode 100644 src/misc/mvc/module.make create mode 100644 src/misc/mvc/mvc.c create mode 100644 src/misc/mvc/mvc.h create mode 100644 src/misc/mvc/mvcApi.c create mode 100644 src/misc/mvc/mvcCompare.c create mode 100644 src/misc/mvc/mvcContain.c create mode 100644 src/misc/mvc/mvcCover.c create mode 100644 src/misc/mvc/mvcCube.c create mode 100644 src/misc/mvc/mvcDivide.c create mode 100644 src/misc/mvc/mvcDivisor.c create mode 100644 src/misc/mvc/mvcList.c create mode 100644 src/misc/mvc/mvcLits.c create mode 100644 src/misc/mvc/mvcMan.c create mode 100644 src/misc/mvc/mvcOpAlg.c create mode 100644 src/misc/mvc/mvcOpBool.c create mode 100644 src/misc/mvc/mvcPrint.c create mode 100644 src/misc/mvc/mvcSort.c create mode 100644 src/misc/mvc/mvcUtils.c create mode 100644 src/opt/sim/module.make create mode 100644 src/opt/sim/sim.h create mode 100644 src/opt/sim/simMan.c create mode 100644 src/opt/sim/simSat.c create mode 100644 src/opt/sim/simSupp.c create mode 100644 src/opt/sim/simSwitch.c create mode 100644 src/opt/sim/simSym.c create mode 100644 src/opt/sim/simSymSat.c create mode 100644 src/opt/sim/simSymSim.c create mode 100644 src/opt/sim/simSymStr.c create mode 100644 src/opt/sim/simUtils.c delete mode 100644 src/sat/sim/module.make delete mode 100644 src/sat/sim/sim.h delete mode 100644 src/sat/sim/simMan.c delete mode 100644 src/sat/sim/simSat.c delete mode 100644 src/sat/sim/simSupp.c delete mode 100644 src/sat/sim/simSym.c delete mode 100644 src/sat/sim/simUnate.c delete mode 100644 src/sat/sim/simUtils.c delete mode 100644 src/seq/module.make delete mode 100644 src/sop/mvc/module.make delete mode 100644 src/sop/mvc/mvc.c delete mode 100644 src/sop/mvc/mvc.h delete mode 100644 src/sop/mvc/mvcApi.c delete mode 100644 src/sop/mvc/mvcCompare.c delete mode 100644 src/sop/mvc/mvcContain.c delete mode 100644 src/sop/mvc/mvcCover.c delete mode 100644 src/sop/mvc/mvcCube.c delete mode 100644 src/sop/mvc/mvcDivide.c delete mode 100644 src/sop/mvc/mvcDivisor.c delete mode 100644 src/sop/mvc/mvcList.c delete mode 100644 src/sop/mvc/mvcLits.c delete mode 100644 src/sop/mvc/mvcMan.c delete mode 100644 src/sop/mvc/mvcOpAlg.c delete mode 100644 src/sop/mvc/mvcOpBool.c delete mode 100644 src/sop/mvc/mvcPrint.c delete mode 100644 src/sop/mvc/mvcSort.c delete mode 100644 src/sop/mvc/mvcUtils.c diff --git a/Makefile b/Makefile index 615dd359..adb4cf94 100644 --- a/Makefile +++ b/Makefile @@ -6,14 +6,12 @@ CP := cp PROG := abc -MODULES := src/base/abc src/base/cmd src/base/io src/base/main \ +MODULES := src/base/abc src/base/abci src/base/abcs src/base/cmd src/base/io src/base/main \ src/bdd/cudd src/bdd/dsd src/bdd/epd src/bdd/mtr src/bdd/parse src/bdd/reo \ src/map/fpga src/map/mapper src/map/mio src/map/super \ - src/misc/extra src/misc/st src/misc/util src/misc/vec \ - src/opt/cut src/opt/dec src/opt/fxu src/opt/rwr \ - src/sat/asat src/sat/csat src/sat/msat src/sat/fraig src/sat/sim \ - src/seq \ - src/sop/mvc + src/misc/extra src/misc/mvc src/misc/st src/misc/util src/misc/vec \ + src/opt/cut src/opt/dec src/opt/fxu src/opt/rwr src/opt/sim \ + src/sat/asat src/sat/csat src/sat/msat src/sat/fraig default: $(PROG) diff --git a/abc.dsp b/abc.dsp index b9ce40a9..4b72e96d 100644 --- a/abc.dsp +++ b/abc.dsp @@ -42,7 +42,7 @@ RSC=rc.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /W3 /GX /O2 /I "src\base\abc" /I "src\base\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\cut" /I "src\opt\dec" /I "src\opt\fxu" /I "src\opt\rwr" /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\ft" /I "src\sat\asat" /I "src\sat\msat" /I "src\sat\fraig" /I "src\opt\cut" /I "src\opt\dec" /I "src\opt\fxu" /I "src\opt\rwr" /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\mvc" /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\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\cut" /I "src\opt\dec" /I "src\opt\fxu" /I "src\opt\rwr" /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\ft" /I "src\sat\asat" /I "src\sat\msat" /I "src\sat\fraig" /I "src\opt\cut" /I "src\opt\dec" /I "src\opt\fxu" /I "src\opt\rwr" /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\mvc" /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 # SUBTRACT CPP /X # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" @@ -94,171 +94,183 @@ LINK32=link.exe # PROP Default_Filter "" # Begin Source File -SOURCE=.\src\base\abc\abc.c +SOURCE=.\src\base\abc\abc.h # End Source File # Begin Source File -SOURCE=.\src\base\abc\abc.h +SOURCE=.\src\base\abc\abcAig.c # End Source File # Begin Source File -SOURCE=.\src\base\abc\abcAig.c +SOURCE=.\src\base\abc\abcCheck.c # End Source File # Begin Source File -SOURCE=.\src\base\abc\abcAttach.c +SOURCE=.\src\base\abc\abcDfs.c # End Source File # Begin Source File -SOURCE=.\src\base\abc\abcBalance.c +SOURCE=.\src\base\abc\abcFanio.c # End Source File # Begin Source File -SOURCE=.\src\base\abc\abcCheck.c +SOURCE=.\src\base\abc\abcFunc.c # End Source File # Begin Source File -SOURCE=.\src\base\abc\abcCollapse.c +SOURCE=.\src\base\abc\abcInt.h # End Source File # Begin Source File -SOURCE=.\src\base\abc\abcCreate.c +SOURCE=.\src\base\abc\abcLatch.c # End Source File # Begin Source File -SOURCE=.\src\base\abc\abcCut.c +SOURCE=.\src\base\abc\abcMinBase.c # End Source File # Begin Source File -SOURCE=.\src\base\abc\abcDfs.c +SOURCE=.\src\base\abc\abcNames.c # End Source File # Begin Source File -SOURCE=.\src\base\abc\abcDsd.c +SOURCE=.\src\base\abc\abcNetlist.c # End Source File # Begin Source File -SOURCE=.\src\base\abc\abcFanio.c +SOURCE=.\src\base\abc\abcNtk.c # End Source File # Begin Source File -SOURCE=.\src\base\abc\abcFpga.c +SOURCE=.\src\base\abc\abcObj.c # End Source File # Begin Source File -SOURCE=.\src\base\abc\abcFraig.c +SOURCE=.\src\base\abc\abcRefs.c # End Source File # Begin Source File -SOURCE=.\src\base\abc\abcFunc.c +SOURCE=.\src\base\abc\abcShow.c # End Source File # Begin Source File -SOURCE=.\src\base\abc\abcFxu.c +SOURCE=.\src\base\abc\abcSop.c # End Source File # Begin Source File -SOURCE=.\src\base\abc\abcInt.h +SOURCE=.\src\base\abc\abcUtil.c # End Source File +# End Group +# Begin Group "abci" + +# PROP Default_Filter "" # Begin Source File -SOURCE=.\src\base\abc\abcLatch.c +SOURCE=.\src\base\abci\abc.c # End Source File # Begin Source File -SOURCE=.\src\base\abc\abcMap.c +SOURCE=.\src\base\abci\abcAttach.c # End Source File # Begin Source File -SOURCE=.\src\base\abc\abcMinBase.c +SOURCE=.\src\base\abci\abcBalance.c # End Source File # Begin Source File -SOURCE=.\src\base\abc\abcMiter.c +SOURCE=.\src\base\abci\abcCollapse.c # End Source File # Begin Source File -SOURCE=.\src\base\abc\abcNames.c +SOURCE=.\src\base\abci\abcCut.c # End Source File # Begin Source File -SOURCE=.\src\base\abc\abcNetlist.c +SOURCE=.\src\base\abci\abcDsd.c # End Source File # Begin Source File -SOURCE=.\src\base\abc\abcNtbdd.c +SOURCE=.\src\base\abci\abcFpga.c # End Source File # Begin Source File -SOURCE=.\src\base\abc\abcPrint.c +SOURCE=.\src\base\abci\abcFraig.c # End Source File # Begin Source File -SOURCE=.\src\base\abc\abcReconv.c +SOURCE=.\src\base\abci\abcFxu.c # End Source File # Begin Source File -SOURCE=.\src\base\abc\abcRefactor.c +SOURCE=.\src\base\abci\abcMap.c # End Source File # Begin Source File -SOURCE=.\src\base\abc\abcRefs.c +SOURCE=.\src\base\abci\abcMiter.c # End Source File # Begin Source File -SOURCE=.\src\base\abc\abcRenode.c +SOURCE=.\src\base\abci\abcNtbdd.c # End Source File # Begin Source File -SOURCE=.\src\base\abc\abcRewrite.c +SOURCE=.\src\base\abci\abcPrint.c # End Source File # Begin Source File -SOURCE=.\src\base\abc\abcSat.c +SOURCE=.\src\base\abci\abcReconv.c # End Source File # Begin Source File -SOURCE=.\src\base\abc\abcSeq.c +SOURCE=.\src\base\abci\abcRefactor.c # End Source File # Begin Source File -SOURCE=.\src\base\abc\abcSeqRetime.c +SOURCE=.\src\base\abci\abcRenode.c # End Source File # Begin Source File -SOURCE=.\src\base\abc\abcShow.c +SOURCE=.\src\base\abci\abcRewrite.c # End Source File # Begin Source File -SOURCE=.\src\base\abc\abcSop.c +SOURCE=.\src\base\abci\abcSat.c # End Source File # Begin Source File -SOURCE=.\src\base\abc\abcStrash.c +SOURCE=.\src\base\abci\abcStrash.c # End Source File # Begin Source File -SOURCE=.\src\base\abc\abcSweep.c +SOURCE=.\src\base\abci\abcSweep.c # End Source File # Begin Source File -SOURCE=.\src\base\abc\abcSymm.c +SOURCE=.\src\base\abci\abcSymm.c # End Source File # Begin Source File -SOURCE=.\src\base\abc\abcTiming.c +SOURCE=.\src\base\abci\abcTiming.c # End Source File # Begin Source File -SOURCE=.\src\base\abc\abcUnreach.c +SOURCE=.\src\base\abci\abcUnreach.c # End Source File # Begin Source File -SOURCE=.\src\base\abc\abcUtil.c +SOURCE=.\src\base\abci\abcVerify.c +# End Source File +# End Group +# Begin Group "abcs" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\src\base\abcs\abcRetime.c # End Source File # Begin Source File -SOURCE=.\src\base\abc\abcVerify.c +SOURCE=.\src\base\abcs\abcSeq.c # End Source File # End Group # Begin Group "cmd" @@ -790,82 +802,6 @@ SOURCE=.\src\bdd\reo\reoUnits.c # End Source File # End Group # End Group -# Begin Group "sop" - -# PROP Default_Filter "" -# Begin Group "mvc" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=.\src\sop\mvc\mvc.c -# End Source File -# Begin Source File - -SOURCE=.\src\sop\mvc\mvc.h -# End Source File -# Begin Source File - -SOURCE=.\src\sop\mvc\mvcApi.c -# End Source File -# Begin Source File - -SOURCE=.\src\sop\mvc\mvcCompare.c -# End Source File -# Begin Source File - -SOURCE=.\src\sop\mvc\mvcContain.c -# End Source File -# Begin Source File - -SOURCE=.\src\sop\mvc\mvcCover.c -# End Source File -# Begin Source File - -SOURCE=.\src\sop\mvc\mvcCube.c -# End Source File -# Begin Source File - -SOURCE=.\src\sop\mvc\mvcDivide.c -# End Source File -# Begin Source File - -SOURCE=.\src\sop\mvc\mvcDivisor.c -# End Source File -# Begin Source File - -SOURCE=.\src\sop\mvc\mvcList.c -# End Source File -# Begin Source File - -SOURCE=.\src\sop\mvc\mvcLits.c -# End Source File -# Begin Source File - -SOURCE=.\src\sop\mvc\mvcMan.c -# End Source File -# Begin Source File - -SOURCE=.\src\sop\mvc\mvcOpAlg.c -# End Source File -# Begin Source File - -SOURCE=.\src\sop\mvc\mvcOpBool.c -# End Source File -# Begin Source File - -SOURCE=.\src\sop\mvc\mvcPrint.c -# End Source File -# Begin Source File - -SOURCE=.\src\sop\mvc\mvcSort.c -# End Source File -# Begin Source File - -SOURCE=.\src\sop\mvc\mvcUtils.c -# End Source File -# End Group -# End Group # Begin Group "sat" # PROP Default_Filter "" @@ -1013,38 +949,6 @@ SOURCE=.\src\sat\fraig\fraigUtil.c SOURCE=.\src\sat\fraig\fraigVec.c # End Source File # End Group -# Begin Group "sim" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=.\src\sat\sim\sim.h -# End Source File -# Begin Source File - -SOURCE=.\src\sat\sim\simMan.c -# End Source File -# Begin Source File - -SOURCE=.\src\sat\sim\simSat.c -# End Source File -# Begin Source File - -SOURCE=.\src\sat\sim\simSupp.c -# End Source File -# Begin Source File - -SOURCE=.\src\sat\sim\simSym.c -# End Source File -# Begin Source File - -SOURCE=.\src\sat\sim\simUnate.c -# End Source File -# Begin Source File - -SOURCE=.\src\sat\sim\simUtils.c -# End Source File -# End Group # Begin Group "csat" # PROP Default_Filter "" @@ -1225,6 +1129,46 @@ SOURCE=.\src\opt\dec\decPrint.c SOURCE=.\src\opt\dec\decUtil.c # End Source File # End Group +# Begin Group "sim" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\src\opt\sim\sim.h +# End Source File +# Begin Source File + +SOURCE=.\src\opt\sim\simMan.c +# End Source File +# Begin Source File + +SOURCE=.\src\opt\sim\simSat.c +# End Source File +# Begin Source File + +SOURCE=.\src\opt\sim\simSupp.c +# End Source File +# Begin Source File + +SOURCE=.\src\opt\sim\simSwitch.c +# End Source File +# Begin Source File + +SOURCE=.\src\opt\sim\simSym.c +# End Source File +# Begin Source File + +SOURCE=.\src\opt\sim\simSymSim.c +# End Source File +# Begin Source File + +SOURCE=.\src\opt\sim\simSymStr.c +# End Source File +# Begin Source File + +SOURCE=.\src\opt\sim\simUtils.c +# End Source File +# End Group # End Group # Begin Group "map" @@ -1274,6 +1218,10 @@ SOURCE=.\src\map\fpga\fpgaMatch.c # End Source File # Begin Source File +SOURCE=.\src\map\fpga\fpgaSwitch.c +# End Source File +# Begin Source File + SOURCE=.\src\map\fpga\fpgaTime.c # End Source File # Begin Source File @@ -1346,6 +1294,10 @@ SOURCE=.\src\map\mapper\mapperSuper.c # End Source File # Begin Source File +SOURCE=.\src\map\mapper\mapperSwitch.c +# End Source File +# Begin Source File + SOURCE=.\src\map\mapper\mapperTable.c # End Source File # Begin Source File @@ -1430,10 +1382,6 @@ SOURCE=.\src\map\super\superWrite.c # End Source File # End Group # End Group -# Begin Group "seq" - -# PROP Default_Filter "" -# End Group # Begin Group "misc" # PROP Default_Filter "" @@ -1549,6 +1497,78 @@ SOURCE=.\src\misc\util\texpand.c SOURCE=.\src\misc\util\util.h # End Source File # End Group +# Begin Group "mvc" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\src\misc\mvc\mvc.c +# End Source File +# Begin Source File + +SOURCE=.\src\misc\mvc\mvc.h +# End Source File +# Begin Source File + +SOURCE=.\src\misc\mvc\mvcApi.c +# End Source File +# Begin Source File + +SOURCE=.\src\misc\mvc\mvcCompare.c +# End Source File +# Begin Source File + +SOURCE=.\src\misc\mvc\mvcContain.c +# End Source File +# Begin Source File + +SOURCE=.\src\misc\mvc\mvcCover.c +# End Source File +# Begin Source File + +SOURCE=.\src\misc\mvc\mvcCube.c +# End Source File +# Begin Source File + +SOURCE=.\src\misc\mvc\mvcDivide.c +# End Source File +# Begin Source File + +SOURCE=.\src\misc\mvc\mvcDivisor.c +# End Source File +# Begin Source File + +SOURCE=.\src\misc\mvc\mvcList.c +# End Source File +# Begin Source File + +SOURCE=.\src\misc\mvc\mvcLits.c +# End Source File +# Begin Source File + +SOURCE=.\src\misc\mvc\mvcMan.c +# End Source File +# Begin Source File + +SOURCE=.\src\misc\mvc\mvcOpAlg.c +# End Source File +# Begin Source File + +SOURCE=.\src\misc\mvc\mvcOpBool.c +# End Source File +# Begin Source File + +SOURCE=.\src\misc\mvc\mvcPrint.c +# End Source File +# Begin Source File + +SOURCE=.\src\misc\mvc\mvcSort.c +# End Source File +# Begin Source File + +SOURCE=.\src\misc\mvc\mvcUtils.c +# End Source File +# End Group # Begin Group "vec" # PROP Default_Filter "" diff --git a/abc.opt b/abc.opt index ed5428ff..166b5648 100644 Binary files a/abc.opt and b/abc.opt differ diff --git a/abc.plg b/abc.plg index 33826d96..7a5d3adc 100644 --- a/abc.plg +++ b/abc.plg @@ -6,55 +6,302 @@ --------------------Configuration: abc - Win32 Debug--------------------

Command Lines

-Creating temporary file "C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP6D.tmp" with contents +Creating temporary file "C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP643.tmp" with contents [ -/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\cut" /I "src\opt\dec" /I "src\opt\fxu" /I "src\opt\rwr" /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 +/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\ft" /I "src\sat\asat" /I "src\sat\msat" /I "src\sat\fraig" /I "src\opt\cut" /I "src\opt\dec" /I "src\opt\fxu" /I "src\opt\rwr" /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\mvc" /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\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\ioReadEdif.c" +"C:\_projects\abc\src\base\io\ioReadEqn.c" +"C:\_projects\abc\src\base\io\ioReadPla.c" +"C:\_projects\abc\src\base\io\ioReadVerilog.c" +"C:\_projects\abc\src\base\io\ioUtil.c" +"C:\_projects\abc\src\base\io\ioWriteBench.c" +"C:\_projects\abc\src\base\io\ioWriteBlif.c" +"C:\_projects\abc\src\base\io\ioWriteCnf.c" "C:\_projects\abc\src\base\io\ioWriteDot.c" +"C:\_projects\abc\src\base\io\ioWriteEqn.c" +"C:\_projects\abc\src\base\io\ioWriteGml.c" +"C:\_projects\abc\src\base\io\ioWritePla.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\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\sat\csat\csat_apis.c" +"C:\_projects\abc\src\opt\fxu\fxu.c" +"C:\_projects\abc\src\opt\fxu\fxuCreate.c" +"C:\_projects\abc\src\opt\fxu\fxuHeapD.c" +"C:\_projects\abc\src\opt\fxu\fxuHeapS.c" +"C:\_projects\abc\src\opt\fxu\fxuList.c" +"C:\_projects\abc\src\opt\fxu\fxuMatrix.c" +"C:\_projects\abc\src\opt\fxu\fxuPair.c" +"C:\_projects\abc\src\opt\fxu\fxuPrint.c" +"C:\_projects\abc\src\opt\fxu\fxuReduce.c" +"C:\_projects\abc\src\opt\fxu\fxuSelect.c" +"C:\_projects\abc\src\opt\fxu\fxuSingle.c" +"C:\_projects\abc\src\opt\fxu\fxuUpdate.c" +"C:\_projects\abc\src\opt\rwr\rwrDec.c" +"C:\_projects\abc\src\opt\rwr\rwrEva.c" +"C:\_projects\abc\src\opt\rwr\rwrExp.c" +"C:\_projects\abc\src\opt\rwr\rwrLib.c" +"C:\_projects\abc\src\opt\rwr\rwrMan.c" +"C:\_projects\abc\src\opt\rwr\rwrPrint.c" +"C:\_projects\abc\src\opt\rwr\rwrUtil.c" +"C:\_projects\abc\src\opt\cut\cutMan.c" +"C:\_projects\abc\src\opt\cut\cutMerge.c" +"C:\_projects\abc\src\opt\cut\cutNode.c" +"C:\_projects\abc\src\opt\cut\cutSeq.c" +"C:\_projects\abc\src\opt\cut\cutTable.c" +"C:\_projects\abc\src\opt\cut\cutTruth.c" +"C:\_projects\abc\src\opt\dec\decAbc.c" +"C:\_projects\abc\src\opt\dec\decFactor.c" +"C:\_projects\abc\src\opt\dec\decMan.c" +"C:\_projects\abc\src\opt\dec\decPrint.c" +"C:\_projects\abc\src\opt\dec\decUtil.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\extraBddMisc.c" +"C:\_projects\abc\src\misc\extra\extraBddSymm.c" +"C:\_projects\abc\src\misc\extra\extraUtilBitMatrix.c" +"C:\_projects\abc\src\misc\extra\extraUtilCanon.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" +"C:\_projects\abc\src\map\mapper\mapperSwitch.c" +"C:\_projects\abc\src\map\fpga\fpgaSwitch.c" +"C:\_projects\abc\src\base\abc\abcUtil.c" +"C:\_projects\abc\src\base\abc\abcAig.c" +"C:\_projects\abc\src\base\abc\abcCheck.c" +"C:\_projects\abc\src\base\abc\abcDfs.c" +"C:\_projects\abc\src\base\abc\abcFanio.c" +"C:\_projects\abc\src\base\abc\abcFunc.c" +"C:\_projects\abc\src\base\abc\abcLatch.c" +"C:\_projects\abc\src\base\abc\abcMinBase.c" +"C:\_projects\abc\src\base\abc\abcNames.c" +"C:\_projects\abc\src\base\abc\abcNetlist.c" +"C:\_projects\abc\src\base\abc\abcRefs.c" +"C:\_projects\abc\src\base\abc\abcShow.c" +"C:\_projects\abc\src\base\abc\abcSop.c" +"C:\_projects\abc\src\base\abci\abc.c" +"C:\_projects\abc\src\base\abci\abcAttach.c" +"C:\_projects\abc\src\base\abci\abcBalance.c" +"C:\_projects\abc\src\base\abci\abcCollapse.c" +"C:\_projects\abc\src\base\abci\abcCut.c" +"C:\_projects\abc\src\base\abci\abcDsd.c" +"C:\_projects\abc\src\base\abci\abcFpga.c" +"C:\_projects\abc\src\base\abci\abcFraig.c" +"C:\_projects\abc\src\base\abci\abcFxu.c" +"C:\_projects\abc\src\base\abci\abcMap.c" +"C:\_projects\abc\src\base\abci\abcMiter.c" +"C:\_projects\abc\src\base\abci\abcNtbdd.c" +"C:\_projects\abc\src\base\abci\abcPrint.c" +"C:\_projects\abc\src\base\abci\abcReconv.c" +"C:\_projects\abc\src\base\abci\abcRefactor.c" +"C:\_projects\abc\src\base\abci\abcRenode.c" +"C:\_projects\abc\src\base\abci\abcRewrite.c" +"C:\_projects\abc\src\base\abci\abcSat.c" +"C:\_projects\abc\src\base\abci\abcStrash.c" +"C:\_projects\abc\src\base\abci\abcSweep.c" +"C:\_projects\abc\src\base\abci\abcSymm.c" +"C:\_projects\abc\src\base\abci\abcTiming.c" +"C:\_projects\abc\src\base\abci\abcUnreach.c" +"C:\_projects\abc\src\base\abci\abcVerify.c" +"C:\_projects\abc\src\base\abcs\abcSeq.c" +"C:\_projects\abc\src\base\abcs\abcRetime.c" +"C:\_projects\abc\src\base\abc\abcNtk.c" +"C:\_projects\abc\src\base\abc\abcObj.c" +"C:\_projects\abc\src\misc\mvc\mvcUtils.c" +"C:\_projects\abc\src\misc\mvc\mvc.c" +"C:\_projects\abc\src\misc\mvc\mvcApi.c" +"C:\_projects\abc\src\misc\mvc\mvcCompare.c" +"C:\_projects\abc\src\misc\mvc\mvcContain.c" +"C:\_projects\abc\src\misc\mvc\mvcCover.c" +"C:\_projects\abc\src\misc\mvc\mvcCube.c" +"C:\_projects\abc\src\misc\mvc\mvcDivide.c" +"C:\_projects\abc\src\misc\mvc\mvcDivisor.c" +"C:\_projects\abc\src\misc\mvc\mvcList.c" +"C:\_projects\abc\src\misc\mvc\mvcLits.c" +"C:\_projects\abc\src\misc\mvc\mvcMan.c" +"C:\_projects\abc\src\misc\mvc\mvcOpAlg.c" +"C:\_projects\abc\src\misc\mvc\mvcOpBool.c" +"C:\_projects\abc\src\misc\mvc\mvcPrint.c" +"C:\_projects\abc\src\misc\mvc\mvcSort.c" +"C:\_projects\abc\src\opt\sim\simUtils.c" +"C:\_projects\abc\src\opt\sim\simMan.c" +"C:\_projects\abc\src\opt\sim\simSat.c" +"C:\_projects\abc\src\opt\sim\simSupp.c" +"C:\_projects\abc\src\opt\sim\simSwitch.c" +"C:\_projects\abc\src\opt\sim\simSym.c" +"C:\_projects\abc\src\opt\sim\simSymSim.c" +"C:\_projects\abc\src\opt\sim\simSymStr.c" ] -Creating command line "cl.exe @C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP6D.tmp" -Creating temporary file "C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP6E.tmp" with contents +Creating command line "cl.exe @C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP643.tmp" +Creating temporary file "C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP644.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:yes /pdb:"Debug/abc.pdb" /debug /machine:I386 /out:"_TEST/abc.exe" /pdbtype:sept -.\Debug\abc.obj -.\Debug\abcAig.obj -.\Debug\abcAttach.obj -.\Debug\abcBalance.obj -.\Debug\abcCheck.obj -.\Debug\abcCollapse.obj -.\Debug\abcCreate.obj -.\Debug\abcCut.obj -.\Debug\abcDfs.obj -.\Debug\abcDsd.obj -.\Debug\abcFanio.obj -.\Debug\abcFpga.obj -.\Debug\abcFraig.obj -.\Debug\abcFunc.obj -.\Debug\abcFxu.obj -.\Debug\abcLatch.obj -.\Debug\abcMap.obj -.\Debug\abcMinBase.obj -.\Debug\abcMiter.obj -.\Debug\abcNames.obj -.\Debug\abcNetlist.obj -.\Debug\abcNtbdd.obj -.\Debug\abcPrint.obj -.\Debug\abcReconv.obj -.\Debug\abcRefactor.obj -.\Debug\abcRefs.obj -.\Debug\abcRenode.obj -.\Debug\abcRewrite.obj -.\Debug\abcSat.obj -.\Debug\abcSeq.obj -.\Debug\abcSeqRetime.obj -.\Debug\abcShow.obj -.\Debug\abcSop.obj -.\Debug\abcStrash.obj -.\Debug\abcSweep.obj -.\Debug\abcSymm.obj -.\Debug\abcTiming.obj -.\Debug\abcUnreach.obj -.\Debug\abcUtil.obj -.\Debug\abcVerify.obj .\Debug\cmd.obj .\Debug\cmdAlias.obj .\Debug\cmdApi.obj @@ -161,22 +408,6 @@ kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32 .\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\added.obj .\Debug\solver.obj .\Debug\msatActivity.obj @@ -204,12 +435,6 @@ kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32 .\Debug\fraigTable.obj .\Debug\fraigUtil.obj .\Debug\fraigVec.obj -.\Debug\simMan.obj -.\Debug\simSat.obj -.\Debug\simSupp.obj -.\Debug\simSym.obj -.\Debug\simUnate.obj -.\Debug\simUtils.obj .\Debug\csat_apis.obj .\Debug\fxu.obj .\Debug\fxuCreate.obj @@ -298,55 +523,382 @@ kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32 .\Debug\safe_mem.obj .\Debug\strsav.obj .\Debug\texpand.obj +.\Debug\mapperSwitch.obj +.\Debug\fpgaSwitch.obj +.\Debug\abcUtil.obj +.\Debug\abcAig.obj +.\Debug\abcCheck.obj +.\Debug\abcDfs.obj +.\Debug\abcFanio.obj +.\Debug\abcFunc.obj +.\Debug\abcLatch.obj +.\Debug\abcMinBase.obj +.\Debug\abcNames.obj +.\Debug\abcNetlist.obj +.\Debug\abcRefs.obj +.\Debug\abcShow.obj +.\Debug\abcSop.obj +.\Debug\abc.obj +.\Debug\abcAttach.obj +.\Debug\abcBalance.obj +.\Debug\abcCollapse.obj +.\Debug\abcCut.obj +.\Debug\abcDsd.obj +.\Debug\abcFpga.obj +.\Debug\abcFraig.obj +.\Debug\abcFxu.obj +.\Debug\abcMap.obj +.\Debug\abcMiter.obj +.\Debug\abcNtbdd.obj +.\Debug\abcPrint.obj +.\Debug\abcReconv.obj +.\Debug\abcRefactor.obj +.\Debug\abcRenode.obj +.\Debug\abcRewrite.obj +.\Debug\abcSat.obj +.\Debug\abcStrash.obj +.\Debug\abcSweep.obj +.\Debug\abcSymm.obj +.\Debug\abcTiming.obj +.\Debug\abcUnreach.obj +.\Debug\abcVerify.obj +.\Debug\abcSeq.obj +.\Debug\abcRetime.obj +.\Debug\abcNtk.obj +.\Debug\abcObj.obj +.\Debug\mvcUtils.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\simUtils.obj +.\Debug\simMan.obj +.\Debug\simSat.obj +.\Debug\simSupp.obj +.\Debug\simSwitch.obj +.\Debug\simSym.obj +.\Debug\simSymSim.obj +.\Debug\simSymStr.obj ] -Creating command line "link.exe @C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP6E.tmp" +Creating command line "link.exe @C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP644.tmp"

Output Window

Compiling... +cmd.c +cmdAlias.c +cmdApi.c +cmdFlag.c +cmdHist.c +cmdUtils.c +io.c +ioRead.c +ioReadBench.c +ioReadBlif.c +ioReadEdif.c +ioReadEqn.c +ioReadPla.c +ioReadVerilog.c +ioUtil.c +ioWriteBench.c +ioWriteBlif.c +ioWriteCnf.c ioWriteDot.c +ioWriteEqn.c +ioWriteGml.c +ioWritePla.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 +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 +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 +csat_apis.c +fxu.c +fxuCreate.c +fxuHeapD.c +fxuHeapS.c +fxuList.c +fxuMatrix.c +fxuPair.c +fxuPrint.c +fxuReduce.c +fxuSelect.c +fxuSingle.c +fxuUpdate.c +rwrDec.c +rwrEva.c +rwrExp.c +rwrLib.c +rwrMan.c +rwrPrint.c +rwrUtil.c +cutMan.c +cutMerge.c +cutNode.c +cutSeq.c +cutTable.c +cutTruth.c +decAbc.c +decFactor.c +decMan.c +decPrint.c +decUtil.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 +extraBddMisc.c +extraBddSymm.c +extraUtilBitMatrix.c +extraUtilCanon.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 +pathsearch.c +safe_mem.c +strsav.c +texpand.c +mapperSwitch.c +fpgaSwitch.c +abcUtil.c +abcAig.c +abcCheck.c +abcDfs.c +abcFanio.c +abcFunc.c +abcLatch.c +abcMinBase.c +abcNames.c +abcNetlist.c +abcRefs.c +abcShow.c +abcSop.c +abc.c +abcAttach.c +abcBalance.c +abcCollapse.c +abcCut.c +abcDsd.c +abcFpga.c +abcFraig.c +abcFxu.c +abcMap.c +abcMiter.c +abcNtbdd.c +abcPrint.c +abcReconv.c +abcRefactor.c +abcRenode.c +abcRewrite.c +abcSat.c +abcStrash.c +abcSweep.c +abcSymm.c +abcTiming.c +abcUnreach.c +abcVerify.c +abcSeq.c +abcRetime.c +abcNtk.c +abcObj.c +mvcUtils.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 +simUtils.c +simMan.c +simSat.c +simSupp.c +simSwitch.c +simSym.c +simSymSim.c +simSymStr.c Linking... -Creating temporary file "C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP6F.tmp" with contents +Creating temporary file "C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP646.tmp" with contents [ /nologo /o"Debug/abc.bsc" -.\Debug\abc.sbr -.\Debug\abcAig.sbr -.\Debug\abcAttach.sbr -.\Debug\abcBalance.sbr -.\Debug\abcCheck.sbr -.\Debug\abcCollapse.sbr -.\Debug\abcCreate.sbr -.\Debug\abcCut.sbr -.\Debug\abcDfs.sbr -.\Debug\abcDsd.sbr -.\Debug\abcFanio.sbr -.\Debug\abcFpga.sbr -.\Debug\abcFraig.sbr -.\Debug\abcFunc.sbr -.\Debug\abcFxu.sbr -.\Debug\abcLatch.sbr -.\Debug\abcMap.sbr -.\Debug\abcMinBase.sbr -.\Debug\abcMiter.sbr -.\Debug\abcNames.sbr -.\Debug\abcNetlist.sbr -.\Debug\abcNtbdd.sbr -.\Debug\abcPrint.sbr -.\Debug\abcReconv.sbr -.\Debug\abcRefactor.sbr -.\Debug\abcRefs.sbr -.\Debug\abcRenode.sbr -.\Debug\abcRewrite.sbr -.\Debug\abcSat.sbr -.\Debug\abcSeq.sbr -.\Debug\abcSeqRetime.sbr -.\Debug\abcShow.sbr -.\Debug\abcSop.sbr -.\Debug\abcStrash.sbr -.\Debug\abcSweep.sbr -.\Debug\abcSymm.sbr -.\Debug\abcTiming.sbr -.\Debug\abcUnreach.sbr -.\Debug\abcUtil.sbr -.\Debug\abcVerify.sbr .\Debug\cmd.sbr .\Debug\cmdAlias.sbr .\Debug\cmdApi.sbr @@ -453,22 +1005,6 @@ Creating temporary file "C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP6F.tmp" with conten .\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\added.sbr .\Debug\solver.sbr .\Debug\msatActivity.sbr @@ -496,12 +1032,6 @@ Creating temporary file "C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP6F.tmp" with conten .\Debug\fraigTable.sbr .\Debug\fraigUtil.sbr .\Debug\fraigVec.sbr -.\Debug\simMan.sbr -.\Debug\simSat.sbr -.\Debug\simSupp.sbr -.\Debug\simSym.sbr -.\Debug\simUnate.sbr -.\Debug\simUtils.sbr .\Debug\csat_apis.sbr .\Debug\fxu.sbr .\Debug\fxuCreate.sbr @@ -589,15 +1119,82 @@ Creating temporary file "C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP6F.tmp" with conten .\Debug\pathsearch.sbr .\Debug\safe_mem.sbr .\Debug\strsav.sbr -.\Debug\texpand.sbr] -Creating command line "bscmake.exe @C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP6F.tmp" +.\Debug\texpand.sbr +.\Debug\mapperSwitch.sbr +.\Debug\fpgaSwitch.sbr +.\Debug\abcUtil.sbr +.\Debug\abcAig.sbr +.\Debug\abcCheck.sbr +.\Debug\abcDfs.sbr +.\Debug\abcFanio.sbr +.\Debug\abcFunc.sbr +.\Debug\abcLatch.sbr +.\Debug\abcMinBase.sbr +.\Debug\abcNames.sbr +.\Debug\abcNetlist.sbr +.\Debug\abcRefs.sbr +.\Debug\abcShow.sbr +.\Debug\abcSop.sbr +.\Debug\abc.sbr +.\Debug\abcAttach.sbr +.\Debug\abcBalance.sbr +.\Debug\abcCollapse.sbr +.\Debug\abcCut.sbr +.\Debug\abcDsd.sbr +.\Debug\abcFpga.sbr +.\Debug\abcFraig.sbr +.\Debug\abcFxu.sbr +.\Debug\abcMap.sbr +.\Debug\abcMiter.sbr +.\Debug\abcNtbdd.sbr +.\Debug\abcPrint.sbr +.\Debug\abcReconv.sbr +.\Debug\abcRefactor.sbr +.\Debug\abcRenode.sbr +.\Debug\abcRewrite.sbr +.\Debug\abcSat.sbr +.\Debug\abcStrash.sbr +.\Debug\abcSweep.sbr +.\Debug\abcSymm.sbr +.\Debug\abcTiming.sbr +.\Debug\abcUnreach.sbr +.\Debug\abcVerify.sbr +.\Debug\abcSeq.sbr +.\Debug\abcRetime.sbr +.\Debug\abcNtk.sbr +.\Debug\abcObj.sbr +.\Debug\mvcUtils.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\simUtils.sbr +.\Debug\simMan.sbr +.\Debug\simSat.sbr +.\Debug\simSupp.sbr +.\Debug\simSwitch.sbr +.\Debug\simSym.sbr +.\Debug\simSymSim.sbr +.\Debug\simSymStr.sbr] +Creating command line "bscmake.exe @C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP646.tmp" Creating browse info file...

Output Window

Results

-abc.exe - 0 error(s), 0 warning(s) +abc.exe - 0 error(s), 13 warning(s) diff --git a/abc.rc b/abc.rc index fb5b02a1..33fabb21 100644 --- a/abc.rc +++ b/abc.rc @@ -30,6 +30,7 @@ alias sa set autoexec ps alias so source -x alias st strash alias sw sweep +alias t "r dalu.blif; st; psu" alias u undo alias wb write_blif alias wl write_blif diff --git a/src/base/abc/abc.c b/src/base/abc/abc.c deleted file mode 100644 index dca80ca5..00000000 --- a/src/base/abc/abc.c +++ /dev/null @@ -1,3974 +0,0 @@ -/**CFile**************************************************************** - - FileName [abc.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Network and node package.] - - Synopsis [Command file.] - - 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" -#include "mainInt.h" -#include "fraig.h" -#include "fxu.h" -#include "cut.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static int Abc_CommandPrintStats ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandPrintIo ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandPrintLatch ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandPrintFanio ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandPrintFactor ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandPrintLevel ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandPrintSupport ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandPrintSymms ( Abc_Frame_t * pAbc, int argc, char ** argv ); - -static int Abc_CommandShowBdd ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandShowCut ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandShowAig ( Abc_Frame_t * pAbc, int argc, char ** argv ); - -static int Abc_CommandCollapse ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandStrash ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandBalance ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandRenode ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandCleanup ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandSweep ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandFastExtract ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandDisjoint ( Abc_Frame_t * pAbc, int argc, char ** argv ); - -static int Abc_CommandRewrite ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandRefactor ( Abc_Frame_t * pAbc, int argc, char ** argv ); - -static int Abc_CommandLogic ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandMiter ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandFrames ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandSop ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandBdd ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandMuxes ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandSat ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandExtSeqDcs ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandOneOutput ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandOneNode ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandShortNames ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandCut ( Abc_Frame_t * pAbc, int argc, char ** argv ); - -static int Abc_CommandFraig ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandFraigTrust ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandFraigStore ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandFraigRestore ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandFraigClean ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandFraigSweep ( Abc_Frame_t * pAbc, int argc, char ** argv ); - -static int Abc_CommandMap ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandUnmap ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandAttach ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandSuperChoice ( Abc_Frame_t * pAbc, int argc, char ** argv ); - -static int Abc_CommandFpga ( Abc_Frame_t * pAbc, int argc, char ** argv ); - -static int Abc_CommandSeq ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandRetime ( Abc_Frame_t * pAbc, int argc, char ** argv ); - -static int Abc_CommandCec ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandSec ( Abc_Frame_t * pAbc, int argc, char ** argv ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_Init( Abc_Frame_t * pAbc ) -{ - Cmd_CommandAdd( pAbc, "Printing", "print_stats", Abc_CommandPrintStats, 0 ); - Cmd_CommandAdd( pAbc, "Printing", "print_io", Abc_CommandPrintIo, 0 ); - Cmd_CommandAdd( pAbc, "Printing", "print_latch", Abc_CommandPrintLatch, 0 ); - Cmd_CommandAdd( pAbc, "Printing", "print_fanio", Abc_CommandPrintFanio, 0 ); - Cmd_CommandAdd( pAbc, "Printing", "print_factor", Abc_CommandPrintFactor, 0 ); - Cmd_CommandAdd( pAbc, "Printing", "print_level", Abc_CommandPrintLevel, 0 ); - Cmd_CommandAdd( pAbc, "Printing", "print_supp", Abc_CommandPrintSupport, 0 ); - Cmd_CommandAdd( pAbc, "Printing", "print_symm", Abc_CommandPrintSymms, 0 ); - - Cmd_CommandAdd( pAbc, "Printing", "show_bdd", Abc_CommandShowBdd, 0 ); - Cmd_CommandAdd( pAbc, "Printing", "show_cut", Abc_CommandShowCut, 0 ); - Cmd_CommandAdd( pAbc, "Printing", "show_aig", Abc_CommandShowAig, 0 ); - - Cmd_CommandAdd( pAbc, "Synthesis", "collapse", Abc_CommandCollapse, 1 ); - Cmd_CommandAdd( pAbc, "Synthesis", "strash", Abc_CommandStrash, 1 ); - Cmd_CommandAdd( pAbc, "Synthesis", "balance", Abc_CommandBalance, 1 ); - Cmd_CommandAdd( pAbc, "Synthesis", "renode", Abc_CommandRenode, 1 ); - Cmd_CommandAdd( pAbc, "Synthesis", "cleanup", Abc_CommandCleanup, 1 ); - Cmd_CommandAdd( pAbc, "Synthesis", "sweep", Abc_CommandSweep, 1 ); - Cmd_CommandAdd( pAbc, "Synthesis", "fx", Abc_CommandFastExtract, 1 ); - Cmd_CommandAdd( pAbc, "Synthesis", "dsd", Abc_CommandDisjoint, 1 ); - - Cmd_CommandAdd( pAbc, "Synthesis", "rewrite", Abc_CommandRewrite, 1 ); - Cmd_CommandAdd( pAbc, "Synthesis", "refactor", Abc_CommandRefactor, 1 ); - - Cmd_CommandAdd( pAbc, "Various", "logic", Abc_CommandLogic, 1 ); - Cmd_CommandAdd( pAbc, "Various", "miter", Abc_CommandMiter, 1 ); - Cmd_CommandAdd( pAbc, "Various", "frames", Abc_CommandFrames, 1 ); - Cmd_CommandAdd( pAbc, "Various", "sop", Abc_CommandSop, 0 ); - Cmd_CommandAdd( pAbc, "Various", "bdd", Abc_CommandBdd, 0 ); - Cmd_CommandAdd( pAbc, "Various", "muxes", Abc_CommandMuxes, 1 ); - Cmd_CommandAdd( pAbc, "Various", "sat", Abc_CommandSat, 0 ); - Cmd_CommandAdd( pAbc, "Various", "ext_seq_dcs", Abc_CommandExtSeqDcs, 0 ); - Cmd_CommandAdd( pAbc, "Various", "one_output", Abc_CommandOneOutput, 1 ); - Cmd_CommandAdd( pAbc, "Various", "one_node", Abc_CommandOneNode, 1 ); - Cmd_CommandAdd( pAbc, "Various", "short_names", Abc_CommandShortNames, 0 ); - Cmd_CommandAdd( pAbc, "Various", "cut", Abc_CommandCut, 0 ); - - Cmd_CommandAdd( pAbc, "Fraiging", "fraig", Abc_CommandFraig, 1 ); - Cmd_CommandAdd( pAbc, "Fraiging", "fraig_trust", Abc_CommandFraigTrust, 1 ); - Cmd_CommandAdd( pAbc, "Fraiging", "fraig_store", Abc_CommandFraigStore, 0 ); - Cmd_CommandAdd( pAbc, "Fraiging", "fraig_restore", Abc_CommandFraigRestore, 1 ); - Cmd_CommandAdd( pAbc, "Fraiging", "fraig_clean", Abc_CommandFraigClean, 0 ); - Cmd_CommandAdd( pAbc, "Fraiging", "fraig_sweep", Abc_CommandFraigSweep, 1 ); - - Cmd_CommandAdd( pAbc, "SC mapping", "map", Abc_CommandMap, 1 ); - Cmd_CommandAdd( pAbc, "SC mapping", "unmap", Abc_CommandUnmap, 1 ); - Cmd_CommandAdd( pAbc, "SC mapping", "attach", Abc_CommandAttach, 1 ); - Cmd_CommandAdd( pAbc, "SC mapping", "sc", Abc_CommandSuperChoice, 1 ); - - Cmd_CommandAdd( pAbc, "FPGA mapping", "fpga", Abc_CommandFpga, 1 ); - - Cmd_CommandAdd( pAbc, "Sequential", "seq", Abc_CommandSeq, 1 ); - Cmd_CommandAdd( pAbc, "Sequential", "retime", Abc_CommandRetime, 1 ); - - Cmd_CommandAdd( pAbc, "Verification", "cec", Abc_CommandCec, 0 ); - Cmd_CommandAdd( pAbc, "Verification", "sec", Abc_CommandSec, 0 ); - -// Rwt_Man4ExploreStart(); -// Map_Var3Print(); -// Map_Var4Test(); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_End() -{ - Abc_NtkFraigStoreClean(); -// Rwt_Man4ExplorePrint(); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_CommandPrintStats( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - FILE * pOut, * pErr; - Abc_Ntk_t * pNtk; - bool fShort; - int c; - int fFactor; - - pNtk = Abc_FrameReadNet(pAbc); - pOut = Abc_FrameReadOut(pAbc); - pErr = Abc_FrameReadErr(pAbc); - - // set the defaults - fShort = 1; - fFactor = 0; - util_getopt_reset(); - while ( ( c = util_getopt( argc, argv, "sfh" ) ) != EOF ) - { - switch ( c ) - { - case 's': - fShort ^= 1; - break; - case 'f': - fFactor ^= 1; - break; - case 'h': - goto usage; - default: - goto usage; - } - } - - if ( pNtk == NULL ) - { - fprintf( Abc_FrameReadErr(pAbc), "Empty network\n" ); - return 1; - } - Abc_NtkPrintStats( pOut, pNtk, fFactor ); - return 0; - -usage: - fprintf( pErr, "usage: print_stats [-fh]\n" ); - fprintf( pErr, "\t prints the network statistics and\n" ); - fprintf( pErr, "\t-f : toggles printing the literal count in the factored forms [default = %s]\n", fFactor? "yes": "no" ); - fprintf( pErr, "\t-h : print the command usage\n"); - return 1; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_CommandPrintIo( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - FILE * pOut, * pErr; - Abc_Ntk_t * pNtk; - Abc_Obj_t * pNode; - int c; - - 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 ( argc > util_optind + 1 ) - { - fprintf( pErr, "Wrong number of auguments.\n" ); - goto usage; - } - - if ( argc == util_optind + 1 ) - { - pNode = Abc_NtkFindNode( pNtk, argv[util_optind] ); - if ( pNode == NULL ) - { - fprintf( pErr, "Cannot find node \"%s\".\n", argv[util_optind] ); - return 1; - } - Abc_NodePrintFanio( pOut, pNode ); - return 0; - } - // print the nodes - Abc_NtkPrintIo( pOut, pNtk ); - return 0; - -usage: - fprintf( pErr, "usage: print_io [-h] \n" ); - fprintf( pErr, "\t prints the PIs/POs or fanins/fanouts of a node\n" ); - fprintf( pErr, "\t-h : print the command usage\n"); - fprintf( pErr, "\tnode : the node to print fanins/fanouts\n"); - return 1; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_CommandPrintLatch( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - FILE * pOut, * pErr; - Abc_Ntk_t * pNtk; - int c; - - 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; - } - // print the nodes - Abc_NtkPrintLatch( pOut, pNtk ); - return 0; - -usage: - fprintf( pErr, "usage: print_latch [-h]\n" ); - fprintf( pErr, "\t prints information about latches\n" ); - fprintf( pErr, "\t-h : print the command usage\n"); - return 1; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_CommandPrintFanio( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - FILE * pOut, * pErr; - Abc_Ntk_t * pNtk; - int c; - - 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; - } - - // print the nodes - Abc_NtkPrintFanio( pOut, pNtk ); - return 0; - -usage: - fprintf( pErr, "usage: print_fanio [-h]\n" ); - fprintf( pErr, "\t prints the statistics about fanins/fanouts of all nodes\n" ); - fprintf( pErr, "\t-h : print the command usage\n"); - return 1; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_CommandPrintFactor( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - FILE * pOut, * pErr; - Abc_Ntk_t * pNtk; - Abc_Obj_t * pNode; - int c; - int fUseRealNames; - - pNtk = Abc_FrameReadNet(pAbc); - pOut = Abc_FrameReadOut(pAbc); - pErr = Abc_FrameReadErr(pAbc); - - // set defaults - fUseRealNames = 1; - util_getopt_reset(); - while ( ( c = util_getopt( argc, argv, "nh" ) ) != EOF ) - { - switch ( c ) - { - case 'n': - fUseRealNames ^= 1; - break; - case 'h': - goto usage; - default: - goto usage; - } - } - - if ( pNtk == NULL ) - { - fprintf( pErr, "Empty network.\n" ); - return 1; - } - - if ( !Abc_NtkIsSopLogic(pNtk) ) - { - fprintf( pErr, "Printing factored forms can be done for SOP networks.\n" ); - return 1; - } - - if ( argc > util_optind + 1 ) - { - fprintf( pErr, "Wrong number of auguments.\n" ); - goto usage; - } - - if ( argc == util_optind + 1 ) - { - pNode = Abc_NtkFindNode( pNtk, argv[util_optind] ); - if ( pNode == NULL ) - { - fprintf( pErr, "Cannot find node \"%s\".\n", argv[util_optind] ); - return 1; - } - Abc_NodePrintFactor( pOut, pNode, fUseRealNames ); - return 0; - } - // print the nodes - Abc_NtkPrintFactor( pOut, pNtk, fUseRealNames ); - return 0; - -usage: - fprintf( pErr, "usage: print_factor [-nh] \n" ); - fprintf( pErr, "\t prints the factored forms of nodes\n" ); - fprintf( pErr, "\t-n : toggles real/dummy fanin names [default = %s]\n", fUseRealNames? "real": "dummy" ); - fprintf( pErr, "\t-h : print the command usage\n"); - fprintf( pErr, "\tnode : (optional) one node to consider\n"); - return 1; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_CommandPrintLevel( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - FILE * pOut, * pErr; - Abc_Ntk_t * pNtk; - Abc_Obj_t * pNode; - int c; - int fProfile; - - pNtk = Abc_FrameReadNet(pAbc); - pOut = Abc_FrameReadOut(pAbc); - pErr = Abc_FrameReadErr(pAbc); - - // set defaults - fProfile = 1; - util_getopt_reset(); - while ( ( c = util_getopt( argc, argv, "ph" ) ) != EOF ) - { - switch ( c ) - { - case 'p': - fProfile ^= 1; - break; - case 'h': - goto usage; - default: - goto usage; - } - } - - if ( pNtk == NULL ) - { - fprintf( pErr, "Empty network.\n" ); - return 1; - } - - if ( !fProfile && !Abc_NtkIsStrash(pNtk) ) - { - fprintf( pErr, "This command works only for AIGs.\n" ); - return 1; - } - - if ( argc > util_optind + 1 ) - { - fprintf( pErr, "Wrong number of auguments.\n" ); - goto usage; - } - - if ( argc == util_optind + 1 ) - { - pNode = Abc_NtkFindNode( pNtk, argv[util_optind] ); - if ( pNode == NULL ) - { - fprintf( pErr, "Cannot find node \"%s\".\n", argv[util_optind] ); - return 1; - } - Abc_NodePrintLevel( pOut, pNode ); - return 0; - } - // process all COs - Abc_NtkPrintLevel( pOut, pNtk, fProfile ); - return 0; - -usage: - fprintf( pErr, "usage: print_level [-ph] \n" ); - fprintf( pErr, "\t prints information about node level and cone size\n" ); - fprintf( pErr, "\t-p : toggles printing level profile [default = %s]\n", fProfile? "yes": "no" ); - fprintf( pErr, "\t-h : print the command usage\n"); - fprintf( pErr, "\tnode : (optional) one node to consider\n"); - return 1; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_CommandPrintSupport( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - FILE * pOut, * pErr; - Abc_Ntk_t * pNtk; - int c; - extern void * Sim_ComputeSupp( 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_NtkIsStrash(pNtk) ) - { - fprintf( pErr, "This command works only for AIGs.\n" ); - return 1; - } - Sim_ComputeSupp( pNtk ); - return 0; - -usage: - fprintf( pErr, "usage: print_supp [-h]\n" ); - fprintf( pErr, "\t prints the supports of the CO nodes\n" ); - fprintf( pErr, "\t-h : print the command usage\n"); - return 1; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_CommandPrintSymms( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - FILE * pOut, * pErr; - Abc_Ntk_t * pNtk; - int c; - int fUseBdds; - int fNaive; - int fVerbose; - extern void Abc_NtkSymmetries( Abc_Ntk_t * pNtk, int fUseBdds, int fNaive, int fVerbose ); - - pNtk = Abc_FrameReadNet(pAbc); - pOut = Abc_FrameReadOut(pAbc); - pErr = Abc_FrameReadErr(pAbc); - - // set defaults - fUseBdds = 1; - fNaive = 0; - fVerbose = 0; - util_getopt_reset(); - while ( ( c = util_getopt( argc, argv, "bnvh" ) ) != EOF ) - { - switch ( c ) - { - case 'b': - fUseBdds ^= 1; - break; - case 'n': - fNaive ^= 1; - break; - case 'v': - fVerbose ^= 1; - break; - case 'h': - goto usage; - default: - goto usage; - } - } - if ( pNtk == NULL ) - { - fprintf( pErr, "Empty network.\n" ); - return 1; - } - if ( !Abc_NtkIsStrash(pNtk) ) - { - fprintf( pErr, "This command works only for AIGs.\n" ); - return 1; - } - Abc_NtkSymmetries( pNtk, fUseBdds, fNaive, fVerbose ); - return 0; - -usage: - fprintf( pErr, "usage: print_symm [-nbvh]\n" ); - fprintf( pErr, "\t computes symmetries of the PO functions\n" ); - fprintf( pErr, "\t-b : enable efficient BDD-based computation [default = %s].\n", fUseBdds? "yes": "no" ); - fprintf( pErr, "\t-n : enable naive BDD-based computation [default = %s].\n", fNaive? "yes": "no" ); - fprintf( pErr, "\t-v : enable verbose output [default = %s].\n", fVerbose? "yes": "no" ); - fprintf( pErr, "\t-h : print the command usage\n"); - return 1; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_CommandShowBdd( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - FILE * pOut, * pErr; - Abc_Ntk_t * pNtk; - Abc_Obj_t * pNode; - int c; - extern void Abc_NodeShowBdd( Abc_Obj_t * pNode ); - - 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_NtkIsBddLogic(pNtk) ) - { - fprintf( pErr, "Visualizing BDDs can only be done for logic BDD networks.\n" ); - return 1; - } - - if ( argc != util_optind + 1 ) - { - fprintf( pErr, "Wrong number of auguments.\n" ); - goto usage; - } - - pNode = Abc_NtkFindNode( pNtk, argv[util_optind] ); - if ( pNode == NULL ) - { - fprintf( pErr, "Cannot find node \"%s\".\n", argv[util_optind] ); - return 1; - } - Abc_NodeShowBdd( pNode ); - return 0; - -usage: - fprintf( pErr, "usage: show_bdd [-h] \n" ); - fprintf( pErr, " visualizes the BDD of a node using DOT and GSVIEW\n" ); -#ifdef WIN32 - fprintf( pErr, " \"dot.exe\" and \"gsview32.exe\" should be set in the paths\n" ); - fprintf( pErr, " (\"gsview32.exe\" may be in \"C:\\Program Files\\Ghostgum\\gsview\\\")\n" ); -#endif - fprintf( pErr, "\tnode : the node to consider\n"); - fprintf( pErr, "\t-h : print the command usage\n"); - return 1; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_CommandShowCut( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - FILE * pOut, * pErr; - Abc_Ntk_t * pNtk; - Abc_Obj_t * pNode; - int c; - int nNodeSizeMax; - int nConeSizeMax; - extern void Abc_NodeShowCut( Abc_Obj_t * pNode, int nNodeSizeMax, int nConeSizeMax ); - - pNtk = Abc_FrameReadNet(pAbc); - pOut = Abc_FrameReadOut(pAbc); - pErr = Abc_FrameReadErr(pAbc); - - // set defaults - nNodeSizeMax = 10; - nConeSizeMax = ABC_INFINITY; - util_getopt_reset(); - while ( ( c = util_getopt( argc, argv, "NCh" ) ) != EOF ) - { - switch ( c ) - { - case 'N': - if ( util_optind >= argc ) - { - fprintf( pErr, "Command line switch \"-N\" should be followed by an integer.\n" ); - goto usage; - } - nNodeSizeMax = atoi(argv[util_optind]); - util_optind++; - if ( nNodeSizeMax < 0 ) - goto usage; - break; - case 'C': - if ( util_optind >= argc ) - { - fprintf( pErr, "Command line switch \"-C\" should be followed by an integer.\n" ); - goto usage; - } - nConeSizeMax = atoi(argv[util_optind]); - util_optind++; - if ( nConeSizeMax < 0 ) - goto usage; - break; - case 'h': - goto usage; - default: - goto usage; - } - } - - if ( pNtk == NULL ) - { - fprintf( pErr, "Empty network.\n" ); - return 1; - } - - if ( !Abc_NtkIsStrash(pNtk) ) - { - fprintf( pErr, "Visualizing cuts only works for AIGs.\n" ); - return 1; - } - if ( argc != util_optind + 1 ) - { - fprintf( pErr, "Wrong number of auguments.\n" ); - goto usage; - } - - pNode = Abc_NtkFindNode( pNtk, argv[util_optind] ); - if ( pNode == NULL ) - { - fprintf( pErr, "Cannot find node \"%s\".\n", argv[util_optind] ); - return 1; - } - Abc_NodeShowCut( pNode, nNodeSizeMax, nConeSizeMax ); - return 0; - -usage: - fprintf( pErr, "usage: show_cut [-N num] [-C num] [-h] \n" ); - fprintf( pErr, " visualizes the cut of a node using DOT and GSVIEW\n" ); -#ifdef WIN32 - fprintf( pErr, " \"dot.exe\" and \"gsview32.exe\" should be set in the paths\n" ); - fprintf( pErr, " (\"gsview32.exe\" may be in \"C:\\Program Files\\Ghostgum\\gsview\\\")\n" ); -#endif - fprintf( pErr, "\t-N num : the max size of the cut to be computed [default = %d]\n", nNodeSizeMax ); - fprintf( pErr, "\t-C num : the max support of the containing cone [default = %d]\n", nConeSizeMax ); - fprintf( pErr, "\tnode : the node to consider\n"); - fprintf( pErr, "\t-h : print the command usage\n"); - return 1; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_CommandShowAig( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - FILE * pOut, * pErr; - Abc_Ntk_t * pNtk; - int c; - extern void Abc_NtkShowAig( 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_NtkIsStrash(pNtk) ) - { - fprintf( pErr, "Visualizing AIG can only be done for AIGs.\n" ); - return 1; - } - Abc_NtkShowAig( pNtk ); - return 0; - -usage: - fprintf( pErr, "usage: show_aig [-h]\n" ); - fprintf( pErr, " visualizes the AIG with choices using DOT and GSVIEW\n" ); -#ifdef WIN32 - fprintf( pErr, " \"dot.exe\" and \"gsview32.exe\" should be set in the paths\n" ); - fprintf( pErr, " (\"gsview32.exe\" may be in \"C:\\Program Files\\Ghostgum\\gsview\\\")\n" ); -#endif - fprintf( pErr, "\t-h : print the command usage\n"); - return 1; -} - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_CommandCollapse( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - FILE * pOut, * pErr; - Abc_Ntk_t * pNtk, * pNtkRes; - int c; - - 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_NtkIsLogic(pNtk) && !Abc_NtkIsStrash(pNtk) ) - { - fprintf( pErr, "Can only collapse a logic network.\n" ); - return 1; - } - - // get the new network - if ( Abc_NtkIsStrash(pNtk) ) - pNtkRes = Abc_NtkCollapse( pNtk, 1 ); - else - { - pNtk = Abc_NtkStrash( pNtk, 0, 0 ); - pNtkRes = Abc_NtkCollapse( pNtk, 1 ); - Abc_NtkDelete( pNtk ); - } - if ( pNtkRes == NULL ) - { - fprintf( pErr, "Collapsing has failed.\n" ); - return 1; - } - // replace the current network - Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); - return 0; - -usage: - fprintf( pErr, "usage: collapse [-h]\n" ); - fprintf( pErr, "\t collapses the network by constructing global BDDs\n" ); - fprintf( pErr, "\t-h : print the command usage\n"); - return 1; -} - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_CommandStrash( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - FILE * pOut, * pErr; - Abc_Ntk_t * pNtk, * pNtkRes; - int c; - int fAllNodes; - int fCleanup; - - pNtk = Abc_FrameReadNet(pAbc); - pOut = Abc_FrameReadOut(pAbc); - pErr = Abc_FrameReadErr(pAbc); - - // set defaults - fAllNodes = 0; - fCleanup = 1; - util_getopt_reset(); - while ( ( c = util_getopt( argc, argv, "ach" ) ) != EOF ) - { - switch ( c ) - { - case 'a': - fAllNodes ^= 1; - break; - case 'c': - fCleanup ^= 1; - break; - case 'h': - goto usage; - default: - goto usage; - } - } - - if ( pNtk == NULL ) - { - fprintf( pErr, "Empty network.\n" ); - return 1; - } - - // get the new network - pNtkRes = Abc_NtkStrash( pNtk, fAllNodes, fCleanup ); - if ( pNtkRes == NULL ) - { - fprintf( pErr, "Strashing has failed.\n" ); - return 1; - } - // replace the current network - Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); - return 0; - -usage: - fprintf( pErr, "usage: strash [-ach]\n" ); - fprintf( pErr, "\t transforms combinational logic into an AIG\n" ); - fprintf( pErr, "\t-a : toggles between using all nodes and DFS nodes [default = %s]\n", fAllNodes? "all": "DFS" ); - fprintf( pErr, "\t-c : toggles cleanup to remove the dagling AIG nodes [default = %s]\n", fCleanup? "all": "DFS" ); - fprintf( pErr, "\t-h : print the command usage\n"); - return 1; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_CommandBalance( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - FILE * pOut, * pErr; - Abc_Ntk_t * pNtk, * pNtkRes, * pNtkTemp; - int c; - int fDuplicate; - - pNtk = Abc_FrameReadNet(pAbc); - pOut = Abc_FrameReadOut(pAbc); - pErr = Abc_FrameReadErr(pAbc); - - // set defaults - fDuplicate = 0; - util_getopt_reset(); - while ( ( c = util_getopt( argc, argv, "dh" ) ) != EOF ) - { - switch ( c ) - { - case 'd': - fDuplicate ^= 1; - break; - case 'h': - goto usage; - default: - goto usage; - } - } - - if ( pNtk == NULL ) - { - fprintf( pErr, "Empty network.\n" ); - return 1; - } - - // get the new network - if ( Abc_NtkIsStrash(pNtk) ) - { - pNtkRes = Abc_NtkBalance( pNtk, fDuplicate ); - } - else - { - pNtkTemp = Abc_NtkStrash( pNtk, 0, 0 ); - if ( pNtkTemp == NULL ) - { - fprintf( pErr, "Strashing before balancing has failed.\n" ); - return 1; - } - pNtkRes = Abc_NtkBalance( pNtkTemp, fDuplicate ); - Abc_NtkDelete( pNtkTemp ); - } - - // check if balancing worked - if ( pNtkRes == NULL ) - { - fprintf( pErr, "Balancing has failed.\n" ); - return 1; - } - // replace the current network - Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); - return 0; - -usage: - fprintf( pErr, "usage: balance [-dh]\n" ); - fprintf( pErr, "\t transforms the current network into a well-balanced AIG\n" ); - fprintf( pErr, "\t-d : toggle duplication of logic [default = %s]\n", fDuplicate? "yes": "no" ); - fprintf( pErr, "\t-h : print the command usage\n"); - return 1; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_CommandRenode( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - FILE * pOut, * pErr; - Abc_Ntk_t * pNtk, * pNtkRes; - int nThresh, nFaninMax, c; - int fCnf; - int fMulti; - int fSimple; - - pNtk = Abc_FrameReadNet(pAbc); - pOut = Abc_FrameReadOut(pAbc); - pErr = Abc_FrameReadErr(pAbc); - - // set defaults - nThresh = 1; - nFaninMax = 20; - fCnf = 0; - fMulti = 0; - fSimple = 0; - util_getopt_reset(); - while ( ( c = util_getopt( argc, argv, "TFmcsh" ) ) != EOF ) - { - switch ( c ) - { - case 'T': - if ( util_optind >= argc ) - { - fprintf( pErr, "Command line switch \"-T\" should be followed by an integer.\n" ); - goto usage; - } - nThresh = atoi(argv[util_optind]); - util_optind++; - if ( nThresh < 0 ) - goto usage; - break; - case 'F': - if ( util_optind >= argc ) - { - fprintf( pErr, "Command line switch \"-F\" should be followed by an integer.\n" ); - goto usage; - } - nFaninMax = atoi(argv[util_optind]); - util_optind++; - if ( nFaninMax < 0 ) - goto usage; - break; - case 'c': - fCnf ^= 1; - break; - case 'm': - fMulti ^= 1; - break; - case 's': - fSimple ^= 1; - break; - case 'h': - goto usage; - default: - goto usage; - } - } - - if ( pNtk == NULL ) - { - fprintf( pErr, "Empty network.\n" ); - return 1; - } - if ( !Abc_NtkIsStrash(pNtk) ) - { - fprintf( pErr, "Cannot renode a network that is not an AIG.\n" ); - return 1; - } - - // get the new network - pNtkRes = Abc_NtkRenode( pNtk, nThresh, nFaninMax, fCnf, fMulti, fSimple ); - if ( pNtkRes == NULL ) - { - fprintf( pErr, "Renoding has failed.\n" ); - return 1; - } - // replace the current network - Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); - return 0; - -usage: - fprintf( pErr, "usage: renode [-T num] [-F num] [-cmsh]\n" ); - fprintf( pErr, "\t transforms an AIG into a logic network by creating larger nodes\n" ); - fprintf( pErr, "\t-F num : the maximum fanin size after renoding [default = %d]\n", nFaninMax ); - fprintf( pErr, "\t-T num : the threshold for AIG node duplication [default = %d]\n", nThresh ); - fprintf( pErr, "\t (an AIG node is the root of a new node after renoding\n" ); - fprintf( pErr, "\t if doing so prevents duplication of more than %d AIG nodes,\n", nThresh ); - fprintf( pErr, "\t that is, if [(numFanouts(Node)-1) * size(MFFC(Node))] > %d)\n", nThresh ); - fprintf( pErr, "\t-m : creates multi-input AND graph [default = %s]\n", fMulti? "yes": "no" ); - fprintf( pErr, "\t-s : creates a simple AIG (no renoding) [default = %s]\n", fSimple? "yes": "no" ); - fprintf( pErr, "\t-c : performs renoding to derive the CNF [default = %s]\n", fCnf? "yes": "no" ); - fprintf( pErr, "\t-h : print the command usage\n"); - return 1; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_CommandCleanup( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - FILE * pOut, * pErr; - Abc_Ntk_t * pNtk; - int c; - - 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_NtkIsStrash(pNtk) ) - { - fprintf( pErr, "Cleanup cannot be performed on the AIG.\n" ); - return 1; - } - // modify the current network - Abc_NtkCleanup( pNtk, 0 ); - return 0; - -usage: - fprintf( pErr, "usage: cleanup [-h]\n" ); - fprintf( pErr, "\t removes dangling nodes\n" ); - fprintf( pErr, "\t-h : print the command usage\n"); - return 1; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_CommandSweep( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - FILE * pOut, * pErr; - Abc_Ntk_t * pNtk; - int c; - - 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_NtkIsSopLogic(pNtk) && !Abc_NtkIsBddLogic(pNtk) ) - { - fprintf( pErr, "Sweep cannot be performed on an AIG or a mapped network (unmap it first).\n" ); - return 1; - } - // modify the current network - Abc_NtkSweep( pNtk, 0 ); - return 0; - -usage: - fprintf( pErr, "usage: sweep [-h]\n" ); - fprintf( pErr, "\t removes dangling nodes; propagates constant, buffers, inverters\n" ); - fprintf( pErr, "\t-h : print the command usage\n"); - return 1; -} - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_CommandFastExtract( 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; - } - - if ( !Abc_NtkIsLogic(pNtk) ) - { - fprintf( pErr, "Fast extract can only be applied to a logic network.\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 [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_CommandDisjoint( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - FILE * pOut, * pErr; - Abc_Ntk_t * pNtk, * pNtkRes, * pNtkNew; - int fGlobal, fRecursive, fVerbose, fPrint, fShort, c; - - extern Abc_Ntk_t * Abc_NtkDsdGlobal( Abc_Ntk_t * pNtk, bool fVerbose, bool fPrint, bool fShort ); - extern int Abc_NtkDsdLocal( Abc_Ntk_t * pNtk, bool fVerbose, bool fRecursive ); - - pNtk = Abc_FrameReadNet(pAbc); - pOut = Abc_FrameReadOut(pAbc); - pErr = Abc_FrameReadErr(pAbc); - - // set defaults - fGlobal = 1; - fRecursive = 0; - fVerbose = 0; - fPrint = 0; - fShort = 0; - util_getopt_reset(); - while ( ( c = util_getopt( argc, argv, "grvpsh" ) ) != EOF ) - { - switch ( c ) - { - case 'g': - fGlobal ^= 1; - break; - case 'r': - fRecursive ^= 1; - break; - case 'v': - fVerbose ^= 1; - break; - case 'p': - fPrint ^= 1; - break; - case 's': - fShort ^= 1; - break; - case 'h': - goto usage; - break; - default: - goto usage; - } - } - - if ( pNtk == NULL ) - { - fprintf( pErr, "Empty network.\n" ); - return 1; - } - - if ( fGlobal ) - { -// fprintf( stdout, "Performing DSD of global functions of the network.\n" ); - // get the new network - if ( !Abc_NtkIsStrash(pNtk) ) - { - pNtkNew = Abc_NtkStrash( pNtk, 0, 0 ); - pNtkRes = Abc_NtkDsdGlobal( pNtkNew, fVerbose, fPrint, fShort ); - Abc_NtkDelete( pNtkNew ); - } - else - { - pNtkRes = Abc_NtkDsdGlobal( pNtk, fVerbose, fPrint, fShort ); - } - if ( pNtkRes == NULL ) - { - fprintf( pErr, "Global DSD has failed.\n" ); - return 1; - } - // replace the current network - Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); - } - else if ( fRecursive ) - { - if ( !Abc_NtkIsBddLogic( pNtk ) ) - { - fprintf( pErr, "This command is only applicable to logic BDD networks.\n" ); - return 1; - } - fprintf( stdout, "Performing recursive DSD and MUX decomposition of local functions.\n" ); - if ( !Abc_NtkDsdLocal( pNtk, fVerbose, fRecursive ) ) - fprintf( pErr, "Recursive DSD has failed.\n" ); - } - else - { - if ( !Abc_NtkIsBddLogic( pNtk ) ) - { - fprintf( pErr, "This command is only applicable to logic BDD networks.\n" ); - return 1; - } - fprintf( stdout, "Performing simple non-recursive DSD of local functions.\n" ); - if ( !Abc_NtkDsdLocal( pNtk, fVerbose, fRecursive ) ) - fprintf( pErr, "Simple DSD of local functions has failed.\n" ); - } - return 0; - -usage: - fprintf( pErr, "usage: dsd [-grvpsh]\n" ); - fprintf( pErr, "\t decomposes the network using disjoint-support decomposition\n" ); - fprintf( pErr, "\t-g : toggle DSD of global and local functions [default = %s]\n", fGlobal? "global": "local" ); - fprintf( pErr, "\t-r : toggle recursive DSD/MUX and simple DSD [default = %s]\n", fRecursive? "recursive DSD/MUX": "simple DSD" ); - fprintf( pErr, "\t-v : prints DSD statistics and runtime [default = %s]\n", fVerbose? "yes": "no" ); - fprintf( pErr, "\t-p : prints DSD structure to the standard output [default = %s]\n", fPrint? "yes": "no" ); - fprintf( pErr, "\t-s : use short PI names when printing DSD structure [default = %s]\n", fShort? "yes": "no" ); - fprintf( pErr, "\t-h : print the command usage\n"); - return 1; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_CommandRewrite( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - FILE * pOut, * pErr; - Abc_Ntk_t * pNtk; - int c; - bool fPrecompute; - bool fUseZeros; - bool fVerbose; - // external functions - extern void Rwr_Precompute(); - extern int Abc_NtkRewrite( Abc_Ntk_t * pNtk, int fUseZeros, int fVerbose ); - - pNtk = Abc_FrameReadNet(pAbc); - pOut = Abc_FrameReadOut(pAbc); - pErr = Abc_FrameReadErr(pAbc); - - // set defaults - fPrecompute = 0; - fUseZeros = 0; - fVerbose = 0; - util_getopt_reset(); - while ( ( c = util_getopt( argc, argv, "xzvh" ) ) != EOF ) - { - switch ( c ) - { - case 'x': - fPrecompute ^= 1; - break; - case 'z': - fUseZeros ^= 1; - break; - case 'v': - fVerbose ^= 1; - break; - case 'h': - goto usage; - default: - goto usage; - } - } - - if ( fPrecompute ) - { - Rwr_Precompute(); - return 0; - } - - if ( pNtk == NULL ) - { - fprintf( pErr, "Empty network.\n" ); - return 1; - } - if ( !Abc_NtkIsStrash(pNtk) ) - { - fprintf( pErr, "This command can only be applied to an AIG.\n" ); - return 1; - } - if ( Abc_NtkGetChoiceNum(pNtk) ) - { - fprintf( pErr, "AIG resynthesis cannot be applied to AIGs with choice nodes.\n" ); - return 1; - } - - // modify the current network - if ( !Abc_NtkRewrite( pNtk, fUseZeros, fVerbose ) ) - { - fprintf( pErr, "Rewriting has failed.\n" ); - return 1; - } - return 0; - -usage: - fprintf( pErr, "usage: rewrite [-zvh]\n" ); - fprintf( pErr, "\t performs technology-independent rewriting of the AIG\n" ); - fprintf( pErr, "\t-z : toggle using zero-cost replacements [default = %s]\n", fUseZeros? "yes": "no" ); - fprintf( pErr, "\t-v : toggle verbose printout [default = %s]\n", fVerbose? "yes": "no" ); - fprintf( pErr, "\t-h : print the command usage\n"); - return 1; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_CommandRefactor( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - FILE * pOut, * pErr; - Abc_Ntk_t * pNtk; - int c; - int nNodeSizeMax; - int nConeSizeMax; - bool fUseZeros; - bool fUseDcs; - bool fVerbose; - extern int Abc_NtkRefactor( Abc_Ntk_t * pNtk, int nNodeSizeMax, int nConeSizeMax, bool fUseZeros, bool fUseDcs, bool fVerbose ); - - pNtk = Abc_FrameReadNet(pAbc); - pOut = Abc_FrameReadOut(pAbc); - pErr = Abc_FrameReadErr(pAbc); - - // set defaults - nNodeSizeMax = 10; - nConeSizeMax = 16; - fUseZeros = 0; - fUseDcs = 0; - fVerbose = 0; - util_getopt_reset(); - while ( ( c = util_getopt( argc, argv, "NCzdvh" ) ) != EOF ) - { - switch ( c ) - { - case 'N': - if ( util_optind >= argc ) - { - fprintf( pErr, "Command line switch \"-N\" should be followed by an integer.\n" ); - goto usage; - } - nNodeSizeMax = atoi(argv[util_optind]); - util_optind++; - if ( nNodeSizeMax < 0 ) - goto usage; - break; - case 'C': - if ( util_optind >= argc ) - { - fprintf( pErr, "Command line switch \"-C\" should be followed by an integer.\n" ); - goto usage; - } - nConeSizeMax = atoi(argv[util_optind]); - util_optind++; - if ( nConeSizeMax < 0 ) - goto usage; - break; - case 'z': - fUseZeros ^= 1; - break; - case 'd': - fUseDcs ^= 1; - break; - case 'v': - fVerbose ^= 1; - break; - case 'h': - goto usage; - default: - goto usage; - } - } - - if ( pNtk == NULL ) - { - fprintf( pErr, "Empty network.\n" ); - return 1; - } - if ( !Abc_NtkIsStrash(pNtk) ) - { - fprintf( pErr, "This command can only be applied to an AIG.\n" ); - return 1; - } - if ( Abc_NtkGetChoiceNum(pNtk) ) - { - fprintf( pErr, "AIG resynthesis cannot be applied to AIGs with choice nodes.\n" ); - return 1; - } - - if ( fUseDcs && nNodeSizeMax >= nConeSizeMax ) - { - fprintf( pErr, "For don't-care to work, containing cone should be larger than collapsed node.\n" ); - return 1; - } - - // modify the current network - if ( !Abc_NtkRefactor( pNtk, nNodeSizeMax, nConeSizeMax, fUseZeros, fUseDcs, fVerbose ) ) - { - fprintf( pErr, "Refactoring has failed.\n" ); - return 1; - } - return 0; - -usage: - fprintf( pErr, "usage: refactor [-N num] [-C num] [-zdvh]\n" ); - fprintf( pErr, "\t performs technology-independent refactoring of the AIG\n" ); - fprintf( pErr, "\t-N num : the max support of the collapsed node [default = %d]\n", nNodeSizeMax ); - fprintf( pErr, "\t-C num : the max support of the containing cone [default = %d]\n", nConeSizeMax ); - fprintf( pErr, "\t-z : toggle using zero-cost replacements [default = %s]\n", fUseZeros? "yes": "no" ); - fprintf( pErr, "\t-d : toggle using don't-cares [default = %s]\n", fUseDcs? "yes": "no" ); - fprintf( pErr, "\t-v : toggle verbose printout [default = %s]\n", fVerbose? "yes": "no" ); - fprintf( pErr, "\t-h : print the command usage\n"); - return 1; -} - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_CommandLogic( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - FILE * pOut, * pErr; - Abc_Ntk_t * pNtk, * pNtkRes; - int c; - - 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_NtkIsNetlist( pNtk ) ) - { - fprintf( pErr, "This command is only applicable to netlists.\n" ); - return 1; - } - - // get the new network - pNtkRes = Abc_NtkNetlistToLogic( pNtk ); - if ( pNtkRes == NULL ) - { - fprintf( pErr, "Converting to a logic network has failed.\n" ); - return 1; - } - // replace the current network - Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); - return 0; - -usage: - fprintf( pErr, "usage: logic [-h]\n" ); - fprintf( pErr, "\t transforms a netlist into a logic network\n" ); - fprintf( pErr, "\t-h : print the command usage\n"); - return 1; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_CommandMiter( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - FILE * pOut, * pErr; - Abc_Ntk_t * pNtk, * pNtk1, * pNtk2, * pNtkRes; - int fDelete1, fDelete2; - char ** pArgvNew; - int nArgcNew; - int c; - int fCheck; - int fComb; - - pNtk = Abc_FrameReadNet(pAbc); - pOut = Abc_FrameReadOut(pAbc); - pErr = Abc_FrameReadErr(pAbc); - - // set defaults - fComb = 1; - fCheck = 1; - util_getopt_reset(); - while ( ( c = util_getopt( argc, argv, "ch" ) ) != EOF ) - { - switch ( c ) - { - case 'c': - fComb ^= 1; - break; - default: - goto usage; - } - } - - pArgvNew = argv + util_optind; - nArgcNew = argc - util_optind; - if ( !Abc_NtkPrepareTwoNtks( pErr, pNtk, pArgvNew, nArgcNew, &pNtk1, &pNtk2, &fDelete1, &fDelete2 ) ) - return 1; - - // compute the miter - pNtkRes = Abc_NtkMiter( pNtk1, pNtk2, fComb ); - if ( fDelete1 ) Abc_NtkDelete( pNtk1 ); - if ( fDelete2 ) Abc_NtkDelete( pNtk2 ); - - // get the new network - if ( pNtkRes == NULL ) - { - fprintf( pErr, "Miter computation has failed.\n" ); - return 1; - } - // replace the current network - Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); - return 0; - -usage: - fprintf( pErr, "usage: miter [-ch] \n" ); - fprintf( pErr, "\t computes the miter of the two circuits\n" ); - fprintf( pErr, "\t-c : computes combinational miter (latches as POs) [default = %s]\n", fComb? "yes": "no" ); - fprintf( pErr, "\t-h : print the command usage\n"); - fprintf( pErr, "\tfile1 : (optional) the file with the first network\n"); - fprintf( pErr, "\tfile2 : (optional) the file with the second network\n"); - fprintf( pErr, "\t if no files are given, uses the current network and its spec\n"); - fprintf( pErr, "\t if one file is given, uses the current network and the file\n"); - return 1; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_CommandFrames( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - FILE * pOut, * pErr; - Abc_Ntk_t * pNtk, * pNtkTemp, * pNtkRes; - int fInitial; - int nFrames; - int c; - - pNtk = Abc_FrameReadNet(pAbc); - pOut = Abc_FrameReadOut(pAbc); - pErr = Abc_FrameReadErr(pAbc); - - // set defaults - fInitial = 0; - nFrames = 5; - util_getopt_reset(); - while ( ( c = util_getopt( argc, argv, "Fih" ) ) != EOF ) - { - switch ( c ) - { - case 'F': - if ( util_optind >= argc ) - { - fprintf( pErr, "Command line switch \"-F\" should be followed by an integer.\n" ); - goto usage; - } - nFrames = atoi(argv[util_optind]); - util_optind++; - if ( nFrames < 0 ) - goto usage; - break; - case 'i': - fInitial ^= 1; - break; - case 'h': - goto usage; - default: - goto usage; - } - } - - if ( pNtk == NULL ) - { - fprintf( pErr, "Empty network.\n" ); - return 1; - } - - // get the new network - if ( !Abc_NtkIsStrash(pNtk) ) - { - pNtkTemp = Abc_NtkStrash( pNtk, 0, 0 ); - pNtkRes = Abc_NtkFrames( pNtkTemp, nFrames, fInitial ); - Abc_NtkDelete( pNtkTemp ); - } - else - pNtkRes = Abc_NtkFrames( pNtk, nFrames, fInitial ); - if ( pNtkRes == NULL ) - { - fprintf( pErr, "Unrolling the network has failed.\n" ); - return 1; - } - // replace the current network - Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); - return 0; - -usage: - fprintf( pErr, "usage: frames [-F num] [-ih]\n" ); - fprintf( pErr, "\t unrolls the network for a number of time frames\n" ); - fprintf( pErr, "\t-F num : the number of frames to unroll [default = %d]\n", nFrames ); - fprintf( pErr, "\t-i : toggles initializing the first frame [default = %s]\n", fInitial? "yes": "no" ); - fprintf( pErr, "\t-h : print the command usage\n"); - return 1; -} - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_CommandSop( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - FILE * pOut, * pErr; - Abc_Ntk_t * pNtk; - int c; - - 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; - } - - // get the new network - if ( !Abc_NtkIsBddLogic(pNtk) ) - { - fprintf( pErr, "Converting to SOP is possible when node functions are BDDs.\n" ); - return 1; - } - if ( !Abc_NtkBddToSop( pNtk ) ) - { - fprintf( pErr, "Converting to SOP has failed.\n" ); - return 1; - } - return 0; - -usage: - fprintf( pErr, "usage: sop [-h]\n" ); - fprintf( pErr, "\t converts node functions from BDD to SOP\n" ); - fprintf( pErr, "\t-h : print the command usage\n"); - return 1; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_CommandBdd( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - FILE * pOut, * pErr; - Abc_Ntk_t * pNtk; - int c; - - 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; - } - - // get the new network - if ( !Abc_NtkIsSopLogic(pNtk) ) - { - fprintf( pErr, "Converting to BDD is possible when node functions are SOPs.\n" ); - return 1; - } - if ( !Abc_NtkSopToBdd( pNtk ) ) - { - fprintf( pErr, "Converting to BDD has failed.\n" ); - return 1; - } - return 0; - -usage: - fprintf( pErr, "usage: bdd [-h]\n" ); - fprintf( pErr, "\t converts node functions from SOP to BDD\n" ); - fprintf( pErr, "\t-h : print the command usage\n"); - return 1; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_CommandMuxes( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - FILE * pOut, * pErr; - Abc_Ntk_t * pNtk, * pNtkRes; - int c; - - 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_NtkIsBddLogic(pNtk) ) - { - fprintf( pErr, "Only a BDD logic network can be converted to MUXes.\n" ); - return 1; - } - - // get the new network - pNtkRes = Abc_NtkBddToMuxes( pNtk ); - if ( pNtkRes == NULL ) - { - fprintf( pErr, "Converting to MUXes has failed.\n" ); - return 1; - } - // replace the current network - Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); - return 0; - -usage: - fprintf( pErr, "usage: muxes [-h]\n" ); - fprintf( pErr, "\t converts the current network by a network derived by\n" ); - fprintf( pErr, "\t replacing all nodes by DAGs isomorphic to the local BDDs\n" ); - fprintf( pErr, "\t-h : print the command usage\n"); - return 1; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_CommandSat( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - FILE * pOut, * pErr; - Abc_Ntk_t * pNtk; - int c; - int fVerbose; - - pNtk = Abc_FrameReadNet(pAbc); - pOut = Abc_FrameReadOut(pAbc); - pErr = Abc_FrameReadErr(pAbc); - - // set defaults - fVerbose = 0; - util_getopt_reset(); - while ( ( c = util_getopt( argc, argv, "vh" ) ) != EOF ) - { - switch ( c ) - { - case 'v': - fVerbose ^= 1; - break; - case 'h': - goto usage; - default: - goto usage; - } - } - - if ( pNtk == NULL ) - { - fprintf( pErr, "Empty network.\n" ); - return 1; - } - if ( Abc_NtkLatchNum(pNtk) > 0 ) - { - fprintf( stdout, "Currently can only solve the miter for combinational circuits.\n" ); - return 0; - } - if ( !Abc_NtkIsLogic(pNtk) ) - { - fprintf( stdout, "This command can only be applied to logic network.\n" ); - return 0; - } - if ( Abc_NtkIsMappedLogic(pNtk) ) - Abc_NtkUnmap(pNtk); - if ( Abc_NtkIsSopLogic(pNtk) ) - Abc_NtkSopToBdd(pNtk); - - if ( Abc_NtkMiterSat( pNtk, fVerbose ) ) - printf( "The miter is satisfiable.\n" ); - else - printf( "The miter is unsatisfiable.\n" ); - return 0; - -usage: - fprintf( pErr, "usage: sat [-vh]\n" ); - fprintf( pErr, "\t solves the miter\n" ); - fprintf( pErr, "\t-v : prints verbose information [default = %s]\n", fVerbose? "yes": "no" ); - fprintf( pErr, "\t-h : print the command usage\n"); - return 1; -} - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_CommandExtSeqDcs( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - FILE * pOut, * pErr; - Abc_Ntk_t * pNtk; - int c; - int fVerbose; - extern int Abc_NtkExtractSequentialDcs( Abc_Ntk_t * pNet, bool fVerbose ); - - pNtk = Abc_FrameReadNet(pAbc); - pOut = Abc_FrameReadOut(pAbc); - pErr = Abc_FrameReadErr(pAbc); - - // set defaults - fVerbose = 0; - util_getopt_reset(); - while ( ( c = util_getopt( argc, argv, "vh" ) ) != EOF ) - { - switch ( c ) - { - case 'v': - fVerbose ^= 1; - break; - case 'h': - goto usage; - default: - goto usage; - } - } - - if ( pNtk == NULL ) - { - fprintf( pErr, "Empty network.\n" ); - return 1; - } - if ( Abc_NtkLatchNum(pNtk) == 0 ) - { - fprintf( stdout, "The current network has no latches.\n" ); - return 0; - } - if ( !Abc_NtkIsStrash(pNtk) ) - { - fprintf( stdout, "This command works only for AIGs.\n" ); - return 0; - } - if ( !Abc_NtkExtractSequentialDcs( pNtk, fVerbose ) ) - { - fprintf( stdout, "Extracting sequential don't-cares has failed.\n" ); - return 1; - } - return 0; - -usage: - fprintf( pErr, "usage: ext_seq_dcs [-vh]\n" ); - fprintf( pErr, "\t create EXDC network using unreachable states\n" ); - fprintf( pErr, "\t-v : prints verbose information [default = %s]\n", fVerbose? "yes": "no" ); - fprintf( pErr, "\t-h : print the command usage\n"); - return 1; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_CommandOneOutput( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - FILE * pOut, * pErr; - Abc_Ntk_t * pNtk, * pNtkRes; - Abc_Obj_t * pNode; - int c; - int fUseAllCis; - int Output; - - pNtk = Abc_FrameReadNet(pAbc); - pOut = Abc_FrameReadOut(pAbc); - pErr = Abc_FrameReadErr(pAbc); - - // set defaults - fUseAllCis = 0; - Output = -1; - util_getopt_reset(); - while ( ( c = util_getopt( argc, argv, "Oah" ) ) != EOF ) - { - switch ( c ) - { - case 'O': - if ( util_optind >= argc ) - { - fprintf( pErr, "Command line switch \"-O\" should be followed by an integer.\n" ); - goto usage; - } - Output = atoi(argv[util_optind]); - util_optind++; - if ( Output < 0 ) - goto usage; - break; - case 'a': - fUseAllCis ^= 1; - break; - case 'h': - goto usage; - default: - goto usage; - } - } - - if ( pNtk == NULL ) - { - fprintf( pErr, "Empty network.\n" ); - return 1; - } - - if ( !Abc_NtkIsLogic(pNtk) && !Abc_NtkIsStrash(pNtk) ) - { - fprintf( pErr, "Currently can only be applied to the logic network or an AIG.\n" ); - return 1; - } - - if ( argc > util_optind + 1 ) - { - fprintf( pErr, "Wrong number of auguments.\n" ); - goto usage; - } - - if ( argc == util_optind + 1 ) - { - pNode = Abc_NtkFindCo( pNtk, argv[util_optind] ); - if ( pNode == NULL ) - { - fprintf( pErr, "Cannot find CO node \"%s\".\n", argv[util_optind] ); - return 1; - } - pNtkRes = Abc_NtkSplitOutput( pNtk, pNode, fUseAllCis ); - } - else - { - if ( Output == -1 ) - { - fprintf( pErr, "The output is not specified.\n" ); - return 1; - } - if ( Output >= Abc_NtkCoNum(pNtk) ) - { - fprintf( pErr, "The 0-based output number (%d) is larger than the number of outputs (%d).\n", Output, Abc_NtkCoNum(pNtk) ); - return 1; - } - pNtkRes = Abc_NtkSplitOutput( pNtk, Abc_NtkCo(pNtk,Output), fUseAllCis ); - } - if ( pNtkRes == NULL ) - { - fprintf( pErr, "Splitting one output has failed.\n" ); - return 1; - } - // replace the current network - Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); - return 0; - -usage: - fprintf( pErr, "usage: one_output [-O num] [-ah] \n" ); - fprintf( pErr, "\t replaces the current network by the logic cone of one output\n" ); - fprintf( pErr, "\t-a : toggle writing all CIs or structral support only [default = %s]\n", fUseAllCis? "all": "structural" ); - fprintf( pErr, "\t-h : print the command usage\n"); - fprintf( pErr, "\t-O num : (optional) the 0-based number of the output\n"); - fprintf( pErr, "\tname : (optional) the name of the output\n"); - return 1; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_CommandOneNode( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - FILE * pOut, * pErr; - Abc_Ntk_t * pNtk, * pNtkRes; - Abc_Obj_t * pNode; - int c; - - 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_NtkIsLogic(pNtk) ) - { - fprintf( pErr, "Currently can only be applied to a logic network.\n" ); - return 1; - } - - if ( argc != util_optind + 1 ) - { - fprintf( pErr, "Wrong number of auguments.\n" ); - goto usage; - } - - pNode = Abc_NtkFindNode( pNtk, argv[util_optind] ); - if ( pNode == NULL ) - { - fprintf( pErr, "Cannot find node \"%s\".\n", argv[util_optind] ); - return 1; - } - - pNtkRes = Abc_NtkSplitNode( pNtk, pNode ); -// pNtkRes = Abc_NtkDeriveFromBdd( pNtk->pManFunc, pNode->pData, NULL, NULL ); - if ( pNtkRes == NULL ) - { - fprintf( pErr, "Splitting one node has failed.\n" ); - return 1; - } - // replace the current network - Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); - return 0; - -usage: - fprintf( pErr, "usage: one_node [-h] \n" ); - fprintf( pErr, "\t replaces the current network by the network composed of one node\n" ); - fprintf( pErr, "\t-h : print the command usage\n"); - fprintf( pErr, "\tname : the node name\n"); - return 1; -} - - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_CommandShortNames( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - FILE * pOut, * pErr; - Abc_Ntk_t * pNtk; - int c; - - 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; - } - Abc_NtkShortNames( pNtk ); - return 0; - -usage: - fprintf( pErr, "usage: short_names [-h]\n" ); - fprintf( pErr, "\t replaces PI/PO/latch names by short char strings\n" ); - fprintf( pErr, "\t-h : print the command usage\n"); - return 1; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_CommandCut( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - Cut_Params_t Params, * pParams = &Params; - Cut_Man_t * pCutMan; - FILE * pOut, * pErr; - Abc_Ntk_t * pNtk; - int c; - extern Cut_Man_t * Abc_NtkCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams ); - - pNtk = Abc_FrameReadNet(pAbc); - pOut = Abc_FrameReadOut(pAbc); - pErr = Abc_FrameReadErr(pAbc); - - // set defaults - pParams->nVarsMax = 5; // the max cut size ("k" of the k-feasible cuts) - pParams->nKeepMax = 250; // the max number of cuts kept at a node - pParams->fTruth = 1; // compute truth tables - pParams->fHash = 0; // hash cuts to detect unique - pParams->fFilter = 0; // filter dominated cuts - pParams->fSeq = 0; // compute sequential cuts - pParams->fDrop = 0; // drop cuts on the fly - pParams->fVerbose = 0; // the verbosiness flag - util_getopt_reset(); - while ( ( c = util_getopt( argc, argv, "KMtrfsdvh" ) ) != EOF ) - { - switch ( c ) - { - case 'K': - if ( util_optind >= argc ) - { - fprintf( pErr, "Command line switch \"-K\" should be followed by an integer.\n" ); - goto usage; - } - pParams->nVarsMax = atoi(argv[util_optind]); - util_optind++; - if ( pParams->nVarsMax < 0 ) - goto usage; - break; - case 'M': - if ( util_optind >= argc ) - { - fprintf( pErr, "Command line switch \"-M\" should be followed by an integer.\n" ); - goto usage; - } - pParams->nKeepMax = atoi(argv[util_optind]); - util_optind++; - if ( pParams->nKeepMax < 0 ) - goto usage; - break; - case 't': - pParams->fTruth ^= 1; - break; - case 'r': - pParams->fHash ^= 1; - break; - case 'f': - pParams->fFilter ^= 1; - break; - case 's': - pParams->fSeq ^= 1; - break; - case 'd': - pParams->fDrop ^= 1; - break; - case 'v': - pParams->fVerbose ^= 1; - break; - case 'h': - goto usage; - default: - goto usage; - } - } - - if ( pNtk == NULL ) - { - fprintf( pErr, "Empty network.\n" ); - return 1; - } - if ( !Abc_NtkIsStrash(pNtk) ) - { - fprintf( pErr, "Cut computation is available only for AIGs.\n" ); - return 1; - } - pCutMan = Abc_NtkCuts( pNtk, pParams ); - Cut_ManPrintStats( pCutMan ); - Cut_ManStop( pCutMan ); - return 0; - -usage: - fprintf( pErr, "usage: cut [-K num] [-M num] [-trfsdvh]\n" ); - fprintf( pErr, "\t computes k-feasible cuts for the AIG\n" ); - fprintf( pErr, "\t-K num : max number of leaves (4 <= num <= 6) [default = %d]\n", pParams->nVarsMax ); - fprintf( pErr, "\t-M num : max number of cuts stored at a node [default = %d]\n", pParams->nKeepMax ); - fprintf( pErr, "\t-t : toggle truth table computation [default = %s]\n", pParams->fTruth? "yes": "no" ); - fprintf( pErr, "\t-r : toggle reduction by hashing [default = %s]\n", pParams->fHash? "yes": "no" ); - fprintf( pErr, "\t-f : toggle filtering by dominance [default = %s]\n", pParams->fFilter? "yes": "no" ); - fprintf( pErr, "\t-s : toggle sequential cut computation [default = %s]\n", pParams->fSeq? "yes": "no" ); - fprintf( pErr, "\t-d : toggle dropping when fanouts are done [default = %s]\n", pParams->fDrop? "yes": "no" ); - fprintf( pErr, "\t-v : toggle printing verbose information [default = %s]\n", pParams->fVerbose? "yes": "no" ); - fprintf( pErr, "\t-h : print the command usage\n"); - return 1; -} - - - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_CommandFraig( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - char Buffer[100]; - Fraig_Params_t Params, * pParams = &Params; - FILE * pOut, * pErr; - Abc_Ntk_t * pNtk, * pNtkRes; - int fAllNodes; - int c; - - pNtk = Abc_FrameReadNet(pAbc); - pOut = Abc_FrameReadOut(pAbc); - pErr = Abc_FrameReadErr(pAbc); - - // set defaults - fAllNodes = 0; - pParams->nPatsRand = 2048; // the number of words of random simulation info - pParams->nPatsDyna = 2048; // the number of words of dynamic simulation info - pParams->nBTLimit = 99; // the max number of backtracks to perform - pParams->fFuncRed = 1; // performs only one level hashing - pParams->fFeedBack = 1; // enables solver feedback - pParams->fDist1Pats = 1; // enables distance-1 patterns - pParams->fDoSparse = 0; // performs equiv tests for sparse functions - pParams->fChoicing = 0; // enables recording structural choices - pParams->fTryProve = 0; // tries to solve the final miter - pParams->fVerbose = 0; // the verbosiness flag - pParams->fVerboseP = 0; // the verbosiness flag - util_getopt_reset(); - while ( ( c = util_getopt( argc, argv, "RDBrscpvah" ) ) != EOF ) - { - switch ( c ) - { - - case 'R': - if ( util_optind >= argc ) - { - fprintf( pErr, "Command line switch \"-R\" should be followed by an integer.\n" ); - goto usage; - } - pParams->nPatsRand = atoi(argv[util_optind]); - util_optind++; - if ( pParams->nPatsRand < 0 ) - goto usage; - break; - case 'D': - if ( util_optind >= argc ) - { - fprintf( pErr, "Command line switch \"-D\" should be followed by an integer.\n" ); - goto usage; - } - pParams->nPatsDyna = atoi(argv[util_optind]); - util_optind++; - if ( pParams->nPatsDyna < 0 ) - goto usage; - break; - case 'B': - if ( util_optind >= argc ) - { - fprintf( pErr, "Command line switch \"-B\" should be followed by an integer.\n" ); - goto usage; - } - pParams->nBTLimit = atoi(argv[util_optind]); - util_optind++; - if ( pParams->nBTLimit < 0 ) - goto usage; - break; - - case 'r': - pParams->fFuncRed ^= 1; - break; - case 's': - pParams->fDoSparse ^= 1; - break; - case 'c': - pParams->fChoicing ^= 1; - break; - case 'p': - pParams->fTryProve ^= 1; - break; - case 'v': - pParams->fVerbose ^= 1; - break; - case 'a': - fAllNodes ^= 1; - break; - case 'h': - goto usage; - default: - goto usage; - } - } - - if ( pNtk == NULL ) - { - fprintf( pErr, "Empty network.\n" ); - return 1; - } - if ( !Abc_NtkIsLogic(pNtk) && !Abc_NtkIsStrash(pNtk) ) - { - fprintf( pErr, "Can only fraig a logic network or an AIG.\n" ); - return 1; - } - - // report the proof - pParams->fVerboseP = pParams->fTryProve; - - // get the new network - if ( Abc_NtkIsStrash(pNtk) ) - pNtkRes = Abc_NtkFraig( pNtk, &Params, fAllNodes ); - else - { - pNtk = Abc_NtkStrash( pNtk, fAllNodes, !fAllNodes ); - pNtkRes = Abc_NtkFraig( pNtk, &Params, fAllNodes ); - Abc_NtkDelete( pNtk ); - } - if ( pNtkRes == NULL ) - { - fprintf( pErr, "Fraiging has failed.\n" ); - return 1; - } - - if ( pParams->fTryProve ) // report the result - Abc_NtkMiterReport( pNtkRes ); - - // replace the current network - Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); - return 0; - -usage: - sprintf( Buffer, "%d", pParams->nBTLimit ); - 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", pParams->nPatsRand ); - fprintf( pErr, "\t-D num : number of systematic patterns (127 < num < 32769) [default = %d]\n", pParams->nPatsDyna ); - fprintf( pErr, "\t-B num : number of backtracks for one SAT problem [default = %s]\n", pParams->nBTLimit==-1? "infinity" : Buffer ); - fprintf( pErr, "\t-r : toggle functional reduction [default = %s]\n", pParams->fFuncRed? "yes": "no" ); - fprintf( pErr, "\t-s : toggle considering sparse functions [default = %s]\n", pParams->fDoSparse? "yes": "no" ); - fprintf( pErr, "\t-c : toggle accumulation of choices [default = %s]\n", pParams->fChoicing? "yes": "no" ); - fprintf( pErr, "\t-p : toggle proving the final miter [default = %s]\n", pParams->fTryProve? "yes": "no" ); - fprintf( pErr, "\t-v : toggle verbose output [default = %s]\n", pParams->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; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_CommandFraigTrust( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - FILE * pOut, * pErr; - Abc_Ntk_t * pNtk, * pNtkRes; - int c; - int fDuplicate; - - pNtk = Abc_FrameReadNet(pAbc); - pOut = Abc_FrameReadOut(pAbc); - pErr = Abc_FrameReadErr(pAbc); - - // set defaults - fDuplicate = 0; - util_getopt_reset(); - while ( ( c = util_getopt( argc, argv, "dh" ) ) != EOF ) - { - switch ( c ) - { - case 'd': - fDuplicate ^= 1; - break; - case 'h': - goto usage; - default: - goto usage; - } - } - - if ( pNtk == NULL ) - { - fprintf( pErr, "Empty network.\n" ); - return 1; - } - - // get the new network - pNtkRes = Abc_NtkFraigTrust( pNtk ); - if ( pNtkRes == NULL ) - { - fprintf( pErr, "Fraiging in the trust mode has failed.\n" ); - return 1; - } - // replace the current network - Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); - return 0; - -usage: - fprintf( pErr, "usage: fraig_trust [-h]\n" ); - fprintf( pErr, "\t transforms the current network into an AIG assuming it is FRAIG with choices\n" ); -// fprintf( pErr, "\t-d : toggle duplication of logic [default = %s]\n", fDuplicate? "yes": "no" ); - fprintf( pErr, "\t-h : print the command usage\n"); - return 1; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_CommandFraigStore( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - FILE * pOut, * pErr; - Abc_Ntk_t * pNtk; - int c; - int fDuplicate; - - pNtk = Abc_FrameReadNet(pAbc); - pOut = Abc_FrameReadOut(pAbc); - pErr = Abc_FrameReadErr(pAbc); - - // set defaults - fDuplicate = 0; - util_getopt_reset(); - while ( ( c = util_getopt( argc, argv, "dh" ) ) != EOF ) - { - switch ( c ) - { - case 'd': - fDuplicate ^= 1; - break; - case 'h': - goto usage; - default: - goto usage; - } - } - - if ( pNtk == NULL ) - { - fprintf( pErr, "Empty network.\n" ); - return 1; - } - - // get the new network - if ( !Abc_NtkFraigStore( pNtk ) ) - { - fprintf( pErr, "Fraig storing has failed.\n" ); - return 1; - } - return 0; - -usage: - fprintf( pErr, "usage: fraig_store [-h]\n" ); - fprintf( pErr, "\t saves the current network in the AIG database\n" ); -// fprintf( pErr, "\t-d : toggle duplication of logic [default = %s]\n", fDuplicate? "yes": "no" ); - fprintf( pErr, "\t-h : print the command usage\n"); - return 1; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_CommandFraigRestore( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - FILE * pOut, * pErr; - Abc_Ntk_t * pNtk, * pNtkRes; - int c; - int fDuplicate; - - pNtk = Abc_FrameReadNet(pAbc); - pOut = Abc_FrameReadOut(pAbc); - pErr = Abc_FrameReadErr(pAbc); - - // set defaults - fDuplicate = 0; - util_getopt_reset(); - while ( ( c = util_getopt( argc, argv, "dh" ) ) != EOF ) - { - switch ( c ) - { - case 'd': - fDuplicate ^= 1; - break; - case 'h': - goto usage; - default: - goto usage; - } - } - - if ( pNtk == NULL ) - { - fprintf( pErr, "Empty network.\n" ); - return 1; - } - - // get the new network - pNtkRes = Abc_NtkFraigRestore(); - if ( pNtkRes == NULL ) - { - fprintf( pErr, "Fraig restoring has failed.\n" ); - return 1; - } - // replace the current network - Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); - return 0; - -usage: - fprintf( pErr, "usage: fraig_restore [-h]\n" ); - fprintf( pErr, "\t makes the current network by fraiging the AIG database\n" ); -// fprintf( pErr, "\t-d : toggle duplication of logic [default = %s]\n", fDuplicate? "yes": "no" ); - fprintf( pErr, "\t-h : print the command usage\n"); - return 1; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_CommandFraigClean( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - FILE * pOut, * pErr; - Abc_Ntk_t * pNtk; - int c; - int fDuplicate; - - pNtk = Abc_FrameReadNet(pAbc); - pOut = Abc_FrameReadOut(pAbc); - pErr = Abc_FrameReadErr(pAbc); - - // set defaults - fDuplicate = 0; - util_getopt_reset(); - while ( ( c = util_getopt( argc, argv, "dh" ) ) != EOF ) - { - switch ( c ) - { - case 'd': - fDuplicate ^= 1; - break; - case 'h': - goto usage; - default: - goto usage; - } - } - Abc_NtkFraigStoreClean(); - return 0; - -usage: - fprintf( pErr, "usage: fraig_clean [-h]\n" ); - fprintf( pErr, "\t cleans the internal FRAIG storage\n" ); -// fprintf( pErr, "\t-d : toggle duplication of logic [default = %s]\n", fDuplicate? "yes": "no" ); - fprintf( pErr, "\t-h : print the command usage\n"); - return 1; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_CommandFraigSweep( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - FILE * pOut, * pErr; - Abc_Ntk_t * pNtk; - int c; - int fUseInv; - int fVerbose; - - pNtk = Abc_FrameReadNet(pAbc); - pOut = Abc_FrameReadOut(pAbc); - pErr = Abc_FrameReadErr(pAbc); - - // set defaults - fUseInv = 1; - fVerbose = 0; - util_getopt_reset(); - while ( ( c = util_getopt( argc, argv, "ivh" ) ) != EOF ) - { - switch ( c ) - { - case 'i': - fUseInv ^= 1; - break; - case 'v': - fVerbose ^= 1; - break; - case 'h': - goto usage; - default: - goto usage; - } - } - - if ( pNtk == NULL ) - { - fprintf( pErr, "Empty network.\n" ); - return 1; - } - if ( Abc_NtkIsStrash(pNtk) ) - { - fprintf( pErr, "Cannot sweep AIGs (use \"fraig\").\n" ); - return 1; - } - if ( !Abc_NtkIsLogic(pNtk) ) - { - fprintf( pErr, "Transform the current network into a logic network.\n" ); - return 1; - } - // modify the current network - if ( !Abc_NtkFraigSweep( pNtk, fUseInv, fVerbose ) ) - { - fprintf( pErr, "Sweeping has failed.\n" ); - return 1; - } - return 0; - -usage: - fprintf( pErr, "usage: fraig_sweep [-vh]\n" ); - fprintf( pErr, "\t performs technology-dependent sweep\n" ); -// fprintf( pErr, "\t-i : toggle using inverter for complemented nodes [default = %s]\n", fUseInv? "yes": "no" ); - fprintf( pErr, "\t-v : prints verbose information [default = %s]\n", fVerbose? "yes": "no" ); - fprintf( pErr, "\t-h : print the command usage\n"); - return 1; -} - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_CommandMap( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - FILE * pOut, * pErr; - Abc_Ntk_t * pNtk, * pNtkRes; - char Buffer[100]; - double DelayTarget; - int fRecovery; - int fVerbose; - int fSweep; - int c; - extern Abc_Ntk_t * Abc_NtkMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, int fVerbose ); - - pNtk = Abc_FrameReadNet(pAbc); - pOut = Abc_FrameReadOut(pAbc); - pErr = Abc_FrameReadErr(pAbc); - - // set defaults - DelayTarget =-1; - fRecovery = 1; - fSweep = 1; - fVerbose = 0; - util_getopt_reset(); - while ( ( c = util_getopt( argc, argv, "Dasvh" ) ) != EOF ) - { - switch ( c ) - { - case 'D': - if ( util_optind >= argc ) - { - fprintf( pErr, "Command line switch \"-D\" should be followed by a floating point number.\n" ); - goto usage; - } - DelayTarget = (float)atof(argv[util_optind]); - util_optind++; - if ( DelayTarget <= 0.0 ) - goto usage; - break; - case 'a': - fRecovery ^= 1; - break; - case 's': - fSweep ^= 1; - break; - case 'v': - fVerbose ^= 1; - break; - case 'h': - goto usage; - default: - goto usage; - } - } - - if ( pNtk == NULL ) - { - fprintf( pErr, "Empty network.\n" ); - return 1; - } - - if ( !Abc_NtkIsStrash(pNtk) ) - { - pNtk = Abc_NtkStrash( pNtk, 0, 0 ); - if ( pNtk == NULL ) - { - fprintf( pErr, "Strashing before mapping has failed.\n" ); - return 1; - } - pNtk = Abc_NtkBalance( pNtkRes = pNtk, 0 ); - Abc_NtkDelete( pNtkRes ); - if ( pNtk == NULL ) - { - fprintf( pErr, "Balancing before mapping has failed.\n" ); - return 1; - } - fprintf( pOut, "The network was strashed and balanced before mapping.\n" ); - // get the new network - pNtkRes = Abc_NtkMap( pNtk, DelayTarget, fRecovery, fVerbose ); - if ( pNtkRes == NULL ) - { - Abc_NtkDelete( pNtk ); - fprintf( pErr, "Mapping has failed.\n" ); - return 1; - } - Abc_NtkDelete( pNtk ); - } - else - { - // get the new network - pNtkRes = Abc_NtkMap( pNtk, DelayTarget, fRecovery, fVerbose ); - if ( pNtkRes == NULL ) - { - fprintf( pErr, "Mapping has failed.\n" ); - return 1; - } - } - - if ( fSweep ) - Abc_NtkFraigSweep( pNtkRes, 0, 0 ); - - // replace the current network - Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); - return 0; - -usage: - if ( DelayTarget == -1 ) - sprintf( Buffer, "not used" ); - else - sprintf( Buffer, "%.3f", DelayTarget ); - fprintf( pErr, "usage: map [-D num] [-asvh]\n" ); - fprintf( pErr, "\t performs standard cell mapping of the current network\n" ); - fprintf( pErr, "\t-D num : sets the global required times [default = %s]\n", Buffer ); - fprintf( pErr, "\t-a : toggles area recovery [default = %s]\n", fRecovery? "yes": "no" ); - fprintf( pErr, "\t-s : toggles sweep after mapping [default = %s]\n", fSweep? "yes": "no" ); - fprintf( pErr, "\t-v : toggles verbose output [default = %s]\n", fVerbose? "yes": "no" ); - fprintf( pErr, "\t-h : print the command usage\n"); - return 1; -} - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_CommandUnmap( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - FILE * pOut, * pErr; - Abc_Ntk_t * pNtk; - int c; - extern int Abc_NtkUnmap( 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_NtkHasMapping(pNtk) ) - { - fprintf( pErr, "Cannot unmap the network that is not mapped.\n" ); - return 1; - } - - // get the new network - if ( !Abc_NtkUnmap( pNtk ) ) - { - fprintf( pErr, "Unmapping has failed.\n" ); - return 1; - } - return 0; - -usage: - fprintf( pErr, "usage: unmap [-h]\n" ); - fprintf( pErr, "\t replaces the library gates by the logic nodes represented using SOPs\n" ); - fprintf( pErr, "\t-h : print the command usage\n"); - return 1; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_CommandAttach( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - FILE * pOut, * pErr; - Abc_Ntk_t * pNtk; - int c; - extern int Abc_NtkUnmap( 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_NtkIsSopLogic(pNtk) ) - { - fprintf( pErr, "Can only attach gates if the nodes have SOP representations.\n" ); - return 1; - } - - // get the new network - if ( !Abc_NtkAttach( pNtk ) ) - { - fprintf( pErr, "Attaching gates has failed.\n" ); - return 1; - } - return 0; - -usage: - fprintf( pErr, "usage: attach [-h]\n" ); - fprintf( pErr, "\t replaces the SOP functions by the gates from the library\n" ); - fprintf( pErr, "\t-h : print the command usage\n"); - return 1; -} - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_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_NtkIsStrash(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 (accumulate: \"r file.blif; rsup; b; sc; f -ac; wb file_sc.blif\")\n" ); - fprintf( pErr, "\t (map without supergate library: \"r file_sc.blif; ft; map\")\n" ); - fprintf( pErr, "\t-h : print the command usage\n"); - return 1; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_CommandFpga( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - FILE * pOut, * pErr; - Abc_Ntk_t * pNtk, * pNtkRes; - int c; - int fRecovery; - int fVerbose; - extern Abc_Ntk_t * Abc_NtkFpga( Abc_Ntk_t * pNtk, int fRecovery, int fVerbose ); - - pNtk = Abc_FrameReadNet(pAbc); - pOut = Abc_FrameReadOut(pAbc); - pErr = Abc_FrameReadErr(pAbc); - - // set defaults - fRecovery = 1; - fVerbose = 0; - util_getopt_reset(); - while ( ( c = util_getopt( argc, argv, "avh" ) ) != EOF ) - { - switch ( c ) - { - case 'a': - fRecovery ^= 1; - break; - case 'v': - fVerbose ^= 1; - break; - case 'h': - goto usage; - default: - goto usage; - } - } - - if ( pNtk == NULL ) - { - fprintf( pErr, "Empty network.\n" ); - return 1; - } - - if ( !Abc_NtkIsStrash(pNtk) ) - { - // strash and balance the network - pNtk = Abc_NtkStrash( pNtk, 0, 0 ); - if ( pNtk == NULL ) - { - fprintf( pErr, "Strashing before FPGA mapping has failed.\n" ); - return 1; - } - pNtk = Abc_NtkBalance( pNtkRes = pNtk, 0 ); - Abc_NtkDelete( pNtkRes ); - if ( pNtk == NULL ) - { - fprintf( pErr, "Balancing before FPGA mapping has failed.\n" ); - return 1; - } - fprintf( pOut, "The network was strashed and balanced before FPGA mapping.\n" ); - // get the new network - pNtkRes = Abc_NtkFpga( pNtk, fRecovery, fVerbose ); - if ( pNtkRes == NULL ) - { - Abc_NtkDelete( pNtk ); - fprintf( pErr, "FPGA mapping has failed.\n" ); - return 1; - } - Abc_NtkDelete( pNtk ); - } - else - { - // get the new network - pNtkRes = Abc_NtkFpga( pNtk, fRecovery, fVerbose ); - if ( pNtkRes == NULL ) - { - fprintf( pErr, "FPGA mapping has failed.\n" ); - return 1; - } - } - // replace the current network - Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); - return 0; - -usage: - fprintf( pErr, "usage: fpga [-avh]\n" ); - fprintf( pErr, "\t performs FPGA mapping of the current network\n" ); - fprintf( pErr, "\t-a : toggles area recovery [default = %s]\n", fRecovery? "yes": "no" ); - fprintf( pErr, "\t-v : toggles verbose output [default = %s]\n", fVerbose? "yes": "no" ); - fprintf( pErr, "\t-h : prints the command usage\n"); - return 1; -} - - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_CommandSeq( 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; - } - - printf( "This command is not yet implemented.\n" ); - return 0; - - if ( !Abc_NtkIsStrash(pNtk) ) - { - fprintf( pErr, "Works only for AIG.\n" ); - return 1; - } - - // get the new network - pNtkRes = Abc_NtkAigToSeq( pNtk ); - if ( pNtkRes == NULL ) - { - fprintf( pErr, "Converting to sequential AIG has failed.\n" ); - return 1; - } - // replace the current network - Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); - return 0; - -usage: - fprintf( pErr, "usage: seq [-h]\n" ); - fprintf( pErr, "\t converts AIG into sequential AIG (while sweeping latches)\n" ); - fprintf( pErr, "\t-h : print the command usage\n"); - return 1; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_CommandRetime( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - FILE * pOut, * pErr; - Abc_Ntk_t * pNtk; - int c; - int fForward; - int fBackward; - - extern Abc_Ntk_t * Abc_NtkSuperChoice( Abc_Ntk_t * pNtk ); - - pNtk = Abc_FrameReadNet(pAbc); - pOut = Abc_FrameReadOut(pAbc); - pErr = Abc_FrameReadErr(pAbc); - - // set defaults - fForward = 0; - fBackward = 0; - util_getopt_reset(); - while ( ( c = util_getopt( argc, argv, "fbh" ) ) != EOF ) - { - switch ( c ) - { - case 'f': - fForward ^= 1; - break; - case 'b': - fBackward ^= 1; - break; - case 'h': - goto usage; - default: - goto usage; - } - } - - if ( pNtk == NULL ) - { - fprintf( pErr, "Empty network.\n" ); - return 1; - } - - printf( "This command is not yet implemented.\n" ); - return 0; - - - if ( !Abc_NtkIsSeq(pNtk) ) - { - fprintf( pErr, "Works only for sequential AIG.\n" ); - return 1; - } - - // get the new network - if ( fForward ) - Abc_NtkSeqRetimeForward( pNtk ); - else if ( fBackward ) - Abc_NtkSeqRetimeBackward( pNtk ); - else - Abc_NtkSeqRetimeDelay( pNtk ); - return 0; - -usage: - fprintf( pErr, "usage: retime [-fbh]\n" ); - fprintf( pErr, "\t retimes sequential AIG (default is Pan's algorithm)\n" ); - fprintf( pErr, "\t-f : toggle forward retiming [default = %s]\n", fForward? "yes": "no" ); - fprintf( pErr, "\t-b : toggle backward retiming [default = %s]\n", fBackward? "yes": "no" ); - fprintf( pErr, "\t-h : print the command usage\n"); - return 1; -} - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_CommandCec( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - FILE * pOut, * pErr; - Abc_Ntk_t * pNtk, * pNtk1, * pNtk2; - int fDelete1, fDelete2; - char ** pArgvNew; - int nArgcNew; - int c; - int fSat; - int fVerbose; - - extern void Abc_NtkCecSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2 ); - extern void Abc_NtkCecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fVerbose ); - - - pNtk = Abc_FrameReadNet(pAbc); - pOut = Abc_FrameReadOut(pAbc); - pErr = Abc_FrameReadErr(pAbc); - - // set defaults - fSat = 0; - fVerbose = 0; - util_getopt_reset(); - while ( ( c = util_getopt( argc, argv, "svh" ) ) != EOF ) - { - switch ( c ) - { - case 's': - fSat ^= 1; - break; - case 'v': - fVerbose ^= 1; - break; - default: - goto usage; - } - } - - pArgvNew = argv + util_optind; - nArgcNew = argc - util_optind; - if ( !Abc_NtkPrepareTwoNtks( pErr, pNtk, pArgvNew, nArgcNew, &pNtk1, &pNtk2, &fDelete1, &fDelete2 ) ) - return 1; - - // perform equivalence checking - if ( fSat ) - Abc_NtkCecSat( pNtk1, pNtk2 ); - else - Abc_NtkCecFraig( pNtk1, pNtk2, fVerbose ); - - if ( fDelete1 ) Abc_NtkDelete( pNtk1 ); - if ( fDelete2 ) Abc_NtkDelete( pNtk2 ); - return 0; - -usage: - fprintf( pErr, "usage: cec [-svh] \n" ); - fprintf( pErr, "\t performs combinational equivalence checking\n" ); - fprintf( pErr, "\t-s : toggle \"SAT only\" and \"FRAIG + SAT\" [default = %s]\n", fSat? "SAT only": "FRAIG + SAT" ); - fprintf( pErr, "\t-v : toggles verbose output [default = %s]\n", fVerbose? "yes": "no" ); - fprintf( pErr, "\t-h : print the command usage\n"); - fprintf( pErr, "\tfile1 : (optional) the file with the first network\n"); - fprintf( pErr, "\tfile2 : (optional) the file with the second network\n"); - fprintf( pErr, "\t if no files are given, uses the current network and its spec\n"); - fprintf( pErr, "\t if one file is given, uses the current network and the file\n"); - return 1; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_CommandSec( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - FILE * pOut, * pErr; - Abc_Ntk_t * pNtk, * pNtk1, * pNtk2; - int fDelete1, fDelete2; - char ** pArgvNew; - int nArgcNew; - int c; - int fSat; - int nFrames; - - extern void Abc_NtkSecSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nFrames ); - extern void Abc_NtkSecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nFrames ); - - - pNtk = Abc_FrameReadNet(pAbc); - pOut = Abc_FrameReadOut(pAbc); - pErr = Abc_FrameReadErr(pAbc); - - // set defaults - nFrames = 3; - fSat = 0; - util_getopt_reset(); - while ( ( c = util_getopt( argc, argv, "Fsh" ) ) != EOF ) - { - switch ( c ) - { - case 'F': - if ( util_optind >= argc ) - { - fprintf( pErr, "Command line switch \"-F\" should be followed by an integer.\n" ); - goto usage; - } - nFrames = atoi(argv[util_optind]); - util_optind++; - if ( nFrames < 0 ) - goto usage; - break; - case 's': - fSat ^= 1; - break; - default: - goto usage; - } - } - - pArgvNew = argv + util_optind; - nArgcNew = argc - util_optind; - if ( !Abc_NtkPrepareTwoNtks( pErr, pNtk, pArgvNew, nArgcNew, &pNtk1, &pNtk2, &fDelete1, &fDelete2 ) ) - return 1; - - // perform equivalence checking - if ( fSat ) - Abc_NtkSecSat( pNtk1, pNtk2, nFrames ); - else - Abc_NtkSecFraig( pNtk1, pNtk2, nFrames ); - - if ( fDelete1 ) Abc_NtkDelete( pNtk1 ); - if ( fDelete2 ) Abc_NtkDelete( pNtk2 ); - return 0; - -usage: - fprintf( pErr, "usage: sec [-sh] [-F num] \n" ); - fprintf( pErr, "\t performs bounded sequential equivalence checking\n" ); - fprintf( pErr, "\t-s : toggle \"SAT only\" and \"FRAIG + SAT\" [default = %s]\n", fSat? "SAT only": "FRAIG + SAT" ); - fprintf( pErr, "\t-h : print the command usage\n"); - fprintf( pErr, "\t-F num : the number of time frames to use [default = %d]\n", nFrames ); - fprintf( pErr, "\tfile1 : (optional) the file with the first network\n"); - fprintf( pErr, "\tfile2 : (optional) the file with the second network\n"); - fprintf( pErr, "\t if no files are given, uses the current network and its spec\n"); - fprintf( pErr, "\t if one file is given, uses the current network and the file\n"); - return 1; -} - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/base/abc/abc.h b/src/base/abc/abc.h index 81a1c328..bff4f9f1 100644 --- a/src/base/abc/abc.h +++ b/src/base/abc/abc.h @@ -165,6 +165,8 @@ struct Abc_Ntk_t_ // level information (for AIGs) int LevelMax; // maximum number of levels Vec_Int_t * vLevelsR; // level in the reverse topological order + // support information + Vec_Ptr_t * vSupps; // the external don't-care if given Abc_Ntk_t * pExdc; // the EXDC network // miscellaneous data members @@ -415,39 +417,6 @@ extern bool Abc_NtkCheckObj( Abc_Ntk_t * pNtk, Abc_Obj_t * pObj ); extern bool Abc_NtkCompareSignals( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb ); /*=== abcCollapse.c ==========================================================*/ extern Abc_Ntk_t * Abc_NtkCollapse( Abc_Ntk_t * pNtk, int fVerbose ); -/*=== abcCreate.c ==========================================================*/ -extern Abc_Ntk_t * Abc_NtkAlloc( Abc_NtkType_t Type, Abc_NtkFunc_t Func ); -extern Abc_Ntk_t * Abc_NtkStartFrom( Abc_Ntk_t * pNtk, Abc_NtkType_t Type, Abc_NtkFunc_t Func ); -extern void Abc_NtkFinalize( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ); -extern void Abc_NtkFinalizeLatches( Abc_Ntk_t * pNtk ); -extern Abc_Ntk_t * Abc_NtkStartRead( char * pName ); -extern void Abc_NtkFinalizeRead( Abc_Ntk_t * pNtk ); -extern Abc_Ntk_t * Abc_NtkDup( Abc_Ntk_t * pNtk ); -extern Abc_Ntk_t * Abc_NtkSplitOutput( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode, int fUseAllCis ); -extern Abc_Ntk_t * Abc_NtkCreateCone( Abc_Ntk_t * pNtk, Vec_Ptr_t * vRoots, Vec_Int_t * vValues ); -extern Abc_Ntk_t * Abc_NtkSplitNode( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode ); -extern void Abc_NtkDelete( Abc_Ntk_t * pNtk ); -extern void Abc_NtkFixNonDrivenNets( Abc_Ntk_t * pNtk ); -extern Abc_Obj_t * Abc_NtkDupObj( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj ); -extern Abc_Obj_t * Abc_NtkDupConst1( Abc_Ntk_t * pNtkAig, Abc_Ntk_t * pNtkNew ); -extern Abc_Obj_t * Abc_NtkDupReset( Abc_Ntk_t * pNtkAig, Abc_Ntk_t * pNtkNew ); -extern void Abc_NtkDeleteObj( Abc_Obj_t * pObj ); -extern Abc_Obj_t * Abc_NtkFindNode( Abc_Ntk_t * pNtk, char * pName ); -extern Abc_Obj_t * Abc_NtkFindCo( Abc_Ntk_t * pNtk, char * pName ); -extern Abc_Obj_t * Abc_NtkFindNet( Abc_Ntk_t * pNtk, char * pName ); -extern Abc_Obj_t * Abc_NtkFindOrCreateNet( Abc_Ntk_t * pNtk, char * pName ); -extern Abc_Obj_t * Abc_NtkCreateNode( Abc_Ntk_t * pNtk ); -extern Abc_Obj_t * Abc_NtkCreatePi( Abc_Ntk_t * pNtk ); -extern Abc_Obj_t * Abc_NtkCreatePo( Abc_Ntk_t * pNtk ); -extern Abc_Obj_t * Abc_NtkCreateLatch( Abc_Ntk_t * pNtk ); -extern Abc_Obj_t * Abc_NodeCreateConst0( Abc_Ntk_t * pNtk ); -extern Abc_Obj_t * Abc_NodeCreateConst1( Abc_Ntk_t * pNtk ); -extern Abc_Obj_t * Abc_NodeCreateInv( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin ); -extern Abc_Obj_t * Abc_NodeCreateBuf( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin ); -extern Abc_Obj_t * Abc_NodeCreateAnd( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins ); -extern Abc_Obj_t * Abc_NodeCreateOr( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins ); -extern Abc_Obj_t * Abc_NodeCreateMux( Abc_Ntk_t * pNtk, Abc_Obj_t * pNodeC, Abc_Obj_t * pNode1, Abc_Obj_t * pNode0 ); -extern Abc_Obj_t * Abc_NodeClone( Abc_Obj_t * pNode ); /*=== abcCut.c ==========================================================*/ extern void * Abc_NodeGetCutsRecursive( void * p, Abc_Obj_t * pObj ); extern void * Abc_NodeGetCuts( void * p, Abc_Obj_t * pObj ); @@ -486,7 +455,6 @@ extern void Abc_NtkLogicMakeDirectSops( Abc_Ntk_t * pNtk ); extern bool Abc_NtkLatchIsSelfFeed( Abc_Obj_t * pLatch ); extern int Abc_NtkCountSelfFeedLatches( Abc_Ntk_t * pNtk ); /*=== abcMap.c ==========================================================*/ -extern Abc_Ntk_t * Abc_NtkMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, int fVerbose ); extern int Abc_NtkUnmap( Abc_Ntk_t * pNtk ); /*=== abcMiter.c ==========================================================*/ extern int Abc_NtkMinimumBase( Abc_Ntk_t * pNtk ); @@ -495,11 +463,35 @@ extern int Abc_NtkRemoveDupFanins( Abc_Ntk_t * pNtk ); extern int Abc_NodeRemoveDupFanins( Abc_Obj_t * pNode ); /*=== abcMiter.c ==========================================================*/ extern Abc_Ntk_t * Abc_NtkMiter( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb ); -extern Abc_Ntk_t * Abc_NtkMiterOne( Abc_Ntk_t * pNtk, int Out, int In1, int In2 ); +extern Abc_Ntk_t * Abc_NtkMiterForCofactors( Abc_Ntk_t * pNtk, int Out, int In1, int In2 ); extern int Abc_NtkMiterIsConstant( Abc_Ntk_t * pMiter ); extern void Abc_NtkMiterReport( Abc_Ntk_t * pMiter ); extern int Abc_NtkAppend( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2 ); extern Abc_Ntk_t * Abc_NtkFrames( Abc_Ntk_t * pNtk, int nFrames, int fInitial ); +/*=== abcObj.c ==========================================================*/ +extern Abc_Obj_t * Abc_ObjAlloc( Abc_Ntk_t * pNtk, Abc_ObjType_t Type ); +extern void Abc_ObjRecycle( Abc_Obj_t * pObj ); +extern void Abc_ObjAdd( Abc_Obj_t * pObj ); +extern Abc_Obj_t * Abc_NtkDupObj( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj ); +extern Abc_Obj_t * Abc_NtkDupConst1( Abc_Ntk_t * pNtkAig, Abc_Ntk_t * pNtkNew ); +extern Abc_Obj_t * Abc_NtkDupReset( Abc_Ntk_t * pNtkAig, Abc_Ntk_t * pNtkNew ); +extern void Abc_NtkDeleteObj( Abc_Obj_t * pObj ); +extern Abc_Obj_t * Abc_NtkFindNode( Abc_Ntk_t * pNtk, char * pName ); +extern Abc_Obj_t * Abc_NtkFindCo( Abc_Ntk_t * pNtk, char * pName ); +extern Abc_Obj_t * Abc_NtkFindNet( Abc_Ntk_t * pNtk, char * pName ); +extern Abc_Obj_t * Abc_NtkFindOrCreateNet( Abc_Ntk_t * pNtk, char * pName ); +extern Abc_Obj_t * Abc_NtkCreateNode( Abc_Ntk_t * pNtk ); +extern Abc_Obj_t * Abc_NtkCreatePi( Abc_Ntk_t * pNtk ); +extern Abc_Obj_t * Abc_NtkCreatePo( Abc_Ntk_t * pNtk ); +extern Abc_Obj_t * Abc_NtkCreateLatch( Abc_Ntk_t * pNtk ); +extern Abc_Obj_t * Abc_NodeCreateConst0( Abc_Ntk_t * pNtk ); +extern Abc_Obj_t * Abc_NodeCreateConst1( Abc_Ntk_t * pNtk ); +extern Abc_Obj_t * Abc_NodeCreateInv( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin ); +extern Abc_Obj_t * Abc_NodeCreateBuf( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin ); +extern Abc_Obj_t * Abc_NodeCreateAnd( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins ); +extern Abc_Obj_t * Abc_NodeCreateOr( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins ); +extern Abc_Obj_t * Abc_NodeCreateMux( Abc_Ntk_t * pNtk, Abc_Obj_t * pNodeC, Abc_Obj_t * pNode1, Abc_Obj_t * pNode0 ); +extern Abc_Obj_t * Abc_NodeClone( Abc_Obj_t * pNode ); /*=== abcNames.c ====================================================*/ extern char * Abc_NtkRegisterName( Abc_Ntk_t * pNtk, char * pName ); extern char * Abc_NtkRegisterNamePlus( Abc_Ntk_t * pNtk, char * pName, char * pSuffix ); @@ -529,6 +521,20 @@ extern Abc_Ntk_t * Abc_NtkDeriveFromBdd( DdManager * dd, DdNode * bFunc, extern Abc_Ntk_t * Abc_NtkBddToMuxes( Abc_Ntk_t * pNtk ); extern DdManager * Abc_NtkGlobalBdds( Abc_Ntk_t * pNtk, int fLatchOnly ); extern void Abc_NtkFreeGlobalBdds( Abc_Ntk_t * pNtk ); +/*=== abcNtk.c ==========================================================*/ +extern Abc_Ntk_t * Abc_NtkAlloc( Abc_NtkType_t Type, Abc_NtkFunc_t Func ); +extern Abc_Ntk_t * Abc_NtkStartFrom( Abc_Ntk_t * pNtk, Abc_NtkType_t Type, Abc_NtkFunc_t Func ); +extern void Abc_NtkFinalize( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ); +extern void Abc_NtkFinalizeRegular( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ); +extern void Abc_NtkFinalizeLatches( Abc_Ntk_t * pNtk ); +extern Abc_Ntk_t * Abc_NtkStartRead( char * pName ); +extern void Abc_NtkFinalizeRead( Abc_Ntk_t * pNtk ); +extern Abc_Ntk_t * Abc_NtkDup( Abc_Ntk_t * pNtk ); +extern Abc_Ntk_t * Abc_NtkSplitOutput( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode, int fUseAllCis ); +extern Abc_Ntk_t * Abc_NtkCreateCone( Abc_Ntk_t * pNtk, Vec_Ptr_t * vRoots, Vec_Int_t * vValues ); +extern Abc_Ntk_t * Abc_NtkSplitNode( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode ); +extern void Abc_NtkDelete( Abc_Ntk_t * pNtk ); +extern void Abc_NtkFixNonDrivenNets( Abc_Ntk_t * pNtk ); /*=== abcPrint.c ==========================================================*/ extern void Abc_NtkPrintStats( FILE * pFile, Abc_Ntk_t * pNtk, int fFactored ); extern void Abc_NtkPrintIo( FILE * pFile, Abc_Ntk_t * pNtk ); diff --git a/src/base/abc/abcAttach.c b/src/base/abc/abcAttach.c deleted file mode 100644 index a8e06555..00000000 --- a/src/base/abc/abcAttach.c +++ /dev/null @@ -1,405 +0,0 @@ -/**CFile**************************************************************** - - FileName [abcAttach.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Network and node package.] - - Synopsis [Attaches the library gates to the current network.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: abcAttach.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" -#include "main.h" -#include "mio.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -#define ATTACH_FULL (~((unsigned)0)) -#define ATTACH_MASK(n) ((~((unsigned)0)) >> (32-(n))) - -static void Abc_AttachSetupTruthTables( unsigned uTruths[][2] ); -static void Abc_AttachComputeTruth( char * pSop, unsigned uTruthsIn[][2], unsigned * uTruthNode ); -static Mio_Gate_t * Abc_AttachFind( Mio_Gate_t ** ppGates, unsigned ** puTruthGates, int nGates, unsigned * uTruthNode, int * Perm ); -static int Abc_AttachCompare( unsigned ** puTruthGates, int nGates, unsigned * uTruthNode ); -static int Abc_NodeAttach( Abc_Obj_t * pNode, Mio_Gate_t ** ppGates, unsigned ** puTruthGates, int nGates, unsigned uTruths[][2] ); -static void Abc_TruthPermute( char * pPerm, int nVars, unsigned * uTruthNode, unsigned * uTruthPerm ); - -static char ** s_pPerms = NULL; -static int s_nPerms; - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Attaches gates from the current library to the internal nodes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkAttach( Abc_Ntk_t * pNtk ) -{ - int fCheck = 1; - Mio_Library_t * pGenlib; - unsigned ** puTruthGates; - unsigned uTruths[6][2]; - Abc_Obj_t * pNode; - Mio_Gate_t ** ppGates; - int nGates, nFanins, i; - - assert( Abc_NtkIsSopLogic(pNtk) ); - - // check that the library is available - pGenlib = Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()); - if ( pGenlib == NULL ) - { - printf( "The current library is not available.\n" ); - return 0; - } - - // start the truth tables - Abc_AttachSetupTruthTables( uTruths ); - - // collect all the gates - ppGates = Mio_CollectRoots( pGenlib, 6, (float)1.0e+20, 1, &nGates ); - - // derive the gate truth tables - puTruthGates = ALLOC( unsigned *, nGates ); - puTruthGates[0] = ALLOC( unsigned, 2 * nGates ); - for ( i = 1; i < nGates; i++ ) - puTruthGates[i] = puTruthGates[i-1] + 2; - for ( i = 0; i < nGates; i++ ) - Mio_DeriveTruthTable( ppGates[i], uTruths, Mio_GateReadInputs(ppGates[i]), 6, puTruthGates[i] ); - - // assign the gates to pNode->pCopy - Abc_NtkCleanCopy( pNtk ); - Abc_NtkForEachNode( pNtk, pNode, i ) - { - nFanins = Abc_ObjFaninNum(pNode); - if ( nFanins == 0 ) - { - if ( Abc_SopIsConst1(pNode->pData) ) - pNode->pCopy = (Abc_Obj_t *)Mio_LibraryReadConst1(pGenlib); - else - pNode->pCopy = (Abc_Obj_t *)Mio_LibraryReadConst0(pGenlib); - } - else if ( nFanins == 1 ) - { - if ( Abc_SopIsBuf(pNode->pData) ) - pNode->pCopy = (Abc_Obj_t *)Mio_LibraryReadBuf(pGenlib); - else - pNode->pCopy = (Abc_Obj_t *)Mio_LibraryReadInv(pGenlib); - } - else if ( nFanins > 6 ) - { - printf( "Cannot attach gate with more than 6 inputs to node %s.\n", Abc_ObjName(pNode) ); - free( puTruthGates[0] ); - free( puTruthGates ); - free( ppGates ); - return 0; - } - else if ( !Abc_NodeAttach( pNode, ppGates, puTruthGates, nGates, uTruths ) ) - { - printf( "Could not attach the library gate to node %s.\n", Abc_ObjName(pNode) ); - free( puTruthGates[0] ); - free( puTruthGates ); - free( ppGates ); - return 0; - } - } - free( puTruthGates[0] ); - free( puTruthGates ); - free( ppGates ); - FREE( s_pPerms ); - - // perform the final transformation - Abc_NtkForEachNode( pNtk, pNode, i ) - { - if ( pNode->pCopy == NULL ) - { - printf( "Some elementary gates (constant, buffer, or inverter) are missing in the library.\n" ); - return 0; - } - } - - // replace SOP representation by the gate representation - Abc_NtkForEachNode( pNtk, pNode, i ) - pNode->pData = pNode->pCopy, pNode->pCopy = NULL; - pNtk->ntkFunc = ABC_FUNC_MAP; - Extra_MmFlexStop( pNtk->pManFunc, 0 ); - pNtk->pManFunc = pGenlib; - - printf( "Library gates are successfully attached to the nodes.\n" ); - - // make sure that everything is okay - if ( fCheck && !Abc_NtkCheck( pNtk ) ) - { - printf( "Abc_NtkAttach: The network check has failed.\n" ); - return 0; - } - return 1; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NodeAttach( Abc_Obj_t * pNode, Mio_Gate_t ** ppGates, unsigned ** puTruthGates, int nGates, unsigned uTruths[][2] ) -{ - int Perm[10]; - int pTempInts[10]; - unsigned uTruthNode[2]; - Abc_Obj_t * pFanin; - Mio_Gate_t * pGate; - int nFanins, i; - - // compute the node's truth table - Abc_AttachComputeTruth( pNode->pData, uTruths, uTruthNode ); - // find the matching gate and permutation - pGate = Abc_AttachFind( ppGates, puTruthGates, nGates, uTruthNode, Perm ); - if ( pGate == NULL ) - return 0; - // permute the fanins - nFanins = Abc_ObjFaninNum(pNode); - Abc_ObjForEachFanin( pNode, pFanin, i ) - pTempInts[i] = pFanin->Id; - for ( i = 0; i < nFanins; i++ ) - pNode->vFanins.pArray[Perm[i]].iFan = pTempInts[i]; - // set the gate - pNode->pCopy = (Abc_Obj_t *)pGate; - return 1; -} - -/**Function************************************************************* - - Synopsis [Sets up the truth tables.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_AttachSetupTruthTables( unsigned uTruths[][2] ) -{ - int m, v; - for ( v = 0; v < 5; v++ ) - uTruths[v][0] = 0; - // set up the truth tables - for ( m = 0; m < 32; m++ ) - for ( v = 0; v < 5; v++ ) - if ( m & (1 << v) ) - uTruths[v][0] |= (1 << m); - // make adjustments for the case of 6 variables - for ( v = 0; v < 5; v++ ) - uTruths[v][1] = uTruths[v][0]; - uTruths[5][0] = 0; - uTruths[5][1] = ATTACH_FULL; -} - -/**Function************************************************************* - - Synopsis [Compute the truth table of the node's cover.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_AttachComputeTruth( char * pSop, unsigned uTruthsIn[][2], unsigned * uTruthRes ) -{ -// Mvc_Cube_t * pCube; - unsigned uSignCube[2]; - int Value; -// int nInputs = pCover->nBits/2; - int nInputs = 6; - int nFanins = Abc_SopGetVarNum(pSop); - char * pCube; - int k; - - // make sure that the number of input truth tables in equal to the number of gate inputs - assert( nInputs < 7 ); - - // clean the resulting truth table - uTruthRes[0] = 0; - uTruthRes[1] = 0; - if ( nInputs < 6 ) - { - // consider the case when only one unsigned can be used -// Mvc_CoverForEachCube( pCover, pCube ) - Abc_SopForEachCube( pSop, nFanins, pCube ) - { - uSignCube[0] = ATTACH_FULL; -// Mvc_CubeForEachVarValue( pCover, pCube, Var, Value ) - Abc_CubeForEachVar( pCube, Value, k ) - { - if ( Value == '0' ) - uSignCube[0] &= ~uTruthsIn[k][0]; - else if ( Value == '1' ) - uSignCube[0] &= uTruthsIn[k][0]; - } - uTruthRes[0] |= uSignCube[0]; - } - if ( Abc_SopGetPhase(pSop) == 0 ) - uTruthRes[0] = ~uTruthRes[0]; - if ( nInputs < 5 ) - uTruthRes[0] &= ATTACH_MASK(1<= 0 ) - { - for ( v = 0; v < 6; v++ ) - Perm[v] = v; - return ppGates[iNum]; - } - // get permutations - if ( s_pPerms == NULL ) - { - s_pPerms = Extra_Permutations( 6 ); - s_nPerms = Extra_Factorial( 6 ); - } - // try permutations - for ( i = 0; i < s_nPerms; i++ ) - { - Abc_TruthPermute( s_pPerms[i], 6, uTruthNode, uTruthPerm ); - if ( (iNum = Abc_AttachCompare( puTruthGates, nGates, uTruthPerm )) >= 0 ) - { - for ( v = 0; v < 6; v++ ) - Perm[v] = (int)s_pPerms[i][v]; - return ppGates[iNum]; - } - } - return NULL; -} - -/**Function************************************************************* - - Synopsis [Find the gate by truth table.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_AttachCompare( unsigned ** puTruthGates, int nGates, unsigned * uTruthNode ) -{ - int i; - for ( i = 0; i < nGates; i++ ) - if ( puTruthGates[i][0] == uTruthNode[0] && puTruthGates[i][1] == uTruthNode[1] ) - return i; - return -1; -} - -/**Function************************************************************* - - Synopsis [Permutes the 6-input truth table.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_TruthPermute( char * pPerm, int nVars, unsigned * uTruthNode, unsigned * uTruthPerm ) -{ - int nMints, iMintPerm, iMint, v; - uTruthPerm[0] = uTruthPerm[1] = 0; - nMints = (1 << nVars); - for ( iMint = 0; iMint < nMints; iMint++ ) - { - if ( (uTruthNode[iMint/32] & (1 << (iMint%32))) == 0 ) - continue; - iMintPerm = 0; - for ( v = 0; v < nVars; v++ ) - if ( iMint & (1 << v) ) - iMintPerm |= (1 << pPerm[v]); - uTruthPerm[iMintPerm/32] |= (1 << (iMintPerm%32)); - } -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/base/abc/abcBalance.c b/src/base/abc/abcBalance.c deleted file mode 100644 index 7deab3ba..00000000 --- a/src/base/abc/abcBalance.c +++ /dev/null @@ -1,236 +0,0 @@ -/**CFile**************************************************************** - - FileName [abcBalance.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Network and node package.] - - Synopsis [Performs global balancing of the AIG by the number of levels.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: abcBalance.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static void Abc_NtkBalancePerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkAig, bool fDuplicate ); -static Abc_Obj_t * Abc_NodeBalance_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode, bool fDuplicate ); -static Vec_Ptr_t * Abc_NodeBalanceCone( Abc_Obj_t * pNode, int fDuplicate ); -static int Abc_NodeBalanceCone_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vSuper, bool fFirst, bool fDuplicate ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Balances the AIG network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_NtkBalance( Abc_Ntk_t * pNtk, bool fDuplicate ) -{ - int fCheck = 1; - Abc_Ntk_t * pNtkAig; - assert( Abc_NtkIsStrash(pNtk) ); - // perform balancing - pNtkAig = Abc_NtkStartFrom( pNtk, ABC_TYPE_STRASH, ABC_FUNC_AIG ); - Abc_NtkBalancePerform( pNtk, pNtkAig, fDuplicate ); - Abc_NtkFinalize( pNtk, pNtkAig ); - // make sure everything is okay - if ( fCheck && !Abc_NtkCheck( pNtkAig ) ) - { - printf( "Abc_NtkBalance: The network check has failed.\n" ); - Abc_NtkDelete( pNtkAig ); - return NULL; - } - return pNtkAig; -} - -/**Function************************************************************* - - Synopsis [Balances the AIG network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkBalancePerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkAig, bool fDuplicate ) -{ - int fCheck = 1; - ProgressBar * pProgress; - Abc_Obj_t * pNode, * pDriver; - int i; - - // copy the constant node - Abc_AigConst1(pNtk->pManFunc)->pCopy = Abc_AigConst1(pNtkAig->pManFunc); - // set the level of PIs of AIG according to the arrival times of the old network - Abc_NtkSetNodeLevelsArrival( pNtk ); - // perform balancing of POs - pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCoNum(pNtk) ); - Abc_NtkForEachCo( pNtk, pNode, i ) - { - Extra_ProgressBarUpdate( pProgress, i, NULL ); - // strash the driver node - pDriver = Abc_ObjFanin0(pNode); - Abc_NodeBalance_rec( pNtkAig, pDriver, fDuplicate ); - } - Extra_ProgressBarStop( pProgress ); -} - -/**Function************************************************************* - - Synopsis [Rebalances the multi-input node rooted at pNodeOld.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_NodeBalance_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNodeOld, bool fDuplicate ) -{ - Abc_Aig_t * pMan = pNtkNew->pManFunc; - Abc_Obj_t * pNodeNew, * pNode1, * pNode2; - Vec_Ptr_t * vSuper; - int i; - assert( !Abc_ObjIsComplement(pNodeOld) ); - // return if the result if known - if ( pNodeOld->pCopy ) - return pNodeOld->pCopy; - assert( Abc_ObjIsNode(pNodeOld) ); - // get the implication supergate - vSuper = Abc_NodeBalanceCone( pNodeOld, fDuplicate ); - if ( vSuper->nSize == 0 ) - { // it means that the supergate contains two nodes in the opposite polarity - Vec_PtrFree( vSuper ); - pNodeOld->pCopy = Abc_ObjNot(Abc_AigConst1(pMan)); - return pNodeOld->pCopy; - } - // for each old node, derive the new well-balanced node - for ( i = 0; i < vSuper->nSize; i++ ) - { - pNodeNew = Abc_NodeBalance_rec( pNtkNew, Abc_ObjRegular(vSuper->pArray[i]), fDuplicate ); - vSuper->pArray[i] = Abc_ObjNotCond( pNodeNew, Abc_ObjIsComplement(vSuper->pArray[i]) ); - } - // sort the new nodes by level in the decreasing order - Vec_PtrSort( vSuper, Abc_NodeCompareLevelsDecrease ); - // balance the nodes - assert( vSuper->nSize > 1 ); - while ( vSuper->nSize > 1 ) - { - pNode1 = Vec_PtrPop(vSuper); - pNode2 = Vec_PtrPop(vSuper); - Abc_VecObjPushUniqueOrderByLevel( vSuper, Abc_AigAnd(pMan, pNode1, pNode2) ); - } - // make sure the balanced node is not assigned - assert( pNodeOld->pCopy == NULL ); - // mark the old node with the new node - pNodeOld->pCopy = vSuper->pArray[0]; - Vec_PtrFree( vSuper ); - return pNodeOld->pCopy; -} - -/**Function************************************************************* - - Synopsis [Collects the nodes in the cone delimited by fMarkA==1.] - - Description [Returns -1 if the AND-cone has the same node in both polarities. - Returns 1 if the AND-cone has the same node in the same polarity. Returns 0 - if the AND-cone has no repeated nodes.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Ptr_t * Abc_NodeBalanceCone( Abc_Obj_t * pNode, int fDuplicate ) -{ - Vec_Ptr_t * vNodes; - int RetValue, i; - assert( !Abc_ObjIsComplement(pNode) ); - vNodes = Vec_PtrAlloc( 4 ); - RetValue = Abc_NodeBalanceCone_rec( pNode, vNodes, 1, fDuplicate ); - assert( vNodes->nSize > 0 ); - for ( i = 0; i < vNodes->nSize; i++ ) - Abc_ObjRegular((Abc_Obj_t *)vNodes->pArray[i])->fMarkB = 0; - if ( RetValue == -1 ) - vNodes->nSize = 0; - return vNodes; -} - - -/**Function************************************************************* - - Synopsis [Collects the nodes in the cone delimited by fMarkA==1.] - - Description [Returns -1 if the AND-cone has the same node in both polarities. - Returns 1 if the AND-cone has the same node in the same polarity. Returns 0 - if the AND-cone has no repeated nodes.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NodeBalanceCone_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vSuper, bool fFirst, bool fDuplicate ) -{ - int RetValue1, RetValue2, i; - // check if the node is visited - if ( Abc_ObjRegular(pNode)->fMarkB ) - { - // check if the node occurs in the same polarity - for ( i = 0; i < vSuper->nSize; i++ ) - if ( vSuper->pArray[i] == pNode ) - return 1; - // check if the node is present in the opposite polarity - for ( i = 0; i < vSuper->nSize; i++ ) - if ( vSuper->pArray[i] == Abc_ObjNot(pNode) ) - return -1; - assert( 0 ); - return 0; - } - // if the new node is complemented or a PI, another gate begins - if ( !fFirst && (Abc_ObjIsComplement(pNode) || !Abc_ObjIsNode(pNode) || !fDuplicate && (Abc_ObjFanoutNum(pNode) > 1)) ) - { - Vec_PtrPush( vSuper, pNode ); - Abc_ObjRegular(pNode)->fMarkB = 1; - return 0; - } - assert( !Abc_ObjIsComplement(pNode) ); - assert( Abc_ObjIsNode(pNode) ); - // go through the branches - RetValue1 = Abc_NodeBalanceCone_rec( Abc_ObjChild0(pNode), vSuper, 0, fDuplicate ); - RetValue2 = Abc_NodeBalanceCone_rec( Abc_ObjChild1(pNode), vSuper, 0, fDuplicate ); - if ( RetValue1 == -1 || RetValue2 == -1 ) - return -1; - // return 1 if at least one branch has a duplicate - return RetValue1 || RetValue2; -} - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/base/abc/abcCollapse.c b/src/base/abc/abcCollapse.c deleted file mode 100644 index 4e359506..00000000 --- a/src/base/abc/abcCollapse.c +++ /dev/null @@ -1,147 +0,0 @@ -/**CFile**************************************************************** - - FileName [abcCollapse.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Network and node package.] - - Synopsis [Collapsing the network into two-levels.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: abcCollapse.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static Abc_Ntk_t * Abc_NtkFromGlobalBdds( Abc_Ntk_t * pNtk ); -static Abc_Obj_t * Abc_NodeFromGlobalBdds( Abc_Ntk_t * pNtkNew, DdManager * dd, DdNode * bFunc ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Collapses the network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_NtkCollapse( Abc_Ntk_t * pNtk, int fVerbose ) -{ - int fCheck = 1; - Abc_Ntk_t * pNtkNew; - - assert( Abc_NtkIsStrash(pNtk) ); - - // compute the global BDDs - if ( Abc_NtkGlobalBdds(pNtk, 0) == NULL ) - return NULL; - if ( fVerbose ) - printf( "The shared BDD size is %d nodes.\n", Cudd_ReadKeys(pNtk->pManGlob) - Cudd_ReadDead(pNtk->pManGlob) ); - - // create the new network - pNtkNew = Abc_NtkFromGlobalBdds( pNtk ); - Abc_NtkFreeGlobalBdds( pNtk ); - if ( pNtkNew == NULL ) - { - Cudd_Quit( pNtk->pManGlob ); - pNtk->pManGlob = NULL; - return NULL; - } - Extra_StopManager( pNtk->pManGlob ); - pNtk->pManGlob = NULL; - - // make the network minimum base - Abc_NtkMinimumBase( pNtkNew ); - - // make sure that everything is okay - if ( fCheck && !Abc_NtkCheck( pNtkNew ) ) - { - printf( "Abc_NtkCollapse: The network check has failed.\n" ); - Abc_NtkDelete( pNtkNew ); - return NULL; - } - return pNtkNew; -} - -/**Function************************************************************* - - Synopsis [Derives the network with the given global BDD.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_NtkFromGlobalBdds( Abc_Ntk_t * pNtk ) -{ - ProgressBar * pProgress; - Abc_Ntk_t * pNtkNew; - Abc_Obj_t * pNode, * pNodeNew; - DdManager * dd = pNtk->pManGlob; - int i; - // start the new network - pNtkNew = Abc_NtkStartFrom( pNtk, ABC_TYPE_LOGIC, ABC_FUNC_BDD ); - // make sure the new manager has the same number of inputs - Cudd_bddIthVar( pNtkNew->pManFunc, dd->size-1 ); - // process the POs - pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCoNum(pNtk) ); - Abc_NtkForEachCo( pNtk, pNode, i ) - { - Extra_ProgressBarUpdate( pProgress, i, NULL ); - pNodeNew = Abc_NodeFromGlobalBdds( pNtkNew, dd, Vec_PtrEntry(pNtk->vFuncsGlob, i) ); - Abc_ObjAddFanin( pNode->pCopy, pNodeNew ); - } - Extra_ProgressBarStop( pProgress ); - return pNtkNew; -} - -/**Function************************************************************* - - Synopsis [Derives the network with the given global BDD.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_NodeFromGlobalBdds( Abc_Ntk_t * pNtkNew, DdManager * dd, DdNode * bFunc ) -{ - Abc_Obj_t * pNodeNew, * pTemp; - int i; - // create a new node - pNodeNew = Abc_NtkCreateNode( pNtkNew ); - // add the fanins in the order, in which they appear in the reordered manager - Abc_NtkForEachCi( pNtkNew, pTemp, i ) - Abc_ObjAddFanin( pNodeNew, Abc_NtkCi(pNtkNew, dd->invperm[i]) ); - // transfer the function - pNodeNew->pData = Extra_TransferLevelByLevel( dd, pNtkNew->pManFunc, bFunc ); Cudd_Ref( pNodeNew->pData ); - return pNodeNew; -} - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/base/abc/abcCreate.c b/src/base/abc/abcCreate.c deleted file mode 100644 index 16d5ec05..00000000 --- a/src/base/abc/abcCreate.c +++ /dev/null @@ -1,1407 +0,0 @@ -/**CFile**************************************************************** - - FileName [abcCreate.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Network and node package.] - - Synopsis [Creation/duplication/deletion procedures.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: abcCreate.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" -#include "main.h" -#include "mio.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -#define ABC_NUM_STEPS 10 - -static Abc_Obj_t * Abc_ObjAlloc( Abc_Ntk_t * pNtk, Abc_ObjType_t Type ); -static void Abc_ObjRecycle( Abc_Obj_t * pObj ); -static void Abc_ObjAdd( Abc_Obj_t * pObj ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Creates a new Ntk.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_NtkAlloc( Abc_NtkType_t Type, Abc_NtkFunc_t Func ) -{ - Abc_Ntk_t * pNtk; - pNtk = ALLOC( Abc_Ntk_t, 1 ); - memset( pNtk, 0, sizeof(Abc_Ntk_t) ); - pNtk->ntkType = Type; - pNtk->ntkFunc = Func; - // start the object storage - pNtk->vObjs = Vec_PtrAlloc( 100 ); - pNtk->vLats = Vec_PtrAlloc( 100 ); - pNtk->vCis = Vec_PtrAlloc( 100 ); - pNtk->vCos = Vec_PtrAlloc( 100 ); - pNtk->vPtrTemp = Vec_PtrAlloc( 100 ); - pNtk->vIntTemp = Vec_IntAlloc( 100 ); - pNtk->vStrTemp = Vec_StrAlloc( 100 ); - // start the hash table - pNtk->tName2Net = stmm_init_table(strcmp, stmm_strhash); - pNtk->tObj2Name = stmm_init_table(stmm_ptrcmp, stmm_ptrhash); - // start the memory managers - pNtk->pMmNames = Extra_MmFlexStart(); - pNtk->pMmObj = Extra_MmFixedStart( sizeof(Abc_Obj_t) ); - pNtk->pMmStep = Extra_MmStepStart( ABC_NUM_STEPS ); - // get ready to assign the first Obj ID - pNtk->nTravIds = 1; - // start the functionality manager - if ( Abc_NtkHasSop(pNtk) ) - pNtk->pManFunc = Extra_MmFlexStart(); - else if ( Abc_NtkHasBdd(pNtk) ) - pNtk->pManFunc = Cudd_Init( 20, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 ); - else if ( Abc_NtkHasAig(pNtk) ) - pNtk->pManFunc = Abc_AigAlloc( pNtk ); - else if ( Abc_NtkHasMapping(pNtk) ) - pNtk->pManFunc = Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()); - else - assert( 0 ); - return pNtk; -} - -/**Function************************************************************* - - Synopsis [Starts a new network using existing network as a model.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_NtkStartFrom( Abc_Ntk_t * pNtk, Abc_NtkType_t Type, Abc_NtkFunc_t Func ) -{ - Abc_Ntk_t * pNtkNew; - Abc_Obj_t * pObj, * pObjNew; - int i; - if ( pNtk == NULL ) - return NULL; - // start the network - pNtkNew = Abc_NtkAlloc( Type, Func ); - // duplicate the name and the spec - pNtkNew->pName = util_strsav(pNtk->pName); - pNtkNew->pSpec = util_strsav(pNtk->pSpec); - // clone the PIs/POs/latches - Abc_NtkForEachPi( pNtk, pObj, i ) - Abc_NtkDupObj(pNtkNew, pObj); - Abc_NtkForEachPo( pNtk, pObj, i ) - Abc_NtkDupObj(pNtkNew, pObj); - Abc_NtkForEachLatch( pNtk, pObj, i ) - { - pObjNew = Abc_NtkDupObj(pNtkNew, pObj); - Vec_PtrPush( pNtkNew->vCis, pObjNew ); - Vec_PtrPush( pNtkNew->vCos, pObjNew ); - } - // clean the node copy fields - Abc_NtkForEachNode( pNtk, pObj, i ) - pObj->pCopy = NULL; - // transfer the names - Abc_NtkDupCioNamesTable( pNtk, pNtkNew ); - Abc_ManTimeDup( pNtk, pNtkNew ); - return pNtkNew; -} - -/**Function************************************************************* - - Synopsis [Finalizes the network using the existing network as a model.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkFinalize( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ) -{ - Abc_Obj_t * pObj, * pDriver, * pDriverNew; - int i; - // set the COs of the strashed network - Abc_NtkForEachCo( pNtk, pObj, i ) - { - pDriver = Abc_ObjFanin0Ntk( Abc_ObjFanin0(pObj) ); - pDriverNew = Abc_ObjNotCond(pDriver->pCopy, Abc_ObjFaninC0(pObj)); - Abc_ObjAddFanin( pObj->pCopy, pDriverNew ); - } -} - -/**Function************************************************************* - - Synopsis [Finalizes the network adding latches to CI/CO lists and creates their names.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkFinalizeLatches( Abc_Ntk_t * pNtk ) -{ - Abc_Obj_t * pLatch; - int i; - // set the COs of the strashed network - Abc_NtkForEachLatch( pNtk, pLatch, i ) - { - Vec_PtrPush( pNtk->vCis, pLatch ); - Vec_PtrPush( pNtk->vCos, pLatch ); - Abc_NtkLogicStoreName( pLatch, Abc_ObjNameSuffix(pLatch, "L") ); - } -} - -/**Function************************************************************* - - Synopsis [Starts a new network using existing network as a model.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_NtkStartRead( char * pName ) -{ - Abc_Ntk_t * pNtkNew; - // allocate the empty network - pNtkNew = Abc_NtkAlloc( ABC_TYPE_NETLIST, ABC_FUNC_SOP ); - // set the specs - pNtkNew->pName = util_strsav( pName ); - pNtkNew->pSpec = util_strsav( pName ); - return pNtkNew; -} - -/**Function************************************************************* - - Synopsis [Finalizes the network using the existing network as a model.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkFinalizeRead( Abc_Ntk_t * pNtk ) -{ - Abc_Obj_t * pLatch; - int i; - assert( Abc_NtkIsNetlist(pNtk) ); - // fix the net drivers - Abc_NtkFixNonDrivenNets( pNtk ); - // create the names table - Abc_NtkCreateCioNamesTable( pNtk ); - // add latches to the CI/CO arrays - Abc_NtkForEachLatch( pNtk, pLatch, i ) - { - Vec_PtrPush( pNtk->vCis, pLatch ); - Vec_PtrPush( pNtk->vCos, pLatch ); - } -} - -/**Function************************************************************* - - Synopsis [Duplicate the network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_NtkDup( Abc_Ntk_t * pNtk ) -{ - Abc_Ntk_t * pNtkNew; - Abc_Obj_t * pObj, * pFanin; - int i, k; - if ( pNtk == NULL ) - return NULL; - // start the network - pNtkNew = Abc_NtkStartFrom( pNtk, pNtk->ntkType, pNtk->ntkFunc ); - // copy the internal nodes - if ( Abc_NtkHasAig(pNtk) ) - Abc_AigDup( pNtk->pManFunc, pNtkNew->pManFunc ); - else - { - // duplicate the nets and nodes (CIs/COs/latches already dupped) - Abc_NtkForEachObj( pNtk, pObj, i ) - if ( pObj->pCopy == NULL ) - Abc_NtkDupObj(pNtkNew, pObj); - // reconnect all objects (no need to transfer attributes on edges) - Abc_NtkForEachObj( pNtk, pObj, i ) - Abc_ObjForEachFanin( pObj, pFanin, k ) - Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy ); - } - // duplicate the EXDC Ntk - if ( pNtk->pExdc ) - pNtkNew->pExdc = Abc_NtkDup( pNtk->pExdc ); - if ( !Abc_NtkCheck( pNtkNew ) ) - fprintf( stdout, "Abc_NtkDup(): Network check has failed.\n" ); - return pNtkNew; -} - -/**Function************************************************************* - - Synopsis [Creates the network composed of one output.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_NtkSplitOutput( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode, int fUseAllCis ) -{ - Vec_Ptr_t * vNodes; - Abc_Ntk_t * pNtkNew; - Abc_Obj_t * pObj, * pFanin; - char Buffer[1000]; - int i, k; - - assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsStrash(pNtk) ); - assert( Abc_ObjIsCo(pNode) ); - - // start the network - pNtkNew = Abc_NtkAlloc( pNtk->ntkType, pNtk->ntkFunc ); - // set the name - sprintf( Buffer, "%s_%s", pNtk->pName, Abc_ObjName(pNode) ); - pNtkNew->pName = util_strsav(Buffer); - - // collect the nodes in the TFI of the output - vNodes = Abc_NtkDfsNodes( pNtk, &pNode, 1 ); - // create the PIs - Abc_NtkForEachCi( pNtk, pObj, i ) - { - if ( fUseAllCis || Abc_NodeIsTravIdCurrent(pObj) ) // TravId is set by DFS - { - pObj->pCopy = Abc_NtkCreatePi(pNtkNew); - Abc_NtkLogicStoreName( pObj->pCopy, Abc_ObjName(pObj) ); - } - } - // establish connection between the constant nodes - if ( Abc_NtkIsStrash(pNtk) ) - Abc_AigConst1(pNtk->pManFunc)->pCopy = Abc_AigConst1(pNtkNew->pManFunc); - - // copy the nodes - Vec_PtrForEachEntry( vNodes, pObj, i ) - { - // if it is an AIG, add to the hash table - if ( Abc_NtkIsStrash(pNtk) ) - { - pObj->pCopy = Abc_AigAnd( pNtkNew->pManFunc, Abc_ObjChild0Copy(pObj), Abc_ObjChild1Copy(pObj) ); - } - else - { - Abc_NtkDupObj( pNtkNew, pObj ); - Abc_ObjForEachFanin( pObj, pFanin, k ) - Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy ); - } - } - Vec_PtrFree( vNodes ); - - // add the PO corresponding to this output - pNode->pCopy = Abc_NtkCreatePo( pNtkNew ); - Abc_ObjAddFanin( pNode->pCopy, Abc_ObjFanin0(pNode)->pCopy ); - Abc_NtkLogicStoreName( pNode->pCopy, Abc_ObjName(pNode) ); - - if ( !Abc_NtkCheck( pNtkNew ) ) - fprintf( stdout, "Abc_NtkSplitOutput(): Network check has failed.\n" ); - return pNtkNew; -} - -/**Function************************************************************* - - Synopsis [Creates the network composed of one output.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_NtkCreateCone( Abc_Ntk_t * pNtk, Vec_Ptr_t * vRoots, Vec_Int_t * vValues ) -{ - Vec_Ptr_t * vNodes; - Abc_Ntk_t * pNtkNew; - Abc_Obj_t * pObj, * pFinal, * pOther, * pNodePo; - int i; - - assert( Abc_NtkIsLogic(pNtk) ); - - // start the network - Abc_NtkCleanCopy( pNtk ); - pNtkNew = Abc_NtkAlloc( ABC_TYPE_STRASH, ABC_FUNC_AIG ); - pNtkNew->pName = util_strsav(pNtk->pName); - - // collect the nodes in the TFI of the output - vNodes = Abc_NtkDfsNodes( pNtk, (Abc_Obj_t **)vRoots->pArray, vRoots->nSize ); - // create the PIs - Abc_NtkForEachCi( pNtk, pObj, i ) - { - pObj->pCopy = Abc_NtkCreatePi(pNtkNew); - Abc_NtkLogicStoreName( pObj->pCopy, Abc_ObjName(pObj) ); - } - // copy the nodes - Vec_PtrForEachEntry( vNodes, pObj, i ) - pObj->pCopy = Abc_NodeStrash( pNtkNew->pManFunc, pObj ); - Vec_PtrFree( vNodes ); - - // add the PO - pFinal = Abc_AigConst1( pNtkNew->pManFunc ); - Vec_PtrForEachEntry( vRoots, pObj, i ) - { - pOther = pObj->pCopy; - if ( Vec_IntEntry(vValues, i) == 0 ) - pOther = Abc_ObjNot(pOther); - pFinal = Abc_AigAnd( pNtkNew->pManFunc, pFinal, pOther ); - } - - // add the PO corresponding to this output - pNodePo = Abc_NtkCreatePo( pNtkNew ); - Abc_ObjAddFanin( pNodePo, pFinal ); - Abc_NtkLogicStoreName( pNodePo, "miter" ); - if ( !Abc_NtkCheck( pNtkNew ) ) - fprintf( stdout, "Abc_NtkCreateCone(): Network check has failed.\n" ); - return pNtkNew; -} - -/**Function************************************************************* - - Synopsis [Deletes the Ntk.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_NtkSplitNode( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode ) -{ - Abc_Ntk_t * pNtkNew; - Abc_Obj_t * pFanin, * pNodePo; - int i; - // start the network - pNtkNew = Abc_NtkAlloc( pNtk->ntkType, pNtk->ntkFunc ); - pNtkNew->pName = util_strsav(Abc_ObjName(pNode)); - // add the PIs corresponding to the fanins of the node - Abc_ObjForEachFanin( pNode, pFanin, i ) - { - pFanin->pCopy = Abc_NtkCreatePi( pNtkNew ); - Abc_NtkLogicStoreName( pFanin->pCopy, Abc_ObjName(pFanin) ); - } - // duplicate and connect the node - pNode->pCopy = Abc_NtkDupObj( pNtkNew, pNode ); - Abc_ObjForEachFanin( pNode, pFanin, i ) - Abc_ObjAddFanin( pNode->pCopy, pFanin->pCopy ); - // create the only PO - pNodePo = Abc_NtkCreatePo( pNtkNew ); - Abc_ObjAddFanin( pNodePo, pNode->pCopy ); - Abc_NtkLogicStoreName( pNodePo, Abc_ObjName(pNode) ); - if ( !Abc_NtkCheck( pNtkNew ) ) - fprintf( stdout, "Abc_NtkSplitNode(): Network check has failed.\n" ); - return pNtkNew; -} - -/**Function************************************************************* - - Synopsis [Deletes the Ntk.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkDelete( Abc_Ntk_t * pNtk ) -{ - Abc_Obj_t * pObj; - int TotalMemory, i; - int LargePiece = (4 << ABC_NUM_STEPS); - if ( pNtk == NULL ) - return; - // make sure all the marks are clean - Abc_NtkForEachObj( pNtk, pObj, i ) - { - // free large fanout arrays - if ( pObj->vFanouts.nCap * 4 > LargePiece ) - FREE( pObj->vFanouts.pArray ); - // check that the other things are okay - assert( pObj->fMarkA == 0 ); - assert( pObj->fMarkB == 0 ); - assert( pObj->fMarkC == 0 ); - } - - // dereference the BDDs - if ( Abc_NtkHasBdd(pNtk) ) - Abc_NtkForEachNode( pNtk, pObj, i ) - Cudd_RecursiveDeref( pNtk->pManFunc, pObj->pData ); - - FREE( pNtk->pName ); - FREE( pNtk->pSpec ); - // copy the EXDC Ntk - if ( pNtk->pExdc ) - Abc_NtkDelete( pNtk->pExdc ); - // free the arrays - Vec_PtrFree( pNtk->vObjs ); - Vec_PtrFree( pNtk->vLats ); - Vec_PtrFree( pNtk->vCis ); - Vec_PtrFree( pNtk->vCos ); - Vec_PtrFree( pNtk->vPtrTemp ); - Vec_IntFree( pNtk->vIntTemp ); - Vec_StrFree( pNtk->vStrTemp ); - // free the hash table of Obj name into Obj ID - stmm_free_table( pNtk->tName2Net ); - stmm_free_table( pNtk->tObj2Name ); - TotalMemory = 0; - TotalMemory += Extra_MmFlexReadMemUsage(pNtk->pMmNames); - TotalMemory += Extra_MmFixedReadMemUsage(pNtk->pMmObj); - TotalMemory += Extra_MmStepReadMemUsage(pNtk->pMmStep); -// fprintf( stdout, "The total memory allocated internally by the network = %0.2f Mb.\n", ((double)TotalMemory)/(1<<20) ); - // free the storage - Extra_MmFlexStop ( pNtk->pMmNames, 0 ); - Extra_MmFixedStop( pNtk->pMmObj, 0 ); - Extra_MmStepStop ( pNtk->pMmStep, 0 ); - // free the timing manager - if ( pNtk->pManTime ) - Abc_ManTimeStop( pNtk->pManTime ); - // start the functionality manager - if ( Abc_NtkHasSop(pNtk) ) - Extra_MmFlexStop( pNtk->pManFunc, 0 ); - else if ( Abc_NtkHasBdd(pNtk) ) - Extra_StopManager( pNtk->pManFunc ); - else if ( Abc_NtkHasAig(pNtk) ) - Abc_AigFree( pNtk->pManFunc ); - else if ( !Abc_NtkHasMapping(pNtk) ) - assert( 0 ); - free( pNtk ); -} - -/**Function************************************************************* - - Synopsis [Reads the verilog file.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkFixNonDrivenNets( Abc_Ntk_t * pNtk ) -{ - Vec_Ptr_t * vNets; - Abc_Obj_t * pNet, * pNode; - int i; - - // check for non-driven nets - vNets = Vec_PtrAlloc( 100 ); - Abc_NtkForEachNet( pNtk, pNet, i ) - { - if ( Abc_ObjFaninNum(pNet) > 0 ) - continue; - // add the constant 0 driver - pNode = Abc_NtkCreateNode( pNtk ); - // set the constant function - Abc_ObjSetData( pNode, Abc_SopRegister(pNtk->pManFunc, " 0\n") ); - // add the fanout net - Abc_ObjAddFanin( pNet, pNode ); - // add the net to those for which the warning will be printed - Vec_PtrPush( vNets, pNet->pData ); - } - - // print the warning - if ( vNets->nSize > 0 ) - { - printf( "Constant-zero drivers were added to %d non-driven nets:\n", vNets->nSize ); - for ( i = 0; i < vNets->nSize; i++ ) - { - if ( i == 0 ) - printf( "%s", vNets->pArray[i] ); - else if ( i == 1 ) - printf( ", %s", vNets->pArray[i] ); - else if ( i == 2 ) - { - printf( ", %s, etc.", vNets->pArray[i] ); - break; - } - } - printf( "\n" ); - } - Vec_PtrFree( vNets ); -} - - - - -/**Function************************************************************* - - Synopsis [Creates a new Obj.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_ObjAlloc( Abc_Ntk_t * pNtk, Abc_ObjType_t Type ) -{ - Abc_Obj_t * pObj; - pObj = (Abc_Obj_t *)Extra_MmFixedEntryFetch( pNtk->pMmObj ); - memset( pObj, 0, sizeof(Abc_Obj_t) ); - pObj->Id = -1; - pObj->pNtk = pNtk; - pObj->Type = Type; - return pObj; -} - -/**Function************************************************************* - - Synopsis [Recycles the Obj.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_ObjRecycle( Abc_Obj_t * pObj ) -{ - Abc_Ntk_t * pNtk = pObj->pNtk; - memset( pObj, 0, sizeof(Abc_Obj_t) ); - Extra_MmFixedEntryRecycle( pNtk->pMmObj, (char *)pObj ); -} - -/**Function************************************************************* - - Synopsis [Adds the node to the network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_ObjAdd( Abc_Obj_t * pObj ) -{ - Abc_Ntk_t * pNtk = pObj->pNtk; - assert( !Abc_ObjIsComplement(pObj) ); - // add to the array of objects - pObj->Id = pNtk->vObjs->nSize; - Vec_PtrPush( pNtk->vObjs, pObj ); - pNtk->nObjs++; - // perform specialized operations depending on the object type - if ( Abc_ObjIsNet(pObj) ) - { - // add the name to the table - if ( pObj->pData && stmm_insert( pNtk->tName2Net, pObj->pData, (char *)pObj ) ) - { - printf( "Error: The net is already in the table...\n" ); - assert( 0 ); - } - pNtk->nNets++; - } - else if ( Abc_ObjIsNode(pObj) ) - { - pNtk->nNodes++; - } - else if ( Abc_ObjIsLatch(pObj) ) - { - Vec_PtrPush( pNtk->vLats, pObj ); - pNtk->nLatches++; - } - else if ( Abc_ObjIsPi(pObj) ) - { - Vec_PtrPush( pNtk->vCis, pObj ); - pNtk->nPis++; - } - else if ( Abc_ObjIsPo(pObj) ) - { - Vec_PtrPush( pNtk->vCos, pObj ); - pNtk->nPos++; - } - else - { - assert( 0 ); - } - assert( pObj->Id >= 0 ); -} - -/**Function************************************************************* - - Synopsis [Duplicate the Obj.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_NtkDupObj( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj ) -{ - Abc_Obj_t * pObjNew; - pObjNew = Abc_ObjAlloc( pNtkNew, pObj->Type ); - if ( Abc_ObjIsNode(pObj) ) // copy the function if functionality is compatible - { - if ( pNtkNew->ntkFunc == pObj->pNtk->ntkFunc ) - { - if ( Abc_NtkHasSop(pNtkNew) ) - pObjNew->pData = Abc_SopRegister( pNtkNew->pManFunc, pObj->pData ); - else if ( Abc_NtkHasBdd(pNtkNew) ) - pObjNew->pData = Cudd_bddTransfer(pObj->pNtk->pManFunc, pNtkNew->pManFunc, pObj->pData), Cudd_Ref(pObjNew->pData); - else if ( Abc_NtkHasMapping(pNtkNew) ) - pObjNew->pData = pObj->pData; - else if ( Abc_NtkHasAig(pNtkNew) ) - assert( 0 ); - } - } - else if ( Abc_ObjIsNet(pObj) ) // copy the name - pObjNew->pData = Abc_NtkRegisterName( pNtkNew, pObj->pData ); - else if ( Abc_ObjIsLatch(pObj) ) // copy the reset value - pObjNew->pData = pObj->pData; - pObj->pCopy = pObjNew; - // add the object to the network - Abc_ObjAdd( pObjNew ); - return pObjNew; -} - -/**Function************************************************************* - - Synopsis [Creates a new constant node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_NtkDupConst1( Abc_Ntk_t * pNtkAig, Abc_Ntk_t * pNtkNew ) -{ - Abc_Obj_t * pConst1; - assert( Abc_NtkIsStrash(pNtkAig) ); - assert( Abc_NtkIsSopLogic(pNtkNew) ); - pConst1 = Abc_AigConst1(pNtkAig->pManFunc); - if ( Abc_ObjFanoutNum(pConst1) > 0 ) - pConst1->pCopy = Abc_NodeCreateConst1( pNtkNew ); - return pConst1->pCopy; -} - -/**Function************************************************************* - - Synopsis [Creates a new constant node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_NtkDupReset( Abc_Ntk_t * pNtkAig, Abc_Ntk_t * pNtkNew ) -{ - Abc_Obj_t * pReset, * pConst1; - assert( Abc_NtkIsStrash(pNtkAig) ); - assert( Abc_NtkIsSopLogic(pNtkNew) ); - pReset = Abc_AigReset(pNtkAig->pManFunc); - if ( Abc_ObjFanoutNum(pReset) > 0 ) - { - // create new latch with reset value 0 - pReset->pCopy = Abc_NtkCreateLatch( pNtkNew ); - // add constant node fanin to the latch - pConst1 = Abc_NodeCreateConst1( pNtkNew ); - Abc_ObjAddFanin( pReset->pCopy, pConst1 ); - } - return pReset->pCopy; -} - -/**Function************************************************************* - - Synopsis [Deletes the object from the network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkDeleteObj( Abc_Obj_t * pObj ) -{ - Vec_Ptr_t * vNodes = pObj->pNtk->vPtrTemp; - Abc_Ntk_t * pNtk = pObj->pNtk; - int i; - - assert( !Abc_ObjIsComplement(pObj) ); - - // delete fanins and fanouts - Abc_NodeCollectFanouts( pObj, vNodes ); - for ( i = 0; i < vNodes->nSize; i++ ) - Abc_ObjDeleteFanin( vNodes->pArray[i], pObj ); - Abc_NodeCollectFanins( pObj, vNodes ); - for ( i = 0; i < vNodes->nSize; i++ ) - Abc_ObjDeleteFanin( pObj, vNodes->pArray[i] ); - - // remove from the list of objects - Vec_PtrWriteEntry( pNtk->vObjs, pObj->Id, NULL ); - pObj->Id = (1<<26)-1; - pNtk->nObjs--; - - // perform specialized operations depending on the object type - if ( Abc_ObjIsNet(pObj) ) - { - // remove the net from the hash table of nets - if ( pObj->pData && !stmm_delete( pNtk->tName2Net, (char **)&pObj->pData, (char **)&pObj ) ) - { - printf( "Error: The net is not in the table...\n" ); - assert( 0 ); - } - pObj->pData = NULL; - pNtk->nNets--; - } - else if ( Abc_ObjIsNode(pObj) ) - { - if ( Abc_NtkHasBdd(pNtk) ) - Cudd_RecursiveDeref( pNtk->pManFunc, pObj->pData ); - pNtk->nNodes--; - } - else if ( Abc_ObjIsLatch(pObj) ) - { - pNtk->nLatches--; - } - else - assert( 0 ); - // recycle the net itself - Abc_ObjRecycle( pObj ); -} - - - - - -/**Function************************************************************* - - Synopsis [Returns the net with the given name.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_NtkFindNode( Abc_Ntk_t * pNtk, char * pName ) -{ - Abc_Obj_t * pObj, * pDriver; - int i, Num; - // check if the node is among CIs - Abc_NtkForEachCi( pNtk, pObj, i ) - { - if ( strcmp( Abc_ObjName(pObj), pName ) == 0 ) - { - if ( i < Abc_NtkPiNum(pNtk) ) - printf( "Node \"%s\" is a primary input.\n", pName ); - else - printf( "Node \"%s\" is a latch output.\n", pName ); - return NULL; - } - } - // search the node among COs - Abc_NtkForEachCo( pNtk, pObj, i ) - { - if ( strcmp( Abc_ObjName(pObj), pName ) == 0 ) - { - pDriver = Abc_ObjFanin0(pObj); - if ( !Abc_ObjIsNode(pDriver) ) - { - printf( "Node \"%s\" does not have logic associated with it.\n", pName ); - return NULL; - } - return pDriver; - } - } - // find the internal node - if ( pName[0] != '[' || pName[strlen(pName)-1] != ']' ) - { - printf( "Name \"%s\" is not found among CIs/COs (internal name looks like this: \"[integer]\").\n", pName ); - return NULL; - } - Num = atoi( pName + 1 ); - if ( Num < 0 || Num >= Abc_NtkObjNumMax(pNtk) ) - { - printf( "The node \"%s\" with ID %d is not in the current network.\n", pName, Num ); - return NULL; - } - pObj = Abc_NtkObj( pNtk, Num ); - if ( pObj == NULL ) - { - printf( "The node \"%s\" with ID %d has been removed from the current network.\n", pName, Num ); - return NULL; - } - if ( !Abc_ObjIsNode(pObj) ) - { - printf( "Object with ID %d is not a node.\n", Num ); - return NULL; - } - return pObj; -} - -/**Function************************************************************* - - Synopsis [Returns the net with the given name.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_NtkFindCo( Abc_Ntk_t * pNtk, char * pName ) -{ - Abc_Obj_t * pNode; - int i; - // search the node among COs - Abc_NtkForEachCo( pNtk, pNode, i ) - { - if ( strcmp( Abc_ObjName(pNode), pName ) == 0 ) - return pNode; - } - return NULL; -} - -/**Function************************************************************* - - Synopsis [Returns the net with the given name.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_NtkFindNet( Abc_Ntk_t * pNtk, char * pName ) -{ - Abc_Obj_t * pNet; - assert( Abc_NtkIsNetlist(pNtk) ); - if ( stmm_lookup( pNtk->tName2Net, pName, (char**)&pNet ) ) - return pNet; - return NULL; -} - -/**Function************************************************************* - - Synopsis [Finds or creates the net.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_NtkFindOrCreateNet( Abc_Ntk_t * pNtk, char * pName ) -{ - Abc_Obj_t * pNet; - assert( Abc_NtkIsNetlist(pNtk) ); - if ( pNet = Abc_NtkFindNet( pNtk, pName ) ) - return pNet; - // create a new net - pNet = Abc_ObjAlloc( pNtk, ABC_OBJ_NET ); - pNet->pData = Abc_NtkRegisterName( pNtk, pName ); - Abc_ObjAdd( pNet ); - return pNet; -} - -/**Function************************************************************* - - Synopsis [Create the new node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_NtkCreateNode( Abc_Ntk_t * pNtk ) -{ - Abc_Obj_t * pObj; - pObj = Abc_ObjAlloc( pNtk, ABC_OBJ_NODE ); - Abc_ObjAdd( pObj ); - return pObj; -} - -/**Function************************************************************* - - Synopsis [Create the new node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_NtkCreatePi( Abc_Ntk_t * pNtk ) -{ - Abc_Obj_t * pObj; - pObj = Abc_ObjAlloc( pNtk, ABC_OBJ_PI ); - Abc_ObjAdd( pObj ); - return pObj; -} - -/**Function************************************************************* - - Synopsis [Create the new node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_NtkCreatePo( Abc_Ntk_t * pNtk ) -{ - Abc_Obj_t * pObj; - pObj = Abc_ObjAlloc( pNtk, ABC_OBJ_PO ); - Abc_ObjAdd( pObj ); - return pObj; -} - -/**Function************************************************************* - - Synopsis [Create the new node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_NtkCreateLatch( Abc_Ntk_t * pNtk ) -{ - Abc_Obj_t * pObj; - pObj = Abc_ObjAlloc( pNtk, ABC_OBJ_LATCH ); - Abc_ObjAdd( pObj ); - return pObj; -} - -/**Function************************************************************* - - Synopsis [Creates inverter.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_NodeCreateConst0( Abc_Ntk_t * pNtk ) -{ - Abc_Obj_t * pNode; - assert( !Abc_NtkHasAig(pNtk) ); - pNode = Abc_NtkCreateNode( pNtk ); - if ( Abc_NtkHasSop(pNtk) ) - pNode->pData = Abc_SopRegister( pNtk->pManFunc, " 0\n" ); - else if ( Abc_NtkHasBdd(pNtk) ) - pNode->pData = Cudd_ReadLogicZero(pNtk->pManFunc), Cudd_Ref( pNode->pData ); - else if ( Abc_NtkHasMapping(pNtk) ) - pNode->pData = Mio_LibraryReadConst0(Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame())); - else - assert( 0 ); - return pNode; -} - -/**Function************************************************************* - - Synopsis [Creates inverter.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_NodeCreateConst1( Abc_Ntk_t * pNtk ) -{ - Abc_Obj_t * pNode; - if ( Abc_NtkHasAig(pNtk) ) - return Abc_AigConst1(pNtk->pManFunc); - pNode = Abc_NtkCreateNode( pNtk ); - if ( Abc_NtkHasSop(pNtk) ) - pNode->pData = Abc_SopRegister( pNtk->pManFunc, " 1\n" ); - else if ( Abc_NtkHasBdd(pNtk) ) - pNode->pData = Cudd_ReadOne(pNtk->pManFunc), Cudd_Ref( pNode->pData ); - else if ( Abc_NtkHasMapping(pNtk) ) - pNode->pData = Mio_LibraryReadConst1(Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame())); - else - assert( 0 ); - return pNode; -} - -/**Function************************************************************* - - Synopsis [Creates inverter.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_NodeCreateInv( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin ) -{ - Abc_Obj_t * pNode; - assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsNetlist(pNtk) ); - pNode = Abc_NtkCreateNode( pNtk ); - Abc_ObjAddFanin( pNode, pFanin ); - if ( Abc_NtkHasSop(pNtk) ) - pNode->pData = Abc_SopRegister( pNtk->pManFunc, "0 1\n" ); - else if ( Abc_NtkHasBdd(pNtk) ) - pNode->pData = Cudd_Not(Cudd_bddIthVar(pNtk->pManFunc,0)), Cudd_Ref( pNode->pData ); - else if ( Abc_NtkHasMapping(pNtk) ) - pNode->pData = Mio_LibraryReadInv(Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame())); - else - assert( 0 ); - return pNode; -} - -/**Function************************************************************* - - Synopsis [Creates buffer.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_NodeCreateBuf( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin ) -{ - Abc_Obj_t * pNode; - assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsNetlist(pNtk) ); - pNode = Abc_NtkCreateNode( pNtk ); - Abc_ObjAddFanin( pNode, pFanin ); - if ( Abc_NtkHasSop(pNtk) ) - pNode->pData = Abc_SopRegister( pNtk->pManFunc, "1 1\n" ); - else if ( Abc_NtkHasBdd(pNtk) ) - pNode->pData = Cudd_bddIthVar(pNtk->pManFunc,0), Cudd_Ref( pNode->pData ); - else if ( Abc_NtkHasMapping(pNtk) ) - pNode->pData = Mio_LibraryReadBuf(Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame())); - else - assert( 0 ); - return pNode; -} - -/**Function************************************************************* - - Synopsis [Creates inverter.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_NodeCreateAnd( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins ) -{ - Abc_Obj_t * pNode; - int i; - assert( Abc_NtkIsLogic(pNtk) ); - pNode = Abc_NtkCreateNode( pNtk ); - for ( i = 0; i < vFanins->nSize; i++ ) - Abc_ObjAddFanin( pNode, vFanins->pArray[i] ); - if ( Abc_NtkHasSop(pNtk) ) - { - char * pSop; - pSop = Extra_MmFlexEntryFetch( pNtk->pManFunc, vFanins->nSize + 4 ); - for ( i = 0; i < vFanins->nSize; i++ ) - pSop[i] = '1'; - pSop[i++] = ' '; - pSop[i++] = '1'; - pSop[i++] = '\n'; - pSop[i++] = 0; - assert( i == vFanins->nSize + 4 ); - pNode->pData = pSop; - } - else if ( Abc_NtkHasBdd(pNtk) ) - { - DdManager * dd = pNtk->pManFunc; - DdNode * bFunc, * bTemp; - bFunc = Cudd_ReadOne(dd); Cudd_Ref( bFunc ); - for ( i = 0; i < vFanins->nSize; i++ ) - { - bFunc = Cudd_bddAnd( dd, bTemp = bFunc, Cudd_bddIthVar(pNtk->pManFunc,i) ); Cudd_Ref( bFunc ); - Cudd_RecursiveDeref( dd, bTemp ); - } - pNode->pData = bFunc; - } - else - assert( 0 ); - return pNode; -} - -/**Function************************************************************* - - Synopsis [Creates inverter.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_NodeCreateOr( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins ) -{ - Abc_Obj_t * pNode; - int i; - assert( Abc_NtkIsLogic(pNtk) ); - pNode = Abc_NtkCreateNode( pNtk ); - for ( i = 0; i < vFanins->nSize; i++ ) - Abc_ObjAddFanin( pNode, vFanins->pArray[i] ); - if ( Abc_NtkHasSop(pNtk) ) - { - char * pSop; - pSop = Extra_MmFlexEntryFetch( pNtk->pManFunc, vFanins->nSize + 4 ); - for ( i = 0; i < vFanins->nSize; i++ ) - pSop[i] = '0'; - pSop[i++] = ' '; - pSop[i++] = '0'; - pSop[i++] = '\n'; - pSop[i++] = 0; - assert( i == vFanins->nSize + 4 ); - pNode->pData = pSop; - } - else if ( Abc_NtkHasBdd(pNtk) ) - { - DdManager * dd = pNtk->pManFunc; - DdNode * bFunc, * bTemp; - bFunc = Cudd_ReadLogicZero(dd); Cudd_Ref( bFunc ); - for ( i = 0; i < vFanins->nSize; i++ ) - { - bFunc = Cudd_bddOr( dd, bTemp = bFunc, Cudd_bddIthVar(pNtk->pManFunc,i) ); Cudd_Ref( bFunc ); - Cudd_RecursiveDeref( dd, bTemp ); - } - pNode->pData = bFunc; - } - else - assert( 0 ); - return pNode; -} - -/**Function************************************************************* - - Synopsis [Creates inverter.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_NodeCreateMux( Abc_Ntk_t * pNtk, Abc_Obj_t * pNodeC, Abc_Obj_t * pNode1, Abc_Obj_t * pNode0 ) -{ - Abc_Obj_t * pNode; - assert( Abc_NtkIsLogic(pNtk) ); - pNode = Abc_NtkCreateNode( pNtk ); - Abc_ObjAddFanin( pNode, pNodeC ); - Abc_ObjAddFanin( pNode, pNode1 ); - Abc_ObjAddFanin( pNode, pNode0 ); - if ( Abc_NtkHasSop(pNtk) ) - pNode->pData = Abc_SopRegister( pNtk->pManFunc, "11- 1\n0-1 1\n" ); - else if ( Abc_NtkHasBdd(pNtk) ) - pNode->pData = Cudd_bddIte(pNtk->pManFunc,Cudd_bddIthVar(pNtk->pManFunc,0),Cudd_bddIthVar(pNtk->pManFunc,1),Cudd_bddIthVar(pNtk->pManFunc,2)), Cudd_Ref( pNode->pData ); - else - assert( 0 ); - return pNode; -} - -/**Function************************************************************* - - Synopsis [Clones the given node but does not assign the function.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_NodeClone( Abc_Obj_t * pNode ) -{ - Abc_Obj_t * pClone, * pFanin; - int i; - assert( Abc_ObjIsNode(pNode) ); - pClone = Abc_NtkCreateNode( pNode->pNtk ); - Abc_ObjForEachFanin( pNode, pFanin, i ) - Abc_ObjAddFanin( pClone, pFanin ); - return pClone; -} - - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -bool Abc_NodeIsConst0( Abc_Obj_t * pNode ) -{ - Abc_Ntk_t * pNtk = pNode->pNtk; - assert(Abc_ObjIsNode(pNode)); - assert(Abc_NodeIsConst(pNode)); - if ( Abc_NtkHasSop(pNtk) ) - return Abc_SopIsConst0(pNode->pData); - if ( Abc_NtkHasBdd(pNtk) ) - return Cudd_IsComplement(pNode->pData); - if ( Abc_NtkHasAig(pNtk) ) - return Abc_ObjNot(pNode) == Abc_AigConst1(pNode->pNtk->pManFunc); - if ( Abc_NtkHasMapping(pNtk) ) - return pNode->pData == Mio_LibraryReadConst0(Abc_FrameReadLibSuper(Abc_FrameGetGlobalFrame())); - assert( 0 ); - return 0; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -bool Abc_NodeIsConst1( Abc_Obj_t * pNode ) -{ - Abc_Ntk_t * pNtk = pNode->pNtk; - assert(Abc_ObjIsNode(pNode)); - assert(Abc_NodeIsConst(pNode)); - if ( Abc_NtkHasSop(pNtk) ) - return Abc_SopIsConst1(pNode->pData); - if ( Abc_NtkHasBdd(pNtk) ) - return !Cudd_IsComplement(pNode->pData); - if ( Abc_NtkHasAig(pNtk) ) - return pNode == Abc_AigConst1(pNode->pNtk->pManFunc); - if ( Abc_NtkHasMapping(pNtk) ) - return pNode->pData == Mio_LibraryReadConst1(Abc_FrameReadLibSuper(Abc_FrameGetGlobalFrame())); - assert( 0 ); - return 0; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -bool Abc_NodeIsBuf( Abc_Obj_t * pNode ) -{ - Abc_Ntk_t * pNtk = pNode->pNtk; - assert(Abc_ObjIsNode(pNode)); - if ( Abc_ObjFaninNum(pNode) != 1 ) - return 0; - if ( Abc_NtkHasSop(pNtk) ) - return Abc_SopIsBuf(pNode->pData); - if ( Abc_NtkHasBdd(pNtk) ) - return !Cudd_IsComplement(pNode->pData); - if ( Abc_NtkHasAig(pNtk) ) - return 0; - if ( Abc_NtkHasMapping(pNtk) ) - return pNode->pData == Mio_LibraryReadBuf(Abc_FrameReadLibSuper(Abc_FrameGetGlobalFrame())); - assert( 0 ); - return 0; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -bool Abc_NodeIsInv( Abc_Obj_t * pNode ) -{ - Abc_Ntk_t * pNtk = pNode->pNtk; - assert(Abc_ObjIsNode(pNode)); - if ( Abc_ObjFaninNum(pNode) != 1 ) - return 0; - if ( Abc_NtkHasSop(pNtk) ) - return Abc_SopIsInv(pNode->pData); - if ( Abc_NtkHasBdd(pNtk) ) - return Cudd_IsComplement(pNode->pData); - if ( Abc_NtkHasAig(pNtk) ) - return 0; - if ( Abc_NtkHasMapping(pNtk) ) - return pNode->pData == Mio_LibraryReadInv(Abc_FrameReadLibSuper(Abc_FrameGetGlobalFrame())); - assert( 0 ); - return 0; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/base/abc/abcCut.c b/src/base/abc/abcCut.c deleted file mode 100644 index f487bd1b..00000000 --- a/src/base/abc/abcCut.c +++ /dev/null @@ -1,190 +0,0 @@ -/**CFile**************************************************************** - - FileName [abcCut.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Network and node package.] - - Synopsis [Interface to cut computation.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: abcCut.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" -#include "cut.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Computes the cuts for the network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Cut_Man_t * Abc_NtkCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams ) -{ - Cut_Man_t * p; - Abc_Obj_t * pObj, * pDriver, * pNode; - Vec_Ptr_t * vNodes; - Vec_Int_t * vChoices; - int i; - int clk = clock(); - - assert( Abc_NtkIsStrash(pNtk) ); - - // start the manager - pParams->nIdsMax = Abc_NtkObjNumMax( pNtk ); - p = Cut_ManStart( pParams ); - if ( pParams->fDrop ) - Cut_ManSetFanoutCounts( p, Abc_NtkFanoutCounts(pNtk) ); - // set cuts for PIs - Abc_NtkForEachCi( pNtk, pObj, i ) - if ( Abc_ObjFanoutNum(pObj) > 0 ) - Cut_NodeSetTriv( p, pObj->Id ); - // compute cuts for internal nodes - vNodes = Abc_AigDfs( pNtk, 0, 1 ); - vChoices = Vec_IntAlloc( 100 ); - Vec_PtrForEachEntry( vNodes, pObj, i ) - { - // when we reached a CO, it is time to deallocate the cuts - if ( Abc_ObjIsCo(pObj) ) - { - if ( pParams->fDrop ) - Cut_NodeTryDroppingCuts( p, Abc_ObjFaninId0(pObj) ); - continue; - } - // skip constant node, it has no cuts - if ( Abc_NodeIsConst(pObj) ) - continue; - // compute the cuts to the internal node - Abc_NodeGetCuts( p, pObj ); - // add cuts due to choices - if ( Abc_NodeIsAigChoice(pObj) ) - { - Vec_IntClear( vChoices ); - for ( pNode = pObj; pNode; pNode = pNode->pData ) - Vec_IntPush( vChoices, pNode->Id ); - Cut_NodeUnionCuts( p, vChoices ); - } - } - if ( !pParams->fSeq ) - { - Vec_PtrFree( vNodes ); - Vec_IntFree( vChoices ); -PRT( "Total", clock() - clk ); - return p; - } - assert( 0 ); - - // compute sequential cuts - Abc_NtkIncrementTravId( pNtk ); - Abc_NtkForEachLatch( pNtk, pObj, i ) - { - pDriver = Abc_ObjFanin0(pObj); - if ( !Abc_ObjIsNode(pDriver) ) - continue; - if ( Abc_NodeIsTravIdCurrent(pDriver) ) - continue; - Abc_NodeSetTravIdCurrent(pDriver); - Cut_NodeSetComputedAsNew( p, pDriver->Id ); - } - // compute as long as new cuts appear - - - return p; -} - -/**Function************************************************************* - - Synopsis [Computes the cuts for the network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void * Abc_NodeGetCutsRecursive( void * p, Abc_Obj_t * pObj ) -{ - void * pList; - if ( pList = Abc_NodeReadCuts( p, pObj ) ) - return pList; - Abc_NodeGetCutsRecursive( p, Abc_ObjFanin0(pObj) ); - Abc_NodeGetCutsRecursive( p, Abc_ObjFanin1(pObj) ); - return Abc_NodeGetCuts( p, pObj ); -} - -/**Function************************************************************* - - Synopsis [Computes the cuts for the network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void * Abc_NodeGetCuts( void * p, Abc_Obj_t * pObj ) -{ - return Cut_NodeComputeCuts( p, pObj->Id, Abc_ObjFaninId0(pObj), Abc_ObjFaninId1(pObj), - Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj) ); -} - -/**Function************************************************************* - - Synopsis [Computes the cuts for the network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void * Abc_NodeReadCuts( void * p, Abc_Obj_t * pObj ) -{ - return Cut_NodeReadCuts( p, pObj->Id ); -} - -/**Function************************************************************* - - Synopsis [Computes the cuts for the network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NodeFreeCuts( void * p, Abc_Obj_t * pObj ) -{ - Cut_NodeFreeCuts( p, pObj->Id ); -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/base/abc/abcDsd.c b/src/base/abc/abcDsd.c deleted file mode 100644 index 013b7ac4..00000000 --- a/src/base/abc/abcDsd.c +++ /dev/null @@ -1,539 +0,0 @@ -/**CFile**************************************************************** - - FileName [abcDsd.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Network and node package.] - - Synopsis [Decomposes the network using disjoint-support decomposition.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: abcDsd.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" -#include "dsd.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static Abc_Ntk_t * Abc_NtkDsdInternal( Abc_Ntk_t * pNtk, bool fVerbose, bool fPrint, bool fShort ); -static void Abc_NtkDsdConstruct( Dsd_Manager_t * pManDsd, Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ); -static Abc_Obj_t * Abc_NtkDsdConstructNode( Dsd_Manager_t * pManDsd, Dsd_Node_t * pNodeDsd, Abc_Ntk_t * pNtkNew ); - -static Vec_Ptr_t * Abc_NtkCollectNodesForDsd( Abc_Ntk_t * pNtk ); -static void Abc_NodeDecompDsdAndMux( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes, Dsd_Manager_t * pManDsd, bool fRecursive ); -static bool Abc_NodeIsForDsd( Abc_Obj_t * pNode ); -static int Abc_NodeFindMuxVar( DdManager * dd, DdNode * bFunc, int nVars ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Derives the DSD network.] - - Description [Takes the strashed network (pNtk), derives global BDDs for - the combinational outputs of this network, and decomposes these BDDs using - disjoint support decomposition. Finally, constructs and return a new - network, which is topologically equivalent to the decomposition tree. - Allocates and frees a new BDD manager and a new DSD manager.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_NtkDsdGlobal( Abc_Ntk_t * pNtk, bool fVerbose, bool fPrint, bool fShort ) -{ - int fCheck = 1; - Abc_Ntk_t * pNtkNew; - - assert( Abc_NtkIsStrash(pNtk) ); - - // perform FPGA mapping - if ( Abc_NtkGlobalBdds(pNtk, 0) == NULL ) - return NULL; - if ( fVerbose ) - printf( "The shared BDD size is %d nodes.\n", Cudd_ReadKeys(pNtk->pManGlob) - Cudd_ReadDead(pNtk->pManGlob) ); - - // transform the result of mapping into a BDD network - pNtkNew = Abc_NtkDsdInternal( pNtk, fVerbose, fPrint, fShort ); - if ( pNtkNew == NULL ) - { - Cudd_Quit( pNtk->pManGlob ); - pNtk->pManGlob = NULL; - return NULL; - } - Extra_StopManager( pNtk->pManGlob ); - pNtk->pManGlob = NULL; - - // make sure that everything is okay - if ( fCheck && !Abc_NtkCheck( pNtkNew ) ) - { - printf( "Abc_NtkDsdGlobal: The network check has failed.\n" ); - Abc_NtkDelete( pNtkNew ); - return NULL; - } - return pNtkNew; -} - -/**Function************************************************************* - - Synopsis [Constructs the decomposed network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_NtkDsdInternal( Abc_Ntk_t * pNtk, bool fVerbose, bool fPrint, bool fShort ) -{ - DdManager * dd = pNtk->pManGlob; - Dsd_Manager_t * pManDsd; - Abc_Ntk_t * pNtkNew; - DdNode * bFunc; - char ** ppNamesCi, ** ppNamesCo; - Abc_Obj_t * pObj; - int i; - - // complement the global functions - Abc_NtkForEachCo( pNtk, pObj, i ) - { - bFunc = Vec_PtrEntry(pNtk->vFuncsGlob, i); - Vec_PtrWriteEntry(pNtk->vFuncsGlob, i, Cudd_NotCond(bFunc, Abc_ObjFaninC0(pObj)) ); - } - - // perform the decomposition - assert( Vec_PtrSize(pNtk->vFuncsGlob) == Abc_NtkCoNum(pNtk) ); - pManDsd = Dsd_ManagerStart( dd, Abc_NtkCiNum(pNtk), fVerbose ); - Dsd_Decompose( pManDsd, (DdNode **)pNtk->vFuncsGlob->pArray, Abc_NtkCoNum(pNtk) ); - Abc_NtkFreeGlobalBdds( pNtk ); - if ( pManDsd == NULL ) - { - Cudd_Quit( dd ); - return NULL; - } - - // start the new network - pNtkNew = Abc_NtkStartFrom( pNtk, ABC_TYPE_LOGIC, ABC_FUNC_BDD ); - // make sure the new manager has enough inputs - Cudd_bddIthVar( pNtkNew->pManFunc, dd->size-1 ); - // put the results into the new network (save new CO drivers in old CO drivers) - Abc_NtkDsdConstruct( pManDsd, pNtk, pNtkNew ); - // finalize the new network - Abc_NtkFinalize( pNtk, pNtkNew ); - // fix the problem with complemented and duplicated CO edges - Abc_NtkLogicMakeSimpleCos( pNtkNew, 0 ); - - if ( fPrint ) - { - ppNamesCi = Abc_NtkCollectCioNames( pNtk, 0 ); - ppNamesCo = Abc_NtkCollectCioNames( pNtk, 1 ); - Dsd_TreePrint( stdout, pManDsd, ppNamesCi, ppNamesCo, fShort, -1 ); - free( ppNamesCi ); - free( ppNamesCo ); - } - - // stop the DSD manager - Dsd_ManagerStop( pManDsd ); - return pNtkNew; -} - -/**Function************************************************************* - - Synopsis [Constructs the decomposed network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkDsdConstruct( Dsd_Manager_t * pManDsd, Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ) -{ - Dsd_Node_t ** ppNodesDsd; - Dsd_Node_t * pNodeDsd; - Abc_Obj_t * pNode, * pNodeNew, * pDriver, * pConst1; - int i, nNodesDsd; - - // save the CI nodes in the DSD nodes - Abc_NtkForEachCi( pNtk, pNode, i ) - { - pNodeDsd = Dsd_ManagerReadInput( pManDsd, i ); - Dsd_NodeSetMark( pNodeDsd, (int)pNode->pCopy ); - } - // set the constant node - pConst1 = Abc_AigConst1(pNtk->pManFunc); - if ( Abc_ObjFanoutNum(pConst1) > 0 ) - pConst1->pCopy = Abc_NodeCreateConst1(pNtkNew); - - // collect DSD nodes in DFS order (leaves and const1 are not collected) - ppNodesDsd = Dsd_TreeCollectNodesDfs( pManDsd, &nNodesDsd ); - for ( i = 0; i < nNodesDsd; i++ ) - Abc_NtkDsdConstructNode( pManDsd, ppNodesDsd[i], pNtkNew ); - free( ppNodesDsd ); - - // set the pointers to the CO drivers - Abc_NtkForEachCo( pNtk, pNode, i ) - { - pDriver = Abc_ObjFanin0( pNode ); - if ( !Abc_ObjIsNode(pDriver) ) - continue; - if ( !Abc_NodeIsAigAnd(pDriver) ) - continue; - pNodeDsd = Dsd_ManagerReadRoot( pManDsd, i ); - pNodeNew = (Abc_Obj_t *)Dsd_NodeReadMark( Dsd_Regular(pNodeDsd) ); - assert( !Abc_ObjIsComplement(pNodeNew) ); - pDriver->pCopy = Abc_ObjNotCond( pNodeNew, Dsd_IsComplement(pNodeDsd) ); - } -} - -/**Function************************************************************* - - Synopsis [Performs DSD using the manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_NtkDsdConstructNode( Dsd_Manager_t * pManDsd, Dsd_Node_t * pNodeDsd, Abc_Ntk_t * pNtkNew ) -{ - DdManager * ddDsd = Dsd_ManagerReadDd( pManDsd ); - DdManager * ddNew = pNtkNew->pManFunc; - Dsd_Node_t * pFaninDsd; - Abc_Obj_t * pNodeNew, * pFanin; - DdNode * bLocal, * bTemp, * bVar; - Dsd_Type_t Type; - int i, nDecs; - - // create the new node - pNodeNew = Abc_NtkCreateNode( pNtkNew ); - // add the fanins - Type = Dsd_NodeReadType( pNodeDsd ); - nDecs = Dsd_NodeReadDecsNum( pNodeDsd ); - assert( nDecs > 1 ); - for ( i = 0; i < nDecs; i++ ) - { - pFaninDsd = Dsd_NodeReadDec( pNodeDsd, i ); - pFanin = (Abc_Obj_t *)Dsd_NodeReadMark(Dsd_Regular(pFaninDsd)); - Abc_ObjAddFanin( pNodeNew, pFanin ); - assert( Type == DSD_NODE_OR || !Dsd_IsComplement(pFaninDsd) ); - } - - // create the local function depending on the type of the node - ddNew = pNtkNew->pManFunc; - switch ( Type ) - { - case DSD_NODE_CONST1: - { - bLocal = ddNew->one; Cudd_Ref( bLocal ); - break; - } - case DSD_NODE_OR: - { - bLocal = Cudd_Not(ddNew->one); Cudd_Ref( bLocal ); - for ( i = 0; i < nDecs; i++ ) - { - pFaninDsd = Dsd_NodeReadDec( pNodeDsd, i ); - bVar = Cudd_NotCond( ddNew->vars[i], Dsd_IsComplement(pFaninDsd) ); - bLocal = Cudd_bddOr( ddNew, bTemp = bLocal, bVar ); Cudd_Ref( bLocal ); - Cudd_RecursiveDeref( ddNew, bTemp ); - } - break; - } - case DSD_NODE_EXOR: - { - bLocal = Cudd_Not(ddNew->one); Cudd_Ref( bLocal ); - for ( i = 0; i < nDecs; i++ ) - { - bLocal = Cudd_bddXor( ddNew, bTemp = bLocal, ddNew->vars[i] ); Cudd_Ref( bLocal ); - Cudd_RecursiveDeref( ddNew, bTemp ); - } - break; - } - case DSD_NODE_PRIME: - { - bLocal = Dsd_TreeGetPrimeFunction( ddDsd, pNodeDsd ); Cudd_Ref( bLocal ); - bLocal = Extra_TransferLevelByLevel( ddDsd, ddNew, bTemp = bLocal ); Cudd_Ref( bLocal ); - Cudd_RecursiveDeref( ddDsd, bTemp ); - // bLocal is now in the new BDD manager - break; - } - default: - { - assert( 0 ); - break; - } - } - pNodeNew->pData = bLocal; - Dsd_NodeSetMark( pNodeDsd, (int)pNodeNew ); - return pNodeNew; -} - - - - - - -/**Function************************************************************* - - Synopsis [Recursively decomposes internal nodes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkDsdLocal( Abc_Ntk_t * pNtk, bool fVerbose, bool fRecursive ) -{ - int fCheck = 1; - Dsd_Manager_t * pManDsd; - DdManager * dd = pNtk->pManFunc; - Vec_Ptr_t * vNodes; - int i; - - assert( Abc_NtkIsBddLogic(pNtk) ); - - // make the network minimum base - Abc_NtkMinimumBase( pNtk ); - - // start the DSD manager - pManDsd = Dsd_ManagerStart( dd, dd->size, 0 ); - - // collect nodes for decomposition - vNodes = Abc_NtkCollectNodesForDsd( pNtk ); - for ( i = 0; i < vNodes->nSize; i++ ) - Abc_NodeDecompDsdAndMux( vNodes->pArray[i], vNodes, pManDsd, fRecursive ); - Vec_PtrFree( vNodes ); - - // stop the DSD manager - Dsd_ManagerStop( pManDsd ); - - // make sure everything is okay - if ( fCheck && !Abc_NtkCheck( pNtk ) ) - { - printf( "Abc_NtkDsdRecursive: The network check has failed.\n" ); - return 0; - } - return 1; -} - -/**Function************************************************************* - - Synopsis [Collects the nodes that may need decomposition.] - - Description [The nodes that do not need decomposition are those - whose BDD has more internal nodes than the support size.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Ptr_t * Abc_NtkCollectNodesForDsd( Abc_Ntk_t * pNtk ) -{ - Vec_Ptr_t * vNodes; - Abc_Obj_t * pNode; - int i; - vNodes = Vec_PtrAlloc( 100 ); - Abc_NtkForEachNode( pNtk, pNode, i ) - { - if ( Abc_NodeIsForDsd(pNode) ) - Vec_PtrPush( vNodes, pNode ); - } - return vNodes; -} - -/**Function************************************************************* - - Synopsis [Performs decomposition of one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NodeDecompDsdAndMux( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes, Dsd_Manager_t * pManDsd, bool fRecursive ) -{ - DdManager * dd = pNode->pNtk->pManFunc; - Abc_Obj_t * pRoot, * pFanin, * pNode1, * pNode2, * pNodeC; - Dsd_Node_t ** ppNodesDsd, * pNodeDsd, * pFaninDsd; - int i, nNodesDsd, iVar, fCompl; - - // try disjoint support decomposition - pNodeDsd = Dsd_DecomposeOne( pManDsd, pNode->pData ); - fCompl = Dsd_IsComplement( pNodeDsd ); - pNodeDsd = Dsd_Regular( pNodeDsd ); - - // determine what decomposition to use - if ( !fRecursive || Dsd_NodeReadDecsNum(pNodeDsd) != Abc_ObjFaninNum(pNode) ) - { // perform DSD - - // set the inputs - Abc_ObjForEachFanin( pNode, pFanin, i ) - { - pFaninDsd = Dsd_ManagerReadInput( pManDsd, i ); - Dsd_NodeSetMark( pFaninDsd, (int)pFanin ); - } - - // construct the intermediate nodes - ppNodesDsd = Dsd_TreeCollectNodesDfsOne( pManDsd, pNodeDsd, &nNodesDsd ); - for ( i = 0; i < nNodesDsd; i++ ) - { - pRoot = Abc_NtkDsdConstructNode( pManDsd, ppNodesDsd[i], pNode->pNtk ); - if ( Abc_NodeIsForDsd(pRoot) && fRecursive ) - Vec_PtrPush( vNodes, pRoot ); - } - free( ppNodesDsd ); - - // remove the current fanins - Abc_ObjRemoveFanins( pNode ); - // add fanin to the root - Abc_ObjAddFanin( pNode, pRoot ); - // update the function to be that of buffer - Cudd_RecursiveDeref( dd, pNode->pData ); - pNode->pData = Cudd_NotCond( dd->vars[0], fCompl ); Cudd_Ref( pNode->pData ); - } - else // perform MUX-decomposition - { - // get the cofactoring variable - iVar = Abc_NodeFindMuxVar( dd, pNode->pData, Abc_ObjFaninNum(pNode) ); - pNodeC = Abc_ObjFanin( pNode, iVar ); - - // get the negative cofactor - pNode1 = Abc_NodeClone( pNode ); - pNode1->pData = Cudd_Cofactor( dd, pNode->pData, Cudd_Not(dd->vars[iVar]) ); Cudd_Ref( pNode1->pData ); - Abc_NodeMinimumBase( pNode1 ); - if ( Abc_NodeIsForDsd(pNode1) ) - Vec_PtrPush( vNodes, pNode1 ); - - // get the positive cofactor - pNode2 = Abc_NodeClone( pNode ); - pNode2->pData = Cudd_Cofactor( dd, pNode->pData, dd->vars[iVar] ); Cudd_Ref( pNode2->pData ); - Abc_NodeMinimumBase( pNode2 ); - if ( Abc_NodeIsForDsd(pNode2) ) - Vec_PtrPush( vNodes, pNode2 ); - - // remove the current fanins - Abc_ObjRemoveFanins( pNode ); - // add new fanins - Abc_ObjAddFanin( pNode, pNodeC ); - Abc_ObjAddFanin( pNode, pNode2 ); - Abc_ObjAddFanin( pNode, pNode1 ); - // update the function to be that of MUX - Cudd_RecursiveDeref( dd, pNode->pData ); - pNode->pData = Cudd_bddIte( dd, dd->vars[0], dd->vars[1], dd->vars[2] ); Cudd_Ref( pNode->pData ); - } -} - -/**Function************************************************************* - - Synopsis [Performs decomposition of one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -bool Abc_NodeIsForDsd( Abc_Obj_t * pNode ) -{ - DdManager * dd = pNode->pNtk->pManFunc; - DdNode * bFunc, * bFunc0, * bFunc1; - assert( Abc_ObjIsNode(pNode) ); -// if ( Cudd_DagSize(pNode->pData)-1 > Abc_ObjFaninNum(pNode) ) -// return 1; -// return 0; - - for ( bFunc = Cudd_Regular(pNode->pData); !cuddIsConstant(bFunc); ) - { - bFunc0 = Cudd_Regular( cuddE(bFunc) ); - bFunc1 = cuddT(bFunc); - if ( bFunc0 == b1 ) - bFunc = bFunc1; - else if ( bFunc1 == b1 || bFunc0 == bFunc1 ) - bFunc = bFunc0; - else - return 1; - } - return 0; -} - -/**Function************************************************************* - - Synopsis [Determines a cofactoring variable.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NodeFindMuxVar( DdManager * dd, DdNode * bFunc, int nVars ) -{ - DdNode * bVar, * bCof0, * bCof1; - int SuppSumMin = 1000000; - int i, nSSD, nSSQ, iVar; - -// printf( "\n\nCofactors:\n\n" ); - iVar = -1; - for ( i = 0; i < nVars; i++ ) - { - bVar = dd->vars[i]; - - bCof0 = Cudd_Cofactor( dd, bFunc, Cudd_Not(bVar) ); Cudd_Ref( bCof0 ); - bCof1 = Cudd_Cofactor( dd, bFunc, bVar ); Cudd_Ref( bCof1 ); - -// nodD = Cudd_DagSize(bCof0); -// nodQ = Cudd_DagSize(bCof1); -// printf( "+%02d: D=%2d. Q=%2d. ", i, nodD, nodQ ); -// printf( "S=%2d. D=%2d. ", nodD + nodQ, abs(nodD-nodQ) ); - - nSSD = Cudd_SupportSize( dd, bCof0 ); - nSSQ = Cudd_SupportSize( dd, bCof1 ); - -// printf( "SD=%2d. SQ=%2d. ", nSSD, nSSQ ); -// printf( "S=%2d. D=%2d. ", nSSD + nSSQ, abs(nSSD - nSSQ) ); -// printf( "Cost=%3d. ", Cost(nodD,nodQ,nSSD,nSSQ) ); -// printf( "\n" ); - - Cudd_RecursiveDeref( dd, bCof0 ); - Cudd_RecursiveDeref( dd, bCof1 ); - - if ( SuppSumMin > nSSD + nSSQ ) - { - SuppSumMin = nSSD + nSSQ; - iVar = i; - } - } - return iVar; -} - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/base/abc/abcFpga.c b/src/base/abc/abcFpga.c deleted file mode 100644 index ad411aa5..00000000 --- a/src/base/abc/abcFpga.c +++ /dev/null @@ -1,246 +0,0 @@ -/**CFile**************************************************************** - - FileName [abcFpga.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Network and node package.] - - Synopsis [Interface with the FPGA mapping package.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: abcFpga.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" -#include "fpgaInt.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static Fpga_Man_t * Abc_NtkToFpga( Abc_Ntk_t * pNtk, int fRecovery, int fVerbose ); -static Abc_Ntk_t * Abc_NtkFromFpga( Fpga_Man_t * pMan, Abc_Ntk_t * pNtk ); -static Abc_Obj_t * Abc_NodeFromFpga_rec( Abc_Ntk_t * pNtkNew, Fpga_Node_t * pNodeFpga ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Interface with the FPGA mapping package.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_NtkFpga( Abc_Ntk_t * pNtk, int fRecovery, int fVerbose ) -{ - int fCheck = 1; - Abc_Ntk_t * pNtkNew; - Fpga_Man_t * pMan; - - assert( Abc_NtkIsStrash(pNtk) ); - - // print a warning about choice nodes - if ( Abc_NtkGetChoiceNum( pNtk ) ) - printf( "Performing FPGA mapping with choices.\n" ); - - // perform FPGA mapping - pMan = Abc_NtkToFpga( pNtk, fRecovery, fVerbose ); - if ( pMan == NULL ) - return NULL; - if ( !Fpga_Mapping( pMan ) ) - { - Fpga_ManFree( pMan ); - return NULL; - } - - // transform the result of mapping into a BDD network - pNtkNew = Abc_NtkFromFpga( pMan, pNtk ); - if ( pNtkNew == NULL ) - return NULL; - Fpga_ManFree( pMan ); - - // make the network minimum base - Abc_NtkMinimumBase( pNtkNew ); - - // make sure that everything is okay - if ( fCheck && !Abc_NtkCheck( pNtkNew ) ) - { - printf( "Abc_NtkFpga: The network check has failed.\n" ); - Abc_NtkDelete( pNtkNew ); - return NULL; - } - return pNtkNew; -} - -/**Function************************************************************* - - Synopsis [Load the network into FPGA manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Fpga_Man_t * Abc_NtkToFpga( Abc_Ntk_t * pNtk, int fRecovery, int fVerbose ) -{ - Fpga_Man_t * pMan; - ProgressBar * pProgress; - Fpga_Node_t * pNodeFpga; - Vec_Ptr_t * vNodes; - Abc_Obj_t * pNode, * pFanin, * pPrev; - int i; - - assert( Abc_NtkIsStrash(pNtk) ); - - // start the mapping manager and set its parameters - pMan = Fpga_ManCreate( Abc_NtkCiNum(pNtk), Abc_NtkCoNum(pNtk), fVerbose ); - if ( pMan == NULL ) - return NULL; - Fpga_ManSetAreaRecovery( pMan, fRecovery ); - Fpga_ManSetOutputNames( pMan, Abc_NtkCollectCioNames(pNtk, 1) ); - Fpga_ManSetInputArrivals( pMan, Abc_NtkGetCiArrivalFloats(pNtk) ); - - // create PIs and remember them in the old nodes - Abc_NtkCleanCopy( pNtk ); - Abc_NtkForEachCi( pNtk, pNode, i ) - pNode->pCopy = (Abc_Obj_t *)Fpga_ManReadInputs(pMan)[i]; - - // load the AIG into the mapper - vNodes = Abc_AigDfs( pNtk, 0, 0 ); - pProgress = Extra_ProgressBarStart( stdout, vNodes->nSize ); - Vec_PtrForEachEntry( vNodes, pNode, i ) - { - Extra_ProgressBarUpdate( pProgress, i, NULL ); - // consider the case of a constant - if ( Abc_NodeIsConst(pNode) ) - { - Abc_AigConst1(pNtk->pManFunc)->pCopy = (Abc_Obj_t *)Fpga_ManReadConst1(pMan); - continue; - } - // add the node to the mapper - pNodeFpga = Fpga_NodeAnd( pMan, - Fpga_NotCond( Abc_ObjFanin0(pNode)->pCopy, Abc_ObjFaninC0(pNode) ), - Fpga_NotCond( Abc_ObjFanin1(pNode)->pCopy, Abc_ObjFaninC1(pNode) ) ); - assert( pNode->pCopy == NULL ); - // remember the node - pNode->pCopy = (Abc_Obj_t *)pNodeFpga; - // set up the choice node - if ( Abc_NodeIsAigChoice( pNode ) ) - for ( pPrev = pNode, pFanin = pNode->pData; pFanin; pPrev = pFanin, pFanin = pFanin->pData ) - { - Fpga_NodeSetNextE( (Fpga_Node_t *)pPrev->pCopy, (Fpga_Node_t *)pFanin->pCopy ); - Fpga_NodeSetRepr( (Fpga_Node_t *)pFanin->pCopy, (Fpga_Node_t *)pNode->pCopy ); - } - } - Extra_ProgressBarStop( pProgress ); - Vec_PtrFree( vNodes ); - - // set the primary outputs without copying the phase - Abc_NtkForEachCo( pNtk, pNode, i ) - Fpga_ManReadOutputs(pMan)[i] = (Fpga_Node_t *)Abc_ObjFanin0(pNode)->pCopy; - return pMan; -} - -/**Function************************************************************* - - Synopsis [Creates the mapped network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_NtkFromFpga( Fpga_Man_t * pMan, Abc_Ntk_t * pNtk ) -{ - ProgressBar * pProgress; - Abc_Ntk_t * pNtkNew; - Abc_Obj_t * pNode, * pNodeNew; - int i, nDupGates; - // create the new network - pNtkNew = Abc_NtkStartFrom( pNtk, ABC_TYPE_LOGIC, ABC_FUNC_BDD ); - // make the mapper point to the new network - Fpga_CutsCleanSign( pMan ); - Fpga_ManCleanData0( pMan ); - Abc_NtkForEachCi( pNtk, pNode, i ) - Fpga_NodeSetData0( Fpga_ManReadInputs(pMan)[i], (char *)pNode->pCopy ); - // set the constant node - if ( Abc_ObjFanoutNum( Abc_AigConst1(pNtk->pManFunc) ) > 0 ) - Fpga_NodeSetData0( Fpga_ManReadConst1(pMan), (char *)Abc_NodeCreateConst1(pNtkNew) ); - // process the nodes in topological order - pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCoNum(pNtk) ); - Abc_NtkForEachCo( pNtk, pNode, i ) - { - Extra_ProgressBarUpdate( pProgress, i, NULL ); - pNodeNew = Abc_NodeFromFpga_rec( pNtkNew, Fpga_ManReadOutputs(pMan)[i] ); - assert( !Abc_ObjIsComplement(pNodeNew) ); - Abc_ObjFanin0(pNode)->pCopy = pNodeNew; - } - Extra_ProgressBarStop( pProgress ); - // finalize the new network - Abc_NtkFinalize( pNtk, pNtkNew ); - // decouple the PO driver nodes to reduce the number of levels - nDupGates = Abc_NtkLogicMakeSimpleCos( pNtkNew, 1 ); - if ( nDupGates && Fpga_ManReadVerbose(pMan) ) - printf( "Duplicated %d gates to decouple the PO drivers.\n", nDupGates ); - return pNtkNew; -} - -/**Function************************************************************* - - Synopsis [Derive one node after FPGA mapping.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_NodeFromFpga_rec( Abc_Ntk_t * pNtkNew, Fpga_Node_t * pNodeFpga ) -{ - Fpga_Cut_t * pCutBest; - Fpga_Node_t ** ppLeaves; - Abc_Obj_t * pNodeNew; - int i, nLeaves; - assert( !Fpga_IsComplement(pNodeFpga) ); - // return if the result if known - pNodeNew = (Abc_Obj_t *)Fpga_NodeReadData0( pNodeFpga ); - if ( pNodeNew ) - return pNodeNew; - assert( Fpga_NodeIsAnd(pNodeFpga) ); - // get the parameters of the best cut - pCutBest = Fpga_NodeReadCutBest( pNodeFpga ); - ppLeaves = Fpga_CutReadLeaves( pCutBest ); - nLeaves = Fpga_CutReadLeavesNum( pCutBest ); - // create a new node - pNodeNew = Abc_NtkCreateNode( pNtkNew ); - for ( i = 0; i < nLeaves; i++ ) - Abc_ObjAddFanin( pNodeNew, Abc_NodeFromFpga_rec(pNtkNew, ppLeaves[i]) ); - // derive the function of this node - pNodeNew->pData = Fpga_TruthsCutBdd( pNtkNew->pManFunc, pCutBest ); Cudd_Ref( pNodeNew->pData ); - Fpga_NodeSetData0( pNodeFpga, (char *)pNodeNew ); - return pNodeNew; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/base/abc/abcFraig.c b/src/base/abc/abcFraig.c deleted file mode 100644 index ef4746d5..00000000 --- a/src/base/abc/abcFraig.c +++ /dev/null @@ -1,583 +0,0 @@ -/**CFile**************************************************************** - - FileName [abcFraig.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Network and node package.] - - Synopsis [Procedures interfacing with the FRAIG package.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: abcFraig.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" -#include "fraig.h" -#include "main.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -extern Fraig_Man_t * Abc_NtkToFraig( Abc_Ntk_t * pNtk, Fraig_Params_t * pParams, int fAllNodes ); -static Abc_Ntk_t * Abc_NtkFromFraig( Fraig_Man_t * pMan, Abc_Ntk_t * pNtk ); -static Abc_Obj_t * Abc_NodeFromFraig_rec( Abc_Ntk_t * pNtkNew, Fraig_Node_t * pNodeFraig ); - -static int Abc_NtkFraigTrustCheck( Abc_Ntk_t * pNtk ); -static void Abc_NtkFraigTrustOne( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ); -static Abc_Obj_t * Abc_NodeFraigTrust( Abc_Aig_t * pMan, Abc_Obj_t * pNode ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Interfaces the network with the FRAIG package.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_NtkFraig( Abc_Ntk_t * pNtk, void * pParams, int fAllNodes ) -{ - int fCheck = 1; - Abc_Ntk_t * pNtkNew; - Fraig_Man_t * pMan; - // perform fraiging - pMan = Abc_NtkToFraig( pNtk, pParams, fAllNodes ); - // prove the miter if asked to - if ( ((Fraig_Params_t *)pParams)->fTryProve ) - Fraig_ManProveMiter( pMan ); - // reconstruct FRAIG in the new network - pNtkNew = Abc_NtkFromFraig( pMan, pNtk ); - Fraig_ManFree( pMan ); - // make sure that everything is okay - if ( fCheck && !Abc_NtkCheck( pNtkNew ) ) - { - printf( "Abc_NtkFraig: The network check has failed.\n" ); - Abc_NtkDelete( pNtkNew ); - return NULL; - } - return pNtkNew; -} - -/**Function************************************************************* - - Synopsis [Transforms the strashed network into FRAIG.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Fraig_Man_t * Abc_NtkToFraig( Abc_Ntk_t * pNtk, Fraig_Params_t * pParams, int fAllNodes ) -{ - Fraig_Man_t * pMan; - ProgressBar * pProgress; - Fraig_Node_t * pNodeFraig; - Vec_Ptr_t * vNodes; - Abc_Obj_t * pNode, * pConst1, * pReset; - int i; - - assert( Abc_NtkIsStrash(pNtk) ); - - // create the FRAIG manager - pMan = Fraig_ManCreate( pParams ); - - // create PIs and remember them in the old nodes - Abc_NtkCleanCopy( pNtk ); - Abc_NtkForEachCi( pNtk, pNode, i ) - pNode->pCopy = (Abc_Obj_t *)Fraig_ManReadIthVar(pMan, i); - pConst1 = Abc_AigConst1( pNtk->pManFunc ); - pReset = Abc_AigReset( pNtk->pManFunc ); - - // perform strashing - vNodes = Abc_AigDfs( pNtk, fAllNodes, 0 ); - pProgress = Extra_ProgressBarStart( stdout, vNodes->nSize ); - Vec_PtrForEachEntry( vNodes, pNode, i ) - { - Extra_ProgressBarUpdate( pProgress, i, NULL ); - if ( pNode == pConst1 ) - pNodeFraig = Fraig_ManReadConst1(pMan); - else if ( pNode == pReset ) - continue; - else - pNodeFraig = Fraig_NodeAnd( pMan, - Fraig_NotCond( Abc_ObjFanin0(pNode)->pCopy, Abc_ObjFaninC0(pNode) ), - Fraig_NotCond( Abc_ObjFanin1(pNode)->pCopy, Abc_ObjFaninC1(pNode) ) ); - assert( pNode->pCopy == NULL ); - pNode->pCopy = (Abc_Obj_t *)pNodeFraig; - } - Extra_ProgressBarStop( pProgress ); - Vec_PtrFree( vNodes ); - - // set the primary outputs - Abc_NtkForEachCo( pNtk, pNode, i ) - Fraig_ManSetPo( pMan, (Fraig_Node_t *)Abc_ObjFanin0(pNode)->pCopy ); - return pMan; -} - -/**Function************************************************************* - - Synopsis [Transforms FRAIG into what looks like a strashed network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_NtkFromFraig( Fraig_Man_t * pMan, Abc_Ntk_t * pNtk ) -{ - ProgressBar * pProgress; - Abc_Ntk_t * pNtkNew; - Abc_Obj_t * pNode;//, * pNodeNew; - int i; - // create the new network - pNtkNew = Abc_NtkStartFrom( pNtk, ABC_TYPE_STRASH, ABC_FUNC_AIG ); - // make the mapper point to the new network - Abc_NtkForEachCi( pNtk, pNode, i ) - Fraig_NodeSetData1( Fraig_ManReadIthVar(pMan, i), (Fraig_Node_t *)pNode->pCopy ); - // set the constant node - Fraig_NodeSetData1( Fraig_ManReadConst1(pMan), (Fraig_Node_t *)Abc_AigConst1(pNtkNew->pManFunc) ); - // process the nodes in topological order - pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCoNum(pNtk) ); - Abc_NtkForEachCo( pNtk, pNode, i ) - { - Extra_ProgressBarUpdate( pProgress, i, NULL ); - Abc_ObjFanin0(pNode)->pCopy = Abc_NodeFromFraig_rec( pNtkNew, Fraig_ManReadOutputs(pMan)[i] ); - } - Extra_ProgressBarStop( pProgress ); - // finalize the new network - Abc_NtkFinalize( pNtk, pNtkNew ); - return pNtkNew; -} - -/**Function************************************************************* - - Synopsis [Transforms into AIG one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_NodeFromFraig_rec( Abc_Ntk_t * pNtkNew, Fraig_Node_t * pNodeFraig ) -{ - Abc_Obj_t * pRes, * pRes0, * pRes1, * pResMin, * pResCur; - Fraig_Node_t * pNodeTemp, * pNodeFraigR = Fraig_Regular(pNodeFraig); - void ** ppTail; - // check if the node was already considered - if ( pRes = (Abc_Obj_t *)Fraig_NodeReadData1(pNodeFraigR) ) - return Abc_ObjNotCond( pRes, Fraig_IsComplement(pNodeFraig) ); - // solve the children - pRes0 = Abc_NodeFromFraig_rec( pNtkNew, Fraig_NodeReadOne(pNodeFraigR) ); - pRes1 = Abc_NodeFromFraig_rec( pNtkNew, Fraig_NodeReadTwo(pNodeFraigR) ); - // derive the new node - pRes = Abc_AigAnd( pNtkNew->pManFunc, pRes0, pRes1 ); - pRes->fPhase = Fraig_NodeReadSimInv( pNodeFraigR ); - // if the node has an equivalence class, find its representative - if ( Fraig_NodeReadRepr(pNodeFraigR) == NULL && Fraig_NodeReadNextE(pNodeFraigR) != NULL ) - { - // go through the FRAIG nodes belonging to this equivalence class - // and find the representative node (the node with the smallest level) - pResMin = pRes; - for ( pNodeTemp = Fraig_NodeReadNextE(pNodeFraigR); pNodeTemp; pNodeTemp = Fraig_NodeReadNextE(pNodeTemp) ) - { - assert( Fraig_NodeReadData1(pNodeTemp) == NULL ); - pResCur = Abc_NodeFromFraig_rec( pNtkNew, pNodeTemp ); - if ( pResMin->Level > pResCur->Level ) - pResMin = pResCur; - } - // link the nodes in such a way that representative goes first - ppTail = &pResMin->pData; - if ( pRes != pResMin ) - { - *ppTail = pRes; - ppTail = &pRes->pData; - } - for ( pNodeTemp = Fraig_NodeReadNextE(pNodeFraigR); pNodeTemp; pNodeTemp = Fraig_NodeReadNextE(pNodeTemp) ) - { - pResCur = (Abc_Obj_t *)Fraig_NodeReadData1(pNodeTemp); - assert( pResCur ); - if ( pResMin == pResCur ) - continue; - *ppTail = pResCur; - ppTail = &pResCur->pData; - } - assert( *ppTail == NULL ); - - // update the phase of the node - pRes = Abc_ObjNotCond( pResMin, (pRes->fPhase ^ pResMin->fPhase) ); - } - Fraig_NodeSetData1( pNodeFraigR, (Fraig_Node_t *)pRes ); - return Abc_ObjNotCond( pRes, Fraig_IsComplement(pNodeFraig) ); -} - - - - -/**Function************************************************************* - - Synopsis [Interfaces the network with the FRAIG package.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_NtkFraigTrust( Abc_Ntk_t * pNtk ) -{ - int fCheck = 1; - Abc_Ntk_t * pNtkNew; - - if ( !Abc_NtkIsSopLogic(pNtk) ) - { - printf( "Abc_NtkFraigTrust: Trust mode works for netlists and logic SOP networks.\n" ); - return NULL; - } - - if ( !Abc_NtkFraigTrustCheck(pNtk) ) - { - printf( "Abc_NtkFraigTrust: The network does not look like an AIG with choice nodes.\n" ); - return NULL; - } - - // perform strashing - pNtkNew = Abc_NtkStartFrom( pNtk, ABC_TYPE_STRASH, ABC_FUNC_AIG ); - Abc_NtkFraigTrustOne( pNtk, pNtkNew ); - Abc_NtkFinalize( pNtk, pNtkNew ); - - // print a warning about choice nodes - printf( "Warning: The resulting AIG contains %d choice nodes.\n", Abc_NtkGetChoiceNum( pNtkNew ) ); - - // make sure that everything is okay - if ( fCheck && !Abc_NtkCheck( pNtkNew ) ) - { - printf( "Abc_NtkFraigTrust: The network check has failed.\n" ); - Abc_NtkDelete( pNtkNew ); - return NULL; - } - return pNtkNew; -} - -/**Function************************************************************* - - Synopsis [Checks whether the node can be processed in the trust mode.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkFraigTrustCheck( Abc_Ntk_t * pNtk ) -{ - Abc_Obj_t * pNode; - int i, nFanins; - Abc_NtkForEachNode( pNtk, pNode, i ) - { - nFanins = Abc_ObjFaninNum(pNode); - if ( nFanins < 2 ) - continue; - if ( nFanins == 2 && Abc_SopIsAndType(pNode->pData) ) - continue; - if ( !Abc_SopIsOrType(pNode->pData) ) - return 0; - } - return 1; -} - -/**Function************************************************************* - - Synopsis [Interfaces the network with the FRAIG package.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkFraigTrustOne( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ) -{ - ProgressBar * pProgress; - Abc_Aig_t * pMan = pNtkNew->pManFunc; - Vec_Ptr_t * vNodes; - Abc_Obj_t * pNode, * pNodeNew, * pObj; - int i; - - // perform strashing - vNodes = Abc_NtkDfs( pNtk, 0 ); - pProgress = Extra_ProgressBarStart( stdout, vNodes->nSize ); - Vec_PtrForEachEntry( vNodes, pNode, i ) - { - Extra_ProgressBarUpdate( pProgress, i, NULL ); - // get the node - assert( Abc_ObjIsNode(pNode) ); - // strash the node - pNodeNew = Abc_NodeFraigTrust( pMan, pNode ); - // get the old object - if ( Abc_NtkIsNetlist(pNtk) ) - pObj = Abc_ObjFanout0( pNode ); // the fanout net - else - pObj = pNode; // the node itself - // make sure the node is not yet strashed - assert( pObj->pCopy == NULL ); - // mark the old object with the new AIG node - pObj->pCopy = pNodeNew; - } - Vec_PtrFree( vNodes ); - Extra_ProgressBarStop( pProgress ); -} - -/**Function************************************************************* - - Synopsis [Transforms one node into a FRAIG in the trust mode.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_NodeFraigTrust( Abc_Aig_t * pMan, Abc_Obj_t * pNode ) -{ - Abc_Obj_t * pSum, * pFanin; - Abc_Obj_t * pConst1 = Abc_AigConst1(pMan); - void ** ppTail; - int i, nFanins, fCompl; - - assert( Abc_ObjIsNode(pNode) ); - // get the number of node's fanins - nFanins = Abc_ObjFaninNum( pNode ); - assert( nFanins == Abc_SopGetVarNum(pNode->pData) ); - // check if it is a constant - if ( nFanins == 0 ) - return Abc_ObjNotCond( pConst1, Abc_SopIsConst0(pNode->pData) ); - if ( nFanins == 1 ) - return Abc_ObjNotCond( Abc_ObjFanin0(pNode)->pCopy, Abc_SopIsInv(pNode->pData) ); - if ( nFanins == 2 && Abc_SopIsAndType(pNode->pData) ) - return Abc_AigAnd( pMan, - Abc_ObjNotCond( Abc_ObjFanin0(pNode)->pCopy, !Abc_SopGetIthCareLit(pNode->pData,0) ), - Abc_ObjNotCond( Abc_ObjFanin1(pNode)->pCopy, !Abc_SopGetIthCareLit(pNode->pData,1) ) ); - assert( Abc_SopIsOrType(pNode->pData) ); - fCompl = Abc_SopGetIthCareLit(pNode->pData,0); - // get the root of the choice node (the first fanin) - pSum = Abc_ObjFanin0(pNode)->pCopy; - // connect other fanins - ppTail = &pSum->pData; - Abc_ObjForEachFanin( pNode, pFanin, i ) - { - if ( i == 0 ) - continue; - *ppTail = pFanin->pCopy; - ppTail = &pFanin->pCopy->pData; - // set the complemented bit of this cut - if ( fCompl ^ Abc_SopGetIthCareLit(pNode->pData, i) ) - pFanin->pCopy->fPhase = 1; - } - assert( *ppTail == NULL ); - return pSum; -} - - - - -/**Function************************************************************* - - Synopsis [Interfaces the network with the FRAIG package.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkFraigStore( Abc_Ntk_t * pNtk ) -{ - Abc_Frame_t * p; - Abc_Ntk_t * pStore; - int nAndsOld; - - if ( !Abc_NtkIsLogic(pNtk) && !Abc_NtkIsStrash(pNtk) ) - { - printf( "The netlist need to be converted into a logic network before adding it to storage.\n" ); - return 0; - } - - // get the network currently stored - p = Abc_FrameGetGlobalFrame(); - pStore = Abc_FrameReadNtkStore(p); - if ( pStore == NULL ) - { - // start the stored network - pStore = Abc_NtkStrash( pNtk, 0, 0 ); - if ( pStore == NULL ) - { - printf( "Abc_NtkFraigStore: Initial strashing has failed.\n" ); - return 0; - } - // save the parameters - Abc_FrameSetNtkStore( p, pStore ); - Abc_FrameSetNtkStoreSize( p, 1 ); - nAndsOld = 0; - } - else - { - // add the new network to storage - nAndsOld = Abc_NtkNodeNum( pStore ); - if ( !Abc_NtkAppend( pStore, pNtk ) ) - { - printf( "The current network cannot be appended to the stored network.\n" ); - return 0; - } - // set the number of networks stored - Abc_FrameSetNtkStoreSize( p, Abc_FrameReadNtkStoreSize(p) + 1 ); - } - printf( "The number of AIG nodes added to storage = %5d.\n", Abc_NtkNodeNum(pStore) - nAndsOld ); - return 1; -} - -/**Function************************************************************* - - Synopsis [Interfaces the network with the FRAIG package.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_NtkFraigRestore() -{ - Abc_Frame_t * p; - Fraig_Params_t Params; - Abc_Ntk_t * pStore, * pFraig; - int nWords1, nWords2, nWordsMin; - - // get the stored network - p = Abc_FrameGetGlobalFrame(); - pStore = Abc_FrameReadNtkStore(p); - Abc_FrameSetNtkStore( p, NULL ); - if ( pStore == NULL ) - { - printf( "There are no network currently in storage.\n" ); - return NULL; - } - printf( "Currently stored %d networks with %d nodes will be fraiged.\n", - Abc_FrameReadNtkStoreSize(p), Abc_NtkNodeNum(pStore) ); - - // to determine the number of simulation patterns - // use the following strategy - // at least 64 words (32 words random and 32 words dynamic) - // no more than 256M for one circuit (128M + 128M) - nWords1 = 32; - nWords2 = (1<<27) / (Abc_NtkNodeNum(pStore) + Abc_NtkCiNum(pStore)); - nWordsMin = ABC_MIN( nWords1, nWords2 ); - - // set parameters for fraiging - Fraig_ParamsSetDefault( &Params ); - Params.nPatsRand = nWordsMin * 32; // the number of words of random simulation info - Params.nPatsDyna = nWordsMin * 32; // the number of words of dynamic simulation info - Params.nBTLimit = 99; // the max number of backtracks to perform - Params.fFuncRed = 1; // performs only one level hashing - Params.fFeedBack = 1; // enables solver feedback - Params.fDist1Pats = 1; // enables distance-1 patterns - Params.fDoSparse = 1; // performs equiv tests for sparse functions - Params.fChoicing = 1; // enables recording structural choices - Params.fTryProve = 0; // tries to solve the final miter - Params.fVerbose = 0; // the verbosiness flag - -// Fraig_ManReportChoices( p ); - // transform it into FRAIG - pFraig = Abc_NtkFraig( pStore, &Params, 1 ); - if ( pFraig == NULL ) - return NULL; - Abc_NtkDelete( pStore ); - return pFraig; -} - -/**Function************************************************************* - - Synopsis [Interfaces the network with the FRAIG package.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkFraigStoreClean() -{ - Abc_Frame_t * p; - Abc_Ntk_t * pStore; - // get the stored network - p = Abc_FrameGetGlobalFrame(); - pStore = Abc_FrameReadNtkStore(p); - if ( pStore ) - Abc_NtkDelete( pStore ); - Abc_FrameSetNtkStore( p, NULL ); -} - -/**Function************************************************************* - - Synopsis [Checks the correctness of stored networks.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkFraigStoreCheck( Abc_Ntk_t * pFraig ) -{ - Abc_Obj_t * pNode0, * pNode1; - int nPoOrig, nPoFinal, nStored; - int i, k; - // check that the PO functions are correct - nPoFinal = Abc_NtkPoNum(pFraig); - nStored = Abc_FrameReadNtkStoreSize(Abc_FrameGetGlobalFrame()); - assert( nPoFinal % nStored == 0 ); - nPoOrig = nPoFinal / nStored; - for ( i = 0; i < nPoOrig; i++ ) - { - pNode0 = Abc_ObjFanin0( Abc_NtkPo(pFraig, i) ); - for ( k = 1; k < nStored; k++ ) - { - pNode1 = Abc_ObjFanin0( Abc_NtkPo(pFraig, k*nPoOrig+i) ); - if ( pNode0 != pNode1 ) - printf( "Verification for PO #%d of network #%d has failed. The PO function is not used.\n", i+1, k+1 ); - } - } -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/base/abc/abcFxu.c b/src/base/abc/abcFxu.c deleted file mode 100644 index 0c8994e1..00000000 --- a/src/base/abc/abcFxu.c +++ /dev/null @@ -1,259 +0,0 @@ -/**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 ) -{ - int fCheck = 1; - - assert( Abc_NtkIsLogic(pNtk) ); - // convert nodes to SOPs - if ( Abc_NtkIsMappedLogic(pNtk) ) - Abc_NtkUnmap(pNtk); - else if ( Abc_NtkIsBddLogic(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 - Abc_NtkFxuCollectInfo( pNtk, p ); - // call the fast extract procedure - if ( Fxu_FastExtract(p) > 0 ) - { - // update the network - Abc_NtkFxuReconstruct( pNtk, p ); - // make sure everything is okay - if ( fCheck && !Abc_NtkCheck( pNtk ) ) - printf( "Abc_NtkFastExtract: The network check has failed.\n" ); - return 1; - } - else - printf( "Warning: The network has not been changed by \"fx\".\n" ); - 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, Abc_NtkObjNumMax(pNtk), NULL ); - Vec_PtrFill( p->vFanins, Abc_NtkObjNumMax(pNtk), NULL ); - Vec_PtrFill( p->vSopsNew, Abc_NtkObjNumMax(pNtk) + p->nNodesExt, NULL ); - Vec_PtrFill( p->vFaninsNew, Abc_NtkObjNumMax(pNtk) + 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 = Abc_NtkObjNumMax(pNtk); -} - -/**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_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 ); - Abc_ObjRemoveFanins( pNode ); - // add new fanins - vFanins = p->vFaninsNew->pArray[i]; - for ( k = 0; k < vFanins->nSize; k++ ) - { - pFanin = Abc_NtkObj( pNtk, vFanins->pArray[k] ); - Abc_ObjAddFanin( pNode, pFanin ); - } - pNode->pData = p->vSopsNew->pArray[i]; - assert( pNode->pData != NULL ); - } - // set up the new nodes - for ( i = p->vFanins->nSize; i < p->vFanins->nSize + p->nNodesNew; i++ ) - { - // get the new node - pNode = Abc_NtkObj( pNtk, i ); - // add the fanins - vFanins = p->vFaninsNew->pArray[i]; - for ( k = 0; k < vFanins->nSize; k++ ) - { - pFanin = Abc_NtkObj( pNtk, vFanins->pArray[k] ); - Abc_ObjAddFanin( pNode, pFanin ); - } - pNode->pData = p->vSopsNew->pArray[i]; - assert( pNode->pData != NULL ); - } -} - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/base/abc/abcMap.c b/src/base/abc/abcMap.c deleted file mode 100644 index 28853c8d..00000000 --- a/src/base/abc/abcMap.c +++ /dev/null @@ -1,668 +0,0 @@ -/**CFile**************************************************************** - - FileName [abcMap.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Network and node package.] - - Synopsis [Interface with the SC mapping package.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: abcMap.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" -#include "main.h" -#include "mio.h" -#include "mapper.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static Map_Man_t * Abc_NtkToMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, int fVerbose ); -static Abc_Ntk_t * Abc_NtkFromMap( Map_Man_t * pMan, Abc_Ntk_t * pNtk ); -static Abc_Obj_t * Abc_NodeFromMap_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, int fPhase ); -static Abc_Obj_t * Abc_NodeFromMapPhase_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, int fPhase ); -static Abc_Obj_t * Abc_NodeFromMapSuper_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, Map_Super_t * pSuper, Abc_Obj_t * pNodePis[], int nNodePis ); - -static Abc_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 /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Interface with the mapping package.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_NtkMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, int fVerbose ) -{ - int fCheck = 1; - Abc_Ntk_t * pNtkNew; - Map_Man_t * pMan; - int clk; - - assert( Abc_NtkIsStrash(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_NtkGetChoiceNum( pNtk ) ) - printf( "Performing mapping with choices.\n" ); - - // perform the mapping - 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 ); - 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 [Load the network into manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Map_Man_t * Abc_NtkToMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, int fVerbose ) -{ - Map_Man_t * pMan; - ProgressBar * pProgress; - Map_Node_t * pNodeMap; - Vec_Ptr_t * vNodes; - Abc_Obj_t * pNode, * pFanin, * pPrev; - int i; - - assert( Abc_NtkIsStrash(pNtk) ); - - // start the mapping manager and set its parameters - pMan = Map_ManCreate( Abc_NtkPiNum(pNtk) + Abc_NtkLatchNum(pNtk), Abc_NtkPoNum(pNtk) + Abc_NtkLatchNum(pNtk), fVerbose ); - if ( pMan == NULL ) - return NULL; - Map_ManSetAreaRecovery( pMan, fRecovery ); - Map_ManSetOutputNames( pMan, Abc_NtkCollectCioNames(pNtk, 1) ); - Map_ManSetDelayTarget( pMan, (float)DelayTarget ); - Map_ManSetInputArrivals( pMan, (Map_Time_t *)Abc_NtkGetCiArrivalTimes(pNtk) ); - - // create PIs and remember them in the old nodes - Abc_NtkCleanCopy( pNtk ); - Abc_NtkForEachCi( pNtk, pNode, i ) - pNode->pCopy = (Abc_Obj_t *)Map_ManReadInputs(pMan)[i]; - - // load the AIG into the mapper - vNodes = Abc_AigDfs( pNtk, 0, 0 ); - pProgress = Extra_ProgressBarStart( stdout, vNodes->nSize ); - Vec_PtrForEachEntry( vNodes, pNode, i ) - { - Extra_ProgressBarUpdate( pProgress, i, NULL ); - // consider the case of a constant - if ( Abc_NodeIsConst(pNode) ) - { - Abc_AigConst1(pNtk->pManFunc)->pCopy = (Abc_Obj_t *)Map_ManReadConst1(pMan); - continue; - } - // add the node to the mapper - pNodeMap = Map_NodeAnd( pMan, - Map_NotCond( Abc_ObjFanin0(pNode)->pCopy, Abc_ObjFaninC0(pNode) ), - Map_NotCond( Abc_ObjFanin1(pNode)->pCopy, Abc_ObjFaninC1(pNode) ) ); - assert( pNode->pCopy == NULL ); - // remember the node - pNode->pCopy = (Abc_Obj_t *)pNodeMap; - // set up the choice node - if ( Abc_NodeIsAigChoice( pNode ) ) - for ( pPrev = pNode, pFanin = pNode->pData; pFanin; pPrev = pFanin, pFanin = pFanin->pData ) - { - Map_NodeSetNextE( (Map_Node_t *)pPrev->pCopy, (Map_Node_t *)pFanin->pCopy ); - Map_NodeSetRepr( (Map_Node_t *)pFanin->pCopy, (Map_Node_t *)pNode->pCopy ); - } - } - Extra_ProgressBarStop( pProgress ); - Vec_PtrFree( vNodes ); - - // set the primary outputs in the required phase - Abc_NtkForEachCo( pNtk, pNode, i ) - Map_ManReadOutputs(pMan)[i] = Map_NotCond( (Map_Node_t *)Abc_ObjFanin0(pNode)->pCopy, Abc_ObjFaninC0(pNode) ); - return pMan; -} - -/**Function************************************************************* - - Synopsis [Creates the mapped network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_NtkFromMap( Map_Man_t * pMan, Abc_Ntk_t * pNtk ) -{ - ProgressBar * pProgress; - Abc_Ntk_t * pNtkNew; - Map_Node_t * pNodeMap; - Abc_Obj_t * pNode, * pNodeNew; - int i, nDupGates; - - // create the new network - pNtkNew = Abc_NtkStartFrom( pNtk, ABC_TYPE_LOGIC, ABC_FUNC_MAP ); - // make the mapper point to the new network - Map_ManCleanData( pMan ); - Abc_NtkForEachCi( pNtk, pNode, i ) - Map_NodeSetData( Map_ManReadInputs(pMan)[i], 1, (char *)pNode->pCopy ); - // set the constant node - if ( Abc_ObjFanoutNum( Abc_AigConst1(pNtk->pManFunc) ) > 0 ) - Map_NodeSetData( Map_ManReadConst1(pMan), 1, (char *)Abc_NodeCreateConst1(pNtkNew) ); - - // assign the mapping of the required phase to the POs - pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCoNum(pNtk) ); - Abc_NtkForEachCo( pNtk, pNode, i ) - { - Extra_ProgressBarUpdate( pProgress, i, NULL ); - pNodeMap = Map_ManReadOutputs(pMan)[i]; - pNodeNew = Abc_NodeFromMap_rec( pNtkNew, Map_Regular(pNodeMap), !Map_IsComplement(pNodeMap) ); - assert( !Abc_ObjIsComplement(pNodeNew) ); - Abc_ObjAddFanin( pNode->pCopy, pNodeNew ); - } - Extra_ProgressBarStop( pProgress ); - // decouple the PO driver nodes to reduce the number of levels - nDupGates = Abc_NtkLogicMakeSimpleCos( pNtkNew, 1 ); - if ( nDupGates && Map_ManReadVerbose(pMan) ) - printf( "Duplicated %d gates to decouple the PO drivers.\n", nDupGates ); - return pNtkNew; -} - -/**Function************************************************************* - - Synopsis [Constructs the nodes corrresponding to one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_NodeFromMap_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, int fPhase ) -{ - Abc_Obj_t * pNodeNew, * pNodeInv; - - // check if the phase is already implemented - pNodeNew = (Abc_Obj_t *)Map_NodeReadData( pNodeMap, fPhase ); - if ( pNodeNew ) - return pNodeNew; - - // implement the node if the best cut is assigned - if ( Map_NodeReadCutBest(pNodeMap, fPhase) != NULL ) - return Abc_NodeFromMapPhase_rec( pNtkNew, pNodeMap, fPhase ); - - // if the cut is not assigned, implement the node - assert( Map_NodeReadCutBest(pNodeMap, !fPhase) != NULL || Map_NodeIsConst(pNodeMap) ); - pNodeNew = Abc_NodeFromMapPhase_rec( pNtkNew, pNodeMap, !fPhase ); - - // add the inverter - pNodeInv = Abc_NtkCreateNode( pNtkNew ); - Abc_ObjAddFanin( pNodeInv, pNodeNew ); - pNodeInv->pData = Mio_LibraryReadInv(Map_ManReadGenLib(Map_NodeReadMan(pNodeMap))); - - // set the inverter - Map_NodeSetData( pNodeMap, fPhase, (char *)pNodeInv ); - return pNodeInv; -} - -/**Function************************************************************* - - Synopsis [Constructs the nodes corrresponding to one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_NodeFromMapPhase_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, int fPhase ) -{ - Abc_Obj_t * pNodePIs[10]; - Abc_Obj_t * pNodeNew; - Map_Node_t ** ppLeaves; - Map_Cut_t * pCutBest; - Map_Super_t * pSuperBest; - unsigned uPhaseBest; - int i, fInvPin, nLeaves; - - // make sure the node can be implemented in this phase - assert( Map_NodeReadCutBest(pNodeMap, fPhase) != NULL || Map_NodeIsConst(pNodeMap) ); - // check if the phase is already implemented - pNodeNew = (Abc_Obj_t *)Map_NodeReadData( pNodeMap, fPhase ); - if ( pNodeNew ) - return pNodeNew; - - // get the information about the best cut - pCutBest = Map_NodeReadCutBest( pNodeMap, fPhase ); - pSuperBest = Map_CutReadSuperBest( pCutBest, fPhase ); - uPhaseBest = Map_CutReadPhaseBest( pCutBest, fPhase ); - nLeaves = Map_CutReadLeavesNum( pCutBest ); - ppLeaves = Map_CutReadLeaves( pCutBest ); - - // collect the PI nodes - for ( i = 0; i < nLeaves; i++ ) - { - fInvPin = ((uPhaseBest & (1 << i)) > 0); - pNodePIs[i] = Abc_NodeFromMap_rec( pNtkNew, ppLeaves[i], !fInvPin ); - assert( pNodePIs[i] != NULL ); - } - - // implement the supergate - pNodeNew = Abc_NodeFromMapSuper_rec( pNtkNew, pNodeMap, pSuperBest, pNodePIs, nLeaves ); - Map_NodeSetData( pNodeMap, fPhase, (char *)pNodeNew ); - return pNodeNew; -} - -/**Function************************************************************* - - Synopsis [Constructs the nodes corrresponding to one supergate.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_NodeFromMapSuper_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, 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_NodeFromMapSuper_rec( pNtkNew, pNodeMap, ppFanins[i], pNodePis, nNodePis ); - Abc_ObjAddFanin( pNodeNew, pNodeFanin ); - } - pNodeNew->pData = pRoot; - return pNodeNew; -} - - -/**Function************************************************************* - - Synopsis [Unmaps the network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkUnmap( Abc_Ntk_t * pNtk ) -{ - Abc_Obj_t * pNode; - char * pSop; - int i; - - assert( Abc_NtkIsMappedLogic(pNtk) ); - // update the functionality manager - assert( pNtk->pManFunc == Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()) ); - pNtk->pManFunc = Extra_MmFlexStart(); - pNtk->ntkFunc = ABC_FUNC_SOP; - // update the nodes - Abc_NtkForEachNode( pNtk, pNode, i ) - { - pSop = Mio_GateReadSop(pNode->pData); - assert( Abc_SopGetVarNum(pSop) == Abc_ObjFaninNum(pNode) ); - pNode->pData = Abc_SopRegister( pNtk->pManFunc, pSop ); - } - return 1; -} - - - - -/**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_NtkIsStrash(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_NtkGetChoiceNum( 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_NtkObjNumMax(pNtk) ); - Abc_NtkForEachNode( pNtk, pNode, i ) - { - Extra_ProgressBarUpdate( pProgress, i, NULL ); - if ( Abc_NodeIsConst(pNode) ) - continue; - Abc_NodeSuperChoice( pNtkNew, pNode ); - } - Extra_ProgressBarStop( pProgress ); - return pNtkNew; -} - - -/**Function************************************************************* - - Synopsis [Creates the mapped network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NodeSuperChoice( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode ) -{ - Map_Node_t * pMapNode = (Map_Node_t *)pNode->pNext; - Map_Cut_t * pCuts, * pTemp; - - pCuts = Map_NodeReadCuts(pMapNode); - for ( pTemp = Map_CutReadNext(pCuts); pTemp; pTemp = Map_CutReadNext(pTemp) ) - { - Abc_NodeFromMapCutPhase( pNtkNew, pTemp, 0 ); - Abc_NodeFromMapCutPhase( pNtkNew, pTemp, 1 ); - } -} - - -/**Function************************************************************* - - Synopsis [Constructs the nodes corrresponding to one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NodeFromMapCutPhase( Abc_Ntk_t * pNtkNew, Map_Cut_t * pCut, int fPhase ) -{ - Abc_Obj_t * pNodePIs[10]; - Map_Node_t ** ppLeaves; - Map_Super_t * pSuperBest; - unsigned uPhaseBest; - int i, fInvPin, nLeaves; - - pSuperBest = Map_CutReadSuperBest( pCut, fPhase ); - if ( pSuperBest == NULL ) - return; - - // get the information about the best cut - uPhaseBest = Map_CutReadPhaseBest( pCut, fPhase ); - nLeaves = Map_CutReadLeavesNum( pCut ); - ppLeaves = Map_CutReadLeaves( pCut ); - - // collect the PI nodes - for ( i = 0; i < nLeaves; i++ ) - { - fInvPin = ((uPhaseBest & (1 << i)) > 0); - pNodePIs[i] = (Abc_Obj_t *)Map_NodeReadData( ppLeaves[i], !fInvPin ); - assert( pNodePIs[i] != NULL ); - } - - // implement the supergate - Abc_NodeFromMapSuperChoice_rec( pNtkNew, pSuperBest, pNodePIs, nLeaves ); -} - - -/**Function************************************************************* - - Synopsis [Constructs the nodes corrresponding to one supergate.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_NodeFromMapSuperChoice_rec( Abc_Ntk_t * pNtkNew, Map_Super_t * pSuper, Abc_Obj_t * pNodePis[], int nNodePis ) -{ - Mio_Gate_t * pRoot; - Map_Super_t ** ppFanins; - Abc_Obj_t * pNodeNew, * pNodeFanin; - int nFanins, Number, i; - - // get the parameters of the supergate - pRoot = Map_SuperReadRoot(pSuper); - if ( pRoot == NULL ) - { - Number = Map_SuperReadNum(pSuper); - if ( Number < nNodePis ) - { - return pNodePis[Number]; - } - else - { -// assert( 0 ); - /* It might happen that a super gate with 5 inputs is constructed that - * actually depends only on the first four variables; i.e the fifth is a - * don't care -- in that case we connect constant node for the fifth - * (since the cut only has 4 variables). An interesting question is what - * if the first variable (and not the fifth one is the redundant one; - * can that happen?) */ - return Abc_NodeCreateConst0(pNtkNew); - } - } - - // get information about the fanins of the supergate - nFanins = Map_SuperReadFaninNum( pSuper ); - ppFanins = Map_SuperReadFanins( pSuper ); - // create a new node with these fanins - pNodeNew = Abc_NtkCreateNode( pNtkNew ); - for ( i = 0; i < nFanins; i++ ) - { - pNodeFanin = Abc_NodeFromMapSuperChoice_rec( pNtkNew, ppFanins[i], pNodePis, nNodePis ); - Abc_ObjAddFanin( pNodeNew, pNodeFanin ); - } - pNodeNew->pData = Abc_SopRegister( pNtkNew->pManFunc, Mio_GateReadSop(pRoot) ); - return pNodeNew; -} - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/base/abc/abcMiter.c b/src/base/abc/abcMiter.c deleted file mode 100644 index a0426dc2..00000000 --- a/src/base/abc/abcMiter.c +++ /dev/null @@ -1,600 +0,0 @@ -/**CFile**************************************************************** - - FileName [abcMiter.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Network and node package.] - - Synopsis [Procedures to derive the miter of two circuits.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: abcMiter.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static Abc_Ntk_t * Abc_NtkMiterInt( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb ); -static void Abc_NtkMiterPrepare( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, Abc_Ntk_t * pNtkMiter, int fComb ); -static void Abc_NtkMiterAddOne( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkMiter ); -static void Abc_NtkMiterAddOneNode( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkMiter, Abc_Obj_t * pNode ); -static void Abc_NtkMiterFinalize( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, Abc_Ntk_t * pNtkMiter, int fComb ); -static void Abc_NtkAddFrame( Abc_Ntk_t * pNetNew, Abc_Ntk_t * pNet, int iFrame, Vec_Ptr_t * vNodes ); - - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Derives the miter of two networks.] - - Description [Preprocesses the networks to make sure that they are strashed.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_NtkMiter( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb ) -{ - Abc_Ntk_t * pTemp = NULL; - int fRemove1, fRemove2; - // check that the networks have the same PIs/POs/latches - if ( !Abc_NtkCompareSignals( pNtk1, pNtk2, fComb ) ) - return NULL; - // make sure the circuits are strashed - fRemove1 = (!Abc_NtkIsStrash(pNtk1)) && (pNtk1 = Abc_NtkStrash(pNtk1, 0, 0)); - fRemove2 = (!Abc_NtkIsStrash(pNtk2)) && (pNtk2 = Abc_NtkStrash(pNtk2, 0, 0)); - if ( pNtk1 && pNtk2 ) - pTemp = Abc_NtkMiterInt( pNtk1, pNtk2, fComb ); - if ( fRemove1 ) Abc_NtkDelete( pNtk1 ); - if ( fRemove2 ) Abc_NtkDelete( pNtk2 ); - return pTemp; -} - -/**Function************************************************************* - - Synopsis [Derives the miter of two sequential networks.] - - Description [Assumes that the networks are strashed.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_NtkMiterInt( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb ) -{ - int fCheck = 1; - char Buffer[100]; - Abc_Ntk_t * pNtkMiter; - - assert( Abc_NtkIsStrash(pNtk1) ); - assert( Abc_NtkIsStrash(pNtk2) ); - - // start the new network - pNtkMiter = Abc_NtkAlloc( ABC_TYPE_STRASH, ABC_FUNC_AIG ); - sprintf( Buffer, "%s_%s_miter", pNtk1->pName, pNtk2->pName ); - pNtkMiter->pName = util_strsav(Buffer); - - // perform strashing - Abc_NtkMiterPrepare( pNtk1, pNtk2, pNtkMiter, fComb ); - Abc_NtkMiterAddOne( pNtk1, pNtkMiter ); - Abc_NtkMiterAddOne( pNtk2, pNtkMiter ); - Abc_NtkMiterFinalize( pNtk1, pNtk2, pNtkMiter, fComb ); - - // make sure that everything is okay - if ( fCheck && !Abc_NtkCheck( pNtkMiter ) ) - { - printf( "Abc_NtkMiter: The network check has failed.\n" ); - Abc_NtkDelete( pNtkMiter ); - return NULL; - } - return pNtkMiter; -} - -/**Function************************************************************* - - Synopsis [Prepares the network for mitering.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkMiterPrepare( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, Abc_Ntk_t * pNtkMiter, int fComb ) -{ - Abc_Obj_t * pObj, * pObjNew; - int i; - // clean the copy field in all objects - Abc_NtkCleanCopy( pNtk1 ); - Abc_NtkCleanCopy( pNtk2 ); - if ( fComb ) - { - // create new PIs and remember them in the old PIs - Abc_NtkForEachCi( pNtk1, pObj, i ) - { - pObjNew = Abc_NtkCreatePi( pNtkMiter ); - // remember this PI in the old PIs - pObj->pCopy = pObjNew; - pObj = Abc_NtkCi(pNtk2, i); - pObj->pCopy = pObjNew; - // add name - Abc_NtkLogicStoreName( pObjNew, Abc_ObjName(pObj) ); - } - // create the only PO - pObjNew = Abc_NtkCreatePo( pNtkMiter ); - // add the PO name - Abc_NtkLogicStoreName( pObjNew, "miter" ); - } - else - { - // create new PIs and remember them in the old PIs - Abc_NtkForEachPi( pNtk1, pObj, i ) - { - pObjNew = Abc_NtkCreatePi( pNtkMiter ); - // remember this PI in the old PIs - pObj->pCopy = pObjNew; - pObj = Abc_NtkPi(pNtk2, i); - pObj->pCopy = pObjNew; - // add name - Abc_NtkLogicStoreName( pObjNew, Abc_ObjName(pObj) ); - } - // create the only PO - pObjNew = Abc_NtkCreatePo( pNtkMiter ); - // add the PO name - Abc_NtkLogicStoreName( pObjNew, "miter" ); - // create the latches - Abc_NtkForEachLatch( pNtk1, pObj, i ) - { - pObjNew = Abc_NtkDupObj( pNtkMiter, pObj ); - Vec_PtrPush( pNtkMiter->vCis, pObjNew ); - Vec_PtrPush( pNtkMiter->vCos, pObjNew ); - // add name - Abc_NtkLogicStoreNamePlus( pObjNew, Abc_ObjName(pObj), "_1" ); - } - Abc_NtkForEachLatch( pNtk2, pObj, i ) - { - pObjNew = Abc_NtkDupObj( pNtkMiter, pObj ); - Vec_PtrPush( pNtkMiter->vCis, pObjNew ); - Vec_PtrPush( pNtkMiter->vCos, pObjNew ); - // add name - Abc_NtkLogicStoreNamePlus( pObjNew, Abc_ObjName(pObj), "_2" ); - } - } -} - -/**Function************************************************************* - - Synopsis [Performs mitering for one network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkMiterAddOne( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkMiter ) -{ - ProgressBar * pProgress; - Vec_Ptr_t * vNodes; - Abc_Obj_t * pNode, * pConst1, * pConst1New; - int i; - // get the constant nodes - pConst1 = Abc_AigConst1( pNtk->pManFunc ); - pConst1New = Abc_AigConst1( pNtkMiter->pManFunc ); - // perform strashing - vNodes = Abc_NtkDfs( pNtk, 0 ); - pProgress = Extra_ProgressBarStart( stdout, vNodes->nSize ); - Vec_PtrForEachEntry( vNodes, pNode, i ) - { - Extra_ProgressBarUpdate( pProgress, i, NULL ); - if ( pNode == pConst1 ) - pNode->pCopy = pConst1New; - else - pNode->pCopy = Abc_AigAnd( pNtkMiter->pManFunc, Abc_ObjChild0Copy(pNode), Abc_ObjChild1Copy(pNode) ); - } - Vec_PtrFree( vNodes ); - Extra_ProgressBarStop( pProgress ); -} - -/**Function************************************************************* - - Synopsis [Performs mitering for one network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkMiterAddOneNode( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkMiter, Abc_Obj_t * pRoot ) -{ - Vec_Ptr_t * vNodes; - Abc_Obj_t * pNode, * pNodeNew, * pConst1, * pConst1New; - int i; - // get the constant nodes - pConst1 = Abc_AigConst1( pNtk->pManFunc ); - pConst1New = Abc_AigConst1( pNtkMiter->pManFunc ); - // perform strashing - vNodes = Abc_NtkDfsNodes( pNtk, &pRoot, 1 ); - for ( i = 0; i < vNodes->nSize; i++ ) - { - pNode = vNodes->pArray[i]; - if ( pNode == pConst1 ) - pNodeNew = pConst1New; - else - pNodeNew = Abc_AigAnd( pNtkMiter->pManFunc, Abc_ObjChild0Copy(pNode), Abc_ObjChild1Copy(pNode) ); - pNode->pCopy = pNodeNew; - } - Vec_PtrFree( vNodes ); -} - - -/**Function************************************************************* - - Synopsis [Finalizes the miter by adding the output part.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkMiterFinalize( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, Abc_Ntk_t * pNtkMiter, int fComb ) -{ - Vec_Ptr_t * vPairs; - Abc_Obj_t * pMiter, * pNode; - int i; - // collect the PO pairs from both networks - vPairs = Vec_PtrAlloc( 100 ); - if ( fComb ) - { - // collect the CO nodes for the miter - Abc_NtkForEachCo( pNtk1, pNode, i ) - { - Vec_PtrPush( vPairs, Abc_ObjChild0Copy(pNode) ); - pNode = Abc_NtkCo( pNtk2, i ); - Vec_PtrPush( vPairs, Abc_ObjChild0Copy(pNode) ); - } - } - else - { - // collect the PO nodes for the miter - Abc_NtkForEachPo( pNtk1, pNode, i ) - { - Vec_PtrPush( vPairs, Abc_ObjChild0Copy(pNode) ); - pNode = Abc_NtkPo( pNtk2, i ); - Vec_PtrPush( vPairs, Abc_ObjChild0Copy(pNode) ); - } - // connect new latches - Abc_NtkForEachLatch( pNtk1, pNode, i ) - Abc_ObjAddFanin( pNode->pCopy, Abc_ObjChild0Copy(pNode) ); - Abc_NtkForEachLatch( pNtk2, pNode, i ) - Abc_ObjAddFanin( pNode->pCopy, Abc_ObjChild0Copy(pNode) ); - } - // add the miter - pMiter = Abc_AigMiter( pNtkMiter->pManFunc, vPairs ); - Abc_ObjAddFanin( Abc_NtkPo(pNtkMiter,0), pMiter ); - Vec_PtrFree( vPairs ); -} - - - - -/**Function************************************************************* - - Synopsis [Derives the miter of two cofactors of one output.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_NtkMiterOne( Abc_Ntk_t * pNtk, int Out, int In1, int In2 ) -{ - int fCheck = 1; - char Buffer[100]; - Abc_Ntk_t * pNtkMiter; - Abc_Obj_t * pRoot, * pOutput1, * pOutput2, * pMiter; - - assert( Abc_NtkIsStrash(pNtk) ); - assert( Out < Abc_NtkCoNum(pNtk) ); - assert( In1 < Abc_NtkCiNum(pNtk) ); - assert( In2 < Abc_NtkCiNum(pNtk) ); - - // start the new network - pNtkMiter = Abc_NtkAlloc( ABC_TYPE_STRASH, ABC_FUNC_AIG ); - sprintf( Buffer, "%s_%s_miter", pNtk->pName, Abc_ObjName(Abc_NtkCo(pNtk, Out)) ); - pNtkMiter->pName = util_strsav(Buffer); - - // get the root output - pRoot = Abc_NtkCo( pNtk, Out ); - - // perform strashing - Abc_NtkMiterPrepare( pNtk, pNtk, pNtkMiter, 1 ); - // set the first cofactor - Abc_NtkCi(pNtk, In1)->pCopy = Abc_ObjNot( Abc_AigConst1(pNtkMiter->pManFunc) ); - if ( In2 >= 0 ) - Abc_NtkCi(pNtk, In2)->pCopy = Abc_AigConst1( pNtkMiter->pManFunc ); - // add the first cofactor - Abc_NtkMiterAddOneNode( pNtk, pNtkMiter, pRoot ); - - // save the output - pOutput1 = Abc_ObjFanin0(pRoot)->pCopy; - - // set the second cofactor - Abc_NtkCi(pNtk, In1)->pCopy = Abc_AigConst1( pNtkMiter->pManFunc ); - if ( In2 >= 0 ) - Abc_NtkCi(pNtk, In2)->pCopy = Abc_ObjNot( Abc_AigConst1(pNtkMiter->pManFunc) ); - // add the second cofactor - Abc_NtkMiterAddOneNode( pNtk, pNtkMiter, pRoot ); - - // save the output - pOutput2 = Abc_ObjFanin0(pRoot)->pCopy; - - // create the miter of the two outputs - pMiter = Abc_AigXor( pNtkMiter->pManFunc, pOutput1, pOutput2 ); - Abc_ObjAddFanin( Abc_NtkPo(pNtkMiter,0), pMiter ); - - // make sure that everything is okay - if ( fCheck && !Abc_NtkCheck( pNtkMiter ) ) - { - printf( "Abc_NtkMiter: The network check has failed.\n" ); - Abc_NtkDelete( pNtkMiter ); - return NULL; - } - return pNtkMiter; -} - - - - - -/**Function************************************************************* - - Synopsis [Checks the status of the miter.] - - Description [Return 1 if the miter is sat for at least one output. - Return 0 if the miter is unsat for all its outputs. Returns -1 if the - miter is undecided for some outputs.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkMiterIsConstant( Abc_Ntk_t * pMiter ) -{ - Abc_Obj_t * pNodePo, * pChild; - int i; - assert( Abc_NtkIsStrash(pMiter) ); - Abc_NtkForEachPo( pMiter, pNodePo, i ) - { - pChild = Abc_ObjChild0( Abc_NtkPo(pMiter,i) ); - if ( Abc_ObjIsNode(Abc_ObjRegular(pChild)) && Abc_NodeIsConst(pChild) ) - { - assert( Abc_ObjRegular(pChild) == Abc_AigConst1(pMiter->pManFunc) ); - if ( !Abc_ObjIsComplement(pChild) ) - { - // if the miter is constant 1, return immediately - printf( "MITER IS CONSTANT 1!\n" ); - return 1; - } - } - // if the miter is undecided (or satisfiable), return immediately - else - return -1; - } - // return 0, meaning all outputs are constant zero - return 0; -} - -/**Function************************************************************* - - Synopsis [Reports the status of the miter.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkMiterReport( Abc_Ntk_t * pMiter ) -{ - Abc_Obj_t * pChild, * pNode; - int i; - if ( Abc_NtkPoNum(pMiter) == 1 ) - { - pChild = Abc_ObjChild0( Abc_NtkPo(pMiter,0) ); - if ( Abc_ObjIsNode(Abc_ObjRegular(pChild)) && Abc_NodeIsConst(pChild) ) - { - if ( Abc_ObjIsComplement(pChild) ) - printf( "Unsatisfiable.\n" ); - else - printf( "Satisfiable. (Constant 1).\n" ); - } - else - printf( "Satisfiable.\n" ); - } - else - { - Abc_NtkForEachPo( pMiter, pNode, i ) - { - pChild = Abc_ObjChild0( Abc_NtkPo(pMiter,i) ); - printf( "Output #%2d : ", i ); - if ( Abc_ObjIsNode(Abc_ObjRegular(pChild)) && Abc_NodeIsConst(pChild) ) - { - if ( Abc_ObjIsComplement(pChild) ) - printf( "Unsatisfiable.\n" ); - else - printf( "Satisfiable. (Constant 1).\n" ); - } - else - printf( "Satisfiable.\n" ); - } - } -} - - -/**Function************************************************************* - - Synopsis [Derives the timeframes of the network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_NtkFrames( Abc_Ntk_t * pNtk, int nFrames, int fInitial ) -{ - int fCheck = 1; - char Buffer[100]; - ProgressBar * pProgress; - Abc_Ntk_t * pNtkFrames; - Vec_Ptr_t * vNodes; - Abc_Obj_t * pLatch, * pLatchNew; - int i, Counter; - assert( nFrames > 0 ); - assert( Abc_NtkIsStrash(pNtk) ); - // start the new network - pNtkFrames = Abc_NtkAlloc( ABC_TYPE_STRASH, ABC_FUNC_AIG ); - sprintf( Buffer, "%s_%d_frames", pNtk->pName, nFrames ); - pNtkFrames->pName = util_strsav(Buffer); - // create new latches (or their initial values) and remember them in the new latches - if ( !fInitial ) - { - Abc_NtkForEachLatch( pNtk, pLatch, i ) - Abc_NtkDupObj( pNtkFrames, pLatch ); - } - else - { - Counter = 0; - Abc_NtkForEachLatch( pNtk, pLatch, i ) - { - if ( Abc_LatchIsInitDc(pLatch) ) // don't-care initial value - create a new PI - { - pLatch->pCopy = Abc_NtkCreatePi(pNtkFrames); - Abc_NtkLogicStoreName( pLatch->pCopy, Abc_ObjName(pLatch) ); - Counter++; - } - else - pLatch->pCopy = Abc_ObjNotCond( Abc_AigConst1(pNtkFrames->pManFunc), Abc_LatchIsInit0(pLatch) ); - } - if ( Counter ) - printf( "Warning: %d uninitialized latches are replaced by free variables.\n", Counter ); - } - - // create the timeframes - vNodes = Abc_NtkDfs( pNtk, 0 ); - pProgress = Extra_ProgressBarStart( stdout, nFrames ); - for ( i = 0; i < nFrames; i++ ) - { - Extra_ProgressBarUpdate( pProgress, i, NULL ); - Abc_NtkAddFrame( pNtkFrames, pNtk, i, vNodes ); - } - Extra_ProgressBarStop( pProgress ); - Vec_PtrFree( vNodes ); - - // connect the new latches to the outputs of the last frame - if ( !fInitial ) - { - Abc_NtkForEachLatch( pNtk, pLatch, i ) - { - pLatchNew = Abc_NtkLatch(pNtkFrames, i); - Abc_ObjAddFanin( pLatchNew, Abc_ObjFanin0(pLatch)->pCopy ); - Vec_PtrPush( pNtkFrames->vCis, pLatchNew ); - Vec_PtrPush( pNtkFrames->vCos, pLatchNew ); - Abc_NtkLogicStoreName( pLatchNew, Abc_ObjName(pLatch) ); - } - } - // make sure that everything is okay - if ( fCheck && !Abc_NtkCheck( pNtkFrames ) ) - { - printf( "Abc_NtkFrames: The network check has failed.\n" ); - Abc_NtkDelete( pNtkFrames ); - return NULL; - } - return pNtkFrames; -} - -/**Function************************************************************* - - Synopsis [Adds one time frame to the new network.] - - Description [Assumes that the latches of the old network point - to the outputs of the previous frame of the new network (pLatch->pCopy). - In the end, updates the latches of the old network to point to the - outputs of the current frame of the new network.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkAddFrame( Abc_Ntk_t * pNtkFrames, Abc_Ntk_t * pNtk, int iFrame, Vec_Ptr_t * vNodes ) -{ - char Buffer[10]; - Abc_Obj_t * pNode, * pNodeNew, * pLatch; - Abc_Obj_t * pConst1, * pConst1New; - int i; - // get the constant nodes - pConst1 = Abc_AigConst1( pNtk->pManFunc ); - pConst1New = Abc_AigConst1( pNtkFrames->pManFunc ); - // create the prefix to be added to the node names - sprintf( Buffer, "_%02d", iFrame ); - // add the new PI nodes - Abc_NtkForEachPi( pNtk, pNode, i ) - { - pNodeNew = Abc_NtkDupObj( pNtkFrames, pNode ); - Abc_NtkLogicStoreNamePlus( pNodeNew, Abc_ObjName(pNode), Buffer ); - } - // add the internal nodes - Vec_PtrForEachEntry( vNodes, pNode, i ) - { - if ( pNode == pConst1 ) - pNodeNew = pConst1New; - else - pNodeNew = Abc_AigAnd( pNtkFrames->pManFunc, Abc_ObjChild0Copy(pNode), Abc_ObjChild1Copy(pNode) ); - pNode->pCopy = pNodeNew; - } - // add the new POs - Abc_NtkForEachPo( pNtk, pNode, i ) - { - pNodeNew = Abc_NtkDupObj( pNtkFrames, pNode ); - Abc_ObjAddFanin( pNodeNew, Abc_ObjChild0Copy(pNode) ); - Abc_NtkLogicStoreNamePlus( pNodeNew, Abc_ObjName(pNode), Buffer ); - } - // transfer the implementation of the latch drivers to the latches - Abc_NtkForEachLatch( pNtk, pLatch, i ) - pLatch->pCopy = Abc_ObjChild0Copy(pLatch); -} - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/base/abc/abcNtbdd.c b/src/base/abc/abcNtbdd.c deleted file mode 100644 index 61c1a110..00000000 --- a/src/base/abc/abcNtbdd.c +++ /dev/null @@ -1,402 +0,0 @@ -/**CFile**************************************************************** - - FileName [abcNtbdd.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Network and node package.] - - Synopsis [Procedures to translate between the BDD and the network.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: abcNtbdd.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static void Abc_NtkBddToMuxesPerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ); -static Abc_Obj_t * Abc_NodeBddToMuxes( Abc_Obj_t * pNodeOld, Abc_Ntk_t * pNtkNew, Abc_Obj_t * pConst1 ); -static Abc_Obj_t * Abc_NodeBddToMuxes_rec( DdManager * dd, DdNode * bFunc, Abc_Ntk_t * pNtkNew, st_table * tBdd2Node ); -static DdNode * Abc_NodeGlobalBdds_rec( DdManager * dd, Abc_Obj_t * pNode ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Constructs the network isomorphic to the given BDD.] - - Description [Assumes that the BDD depends on the variables whose indexes - correspond to the names in the array (pNamesPi). Otherwise, returns NULL. - The resulting network comes with one node, whose functionality is - equal to the given BDD. To decompose this BDD into the network of - multiplexers use Abc_NtkBddToMuxes(). To decompose this BDD into - an And-Inverter Graph, use Abc_NtkStrash().] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_NtkDeriveFromBdd( DdManager * dd, DdNode * bFunc, char * pNamePo, Vec_Ptr_t * vNamesPi ) -{ - Abc_Ntk_t * pNtk; - Vec_Ptr_t * vNamesPiFake = NULL; - Abc_Obj_t * pNode, * pNodePi, * pNodePo; - DdNode * bSupp, * bTemp; - char * pName; - int i; - - // supply fake names if real names are not given - if ( pNamePo == NULL ) - pNamePo = "F"; - if ( vNamesPi == NULL ) - { - vNamesPiFake = Abc_NodeGetFakeNames( dd->size ); - vNamesPi = vNamesPiFake; - } - - // make sure BDD depends on the variables whose index - // does not exceed the size of the array with PI names - bSupp = Cudd_Support( dd, bFunc ); Cudd_Ref( bSupp ); - for ( bTemp = bSupp; bTemp != Cudd_ReadOne(dd); bTemp = cuddT(bTemp) ) - if ( (int)Cudd_NodeReadIndex(bTemp) >= Vec_PtrSize(vNamesPi) ) - break; - Cudd_RecursiveDeref( dd, bSupp ); - if ( bTemp != Cudd_ReadOne(dd) ) - return NULL; - - // start the network - pNtk = Abc_NtkAlloc( ABC_TYPE_LOGIC, ABC_FUNC_BDD ); - pNtk->pName = util_strsav(pNamePo); - // make sure the new manager has enough inputs - Cudd_bddIthVar( pNtk->pManFunc, Vec_PtrSize(vNamesPi) ); - // add the PIs corresponding to the names - Vec_PtrForEachEntry( vNamesPi, pName, i ) - Abc_NtkLogicStoreName( Abc_NtkCreatePi(pNtk), pName ); - // create the node - pNode = Abc_NtkCreateNode( pNtk ); - pNode->pData = Cudd_bddTransfer( dd, pNtk->pManFunc, bFunc ); Cudd_Ref(pNode->pData); - Abc_NtkForEachPi( pNtk, pNodePi, i ) - Abc_ObjAddFanin( pNode, pNodePi ); - // create the only PO - pNodePo = Abc_NtkCreatePo( pNtk ); - Abc_ObjAddFanin( pNodePo, pNode ); - Abc_NtkLogicStoreName( pNodePo, pNamePo ); - // make the network minimum base - Abc_NtkMinimumBase( pNtk ); - if ( vNamesPiFake ) - Abc_NodeFreeNames( vNamesPiFake ); - if ( !Abc_NtkCheck( pNtk ) ) - fprintf( stdout, "Abc_NtkDeriveFromBdd(): Network check has failed.\n" ); - return pNtk; -} - - - -/**Function************************************************************* - - Synopsis [Creates the network isomorphic to the union of local BDDs of the nodes.] - - Description [The nodes of the local BDDs are converted into the network nodes - with logic functions equal to the MUX.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_NtkBddToMuxes( Abc_Ntk_t * pNtk ) -{ - int fCheck = 1; - Abc_Ntk_t * pNtkNew; - assert( Abc_NtkIsBddLogic(pNtk) ); - pNtkNew = Abc_NtkStartFrom( pNtk, ABC_TYPE_LOGIC, ABC_FUNC_SOP ); - Abc_NtkBddToMuxesPerform( pNtk, pNtkNew ); - Abc_NtkFinalize( pNtk, pNtkNew ); - // make sure everything is okay - if ( fCheck && !Abc_NtkCheck( pNtkNew ) ) - { - printf( "Abc_NtkBddToMuxes: The network check has failed.\n" ); - Abc_NtkDelete( pNtkNew ); - return NULL; - } - return pNtkNew; -} - -/**Function************************************************************* - - Synopsis [Converts the network to MUXes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkBddToMuxesPerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ) -{ - ProgressBar * pProgress; - DdManager * dd = pNtk->pManFunc; - Abc_Obj_t * pNode, * pNodeNew, * pConst1; - Vec_Ptr_t * vNodes; - int i; - // create the constant one node - pConst1 = Abc_NodeCreateConst1( pNtkNew ); - // perform conversion in the topological order - vNodes = Abc_NtkDfs( pNtk, 0 ); - pProgress = Extra_ProgressBarStart( stdout, vNodes->nSize ); - Vec_PtrForEachEntry( vNodes, pNode, i ) - { - Extra_ProgressBarUpdate( pProgress, i, NULL ); - // convert one node - assert( Abc_ObjIsNode(pNode) ); - pNodeNew = Abc_NodeBddToMuxes( pNode, pNtkNew, pConst1 ); - // mark the old node with the new one - assert( pNode->pCopy == NULL ); - pNode->pCopy = pNodeNew; - } - Vec_PtrFree( vNodes ); - Extra_ProgressBarStop( pProgress ); -} - -/**Function************************************************************* - - Synopsis [Converts the node to MUXes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_NodeBddToMuxes( Abc_Obj_t * pNodeOld, Abc_Ntk_t * pNtkNew, Abc_Obj_t * pConst1 ) -{ - DdManager * dd = pNodeOld->pNtk->pManFunc; - DdNode * bFunc = pNodeOld->pData; - Abc_Obj_t * pFaninOld, * pNodeNew; - st_table * tBdd2Node; - int i; - // create the table mapping BDD nodes into the ABC nodes - tBdd2Node = st_init_table( st_ptrcmp, st_ptrhash ); - // add the constant and the elementary vars - st_insert( tBdd2Node, (char *)b1, (char *)pConst1 ); - Abc_ObjForEachFanin( pNodeOld, pFaninOld, i ) - st_insert( tBdd2Node, (char *)Cudd_bddIthVar(dd, i), (char *)pFaninOld->pCopy ); - // create the new nodes recursively - pNodeNew = Abc_NodeBddToMuxes_rec( dd, Cudd_Regular(bFunc), pNtkNew, tBdd2Node ); - st_free_table( tBdd2Node ); - if ( Cudd_IsComplement(bFunc) ) - pNodeNew = Abc_NodeCreateInv( pNtkNew, pNodeNew ); - return pNodeNew; -} - -/**Function************************************************************* - - Synopsis [Converts the node to MUXes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_NodeBddToMuxes_rec( DdManager * dd, DdNode * bFunc, Abc_Ntk_t * pNtkNew, st_table * tBdd2Node ) -{ - Abc_Obj_t * pNodeNew, * pNodeNew0, * pNodeNew1, * pNodeNewC; - assert( !Cudd_IsComplement(bFunc) ); - if ( st_lookup( tBdd2Node, (char *)bFunc, (char **)&pNodeNew ) ) - return pNodeNew; - // solve for the children nodes - pNodeNew0 = Abc_NodeBddToMuxes_rec( dd, Cudd_Regular(cuddE(bFunc)), pNtkNew, tBdd2Node ); - if ( Cudd_IsComplement(cuddE(bFunc)) ) - pNodeNew0 = Abc_NodeCreateInv( pNtkNew, pNodeNew0 ); - pNodeNew1 = Abc_NodeBddToMuxes_rec( dd, cuddT(bFunc), pNtkNew, tBdd2Node ); - if ( !st_lookup( tBdd2Node, (char *)Cudd_bddIthVar(dd, bFunc->index), (char **)&pNodeNewC ) ) - assert( 0 ); - // create the MUX node - pNodeNew = Abc_NodeCreateMux( pNtkNew, pNodeNewC, pNodeNew1, pNodeNew0 ); - st_insert( tBdd2Node, (char *)bFunc, (char *)pNodeNew ); - return pNodeNew; -} - - -/**Function************************************************************* - - Synopsis [Derives global BDDs for the COs of the network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -DdManager * Abc_NtkGlobalBdds( Abc_Ntk_t * pNtk, int fLatchOnly ) -{ - int fReorder = 1; - ProgressBar * pProgress; - Vec_Ptr_t * vFuncsGlob; - Abc_Obj_t * pNode; - DdNode * bFunc; - DdManager * dd; - int i; - - // start the manager - assert( pNtk->pManGlob == NULL ); - dd = Cudd_Init( Abc_NtkCiNum(pNtk), 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 ); - if ( fReorder ) - Cudd_AutodynEnable( dd, CUDD_REORDER_SYMM_SIFT ); - - // set the elementary variables - Abc_NtkCleanCopy( pNtk ); - Abc_NtkForEachCi( pNtk, pNode, i ) - pNode->pCopy = (Abc_Obj_t *)dd->vars[i]; - // assign the constant node BDD - pNode = Abc_AigConst1( pNtk->pManFunc ); - pNode->pCopy = (Abc_Obj_t *)dd->one; Cudd_Ref( dd->one ); - - // collect the global functions of the COs - vFuncsGlob = Vec_PtrAlloc( 100 ); - if ( fLatchOnly ) - { - // construct the BDDs - pProgress = Extra_ProgressBarStart( stdout, Abc_NtkLatchNum(pNtk) ); - Abc_NtkForEachLatch( pNtk, pNode, i ) - { - Extra_ProgressBarUpdate( pProgress, i, NULL ); - bFunc = Abc_NodeGlobalBdds_rec( dd, Abc_ObjFanin0(pNode) ); - if ( bFunc == NULL ) - { - printf( "Constructing global BDDs timed out.\n" ); - Extra_ProgressBarStop( pProgress ); - Cudd_Quit( dd ); - return NULL; - } - bFunc = Cudd_NotCond( bFunc, Abc_ObjFaninC0(pNode) ); Cudd_Ref( bFunc ); - Vec_PtrPush( vFuncsGlob, bFunc ); - } - Extra_ProgressBarStop( pProgress ); - } - else - { - // construct the BDDs - pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCoNum(pNtk) ); - Abc_NtkForEachCo( pNtk, pNode, i ) - { - Extra_ProgressBarUpdate( pProgress, i, NULL ); - bFunc = Abc_NodeGlobalBdds_rec( dd, Abc_ObjFanin0(pNode) ); - if ( bFunc == NULL ) - { - printf( "Constructing global BDDs timed out.\n" ); - Extra_ProgressBarStop( pProgress ); - Cudd_Quit( dd ); - return NULL; - } - bFunc = Cudd_NotCond( bFunc, Abc_ObjFaninC0(pNode) ); Cudd_Ref( bFunc ); - Vec_PtrPush( vFuncsGlob, bFunc ); - } - Extra_ProgressBarStop( pProgress ); - } - - // derefence the intermediate BDDs - Abc_NtkForEachNode( pNtk, pNode, i ) - if ( pNode->pCopy ) - { - Cudd_RecursiveDeref( dd, (DdNode *)pNode->pCopy ); - pNode->pCopy = NULL; - } - // reorder one more time - if ( fReorder ) - { - Cudd_ReduceHeap( dd, CUDD_REORDER_SYMM_SIFT, 1 ); - Cudd_AutodynDisable( dd ); - } - pNtk->pManGlob = dd; - pNtk->vFuncsGlob = vFuncsGlob; - return dd; -} - -/**Function************************************************************* - - Synopsis [Derives the global BDD for one AIG node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -DdNode * Abc_NodeGlobalBdds_rec( DdManager * dd, Abc_Obj_t * pNode ) -{ - DdNode * bFunc, * bFunc0, * bFunc1; - assert( !Abc_ObjIsComplement(pNode) ); - if ( Cudd_ReadKeys(dd) > 500000 ) - return NULL; - // if the result is available return - if ( pNode->pCopy ) - return (DdNode *)pNode->pCopy; - // compute the result for both branches - bFunc0 = Abc_NodeGlobalBdds_rec( dd, Abc_ObjFanin(pNode,0) ); - if ( bFunc0 == NULL ) - return NULL; - Cudd_Ref( bFunc0 ); - bFunc1 = Abc_NodeGlobalBdds_rec( dd, Abc_ObjFanin(pNode,1) ); - if ( bFunc1 == NULL ) - return NULL; - Cudd_Ref( bFunc1 ); - bFunc0 = Cudd_NotCond( bFunc0, Abc_ObjFaninC0(pNode) ); - bFunc1 = Cudd_NotCond( bFunc1, Abc_ObjFaninC1(pNode) ); - // get the final result - bFunc = Cudd_bddAnd( dd, bFunc0, bFunc1 ); Cudd_Ref( bFunc ); - Cudd_RecursiveDeref( dd, bFunc0 ); - Cudd_RecursiveDeref( dd, bFunc1 ); - // set the result - assert( pNode->pCopy == NULL ); - pNode->pCopy = (Abc_Obj_t *)bFunc; - return bFunc; -} - -/**Function************************************************************* - - Synopsis [Dereferences global BDDs of the network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkFreeGlobalBdds( Abc_Ntk_t * pNtk ) -{ - DdNode * bFunc; - int i; - assert( pNtk->pManGlob ); - assert( pNtk->vFuncsGlob ); - Vec_PtrForEachEntry( pNtk->vFuncsGlob, bFunc, i ) - Cudd_RecursiveDeref( pNtk->pManGlob, bFunc ); - Vec_PtrFree( pNtk->vFuncsGlob ); - pNtk->vFuncsGlob = NULL; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/base/abc/abcNtk.c b/src/base/abc/abcNtk.c new file mode 100644 index 00000000..5c199141 --- /dev/null +++ b/src/base/abc/abcNtk.c @@ -0,0 +1,592 @@ +/**CFile**************************************************************** + + FileName [abcNtk.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Network and node package.] + + Synopsis [Network creation/duplication/deletion procedures.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: abcNtk.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abc.h" +#include "main.h" +#include "mio.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +#define ABC_NUM_STEPS 10 + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Creates a new Ntk.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkAlloc( Abc_NtkType_t Type, Abc_NtkFunc_t Func ) +{ + Abc_Ntk_t * pNtk; + pNtk = ALLOC( Abc_Ntk_t, 1 ); + memset( pNtk, 0, sizeof(Abc_Ntk_t) ); + pNtk->ntkType = Type; + pNtk->ntkFunc = Func; + // start the object storage + pNtk->vObjs = Vec_PtrAlloc( 100 ); + pNtk->vLats = Vec_PtrAlloc( 100 ); + pNtk->vCis = Vec_PtrAlloc( 100 ); + pNtk->vCos = Vec_PtrAlloc( 100 ); + pNtk->vPtrTemp = Vec_PtrAlloc( 100 ); + pNtk->vIntTemp = Vec_IntAlloc( 100 ); + pNtk->vStrTemp = Vec_StrAlloc( 100 ); + // start the hash table + pNtk->tName2Net = stmm_init_table(strcmp, stmm_strhash); + pNtk->tObj2Name = stmm_init_table(stmm_ptrcmp, stmm_ptrhash); + // start the memory managers + pNtk->pMmNames = Extra_MmFlexStart(); + pNtk->pMmObj = Extra_MmFixedStart( sizeof(Abc_Obj_t) ); + pNtk->pMmStep = Extra_MmStepStart( ABC_NUM_STEPS ); + // get ready to assign the first Obj ID + pNtk->nTravIds = 1; + // start the functionality manager + if ( Abc_NtkHasSop(pNtk) ) + pNtk->pManFunc = Extra_MmFlexStart(); + else if ( Abc_NtkHasBdd(pNtk) ) + pNtk->pManFunc = Cudd_Init( 20, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 ); + else if ( Abc_NtkHasAig(pNtk) ) + pNtk->pManFunc = Abc_AigAlloc( pNtk ); + else if ( Abc_NtkHasMapping(pNtk) ) + pNtk->pManFunc = Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()); + else + assert( 0 ); + return pNtk; +} + +/**Function************************************************************* + + Synopsis [Starts a new network using existing network as a model.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkStartFrom( Abc_Ntk_t * pNtk, Abc_NtkType_t Type, Abc_NtkFunc_t Func ) +{ + Abc_Ntk_t * pNtkNew; + Abc_Obj_t * pObj, * pObjNew; + int i; + if ( pNtk == NULL ) + return NULL; + // start the network + pNtkNew = Abc_NtkAlloc( Type, Func ); + // duplicate the name and the spec + pNtkNew->pName = util_strsav(pNtk->pName); + pNtkNew->pSpec = util_strsav(pNtk->pSpec); + // clone the PIs/POs/latches + Abc_NtkForEachPi( pNtk, pObj, i ) + Abc_NtkDupObj(pNtkNew, pObj); + Abc_NtkForEachPo( pNtk, pObj, i ) + Abc_NtkDupObj(pNtkNew, pObj); + Abc_NtkForEachLatch( pNtk, pObj, i ) + { + pObjNew = Abc_NtkDupObj(pNtkNew, pObj); + Vec_PtrPush( pNtkNew->vCis, pObjNew ); + Vec_PtrPush( pNtkNew->vCos, pObjNew ); + } + // clean the node copy fields + Abc_NtkForEachNode( pNtk, pObj, i ) + pObj->pCopy = NULL; + // transfer the names + Abc_NtkDupCioNamesTable( pNtk, pNtkNew ); + Abc_ManTimeDup( pNtk, pNtkNew ); + return pNtkNew; +} + +/**Function************************************************************* + + Synopsis [Finalizes the network using the existing network as a model.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkFinalize( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ) +{ + Abc_Obj_t * pObj, * pDriver, * pDriverNew; + int i; + // set the COs of the strashed network + Abc_NtkForEachCo( pNtk, pObj, i ) + { + pDriver = Abc_ObjFanin0Ntk( Abc_ObjFanin0(pObj) ); + pDriverNew = Abc_ObjNotCond(pDriver->pCopy, Abc_ObjFaninC0(pObj)); + Abc_ObjAddFanin( pObj->pCopy, pDriverNew ); + } +} + +/**Function************************************************************* + + Synopsis [Finalizes the network using the existing network as a model.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkFinalizeRegular( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ) +{ + Abc_Obj_t * pObj, * pDriver, * pDriverNew; + int i; + // set the COs of the strashed network + Abc_NtkForEachCo( pNtk, pObj, i ) + { + pDriver = Abc_ObjFanin0Ntk( Abc_ObjFanin0(pObj) ); + pDriverNew = pDriver->pCopy; + Abc_ObjAddFanin( pObj->pCopy, pDriverNew ); + } +} + +/**Function************************************************************* + + Synopsis [Finalizes the network adding latches to CI/CO lists and creates their names.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkFinalizeLatches( Abc_Ntk_t * pNtk ) +{ + Abc_Obj_t * pLatch; + int i; + // set the COs of the strashed network + Abc_NtkForEachLatch( pNtk, pLatch, i ) + { + Vec_PtrPush( pNtk->vCis, pLatch ); + Vec_PtrPush( pNtk->vCos, pLatch ); + Abc_NtkLogicStoreName( pLatch, Abc_ObjNameSuffix(pLatch, "L") ); + } +} + +/**Function************************************************************* + + Synopsis [Starts a new network using existing network as a model.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkStartRead( char * pName ) +{ + Abc_Ntk_t * pNtkNew; + // allocate the empty network + pNtkNew = Abc_NtkAlloc( ABC_TYPE_NETLIST, ABC_FUNC_SOP ); + // set the specs + pNtkNew->pName = util_strsav( pName ); + pNtkNew->pSpec = util_strsav( pName ); + return pNtkNew; +} + +/**Function************************************************************* + + Synopsis [Finalizes the network using the existing network as a model.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkFinalizeRead( Abc_Ntk_t * pNtk ) +{ + Abc_Obj_t * pLatch; + int i; + assert( Abc_NtkIsNetlist(pNtk) ); + // fix the net drivers + Abc_NtkFixNonDrivenNets( pNtk ); + // create the names table + Abc_NtkCreateCioNamesTable( pNtk ); + // add latches to the CI/CO arrays + Abc_NtkForEachLatch( pNtk, pLatch, i ) + { + Vec_PtrPush( pNtk->vCis, pLatch ); + Vec_PtrPush( pNtk->vCos, pLatch ); + } +} + +/**Function************************************************************* + + Synopsis [Duplicate the network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkDup( Abc_Ntk_t * pNtk ) +{ + Abc_Ntk_t * pNtkNew; + Abc_Obj_t * pObj, * pFanin; + int i, k; + if ( pNtk == NULL ) + return NULL; + // start the network + pNtkNew = Abc_NtkStartFrom( pNtk, pNtk->ntkType, pNtk->ntkFunc ); + // copy the internal nodes + if ( Abc_NtkHasAig(pNtk) ) + Abc_AigDup( pNtk->pManFunc, pNtkNew->pManFunc ); + else + { + // duplicate the nets and nodes (CIs/COs/latches already dupped) + Abc_NtkForEachObj( pNtk, pObj, i ) + if ( pObj->pCopy == NULL ) + Abc_NtkDupObj(pNtkNew, pObj); + // reconnect all objects (no need to transfer attributes on edges) + Abc_NtkForEachObj( pNtk, pObj, i ) + Abc_ObjForEachFanin( pObj, pFanin, k ) + Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy ); + } + // duplicate the EXDC Ntk + if ( pNtk->pExdc ) + pNtkNew->pExdc = Abc_NtkDup( pNtk->pExdc ); + if ( !Abc_NtkCheck( pNtkNew ) ) + fprintf( stdout, "Abc_NtkDup(): Network check has failed.\n" ); + return pNtkNew; +} + +/**Function************************************************************* + + Synopsis [Creates the network composed of one output.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkSplitOutput( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode, int fUseAllCis ) +{ + Vec_Ptr_t * vNodes; + Abc_Ntk_t * pNtkNew; + Abc_Obj_t * pObj, * pFanin; + char Buffer[1000]; + int i, k; + + assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsStrash(pNtk) ); + assert( Abc_ObjIsCo(pNode) ); + + // start the network + pNtkNew = Abc_NtkAlloc( pNtk->ntkType, pNtk->ntkFunc ); + // set the name + sprintf( Buffer, "%s_%s", pNtk->pName, Abc_ObjName(pNode) ); + pNtkNew->pName = util_strsav(Buffer); + + // collect the nodes in the TFI of the output + vNodes = Abc_NtkDfsNodes( pNtk, &pNode, 1 ); + // create the PIs + Abc_NtkForEachCi( pNtk, pObj, i ) + { + if ( fUseAllCis || Abc_NodeIsTravIdCurrent(pObj) ) // TravId is set by DFS + { + pObj->pCopy = Abc_NtkCreatePi(pNtkNew); + Abc_NtkLogicStoreName( pObj->pCopy, Abc_ObjName(pObj) ); + } + } + // establish connection between the constant nodes + if ( Abc_NtkIsStrash(pNtk) ) + Abc_AigConst1(pNtk->pManFunc)->pCopy = Abc_AigConst1(pNtkNew->pManFunc); + + // copy the nodes + Vec_PtrForEachEntry( vNodes, pObj, i ) + { + // if it is an AIG, add to the hash table + if ( Abc_NtkIsStrash(pNtk) ) + { + pObj->pCopy = Abc_AigAnd( pNtkNew->pManFunc, Abc_ObjChild0Copy(pObj), Abc_ObjChild1Copy(pObj) ); + } + else + { + Abc_NtkDupObj( pNtkNew, pObj ); + Abc_ObjForEachFanin( pObj, pFanin, k ) + Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy ); + } + } + Vec_PtrFree( vNodes ); + + // add the PO corresponding to this output + pNode->pCopy = Abc_NtkCreatePo( pNtkNew ); + Abc_ObjAddFanin( pNode->pCopy, Abc_ObjFanin0(pNode)->pCopy ); + Abc_NtkLogicStoreName( pNode->pCopy, Abc_ObjName(pNode) ); + + if ( !Abc_NtkCheck( pNtkNew ) ) + fprintf( stdout, "Abc_NtkSplitOutput(): Network check has failed.\n" ); + return pNtkNew; +} + +/**Function************************************************************* + + Synopsis [Creates the network composed of one output.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkCreateCone( Abc_Ntk_t * pNtk, Vec_Ptr_t * vRoots, Vec_Int_t * vValues ) +{ + Vec_Ptr_t * vNodes; + Abc_Ntk_t * pNtkNew; + Abc_Obj_t * pObj, * pFinal, * pOther, * pNodePo; + int i; + + assert( Abc_NtkIsLogic(pNtk) ); + + // start the network + Abc_NtkCleanCopy( pNtk ); + pNtkNew = Abc_NtkAlloc( ABC_TYPE_STRASH, ABC_FUNC_AIG ); + pNtkNew->pName = util_strsav(pNtk->pName); + + // collect the nodes in the TFI of the output + vNodes = Abc_NtkDfsNodes( pNtk, (Abc_Obj_t **)vRoots->pArray, vRoots->nSize ); + // create the PIs + Abc_NtkForEachCi( pNtk, pObj, i ) + { + pObj->pCopy = Abc_NtkCreatePi(pNtkNew); + Abc_NtkLogicStoreName( pObj->pCopy, Abc_ObjName(pObj) ); + } + // copy the nodes + Vec_PtrForEachEntry( vNodes, pObj, i ) + pObj->pCopy = Abc_NodeStrash( pNtkNew->pManFunc, pObj ); + Vec_PtrFree( vNodes ); + + // add the PO + pFinal = Abc_AigConst1( pNtkNew->pManFunc ); + Vec_PtrForEachEntry( vRoots, pObj, i ) + { + pOther = pObj->pCopy; + if ( Vec_IntEntry(vValues, i) == 0 ) + pOther = Abc_ObjNot(pOther); + pFinal = Abc_AigAnd( pNtkNew->pManFunc, pFinal, pOther ); + } + + // add the PO corresponding to this output + pNodePo = Abc_NtkCreatePo( pNtkNew ); + Abc_ObjAddFanin( pNodePo, pFinal ); + Abc_NtkLogicStoreName( pNodePo, "miter" ); + if ( !Abc_NtkCheck( pNtkNew ) ) + fprintf( stdout, "Abc_NtkCreateCone(): Network check has failed.\n" ); + return pNtkNew; +} + +/**Function************************************************************* + + Synopsis [Deletes the Ntk.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkSplitNode( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode ) +{ + Abc_Ntk_t * pNtkNew; + Abc_Obj_t * pFanin, * pNodePo; + int i; + // start the network + pNtkNew = Abc_NtkAlloc( pNtk->ntkType, pNtk->ntkFunc ); + pNtkNew->pName = util_strsav(Abc_ObjName(pNode)); + // add the PIs corresponding to the fanins of the node + Abc_ObjForEachFanin( pNode, pFanin, i ) + { + pFanin->pCopy = Abc_NtkCreatePi( pNtkNew ); + Abc_NtkLogicStoreName( pFanin->pCopy, Abc_ObjName(pFanin) ); + } + // duplicate and connect the node + pNode->pCopy = Abc_NtkDupObj( pNtkNew, pNode ); + Abc_ObjForEachFanin( pNode, pFanin, i ) + Abc_ObjAddFanin( pNode->pCopy, pFanin->pCopy ); + // create the only PO + pNodePo = Abc_NtkCreatePo( pNtkNew ); + Abc_ObjAddFanin( pNodePo, pNode->pCopy ); + Abc_NtkLogicStoreName( pNodePo, Abc_ObjName(pNode) ); + if ( !Abc_NtkCheck( pNtkNew ) ) + fprintf( stdout, "Abc_NtkSplitNode(): Network check has failed.\n" ); + return pNtkNew; +} + +/**Function************************************************************* + + Synopsis [Deletes the Ntk.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkDelete( Abc_Ntk_t * pNtk ) +{ + Abc_Obj_t * pObj; + int TotalMemory, i; + int LargePiece = (4 << ABC_NUM_STEPS); + if ( pNtk == NULL ) + return; + // make sure all the marks are clean + Abc_NtkForEachObj( pNtk, pObj, i ) + { + // free large fanout arrays + if ( pObj->vFanouts.nCap * 4 > LargePiece ) + FREE( pObj->vFanouts.pArray ); + // check that the other things are okay + assert( pObj->fMarkA == 0 ); + assert( pObj->fMarkB == 0 ); + assert( pObj->fMarkC == 0 ); + } + + // dereference the BDDs + if ( Abc_NtkHasBdd(pNtk) ) + Abc_NtkForEachNode( pNtk, pObj, i ) + Cudd_RecursiveDeref( pNtk->pManFunc, pObj->pData ); + + FREE( pNtk->pName ); + FREE( pNtk->pSpec ); + // copy the EXDC Ntk + if ( pNtk->pExdc ) + Abc_NtkDelete( pNtk->pExdc ); + // free the arrays + Vec_PtrFree( pNtk->vObjs ); + Vec_PtrFree( pNtk->vLats ); + Vec_PtrFree( pNtk->vCis ); + Vec_PtrFree( pNtk->vCos ); + Vec_PtrFree( pNtk->vPtrTemp ); + Vec_IntFree( pNtk->vIntTemp ); + Vec_StrFree( pNtk->vStrTemp ); + // free the hash table of Obj name into Obj ID + stmm_free_table( pNtk->tName2Net ); + stmm_free_table( pNtk->tObj2Name ); + TotalMemory = 0; + TotalMemory += Extra_MmFlexReadMemUsage(pNtk->pMmNames); + TotalMemory += Extra_MmFixedReadMemUsage(pNtk->pMmObj); + TotalMemory += Extra_MmStepReadMemUsage(pNtk->pMmStep); +// fprintf( stdout, "The total memory allocated internally by the network = %0.2f Mb.\n", ((double)TotalMemory)/(1<<20) ); + // free the storage + Extra_MmFlexStop ( pNtk->pMmNames, 0 ); + Extra_MmFixedStop( pNtk->pMmObj, 0 ); + Extra_MmStepStop ( pNtk->pMmStep, 0 ); + // free the timing manager + if ( pNtk->pManTime ) + Abc_ManTimeStop( pNtk->pManTime ); + // start the functionality manager + if ( Abc_NtkHasSop(pNtk) ) + Extra_MmFlexStop( pNtk->pManFunc, 0 ); + else if ( Abc_NtkHasBdd(pNtk) ) + Extra_StopManager( pNtk->pManFunc ); + else if ( Abc_NtkHasAig(pNtk) ) + Abc_AigFree( pNtk->pManFunc ); + else if ( !Abc_NtkHasMapping(pNtk) ) + assert( 0 ); + free( pNtk ); +} + +/**Function************************************************************* + + Synopsis [Reads the verilog file.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkFixNonDrivenNets( Abc_Ntk_t * pNtk ) +{ + Vec_Ptr_t * vNets; + Abc_Obj_t * pNet, * pNode; + int i; + + // check for non-driven nets + vNets = Vec_PtrAlloc( 100 ); + Abc_NtkForEachNet( pNtk, pNet, i ) + { + if ( Abc_ObjFaninNum(pNet) > 0 ) + continue; + // add the constant 0 driver + pNode = Abc_NtkCreateNode( pNtk ); + // set the constant function + Abc_ObjSetData( pNode, Abc_SopRegister(pNtk->pManFunc, " 0\n") ); + // add the fanout net + Abc_ObjAddFanin( pNet, pNode ); + // add the net to those for which the warning will be printed + Vec_PtrPush( vNets, pNet->pData ); + } + + // print the warning + if ( vNets->nSize > 0 ) + { + printf( "Constant-zero drivers were added to %d non-driven nets:\n", vNets->nSize ); + for ( i = 0; i < vNets->nSize; i++ ) + { + if ( i == 0 ) + printf( "%s", vNets->pArray[i] ); + else if ( i == 1 ) + printf( ", %s", vNets->pArray[i] ); + else if ( i == 2 ) + { + printf( ", %s, etc.", vNets->pArray[i] ); + break; + } + } + printf( "\n" ); + } + Vec_PtrFree( vNets ); +} + + + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/base/abc/abcObj.c b/src/base/abc/abcObj.c new file mode 100644 index 00000000..f869abf3 --- /dev/null +++ b/src/base/abc/abcObj.c @@ -0,0 +1,871 @@ +/**CFile**************************************************************** + + FileName [abcCreate.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Network and node package.] + + Synopsis [Object creation/duplication/deletion procedures.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: abcCreate.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abc.h" +#include "main.h" +#include "mio.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Creates a new Obj.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Abc_ObjAlloc( Abc_Ntk_t * pNtk, Abc_ObjType_t Type ) +{ + Abc_Obj_t * pObj; + pObj = (Abc_Obj_t *)Extra_MmFixedEntryFetch( pNtk->pMmObj ); + memset( pObj, 0, sizeof(Abc_Obj_t) ); + pObj->Id = -1; + pObj->pNtk = pNtk; + pObj->Type = Type; + return pObj; +} + +/**Function************************************************************* + + Synopsis [Recycles the Obj.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_ObjRecycle( Abc_Obj_t * pObj ) +{ + Abc_Ntk_t * pNtk = pObj->pNtk; + memset( pObj, 0, sizeof(Abc_Obj_t) ); + Extra_MmFixedEntryRecycle( pNtk->pMmObj, (char *)pObj ); +} + +/**Function************************************************************* + + Synopsis [Adds the node to the network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_ObjAdd( Abc_Obj_t * pObj ) +{ + Abc_Ntk_t * pNtk = pObj->pNtk; + assert( !Abc_ObjIsComplement(pObj) ); + // add to the array of objects + pObj->Id = pNtk->vObjs->nSize; + Vec_PtrPush( pNtk->vObjs, pObj ); + pNtk->nObjs++; + // perform specialized operations depending on the object type + if ( Abc_ObjIsNet(pObj) ) + { + // add the name to the table + if ( pObj->pData && stmm_insert( pNtk->tName2Net, pObj->pData, (char *)pObj ) ) + { + printf( "Error: The net is already in the table...\n" ); + assert( 0 ); + } + pNtk->nNets++; + } + else if ( Abc_ObjIsNode(pObj) ) + { + pNtk->nNodes++; + } + else if ( Abc_ObjIsLatch(pObj) ) + { + Vec_PtrPush( pNtk->vLats, pObj ); + pNtk->nLatches++; + } + else if ( Abc_ObjIsPi(pObj) ) + { + Vec_PtrPush( pNtk->vCis, pObj ); + pNtk->nPis++; + } + else if ( Abc_ObjIsPo(pObj) ) + { + Vec_PtrPush( pNtk->vCos, pObj ); + pNtk->nPos++; + } + else + { + assert( 0 ); + } + assert( pObj->Id >= 0 ); +} + +/**Function************************************************************* + + Synopsis [Duplicate the Obj.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Abc_NtkDupObj( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj ) +{ + Abc_Obj_t * pObjNew; + pObjNew = Abc_ObjAlloc( pNtkNew, pObj->Type ); + if ( Abc_ObjIsNode(pObj) ) // copy the function if functionality is compatible + { + if ( pNtkNew->ntkFunc == pObj->pNtk->ntkFunc ) + { + if ( Abc_NtkHasSop(pNtkNew) ) + pObjNew->pData = Abc_SopRegister( pNtkNew->pManFunc, pObj->pData ); + else if ( Abc_NtkHasBdd(pNtkNew) ) + pObjNew->pData = Cudd_bddTransfer(pObj->pNtk->pManFunc, pNtkNew->pManFunc, pObj->pData), Cudd_Ref(pObjNew->pData); + else if ( Abc_NtkHasMapping(pNtkNew) ) + pObjNew->pData = pObj->pData; + else if ( Abc_NtkHasAig(pNtkNew) ) + assert( 0 ); + } + } + else if ( Abc_ObjIsNet(pObj) ) // copy the name + pObjNew->pData = Abc_NtkRegisterName( pNtkNew, pObj->pData ); + else if ( Abc_ObjIsLatch(pObj) ) // copy the reset value + pObjNew->pData = pObj->pData; + pObj->pCopy = pObjNew; + // add the object to the network + Abc_ObjAdd( pObjNew ); + return pObjNew; +} + +/**Function************************************************************* + + Synopsis [Creates a new constant node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Abc_NtkDupConst1( Abc_Ntk_t * pNtkAig, Abc_Ntk_t * pNtkNew ) +{ + Abc_Obj_t * pConst1; + assert( Abc_NtkIsStrash(pNtkAig) ); + assert( Abc_NtkIsSopLogic(pNtkNew) ); + pConst1 = Abc_AigConst1(pNtkAig->pManFunc); + if ( Abc_ObjFanoutNum(pConst1) > 0 ) + pConst1->pCopy = Abc_NodeCreateConst1( pNtkNew ); + return pConst1->pCopy; +} + +/**Function************************************************************* + + Synopsis [Creates a new constant node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Abc_NtkDupReset( Abc_Ntk_t * pNtkAig, Abc_Ntk_t * pNtkNew ) +{ + Abc_Obj_t * pReset, * pConst1; + assert( Abc_NtkIsStrash(pNtkAig) ); + assert( Abc_NtkIsSopLogic(pNtkNew) ); + pReset = Abc_AigReset(pNtkAig->pManFunc); + if ( Abc_ObjFanoutNum(pReset) > 0 ) + { + // create new latch with reset value 0 + pReset->pCopy = Abc_NtkCreateLatch( pNtkNew ); + // add constant node fanin to the latch + pConst1 = Abc_NodeCreateConst1( pNtkNew ); + Abc_ObjAddFanin( pReset->pCopy, pConst1 ); + } + return pReset->pCopy; +} + +/**Function************************************************************* + + Synopsis [Deletes the object from the network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkDeleteObj( Abc_Obj_t * pObj ) +{ + Vec_Ptr_t * vNodes = pObj->pNtk->vPtrTemp; + Abc_Ntk_t * pNtk = pObj->pNtk; + int i; + + assert( !Abc_ObjIsComplement(pObj) ); + + // delete fanins and fanouts + Abc_NodeCollectFanouts( pObj, vNodes ); + for ( i = 0; i < vNodes->nSize; i++ ) + Abc_ObjDeleteFanin( vNodes->pArray[i], pObj ); + Abc_NodeCollectFanins( pObj, vNodes ); + for ( i = 0; i < vNodes->nSize; i++ ) + Abc_ObjDeleteFanin( pObj, vNodes->pArray[i] ); + + // remove from the list of objects + Vec_PtrWriteEntry( pNtk->vObjs, pObj->Id, NULL ); + pObj->Id = (1<<26)-1; + pNtk->nObjs--; + + // perform specialized operations depending on the object type + if ( Abc_ObjIsNet(pObj) ) + { + // remove the net from the hash table of nets + if ( pObj->pData && !stmm_delete( pNtk->tName2Net, (char **)&pObj->pData, (char **)&pObj ) ) + { + printf( "Error: The net is not in the table...\n" ); + assert( 0 ); + } + pObj->pData = NULL; + pNtk->nNets--; + } + else if ( Abc_ObjIsNode(pObj) ) + { + if ( Abc_NtkHasBdd(pNtk) ) + Cudd_RecursiveDeref( pNtk->pManFunc, pObj->pData ); + pNtk->nNodes--; + } + else if ( Abc_ObjIsLatch(pObj) ) + { + pNtk->nLatches--; + } + else + assert( 0 ); + // recycle the net itself + Abc_ObjRecycle( pObj ); +} + + + + + +/**Function************************************************************* + + Synopsis [Returns the net with the given name.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Abc_NtkFindNode( Abc_Ntk_t * pNtk, char * pName ) +{ + Abc_Obj_t * pObj, * pDriver; + int i, Num; + // check if the node is among CIs + Abc_NtkForEachCi( pNtk, pObj, i ) + { + if ( strcmp( Abc_ObjName(pObj), pName ) == 0 ) + { + if ( i < Abc_NtkPiNum(pNtk) ) + printf( "Node \"%s\" is a primary input.\n", pName ); + else + printf( "Node \"%s\" is a latch output.\n", pName ); + return NULL; + } + } + // search the node among COs + Abc_NtkForEachCo( pNtk, pObj, i ) + { + if ( strcmp( Abc_ObjName(pObj), pName ) == 0 ) + { + pDriver = Abc_ObjFanin0(pObj); + if ( !Abc_ObjIsNode(pDriver) ) + { + printf( "Node \"%s\" does not have logic associated with it.\n", pName ); + return NULL; + } + return pDriver; + } + } + // find the internal node + if ( pName[0] != '[' || pName[strlen(pName)-1] != ']' ) + { + printf( "Name \"%s\" is not found among CIs/COs (internal name looks like this: \"[integer]\").\n", pName ); + return NULL; + } + Num = atoi( pName + 1 ); + if ( Num < 0 || Num >= Abc_NtkObjNumMax(pNtk) ) + { + printf( "The node \"%s\" with ID %d is not in the current network.\n", pName, Num ); + return NULL; + } + pObj = Abc_NtkObj( pNtk, Num ); + if ( pObj == NULL ) + { + printf( "The node \"%s\" with ID %d has been removed from the current network.\n", pName, Num ); + return NULL; + } + if ( !Abc_ObjIsNode(pObj) ) + { + printf( "Object with ID %d is not a node.\n", Num ); + return NULL; + } + return pObj; +} + +/**Function************************************************************* + + Synopsis [Returns the net with the given name.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Abc_NtkFindCo( Abc_Ntk_t * pNtk, char * pName ) +{ + Abc_Obj_t * pNode; + int i; + // search the node among COs + Abc_NtkForEachCo( pNtk, pNode, i ) + { + if ( strcmp( Abc_ObjName(pNode), pName ) == 0 ) + return pNode; + } + return NULL; +} + +/**Function************************************************************* + + Synopsis [Returns the net with the given name.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Abc_NtkFindNet( Abc_Ntk_t * pNtk, char * pName ) +{ + Abc_Obj_t * pNet; + assert( Abc_NtkIsNetlist(pNtk) ); + if ( stmm_lookup( pNtk->tName2Net, pName, (char**)&pNet ) ) + return pNet; + return NULL; +} + +/**Function************************************************************* + + Synopsis [Finds or creates the net.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Abc_NtkFindOrCreateNet( Abc_Ntk_t * pNtk, char * pName ) +{ + Abc_Obj_t * pNet; + assert( Abc_NtkIsNetlist(pNtk) ); + if ( pNet = Abc_NtkFindNet( pNtk, pName ) ) + return pNet; + // create a new net + pNet = Abc_ObjAlloc( pNtk, ABC_OBJ_NET ); + pNet->pData = Abc_NtkRegisterName( pNtk, pName ); + Abc_ObjAdd( pNet ); + return pNet; +} + +/**Function************************************************************* + + Synopsis [Create the new node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Abc_NtkCreateNode( Abc_Ntk_t * pNtk ) +{ + Abc_Obj_t * pObj; + pObj = Abc_ObjAlloc( pNtk, ABC_OBJ_NODE ); + Abc_ObjAdd( pObj ); + return pObj; +} + +/**Function************************************************************* + + Synopsis [Create the new node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Abc_NtkCreatePi( Abc_Ntk_t * pNtk ) +{ + Abc_Obj_t * pObj; + pObj = Abc_ObjAlloc( pNtk, ABC_OBJ_PI ); + Abc_ObjAdd( pObj ); + return pObj; +} + +/**Function************************************************************* + + Synopsis [Create the new node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Abc_NtkCreatePo( Abc_Ntk_t * pNtk ) +{ + Abc_Obj_t * pObj; + pObj = Abc_ObjAlloc( pNtk, ABC_OBJ_PO ); + Abc_ObjAdd( pObj ); + return pObj; +} + +/**Function************************************************************* + + Synopsis [Create the new node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Abc_NtkCreateLatch( Abc_Ntk_t * pNtk ) +{ + Abc_Obj_t * pObj; + pObj = Abc_ObjAlloc( pNtk, ABC_OBJ_LATCH ); + Abc_ObjAdd( pObj ); + return pObj; +} + +/**Function************************************************************* + + Synopsis [Creates inverter.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Abc_NodeCreateConst0( Abc_Ntk_t * pNtk ) +{ + Abc_Obj_t * pNode; + assert( !Abc_NtkHasAig(pNtk) ); + pNode = Abc_NtkCreateNode( pNtk ); + if ( Abc_NtkHasSop(pNtk) ) + pNode->pData = Abc_SopRegister( pNtk->pManFunc, " 0\n" ); + else if ( Abc_NtkHasBdd(pNtk) ) + pNode->pData = Cudd_ReadLogicZero(pNtk->pManFunc), Cudd_Ref( pNode->pData ); + else if ( Abc_NtkHasMapping(pNtk) ) + pNode->pData = Mio_LibraryReadConst0(Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame())); + else + assert( 0 ); + return pNode; +} + +/**Function************************************************************* + + Synopsis [Creates inverter.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Abc_NodeCreateConst1( Abc_Ntk_t * pNtk ) +{ + Abc_Obj_t * pNode; + if ( Abc_NtkHasAig(pNtk) ) + return Abc_AigConst1(pNtk->pManFunc); + pNode = Abc_NtkCreateNode( pNtk ); + if ( Abc_NtkHasSop(pNtk) ) + pNode->pData = Abc_SopRegister( pNtk->pManFunc, " 1\n" ); + else if ( Abc_NtkHasBdd(pNtk) ) + pNode->pData = Cudd_ReadOne(pNtk->pManFunc), Cudd_Ref( pNode->pData ); + else if ( Abc_NtkHasMapping(pNtk) ) + pNode->pData = Mio_LibraryReadConst1(Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame())); + else + assert( 0 ); + return pNode; +} + +/**Function************************************************************* + + Synopsis [Creates inverter.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Abc_NodeCreateInv( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin ) +{ + Abc_Obj_t * pNode; + assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsNetlist(pNtk) ); + pNode = Abc_NtkCreateNode( pNtk ); + Abc_ObjAddFanin( pNode, pFanin ); + if ( Abc_NtkHasSop(pNtk) ) + pNode->pData = Abc_SopRegister( pNtk->pManFunc, "0 1\n" ); + else if ( Abc_NtkHasBdd(pNtk) ) + pNode->pData = Cudd_Not(Cudd_bddIthVar(pNtk->pManFunc,0)), Cudd_Ref( pNode->pData ); + else if ( Abc_NtkHasMapping(pNtk) ) + pNode->pData = Mio_LibraryReadInv(Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame())); + else + assert( 0 ); + return pNode; +} + +/**Function************************************************************* + + Synopsis [Creates buffer.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Abc_NodeCreateBuf( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin ) +{ + Abc_Obj_t * pNode; + assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsNetlist(pNtk) ); + pNode = Abc_NtkCreateNode( pNtk ); + Abc_ObjAddFanin( pNode, pFanin ); + if ( Abc_NtkHasSop(pNtk) ) + pNode->pData = Abc_SopRegister( pNtk->pManFunc, "1 1\n" ); + else if ( Abc_NtkHasBdd(pNtk) ) + pNode->pData = Cudd_bddIthVar(pNtk->pManFunc,0), Cudd_Ref( pNode->pData ); + else if ( Abc_NtkHasMapping(pNtk) ) + pNode->pData = Mio_LibraryReadBuf(Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame())); + else + assert( 0 ); + return pNode; +} + +/**Function************************************************************* + + Synopsis [Creates inverter.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Abc_NodeCreateAnd( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins ) +{ + Abc_Obj_t * pNode; + int i; + assert( Abc_NtkIsLogic(pNtk) ); + pNode = Abc_NtkCreateNode( pNtk ); + for ( i = 0; i < vFanins->nSize; i++ ) + Abc_ObjAddFanin( pNode, vFanins->pArray[i] ); + if ( Abc_NtkHasSop(pNtk) ) + { + char * pSop; + pSop = Extra_MmFlexEntryFetch( pNtk->pManFunc, vFanins->nSize + 4 ); + for ( i = 0; i < vFanins->nSize; i++ ) + pSop[i] = '1'; + pSop[i++] = ' '; + pSop[i++] = '1'; + pSop[i++] = '\n'; + pSop[i++] = 0; + assert( i == vFanins->nSize + 4 ); + pNode->pData = pSop; + } + else if ( Abc_NtkHasBdd(pNtk) ) + { + DdManager * dd = pNtk->pManFunc; + DdNode * bFunc, * bTemp; + bFunc = Cudd_ReadOne(dd); Cudd_Ref( bFunc ); + for ( i = 0; i < vFanins->nSize; i++ ) + { + bFunc = Cudd_bddAnd( dd, bTemp = bFunc, Cudd_bddIthVar(pNtk->pManFunc,i) ); Cudd_Ref( bFunc ); + Cudd_RecursiveDeref( dd, bTemp ); + } + pNode->pData = bFunc; + } + else + assert( 0 ); + return pNode; +} + +/**Function************************************************************* + + Synopsis [Creates inverter.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Abc_NodeCreateOr( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins ) +{ + Abc_Obj_t * pNode; + int i; + assert( Abc_NtkIsLogic(pNtk) ); + pNode = Abc_NtkCreateNode( pNtk ); + for ( i = 0; i < vFanins->nSize; i++ ) + Abc_ObjAddFanin( pNode, vFanins->pArray[i] ); + if ( Abc_NtkHasSop(pNtk) ) + { + char * pSop; + pSop = Extra_MmFlexEntryFetch( pNtk->pManFunc, vFanins->nSize + 4 ); + for ( i = 0; i < vFanins->nSize; i++ ) + pSop[i] = '0'; + pSop[i++] = ' '; + pSop[i++] = '0'; + pSop[i++] = '\n'; + pSop[i++] = 0; + assert( i == vFanins->nSize + 4 ); + pNode->pData = pSop; + } + else if ( Abc_NtkHasBdd(pNtk) ) + { + DdManager * dd = pNtk->pManFunc; + DdNode * bFunc, * bTemp; + bFunc = Cudd_ReadLogicZero(dd); Cudd_Ref( bFunc ); + for ( i = 0; i < vFanins->nSize; i++ ) + { + bFunc = Cudd_bddOr( dd, bTemp = bFunc, Cudd_bddIthVar(pNtk->pManFunc,i) ); Cudd_Ref( bFunc ); + Cudd_RecursiveDeref( dd, bTemp ); + } + pNode->pData = bFunc; + } + else + assert( 0 ); + return pNode; +} + +/**Function************************************************************* + + Synopsis [Creates inverter.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Abc_NodeCreateMux( Abc_Ntk_t * pNtk, Abc_Obj_t * pNodeC, Abc_Obj_t * pNode1, Abc_Obj_t * pNode0 ) +{ + Abc_Obj_t * pNode; + assert( Abc_NtkIsLogic(pNtk) ); + pNode = Abc_NtkCreateNode( pNtk ); + Abc_ObjAddFanin( pNode, pNodeC ); + Abc_ObjAddFanin( pNode, pNode1 ); + Abc_ObjAddFanin( pNode, pNode0 ); + if ( Abc_NtkHasSop(pNtk) ) + pNode->pData = Abc_SopRegister( pNtk->pManFunc, "11- 1\n0-1 1\n" ); + else if ( Abc_NtkHasBdd(pNtk) ) + pNode->pData = Cudd_bddIte(pNtk->pManFunc,Cudd_bddIthVar(pNtk->pManFunc,0),Cudd_bddIthVar(pNtk->pManFunc,1),Cudd_bddIthVar(pNtk->pManFunc,2)), Cudd_Ref( pNode->pData ); + else + assert( 0 ); + return pNode; +} + +/**Function************************************************************* + + Synopsis [Clones the given node but does not assign the function.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Abc_NodeClone( Abc_Obj_t * pNode ) +{ + Abc_Obj_t * pClone, * pFanin; + int i; + assert( Abc_ObjIsNode(pNode) ); + pClone = Abc_NtkCreateNode( pNode->pNtk ); + Abc_ObjForEachFanin( pNode, pFanin, i ) + Abc_ObjAddFanin( pClone, pFanin ); + return pClone; +} + + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +bool Abc_NodeIsConst0( Abc_Obj_t * pNode ) +{ + Abc_Ntk_t * pNtk = pNode->pNtk; + assert(Abc_ObjIsNode(pNode)); + assert(Abc_NodeIsConst(pNode)); + if ( Abc_NtkHasSop(pNtk) ) + return Abc_SopIsConst0(pNode->pData); + if ( Abc_NtkHasBdd(pNtk) ) + return Cudd_IsComplement(pNode->pData); + if ( Abc_NtkHasAig(pNtk) ) + return Abc_ObjNot(pNode) == Abc_AigConst1(pNode->pNtk->pManFunc); + if ( Abc_NtkHasMapping(pNtk) ) + return pNode->pData == Mio_LibraryReadConst0(Abc_FrameReadLibSuper(Abc_FrameGetGlobalFrame())); + assert( 0 ); + return 0; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +bool Abc_NodeIsConst1( Abc_Obj_t * pNode ) +{ + Abc_Ntk_t * pNtk = pNode->pNtk; + assert(Abc_ObjIsNode(pNode)); + assert(Abc_NodeIsConst(pNode)); + if ( Abc_NtkHasSop(pNtk) ) + return Abc_SopIsConst1(pNode->pData); + if ( Abc_NtkHasBdd(pNtk) ) + return !Cudd_IsComplement(pNode->pData); + if ( Abc_NtkHasAig(pNtk) ) + return pNode == Abc_AigConst1(pNode->pNtk->pManFunc); + if ( Abc_NtkHasMapping(pNtk) ) + return pNode->pData == Mio_LibraryReadConst1(Abc_FrameReadLibSuper(Abc_FrameGetGlobalFrame())); + assert( 0 ); + return 0; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +bool Abc_NodeIsBuf( Abc_Obj_t * pNode ) +{ + Abc_Ntk_t * pNtk = pNode->pNtk; + assert(Abc_ObjIsNode(pNode)); + if ( Abc_ObjFaninNum(pNode) != 1 ) + return 0; + if ( Abc_NtkHasSop(pNtk) ) + return Abc_SopIsBuf(pNode->pData); + if ( Abc_NtkHasBdd(pNtk) ) + return !Cudd_IsComplement(pNode->pData); + if ( Abc_NtkHasAig(pNtk) ) + return 0; + if ( Abc_NtkHasMapping(pNtk) ) + return pNode->pData == Mio_LibraryReadBuf(Abc_FrameReadLibSuper(Abc_FrameGetGlobalFrame())); + assert( 0 ); + return 0; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +bool Abc_NodeIsInv( Abc_Obj_t * pNode ) +{ + Abc_Ntk_t * pNtk = pNode->pNtk; + assert(Abc_ObjIsNode(pNode)); + if ( Abc_ObjFaninNum(pNode) != 1 ) + return 0; + if ( Abc_NtkHasSop(pNtk) ) + return Abc_SopIsInv(pNode->pData); + if ( Abc_NtkHasBdd(pNtk) ) + return Cudd_IsComplement(pNode->pData); + if ( Abc_NtkHasAig(pNtk) ) + return 0; + if ( Abc_NtkHasMapping(pNtk) ) + return pNode->pData == Mio_LibraryReadInv(Abc_FrameReadLibSuper(Abc_FrameGetGlobalFrame())); + assert( 0 ); + return 0; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + diff --git a/src/base/abc/abcPrint.c b/src/base/abc/abcPrint.c deleted file mode 100644 index 41b9288e..00000000 --- a/src/base/abc/abcPrint.c +++ /dev/null @@ -1,505 +0,0 @@ -/**CFile**************************************************************** - - FileName [abcPrint.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Network and node package.] - - Synopsis [Printing statistics.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: abcPrint.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" -#include "dec.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Print the vital stats of the network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkPrintStats( FILE * pFile, Abc_Ntk_t * pNtk, int fFactored ) -{ - int Num; - - fprintf( pFile, "%-13s:", pNtk->pName ); - fprintf( pFile, " i/o = %4d/%4d", Abc_NtkPiNum(pNtk), Abc_NtkPoNum(pNtk) ); - - if ( !Abc_NtkIsSeq(pNtk) ) - fprintf( pFile, " lat = %4d", Abc_NtkLatchNum(pNtk) ); - else - fprintf( pFile, " lat = %4d", Abc_NtkSeqLatchNum(pNtk) ); - - if ( Abc_NtkIsNetlist(pNtk) ) - { - fprintf( pFile, " net = %5d", Abc_NtkNetNum(pNtk) ); - fprintf( pFile, " nd = %5d", Abc_NtkNodeNum(pNtk) ); - } - else if ( Abc_NtkIsStrash(pNtk) ) - { - fprintf( pFile, " and = %5d", Abc_NtkNodeNum(pNtk) ); - if ( Num = Abc_NtkGetChoiceNum(pNtk) ) - fprintf( pFile, " (choice = %d)", Num ); - if ( Num = Abc_NtkGetExorNum(pNtk) ) - fprintf( pFile, " (exor = %d)", Num ); - } - else if ( Abc_NtkIsSeq(pNtk) ) - fprintf( pFile, " and = %5d", Abc_NtkNodeNum(pNtk) ); - else - fprintf( pFile, " nd = %5d", Abc_NtkNodeNum(pNtk) ); - - if ( Abc_NtkHasSop(pNtk) ) - { - fprintf( pFile, " cube = %5d", Abc_NtkGetCubeNum(pNtk) ); -// fprintf( pFile, " lit(sop) = %5d", Abc_NtkGetLitNum(pNtk) ); - if ( fFactored ) - fprintf( pFile, " lit(fac) = %5d", Abc_NtkGetLitFactNum(pNtk) ); - } - else if ( Abc_NtkHasBdd(pNtk) ) - fprintf( pFile, " bdd = %5d", Abc_NtkGetBddNodeNum(pNtk) ); - else if ( Abc_NtkHasMapping(pNtk) ) - { - fprintf( pFile, " area = %5.2f", Abc_NtkGetMappedArea(pNtk) ); - fprintf( pFile, " delay = %5.2f", Abc_NtkDelayTrace(pNtk) ); - } - else if ( !Abc_NtkHasAig(pNtk) ) - { - assert( 0 ); - } - - if ( Abc_NtkIsStrash(pNtk) ) - fprintf( pFile, " lev = %3d", Abc_AigGetLevelNum(pNtk) ); - else if ( !Abc_NtkIsSeq(pNtk) ) - fprintf( pFile, " lev = %3d", Abc_NtkGetLevelNum(pNtk) ); - - fprintf( pFile, "\n" ); -} - -/**Function************************************************************* - - Synopsis [Prints PIs/POs and LIs/LOs.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkPrintIo( FILE * pFile, Abc_Ntk_t * pNtk ) -{ - Abc_Obj_t * pObj; - int i; - - fprintf( pFile, "Primary inputs (%d): ", Abc_NtkPiNum(pNtk) ); - Abc_NtkForEachPi( pNtk, pObj, i ) - fprintf( pFile, " %s", Abc_ObjName(pObj) ); - fprintf( pFile, "\n" ); - - fprintf( pFile, "Primary outputs (%d):", Abc_NtkPoNum(pNtk) ); - Abc_NtkForEachPo( pNtk, pObj, i ) - fprintf( pFile, " %s", Abc_ObjName(pObj) ); - fprintf( pFile, "\n" ); - - fprintf( pFile, "Latches (%d): ", Abc_NtkLatchNum(pNtk) ); - Abc_NtkForEachLatch( pNtk, pObj, i ) - fprintf( pFile, " %s", Abc_ObjName(pObj) ); - fprintf( pFile, "\n" ); -} - -/**Function************************************************************* - - Synopsis [Prints statistics about latches.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkPrintLatch( FILE * pFile, Abc_Ntk_t * pNtk ) -{ - Abc_Obj_t * pLatch, * pFanin; - int i, Counter0, Counter1, Counter2; - int Init0, Init1, Init2; - - if ( Abc_NtkLatchNum(pNtk) == 0 ) - { - fprintf( pFile, "The network is combinational.\n" ); - return; - } - - assert( !Abc_NtkIsNetlist(pNtk) ); - - Init0 = Init1 = Init2 = 0; - Counter0 = Counter1 = Counter2 = 0; - - Abc_NtkForEachLatch( pNtk, pLatch, i ) - { - if ( Abc_LatchIsInit0(pLatch) ) - Init0++; - else if ( Abc_LatchIsInit1(pLatch) ) - Init1++; - else if ( Abc_LatchIsInitDc(pLatch) ) - Init2++; - else - assert( 0 ); - - pFanin = Abc_ObjFanin0(pLatch); - if ( !Abc_ObjIsNode(pFanin) || !Abc_NodeIsConst(pFanin) ) - continue; - - // the latch input is a constant node - Counter0++; - if ( Abc_LatchIsInitDc(pLatch) ) - { - Counter1++; - continue; - } - // count the number of cases when the constant is equal to the initial value - if ( Abc_NtkIsStrash(pNtk) ) - { - if ( Abc_LatchIsInit1(pLatch) == !Abc_ObjFaninC0(pLatch) ) - Counter2++; - } - else - { - if ( Abc_LatchIsInit1(pLatch) == Abc_NodeIsConst1(pLatch) ) - Counter2++; - } - } -// fprintf( pFile, "%-15s: ", pNtk->pName ); -// fprintf( pFile, "L = %5d: 0 = %4d. 1 = %3d. DC = %4d. ", Abc_NtkLatchNum(pNtk), Init0, Init1, Init2 ); -// fprintf( pFile, "Con = %3d. DC = %3d. Mat = %3d. ", Counter0, Counter1, Counter2 ); -// fprintf( pFile, "SFeed = %2d.\n", Abc_NtkCountSelfFeedLatches(pNtk) ); - fprintf( pFile, "%-15s: ", pNtk->pName ); - fprintf( pFile, "Lat = %5d: 0 = %4d. 1 = %3d. DC = %4d. \n", Abc_NtkLatchNum(pNtk), Init0, Init1, Init2 ); - fprintf( pFile, "Con = %3d. DC = %3d. Mat = %3d. ", Counter0, Counter1, Counter2 ); - fprintf( pFile, "SFeed = %2d.\n", Abc_NtkCountSelfFeedLatches(pNtk) ); -} - -/**Function************************************************************* - - Synopsis [Prints the distribution of fanins/fanouts in the network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkPrintFanio( FILE * pFile, Abc_Ntk_t * pNtk ) -{ - Abc_Obj_t * pNode; - int i, k, nFanins, nFanouts; - Vec_Int_t * vFanins, * vFanouts; - int nOldSize, nNewSize; - - vFanins = Vec_IntAlloc( 0 ); - vFanouts = Vec_IntAlloc( 0 ); - Vec_IntFill( vFanins, 100, 0 ); - Vec_IntFill( vFanouts, 100, 0 ); - Abc_NtkForEachNode( pNtk, pNode, i ) - { - nFanins = Abc_ObjFaninNum(pNode); - if ( Abc_NtkIsNetlist(pNtk) ) - nFanouts = Abc_ObjFanoutNum( Abc_ObjFanout0(pNode) ); - else - nFanouts = Abc_ObjFanoutNum(pNode); - if ( nFanins > vFanins->nSize || nFanouts > vFanouts->nSize ) - { - nOldSize = vFanins->nSize; - nNewSize = ABC_MAX(nFanins, nFanouts) + 10; - Vec_IntGrow( vFanins, nNewSize ); - Vec_IntGrow( vFanouts, nNewSize ); - for ( k = nOldSize; k < nNewSize; k++ ) - { - Vec_IntPush( vFanins, 0 ); - Vec_IntPush( vFanouts, 0 ); - } - } - vFanins->pArray[nFanins]++; - vFanouts->pArray[nFanouts]++; - } - fprintf( pFile, "The distribution of fanins and fanouts in the network:\n" ); - fprintf( pFile, " Number Nodes with fanin Nodes with fanout\n" ); - for ( k = 0; k < vFanins->nSize; k++ ) - { - if ( vFanins->pArray[k] == 0 && vFanouts->pArray[k] == 0 ) - continue; - fprintf( pFile, "%5d : ", k ); - if ( vFanins->pArray[k] == 0 ) - fprintf( pFile, " " ); - else - fprintf( pFile, "%12d ", vFanins->pArray[k] ); - fprintf( pFile, " " ); - if ( vFanouts->pArray[k] == 0 ) - fprintf( pFile, " " ); - else - fprintf( pFile, "%12d ", vFanouts->pArray[k] ); - fprintf( pFile, "\n" ); - } - Vec_IntFree( vFanins ); - Vec_IntFree( vFanouts ); -} - -/**Function************************************************************* - - Synopsis [Prints the fanins/fanouts of a node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NodePrintFanio( FILE * pFile, Abc_Obj_t * pNode ) -{ - Abc_Obj_t * pNode2; - int i; - if ( Abc_ObjIsPo(pNode) ) - pNode = Abc_ObjFanin0(pNode); - - fprintf( pFile, "Node %s", Abc_ObjName(pNode) ); - fprintf( pFile, "\n" ); - - fprintf( pFile, "Fanins (%d): ", Abc_ObjFaninNum(pNode) ); - Abc_ObjForEachFanin( pNode, pNode2, i ) - fprintf( pFile, " %s", Abc_ObjName(pNode2) ); - fprintf( pFile, "\n" ); - - fprintf( pFile, "Fanouts (%d): ", Abc_ObjFaninNum(pNode) ); - Abc_ObjForEachFanout( pNode, pNode2, i ) - fprintf( pFile, " %s", Abc_ObjName(pNode2) ); - fprintf( pFile, "\n" ); -} - -/**Function************************************************************* - - Synopsis [Prints the factored form of one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkPrintFactor( FILE * pFile, Abc_Ntk_t * pNtk, int fUseRealNames ) -{ - Abc_Obj_t * pNode; - int i; - assert( Abc_NtkIsSopLogic(pNtk) ); - Abc_NtkForEachNode( pNtk, pNode, i ) - Abc_NodePrintFactor( pFile, pNode, fUseRealNames ); -} - -/**Function************************************************************* - - Synopsis [Prints the factored form of one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NodePrintFactor( FILE * pFile, Abc_Obj_t * pNode, int fUseRealNames ) -{ - Dec_Graph_t * pGraph; - Vec_Ptr_t * vNamesIn; - if ( Abc_ObjIsCo(pNode) ) - pNode = Abc_ObjFanin0(pNode); - if ( Abc_ObjIsPi(pNode) ) - { - fprintf( pFile, "Skipping the PI node.\n" ); - return; - } - if ( Abc_ObjIsLatch(pNode) ) - { - fprintf( pFile, "Skipping the latch.\n" ); - return; - } - assert( Abc_ObjIsNode(pNode) ); - pGraph = Dec_Factor( pNode->pData ); - if ( fUseRealNames ) - { - vNamesIn = Abc_NodeGetFaninNames(pNode); - Dec_GraphPrint( stdout, pGraph, (char **)vNamesIn->pArray, Abc_ObjName(pNode) ); - Abc_NodeFreeNames( vNamesIn ); - } - else - Dec_GraphPrint( stdout, pGraph, (char **)NULL, Abc_ObjName(pNode) ); - Dec_GraphFree( pGraph ); -} - - -/**Function************************************************************* - - Synopsis [Prints the level stats of the PO node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkPrintLevel( FILE * pFile, Abc_Ntk_t * pNtk, int fProfile ) -{ - Abc_Obj_t * pNode; - int i, Length; - - // print the delay profile - if ( fProfile && Abc_NtkHasMapping(pNtk) ) - { - int nIntervals = 12; - float DelayMax, DelayCur, DelayDelta; - int * pLevelCounts; - int DelayInt, nOutsSum, nOutsTotal; - - // get the max delay and delta - DelayMax = Abc_NtkDelayTrace( pNtk ); - DelayDelta = DelayMax/nIntervals; - // collect outputs by delay - pLevelCounts = ALLOC( int, nIntervals ); - memset( pLevelCounts, 0, sizeof(int) * nIntervals ); - Abc_NtkForEachCo( pNtk, pNode, i ) - { - DelayCur = Abc_NodeReadArrival( Abc_ObjFanin0(pNode) )->Worst; - DelayInt = (int)(DelayCur / DelayDelta); - if ( DelayInt >= nIntervals ) - DelayInt = nIntervals - 1; - pLevelCounts[DelayInt]++; - } - - nOutsSum = 0; - nOutsTotal = Abc_NtkCoNum(pNtk); - for ( i = 0; i < nIntervals; i++ ) - { - nOutsSum += pLevelCounts[i]; - printf( "[%8.2f - %8.2f] : COs = %4d. %5.1f %%\n", - DelayDelta * i, DelayDelta * (i+1), pLevelCounts[i], 100.0 * nOutsSum/nOutsTotal ); - } - free( pLevelCounts ); - return; - } - else if ( fProfile ) - { - int LevelMax, * pLevelCounts; - int nOutsSum, nOutsTotal; - - if ( !Abc_NtkIsStrash(pNtk) ) - Abc_NtkGetLevelNum(pNtk); - - LevelMax = 0; - Abc_NtkForEachCo( pNtk, pNode, i ) - if ( LevelMax < (int)Abc_ObjFanin0(pNode)->Level ) - LevelMax = Abc_ObjFanin0(pNode)->Level; - pLevelCounts = ALLOC( int, LevelMax + 1 ); - memset( pLevelCounts, 0, sizeof(int) * (LevelMax + 1) ); - Abc_NtkForEachCo( pNtk, pNode, i ) - pLevelCounts[Abc_ObjFanin0(pNode)->Level]++; - - nOutsSum = 0; - nOutsTotal = Abc_NtkCoNum(pNtk); - for ( i = 0; i <= LevelMax; i++ ) - if ( pLevelCounts[i] ) - { - nOutsSum += pLevelCounts[i]; - printf( "Level = %4d. COs = %4d. %5.1f %%\n", i, pLevelCounts[i], 100.0 * nOutsSum/nOutsTotal ); - } - free( pLevelCounts ); - return; - } - assert( Abc_NtkIsStrash(pNtk) ); - - // find the longest name - Length = 0; - Abc_NtkForEachCo( pNtk, pNode, i ) - if ( Length < (int)strlen(Abc_ObjName(pNode)) ) - Length = strlen(Abc_ObjName(pNode)); - if ( Length < 5 ) - Length = 5; - // print stats for each output - Abc_NtkForEachCo( pNtk, pNode, i ) - { - fprintf( pFile, "CO %4d : %*s ", i, Length, Abc_ObjName(pNode) ); - Abc_NodePrintLevel( pFile, pNode ); - } -} - -/**Function************************************************************* - - Synopsis [Prints the factored form of one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NodePrintLevel( FILE * pFile, Abc_Obj_t * pNode ) -{ - Abc_Obj_t * pDriver; - Vec_Ptr_t * vNodes; - - pDriver = Abc_ObjIsCo(pNode)? Abc_ObjFanin0(pNode) : pNode; - if ( Abc_ObjIsPi(pDriver) ) - { - fprintf( pFile, "Primary input.\n" ); - return; - } - if ( Abc_ObjIsLatch(pDriver) ) - { - fprintf( pFile, "Latch.\n" ); - return; - } - if ( Abc_NodeIsConst(pDriver) ) - { - fprintf( pFile, "Constant %d.\n", !Abc_ObjFaninC0(pNode) ); - return; - } - // print the level - fprintf( pFile, "Level = %3d. ", pDriver->Level ); - // print the size of MFFC - fprintf( pFile, "Mffc = %5d. ", Abc_NodeMffcSize(pDriver) ); - // print the size of the shole cone - vNodes = Abc_NtkDfsNodes( pNode->pNtk, &pDriver, 1 ); - fprintf( pFile, "Cone = %5d. ", Vec_PtrSize(vNodes) ); - Vec_PtrFree( vNodes ); - fprintf( pFile, "\n" ); -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/base/abc/abcReconv.c b/src/base/abc/abcReconv.c deleted file mode 100644 index 766c14f3..00000000 --- a/src/base/abc/abcReconv.c +++ /dev/null @@ -1,742 +0,0 @@ -/**CFile**************************************************************** - - FileName [abcRes.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Network and node package.] - - Synopsis [Reconvergence=driven cut computation.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: abcRes.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -struct Abc_ManCut_t_ -{ - // user specified parameters - int nNodeSizeMax; // the limit on the size of the supernode - int nConeSizeMax; // the limit on the size of the containing cone - int nNodeFanStop; // the limit on the size of the supernode - int nConeFanStop; // the limit on the size of the containing cone - // internal parameters - Vec_Ptr_t * vNodeLeaves; // fanins of the collapsed node (the cut) - Vec_Ptr_t * vConeLeaves; // fanins of the containing cone - Vec_Ptr_t * vVisited; // the visited nodes - Vec_Vec_t * vLevels; // the data structure to compute TFO nodes - Vec_Ptr_t * vNodesTfo; // the nodes in the TFO of the cut -}; - -static int Abc_NodeBuildCutLevelOne_int( Vec_Ptr_t * vVisited, Vec_Ptr_t * vLeaves, int nSizeLimit, int nFaninLimit ); -static int Abc_NodeBuildCutLevelTwo_int( Vec_Ptr_t * vVisited, Vec_Ptr_t * vLeaves, int nFaninLimit ); -static void Abc_NodeConeMarkCollect_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vVisited ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Unmarks the TFI cone.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Abc_NodesMark( Vec_Ptr_t * vVisited ) -{ - Abc_Obj_t * pNode; - int i; - Vec_PtrForEachEntry( vVisited, pNode, i ) - pNode->fMarkA = 1; -} - -/**Function************************************************************* - - Synopsis [Unmarks the TFI cone.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Abc_NodesUnmark( Vec_Ptr_t * vVisited ) -{ - Abc_Obj_t * pNode; - int i; - Vec_PtrForEachEntry( vVisited, pNode, i ) - pNode->fMarkA = 0; -} - -/**Function************************************************************* - - Synopsis [Unmarks the TFI cone.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Abc_NodesUnmarkB( Vec_Ptr_t * vVisited ) -{ - Abc_Obj_t * pNode; - int i; - Vec_PtrForEachEntry( vVisited, pNode, i ) - pNode->fMarkB = 0; -} - -/**Function************************************************************* - - Synopsis [Evaluate the cost of removing the node from the set of leaves.] - - Description [Returns the number of new leaves that will be brought in. - Returns large number if the node cannot be removed from the set of leaves.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Abc_NodeGetLeafCostOne( Abc_Obj_t * pNode, int nFaninLimit ) -{ - int Cost; - // make sure the node is in the construction zone - assert( pNode->fMarkB == 1 ); - // cannot expand over the PI node - if ( Abc_ObjIsCi(pNode) ) - return 999; - // get the cost of the cone - Cost = (!Abc_ObjFanin0(pNode)->fMarkB) + (!Abc_ObjFanin1(pNode)->fMarkB); - // always accept if the number of leaves does not increase - if ( Cost < 2 ) - return Cost; - // skip nodes with many fanouts - if ( Abc_ObjFanoutNum(pNode) > nFaninLimit ) - return 999; - // return the number of nodes that will be on the leaves if this node is removed - return Cost; -} - -/**Function************************************************************* - - Synopsis [Evaluate the cost of removing the node from the set of leaves.] - - Description [Returns the number of new leaves that will be brought in. - Returns large number if the node cannot be removed from the set of leaves.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Abc_NodeGetLeafCostTwo( Abc_Obj_t * pNode, int nFaninLimit, - Abc_Obj_t ** ppLeafToAdd, Abc_Obj_t ** pNodeToMark1, Abc_Obj_t ** pNodeToMark2 ) -{ - Abc_Obj_t * pFanin0, * pFanin1, * pTemp; - Abc_Obj_t * pGrand, * pGrandToAdd; - // make sure the node is in the construction zone - assert( pNode->fMarkB == 1 ); - // cannot expand over the PI node - if ( Abc_ObjIsCi(pNode) ) - return 999; - // skip nodes with many fanouts -// if ( Abc_ObjFanoutNum(pNode) > nFaninLimit ) -// return 999; - // get the children - pFanin0 = Abc_ObjFanin0(pNode); - pFanin1 = Abc_ObjFanin1(pNode); - assert( !pFanin0->fMarkB && !pFanin1->fMarkB ); - // count the number of unique grandchildren that will be included - // return infinite cost if this number if more than 1 - if ( Abc_ObjIsCi(pFanin0) && Abc_ObjIsCi(pFanin1) ) - return 999; - // consider the special case when a non-CI fanin can be dropped - if ( !Abc_ObjIsCi(pFanin0) && Abc_ObjFanin0(pFanin0)->fMarkB && Abc_ObjFanin1(pFanin0)->fMarkB ) - { - *ppLeafToAdd = pFanin1; - *pNodeToMark1 = pFanin0; - *pNodeToMark2 = NULL; - return 1; - } - if ( !Abc_ObjIsCi(pFanin1) && Abc_ObjFanin0(pFanin1)->fMarkB && Abc_ObjFanin1(pFanin1)->fMarkB ) - { - *ppLeafToAdd = pFanin0; - *pNodeToMark1 = pFanin1; - *pNodeToMark2 = NULL; - return 1; - } - - // make the first node CI if any - if ( Abc_ObjIsCi(pFanin1) ) - pTemp = pFanin0, pFanin0 = pFanin1, pFanin1 = pTemp; - // consider the first node - pGrandToAdd = NULL; - if ( Abc_ObjIsCi(pFanin0) ) - { - *pNodeToMark1 = NULL; - pGrandToAdd = pFanin0; - } - else - { - *pNodeToMark1 = pFanin0; - pGrand = Abc_ObjFanin0(pFanin0); - if ( !pGrand->fMarkB ) - { - if ( pGrandToAdd && pGrandToAdd != pGrand ) - return 999; - pGrandToAdd = pGrand; - } - pGrand = Abc_ObjFanin1(pFanin0); - if ( !pGrand->fMarkB ) - { - if ( pGrandToAdd && pGrandToAdd != pGrand ) - return 999; - pGrandToAdd = pGrand; - } - } - // consider the second node - *pNodeToMark2 = pFanin1; - pGrand = Abc_ObjFanin0(pFanin1); - if ( !pGrand->fMarkB ) - { - if ( pGrandToAdd && pGrandToAdd != pGrand ) - return 999; - pGrandToAdd = pGrand; - } - pGrand = Abc_ObjFanin1(pFanin1); - if ( !pGrand->fMarkB ) - { - if ( pGrandToAdd && pGrandToAdd != pGrand ) - return 999; - pGrandToAdd = pGrand; - } - assert( pGrandToAdd != NULL ); - *ppLeafToAdd = pGrandToAdd; - return 1; -} - - -/**Function************************************************************* - - Synopsis [Finds a fanin-limited, reconvergence-driven cut for the node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Ptr_t * Abc_NodeFindCut( Abc_ManCut_t * p, Abc_Obj_t * pRoot, bool fContain ) -{ - Abc_Obj_t * pNode; - int i; - - assert( !Abc_ObjIsComplement(pRoot) ); - assert( Abc_ObjIsNode(pRoot) ); - - // start the visited nodes and mark them - Vec_PtrClear( p->vVisited ); - Vec_PtrPush( p->vVisited, pRoot ); - Vec_PtrPush( p->vVisited, Abc_ObjFanin0(pRoot) ); - Vec_PtrPush( p->vVisited, Abc_ObjFanin1(pRoot) ); - pRoot->fMarkB = 1; - Abc_ObjFanin0(pRoot)->fMarkB = 1; - Abc_ObjFanin1(pRoot)->fMarkB = 1; - - // start the cut - Vec_PtrClear( p->vNodeLeaves ); - Vec_PtrPush( p->vNodeLeaves, Abc_ObjFanin0(pRoot) ); - Vec_PtrPush( p->vNodeLeaves, Abc_ObjFanin1(pRoot) ); - - // compute the cut - while ( Abc_NodeBuildCutLevelOne_int( p->vVisited, p->vNodeLeaves, p->nNodeSizeMax, p->nNodeFanStop ) ); - assert( Vec_PtrSize(p->vNodeLeaves) <= p->nNodeSizeMax ); - - // return if containing cut is not requested - if ( !fContain ) - { - // unmark both fMarkA and fMarkB in tbe TFI - Abc_NodesUnmarkB( p->vVisited ); - return p->vNodeLeaves; - } - -//printf( "\n\n\n" ); - // compute the containing cut - assert( p->nNodeSizeMax < p->nConeSizeMax ); - // copy the current boundary - Vec_PtrClear( p->vConeLeaves ); - Vec_PtrForEachEntry( p->vNodeLeaves, pNode, i ) - Vec_PtrPush( p->vConeLeaves, pNode ); - // compute the containing cut - while ( Abc_NodeBuildCutLevelOne_int( p->vVisited, p->vConeLeaves, p->nConeSizeMax, p->nConeFanStop ) ); - assert( Vec_PtrSize(p->vConeLeaves) <= p->nConeSizeMax ); - // unmark TFI using fMarkA and fMarkB - Abc_NodesUnmarkB( p->vVisited ); - return p->vNodeLeaves; -} - -/**Function************************************************************* - - Synopsis [Builds reconvergence-driven cut by changing one leaf at a time.] - - Description [This procedure looks at the current leaves and tries to change - one leaf at a time in such a way that the cut grows as little as possible. - In evaluating the fanins, this procedure looks only at their immediate - predecessors (this is why it is called a one-level construction procedure).] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NodeBuildCutLevelOne_int( Vec_Ptr_t * vVisited, Vec_Ptr_t * vLeaves, int nSizeLimit, int nFaninLimit ) -{ - Abc_Obj_t * pNode, * pFaninBest, * pNext; - int CostBest, CostCur, i; - // find the best fanin - CostBest = 100; - pFaninBest = NULL; -//printf( "Evaluating fanins of the cut:\n" ); - Vec_PtrForEachEntry( vLeaves, pNode, i ) - { - CostCur = Abc_NodeGetLeafCostOne( pNode, nFaninLimit ); -//printf( " Fanin %s has cost %d.\n", Abc_ObjName(pNode), CostCur ); - if ( CostBest > CostCur ) - { - CostBest = CostCur; - pFaninBest = pNode; - } - if ( CostBest == 0 ) - break; - } - if ( pFaninBest == NULL ) - return 0; -// return Abc_NodeBuildCutLevelTwo_int( vVisited, vLeaves, nFaninLimit ); - - assert( CostBest < 3 ); - if ( vLeaves->nSize - 1 + CostBest > nSizeLimit ) - return 0; -// return Abc_NodeBuildCutLevelTwo_int( vVisited, vLeaves, nFaninLimit ); - - assert( Abc_ObjIsNode(pFaninBest) ); - // remove the node from the array - Vec_PtrRemove( vLeaves, pFaninBest ); -//printf( "Removing fanin %s.\n", Abc_ObjName(pFaninBest) ); - - // add the left child to the fanins - pNext = Abc_ObjFanin0(pFaninBest); - if ( !pNext->fMarkB ) - { -//printf( "Adding fanin %s.\n", Abc_ObjName(pNext) ); - pNext->fMarkB = 1; - Vec_PtrPush( vLeaves, pNext ); - Vec_PtrPush( vVisited, pNext ); - } - // add the right child to the fanins - pNext = Abc_ObjFanin1(pFaninBest); - if ( !pNext->fMarkB ) - { -//printf( "Adding fanin %s.\n", Abc_ObjName(pNext) ); - pNext->fMarkB = 1; - Vec_PtrPush( vLeaves, pNext ); - Vec_PtrPush( vVisited, pNext ); - } - assert( vLeaves->nSize <= nSizeLimit ); - // keep doing this - return 1; -} - -/**Function************************************************************* - - Synopsis [Builds reconvergence-driven cut by changing one leaf at a time.] - - Description [This procedure looks at the current leaves and tries to change - one leaf at a time in such a way that the cut grows as little as possible. - In evaluating the fanins, this procedure looks across two levels of fanins - (this is why it is called a two-level construction procedure).] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NodeBuildCutLevelTwo_int( Vec_Ptr_t * vVisited, Vec_Ptr_t * vLeaves, int nFaninLimit ) -{ - Abc_Obj_t * pNode, * pLeafToAdd, * pNodeToMark1, * pNodeToMark2; - int CostCur, i; - // find the best fanin - Vec_PtrForEachEntry( vLeaves, pNode, i ) - { - CostCur = Abc_NodeGetLeafCostTwo( pNode, nFaninLimit, &pLeafToAdd, &pNodeToMark1, &pNodeToMark2 ); - if ( CostCur < 2 ) - break; - } - if ( CostCur > 2 ) - return 0; - // remove the node from the array - Vec_PtrRemove( vLeaves, pNode ); - // add the node to the leaves - if ( pLeafToAdd ) - { - assert( !pLeafToAdd->fMarkB ); - pLeafToAdd->fMarkB = 1; - Vec_PtrPush( vLeaves, pLeafToAdd ); - Vec_PtrPush( vVisited, pLeafToAdd ); - } - // mark the other nodes - if ( pNodeToMark1 ) - { - assert( !pNodeToMark1->fMarkB ); - pNodeToMark1->fMarkB = 1; - Vec_PtrPush( vVisited, pNodeToMark1 ); - } - if ( pNodeToMark2 ) - { - assert( !pNodeToMark2->fMarkB ); - pNodeToMark2->fMarkB = 1; - Vec_PtrPush( vVisited, pNodeToMark2 ); - } - // keep doing this - return 1; -} - - -/**Function************************************************************* - - Synopsis [Get the nodes contained in the cut.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NodeConeCollect( Abc_Obj_t ** ppRoots, int nRoots, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vVisited, int fIncludeFanins ) -{ - Abc_Obj_t * pTemp; - int i; - // mark the fanins of the cone - Abc_NodesMark( vLeaves ); - // collect the nodes in the DFS order - Vec_PtrClear( vVisited ); - // add the fanins - if ( fIncludeFanins ) - Vec_PtrForEachEntry( vLeaves, pTemp, i ) - Vec_PtrPush( vVisited, pTemp ); - // add other nodes - for ( i = 0; i < nRoots; i++ ) - Abc_NodeConeMarkCollect_rec( ppRoots[i], vVisited ); - // unmark both sets - Abc_NodesUnmark( vLeaves ); - Abc_NodesUnmark( vVisited ); -} - -/**Function************************************************************* - - Synopsis [Marks the TFI cone.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NodeConeMarkCollect_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vVisited ) -{ - if ( pNode->fMarkA == 1 ) - return; - // visit transitive fanin - if ( Abc_ObjIsNode(pNode) ) - { - Abc_NodeConeMarkCollect_rec( Abc_ObjFanin0(pNode), vVisited ); - Abc_NodeConeMarkCollect_rec( Abc_ObjFanin1(pNode), vVisited ); - } - assert( pNode->fMarkA == 0 ); - pNode->fMarkA = 1; - Vec_PtrPush( vVisited, pNode ); -} - -/**Function************************************************************* - - Synopsis [Returns BDD representing the logic function of the cone.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -DdNode * Abc_NodeConeBdd( DdManager * dd, DdNode ** pbVars, Abc_Obj_t * pNode, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vVisited ) -{ - DdNode * bFunc0, * bFunc1, * bFunc; - int i; - // get the nodes in the cut without fanins in the DFS order - Abc_NodeConeCollect( &pNode, 1, vLeaves, vVisited, 0 ); - // set the elementary BDDs - Vec_PtrForEachEntry( vLeaves, pNode, i ) - pNode->pCopy = (Abc_Obj_t *)pbVars[i]; - // compute the BDDs for the collected nodes - Vec_PtrForEachEntry( vVisited, pNode, i ) - { - bFunc0 = Cudd_NotCond( Abc_ObjFanin0(pNode)->pCopy, Abc_ObjFaninC0(pNode) ); - bFunc1 = Cudd_NotCond( Abc_ObjFanin1(pNode)->pCopy, Abc_ObjFaninC1(pNode) ); - bFunc = Cudd_bddAnd( dd, bFunc0, bFunc1 ); Cudd_Ref( bFunc ); - pNode->pCopy = (Abc_Obj_t *)bFunc; - } - Cudd_Ref( bFunc ); - // dereference the intermediate ones - Vec_PtrForEachEntry( vVisited, pNode, i ) - Cudd_RecursiveDeref( dd, (DdNode *)pNode->pCopy ); - Cudd_Deref( bFunc ); - return bFunc; -} - -/**Function************************************************************* - - Synopsis [Returns BDD representing the transition relation of the cone.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -DdNode * Abc_NodeConeDcs( DdManager * dd, DdNode ** pbVarsX, DdNode ** pbVarsY, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vRoots, Vec_Ptr_t * vVisited ) -{ - DdNode * bFunc0, * bFunc1, * bFunc, * bTrans, * bTemp, * bCube, * bResult; - Abc_Obj_t * pNode; - int i; - // get the nodes in the cut without fanins in the DFS order - Abc_NodeConeCollect( (Abc_Obj_t **)vRoots->pArray, vRoots->nSize, vLeaves, vVisited, 0 ); - // set the elementary BDDs - Vec_PtrForEachEntry( vLeaves, pNode, i ) - pNode->pCopy = (Abc_Obj_t *)pbVarsX[i]; - // compute the BDDs for the collected nodes - Vec_PtrForEachEntry( vVisited, pNode, i ) - { - bFunc0 = Cudd_NotCond( Abc_ObjFanin0(pNode)->pCopy, Abc_ObjFaninC0(pNode) ); - bFunc1 = Cudd_NotCond( Abc_ObjFanin1(pNode)->pCopy, Abc_ObjFaninC1(pNode) ); - bFunc = Cudd_bddAnd( dd, bFunc0, bFunc1 ); Cudd_Ref( bFunc ); - pNode->pCopy = (Abc_Obj_t *)bFunc; - } - // compute the transition relation of the cone - bTrans = b1; Cudd_Ref( bTrans ); - Vec_PtrForEachEntry( vRoots, pNode, i ) - { - bFunc = Cudd_bddXnor( dd, (DdNode *)pNode->pCopy, pbVarsY[i] ); Cudd_Ref( bFunc ); - bTrans = Cudd_bddAnd( dd, bTemp = bTrans, bFunc ); Cudd_Ref( bTrans ); - Cudd_RecursiveDeref( dd, bTemp ); - Cudd_RecursiveDeref( dd, bFunc ); - } - // dereference the intermediate ones - Vec_PtrForEachEntry( vVisited, pNode, i ) - Cudd_RecursiveDeref( dd, (DdNode *)pNode->pCopy ); - // compute don't-cares - bCube = Extra_bddComputeRangeCube( dd, vRoots->nSize, vRoots->nSize + vLeaves->nSize ); Cudd_Ref( bCube ); - bResult = Cudd_bddExistAbstract( dd, bTrans, bCube ); Cudd_Ref( bResult ); - bResult = Cudd_Not( bResult ); - Cudd_RecursiveDeref( dd, bCube ); - Cudd_RecursiveDeref( dd, bTrans ); - Cudd_Deref( bResult ); - return bResult; -} - -/**Function************************************************************* - - Synopsis [Starts the resynthesis manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_ManCut_t * Abc_NtkManCutStart( int nNodeSizeMax, int nConeSizeMax, int nNodeFanStop, int nConeFanStop ) -{ - Abc_ManCut_t * p; - p = ALLOC( Abc_ManCut_t, 1 ); - memset( p, 0, sizeof(Abc_ManCut_t) ); - p->vNodeLeaves = Vec_PtrAlloc( 100 ); - p->vConeLeaves = Vec_PtrAlloc( 100 ); - p->vVisited = Vec_PtrAlloc( 100 ); - p->vLevels = Vec_VecAlloc( 100 ); - p->vNodesTfo = Vec_PtrAlloc( 100 ); - p->nNodeSizeMax = nNodeSizeMax; - p->nConeSizeMax = nConeSizeMax; - p->nNodeFanStop = nNodeFanStop; - p->nConeFanStop = nConeFanStop; - return p; -} - -/**Function************************************************************* - - Synopsis [Stops the resynthesis manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkManCutStop( Abc_ManCut_t * p ) -{ - Vec_PtrFree( p->vNodeLeaves ); - Vec_PtrFree( p->vConeLeaves ); - Vec_PtrFree( p->vVisited ); - Vec_VecFree( p->vLevels ); - Vec_PtrFree( p->vNodesTfo ); - free( p ); -} - -/**Function************************************************************* - - Synopsis [Returns the leaves of the cone.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Ptr_t * Abc_NtkManCutReadCutLarge( Abc_ManCut_t * p ) -{ - return p->vConeLeaves; -} - -/**Function************************************************************* - - Synopsis [Returns the leaves of the cone.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Ptr_t * Abc_NtkManCutReadVisited( Abc_ManCut_t * p ) -{ - return p->vVisited; -} - - - -/**Function************************************************************* - - Synopsis [Collects the TFO of the cut in the topological order.] - - Description [TFO of the cut is defined as a set of nodes, for which the cut - is a cut, that is, every path from the collected nodes to the CIs goes through - a node in the cut. The nodes are collected if their level does not exceed - the given number (LevelMax). The nodes are returned in the topological order. - If the root node is given, its MFFC is marked, so that the collected nodes - do not contain any nodes in the MFFC.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Ptr_t * Abc_NodeCollectTfoCands( Abc_ManCut_t * p, Abc_Obj_t * pRoot, Vec_Ptr_t * vLeaves, int LevelMax ) -{ - Abc_Ntk_t * pNtk = pRoot->pNtk; - Vec_Ptr_t * vVec; - Abc_Obj_t * pNode, * pFanout; - int i, k, v, LevelMin; - assert( Abc_NtkIsStrash(pNtk) ); - - // assuming that the structure is clean - Vec_VecForEachLevel( p->vLevels, vVec, i ) - assert( vVec->nSize == 0 ); - - // put fanins into the structure while labeling them - Abc_NtkIncrementTravId( pNtk ); - LevelMin = -1; - Vec_PtrForEachEntry( vLeaves, pNode, i ) - { - if ( pNode->Level > (unsigned)LevelMax ) - continue; - Abc_NodeSetTravIdCurrent( pNode ); - Vec_VecPush( p->vLevels, pNode->Level, pNode ); - if ( LevelMin < (int)pNode->Level ) - LevelMin = pNode->Level; - } - assert( LevelMin >= 0 ); - - // mark MFFC - if ( pRoot ) - Abc_NodeMffcLabel( pRoot ); - - // go through the levels up - Vec_PtrClear( p->vNodesTfo ); - Vec_VecForEachEntryStart( p->vLevels, pNode, i, k, LevelMin ) - { - if ( i > LevelMax ) - break; - // if the node is not marked, it is not a fanin - if ( !Abc_NodeIsTravIdCurrent(pNode) ) - { - // check if it belongs to the TFO - if ( !Abc_NodeIsTravIdCurrent(Abc_ObjFanin0(pNode)) || - !Abc_NodeIsTravIdCurrent(Abc_ObjFanin1(pNode)) ) - continue; - // save the node in the TFO and label it - Vec_PtrPush( p->vNodesTfo, pNode ); - Abc_NodeSetTravIdCurrent( pNode ); - } - // go through the fanouts and add them to the structure if they meet the conditions - Abc_ObjForEachFanout( pNode, pFanout, v ) - { - // skip if fanout is a CO or its level exceeds - if ( Abc_ObjIsCo(pFanout) || pFanout->Level > (unsigned)LevelMax ) - continue; - // skip if it is already added or if it is in MFFC - if ( Abc_NodeIsTravIdCurrent(pFanout) ) - continue; - // add it to the structure but do not mark it (until tested later) - Vec_VecPushUnique( p->vLevels, pFanout->Level, pFanout ); - } - } - - // clear the levelized structure - Vec_VecForEachLevelStart( p->vLevels, vVec, i, LevelMin ) - { - if ( i > LevelMax ) - break; - Vec_PtrClear( vVec ); - } - return p->vNodesTfo; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/base/abc/abcRefactor.c b/src/base/abc/abcRefactor.c deleted file mode 100644 index 791d2d53..00000000 --- a/src/base/abc/abcRefactor.c +++ /dev/null @@ -1,354 +0,0 @@ -/**CFile**************************************************************** - - FileName [abcResRef.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Network and node package.] - - Synopsis [Resynthesis based on refactoring.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: abcResRef.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" -#include "dec.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -typedef struct Abc_ManRef_t_ Abc_ManRef_t; -struct Abc_ManRef_t_ -{ - // user specified parameters - int nNodeSizeMax; // the limit on the size of the supernode - int nConeSizeMax; // the limit on the size of the containing cone - int fVerbose; // the verbosity flag - // internal data structures - DdManager * dd; // the BDD manager - Vec_Str_t * vCube; // temporary - Vec_Int_t * vForm; // temporary - Vec_Ptr_t * vVisited; // temporary - Vec_Ptr_t * vLeaves; // temporary - // node statistics - int nLastGain; - int nNodesConsidered; - int nNodesRefactored; - int nNodesGained; - // runtime statistics - int timeCut; - int timeBdd; - int timeDcs; - int timeSop; - int timeFact; - int timeEval; - int timeRes; - int timeNtk; - int timeTotal; -}; - -static void Abc_NtkManRefPrintStats( Abc_ManRef_t * p ); -static Abc_ManRef_t * Abc_NtkManRefStart( int nNodeSizeMax, int nConeSizeMax, bool fUseDcs, bool fVerbose ); -static void Abc_NtkManRefStop( Abc_ManRef_t * p ); -static Dec_Graph_t * Abc_NodeRefactor( Abc_ManRef_t * p, Abc_Obj_t * pNode, Vec_Ptr_t * vFanins, bool fUseZeros, bool fUseDcs, bool fVerbose ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Performs incremental resynthesis of the AIG.] - - Description [Starting from each node, computes a reconvergence-driven cut, - derives BDD of the cut function, constructs ISOP, factors the ISOP, - and replaces the current implementation of the MFFC of the node by the - new factored form, if the number of AIG nodes is reduced and the total - number of levels of the AIG network is not increated. Returns the - number of AIG nodes saved.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkRefactor( Abc_Ntk_t * pNtk, int nNodeSizeMax, int nConeSizeMax, bool fUseZeros, bool fUseDcs, bool fVerbose ) -{ - int fCheck = 1; - ProgressBar * pProgress; - Abc_ManRef_t * pManRef; - Abc_ManCut_t * pManCut; - Dec_Graph_t * pFForm; - Vec_Ptr_t * vFanins; - Abc_Obj_t * pNode; - int clk, clkStart = clock(); - int i, nNodes; - - assert( Abc_NtkIsStrash(pNtk) ); - // cleanup the AIG - Abc_AigCleanup(pNtk->pManFunc); - // start the managers - pManCut = Abc_NtkManCutStart( nNodeSizeMax, nConeSizeMax, 2, 1000 ); - pManRef = Abc_NtkManRefStart( nNodeSizeMax, nConeSizeMax, fUseDcs, fVerbose ); - pManRef->vLeaves = Abc_NtkManCutReadCutLarge( pManCut ); - Abc_NtkStartReverseLevels( pNtk ); - - // resynthesize each node once - nNodes = Abc_NtkObjNumMax(pNtk); - pProgress = Extra_ProgressBarStart( stdout, nNodes ); - Abc_NtkForEachNode( pNtk, pNode, i ) - { - Extra_ProgressBarUpdate( pProgress, i, NULL ); - // skip the constant node - if ( Abc_NodeIsConst(pNode) ) - continue; - // stop if all nodes have been tried once - if ( i >= nNodes ) - break; - // compute a reconvergence-driven cut -clk = clock(); - vFanins = Abc_NodeFindCut( pManCut, pNode, fUseDcs ); -pManRef->timeCut += clock() - clk; - // evaluate this cut -clk = clock(); - pFForm = Abc_NodeRefactor( pManRef, pNode, vFanins, fUseZeros, fUseDcs, fVerbose ); -pManRef->timeRes += clock() - clk; - if ( pFForm == NULL ) - continue; - // acceptable replacement found, update the graph -clk = clock(); - Dec_GraphUpdateNetwork( pNode, pFForm, pManRef->nLastGain ); -pManRef->timeNtk += clock() - clk; - Dec_GraphFree( pFForm ); - } - Extra_ProgressBarStop( pProgress ); -pManRef->timeTotal = clock() - clkStart; - - // print statistics of the manager - if ( fVerbose ) - Abc_NtkManRefPrintStats( pManRef ); - // delete the managers - Abc_NtkManCutStop( pManCut ); - Abc_NtkManRefStop( pManRef ); - Abc_NtkStopReverseLevels( pNtk ); - // check - if ( fCheck && !Abc_NtkCheck( pNtk ) ) - { - printf( "Abc_NtkRefactor: The network check has failed.\n" ); - return 0; - } - return 1; -} - -/**Function************************************************************* - - Synopsis [Resynthesizes the node using refactoring.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Dec_Graph_t * Abc_NodeRefactor( Abc_ManRef_t * p, Abc_Obj_t * pNode, Vec_Ptr_t * vFanins, bool fUseZeros, bool fUseDcs, bool fVerbose ) -{ - int fVeryVerbose = 0; - Abc_Obj_t * pFanin; - Dec_Graph_t * pFForm; - DdNode * bNodeFunc; - int nNodesSaved, nNodesAdded, i, clk; - char * pSop; - - p->nNodesConsidered++; - - // get the function of the cut -clk = clock(); - bNodeFunc = Abc_NodeConeBdd( p->dd, p->dd->vars, pNode, vFanins, p->vVisited ); Cudd_Ref( bNodeFunc ); -p->timeBdd += clock() - clk; - - // if don't-care are used, transform the function into ISOP - if ( fUseDcs ) - { - DdNode * bNodeDc, * bNodeOn, * bNodeOnDc; - int nMints, nMintsDc; -clk = clock(); - // get the don't-cares - bNodeDc = Abc_NodeConeDcs( p->dd, p->dd->vars + vFanins->nSize, p->dd->vars, p->vLeaves, vFanins, p->vVisited ); Cudd_Ref( bNodeDc ); - nMints = (1 << vFanins->nSize); - nMintsDc = (int)Cudd_CountMinterm( p->dd, bNodeDc, vFanins->nSize ); -// printf( "Percentage of minterms = %5.2f.\n", 100.0 * nMintsDc / nMints ); - // get the ISF - bNodeOn = Cudd_bddAnd( p->dd, bNodeFunc, Cudd_Not(bNodeDc) ); Cudd_Ref( bNodeOn ); - bNodeOnDc = Cudd_bddOr ( p->dd, bNodeFunc, bNodeDc ); Cudd_Ref( bNodeOnDc ); - Cudd_RecursiveDeref( p->dd, bNodeFunc ); - Cudd_RecursiveDeref( p->dd, bNodeDc ); - // get the ISOP - bNodeFunc = Cudd_bddIsop( p->dd, bNodeOn, bNodeOnDc ); Cudd_Ref( bNodeFunc ); - Cudd_RecursiveDeref( p->dd, bNodeOn ); - Cudd_RecursiveDeref( p->dd, bNodeOnDc ); -p->timeDcs += clock() - clk; - } - - // always accept the case of constant node - if ( Cudd_IsConstant(bNodeFunc) ) - { - p->nLastGain = Abc_NodeMffcSize( pNode ); - p->nNodesGained += p->nLastGain; - p->nNodesRefactored++; - Cudd_RecursiveDeref( p->dd, bNodeFunc ); - if ( Cudd_IsComplement(bNodeFunc) ) - return Dec_GraphCreateConst0(); - return Dec_GraphCreateConst1(); - } - - // get the SOP of the cut -clk = clock(); - pSop = Abc_ConvertBddToSop( NULL, p->dd, bNodeFunc, bNodeFunc, vFanins->nSize, p->vCube, -1 ); -p->timeSop += clock() - clk; - - // get the factored form -clk = clock(); - pFForm = Dec_Factor( pSop ); - free( pSop ); -p->timeFact += clock() - clk; - - // mark the fanin boundary - // (can mark only essential fanins, belonging to bNodeFunc!) - Vec_PtrForEachEntry( vFanins, pFanin, i ) - pFanin->vFanouts.nSize++; - // label MFFC with current traversal ID - Abc_NtkIncrementTravId( pNode->pNtk ); - nNodesSaved = Abc_NodeMffcLabel( pNode ); - // unmark the fanin boundary and set the fanins as leaves in the form - Vec_PtrForEachEntry( vFanins, pFanin, i ) - { - pFanin->vFanouts.nSize--; - Dec_GraphNode(pFForm, i)->pFunc = pFanin; - } - - // detect how many new nodes will be added (while taking into account reused nodes) -clk = clock(); - nNodesAdded = Dec_GraphToNetworkCount( pNode, pFForm, nNodesSaved, Abc_NodeReadRequiredLevel(pNode) ); -p->timeEval += clock() - clk; - // quit if there is no improvement - if ( nNodesAdded == -1 || nNodesAdded == nNodesSaved && !fUseZeros ) - { - Cudd_RecursiveDeref( p->dd, bNodeFunc ); - Dec_GraphFree( pFForm ); - return NULL; - } - - // compute the total gain in the number of nodes - p->nLastGain = nNodesSaved - nNodesAdded; - p->nNodesGained += p->nLastGain; - p->nNodesRefactored++; - - // report the progress - if ( fVeryVerbose ) - { - printf( "Node %6s : ", Abc_ObjName(pNode) ); - printf( "Cone = %2d. ", vFanins->nSize ); - printf( "BDD = %2d. ", Cudd_DagSize(bNodeFunc) ); - printf( "FF = %2d. ", 1 + Dec_GraphNodeNum(pFForm) ); - printf( "MFFC = %2d. ", nNodesSaved ); - printf( "Add = %2d. ", nNodesAdded ); - printf( "GAIN = %2d. ", p->nLastGain ); - printf( "\n" ); - } - Cudd_RecursiveDeref( p->dd, bNodeFunc ); - return pFForm; -} - - -/**Function************************************************************* - - Synopsis [Starts the resynthesis manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_ManRef_t * Abc_NtkManRefStart( int nNodeSizeMax, int nConeSizeMax, bool fUseDcs, bool fVerbose ) -{ - Abc_ManRef_t * p; - p = ALLOC( Abc_ManRef_t, 1 ); - memset( p, 0, sizeof(Abc_ManRef_t) ); - p->vCube = Vec_StrAlloc( 100 ); - p->vVisited = Vec_PtrAlloc( 100 ); - p->nNodeSizeMax = nNodeSizeMax; - p->nConeSizeMax = nConeSizeMax; - p->fVerbose = fVerbose; - // start the BDD manager - if ( fUseDcs ) - p->dd = Cudd_Init( p->nNodeSizeMax + p->nConeSizeMax, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 ); - else - p->dd = Cudd_Init( p->nNodeSizeMax, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 ); - Cudd_zddVarsFromBddVars( p->dd, 2 ); - return p; -} - -/**Function************************************************************* - - Synopsis [Stops the resynthesis manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkManRefStop( Abc_ManRef_t * p ) -{ - Extra_StopManager( p->dd ); - Vec_PtrFree( p->vVisited ); - Vec_StrFree( p->vCube ); - free( p ); -} - -/**Function************************************************************* - - Synopsis [Stops the resynthesis manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkManRefPrintStats( Abc_ManRef_t * p ) -{ - printf( "Refactoring statistics:\n" ); - printf( "Nodes considered = %8d.\n", p->nNodesConsidered ); - printf( "Nodes refactored = %8d.\n", p->nNodesRefactored ); - printf( "Calculated gain = %8d.\n", p->nNodesGained ); - PRT( "Cuts ", p->timeCut ); - PRT( "Resynthesis", p->timeRes ); - PRT( " BDD ", p->timeBdd ); - PRT( " DCs ", p->timeDcs ); - PRT( " SOP ", p->timeSop ); - PRT( " FF ", p->timeFact ); - PRT( " Eval ", p->timeEval ); - PRT( "AIG update ", p->timeNtk ); - PRT( "TOTAL ", p->timeTotal ); -} - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/base/abc/abcRenode.c b/src/base/abc/abcRenode.c deleted file mode 100644 index c77c0d70..00000000 --- a/src/base/abc/abcRenode.c +++ /dev/null @@ -1,609 +0,0 @@ -/**CFile**************************************************************** - - FileName [abcRenode.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Network and node package.] - - Synopsis [Procedures which transform an AIG into the network of nodes.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: abcRenode.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static void Abc_NtkRenodeInt( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ); -static Abc_Obj_t * Abc_NtkRenode_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNodeOld ); - -static DdNode * Abc_NtkRenodeDeriveBdd_rec( DdManager * dd, Abc_Obj_t * pNodeOld, Vec_Ptr_t * vFanins ); - -static void Abc_NtkRenodeSetBounds( Abc_Ntk_t * pNtk, int nThresh, int nFaninMax ); -static void Abc_NtkRenodeSetBoundsCnf( Abc_Ntk_t * pNtk ); -static void Abc_NtkRenodeSetBoundsMulti( Abc_Ntk_t * pNtk, int nThresh ); -static void Abc_NtkRenodeSetBoundsSimple( Abc_Ntk_t * pNtk ); -static void Abc_NtkRenodeCone( Abc_Obj_t * pNode, Vec_Ptr_t * vCone ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Transforms the AIG into nodes.] - - Description [Threhold is the max number of nodes duplicated at a node.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_NtkRenode( Abc_Ntk_t * pNtk, int nThresh, int nFaninMax, int fCnf, int fMulti, int fSimple ) -{ - int fCheck = 1; - Abc_Ntk_t * pNtkNew; - - assert( Abc_NtkIsStrash(pNtk) ); - assert( nThresh >= 0 ); - assert( nFaninMax > 1 ); - - // print a warning about choice nodes - if ( Abc_NtkGetChoiceNum( pNtk ) ) - printf( "Warning: The choice nodes in the AIG are removed by renoding.\n" ); - - // define the boundary - if ( fCnf ) - Abc_NtkRenodeSetBoundsCnf( pNtk ); - else if ( fMulti ) - Abc_NtkRenodeSetBoundsMulti( pNtk, nThresh ); - else if ( fSimple ) - Abc_NtkRenodeSetBoundsSimple( pNtk ); - else - Abc_NtkRenodeSetBounds( pNtk, nThresh, nFaninMax ); - - // perform renoding for this boundary - pNtkNew = Abc_NtkStartFrom( pNtk, ABC_TYPE_LOGIC, ABC_FUNC_BDD ); - Abc_NtkRenodeInt( pNtk, pNtkNew ); - Abc_NtkFinalize( pNtk, pNtkNew ); - - // make the network minimum base - Abc_NtkMinimumBase( pNtkNew ); - - // fix the problem with complemented and duplicated CO edges - Abc_NtkLogicMakeSimpleCos( pNtkNew, 0 ); - - // report the number of CNF objects - if ( fCnf ) - { -// int nClauses = Abc_NtkGetClauseNum(pNtkNew) + 2*Abc_NtkPoNum(pNtkNew) + 2*Abc_NtkLatchNum(pNtkNew); -// printf( "CNF variables = %d. CNF clauses = %d.\n", Abc_NtkNodeNum(pNtkNew), nClauses ); - } -//printf( "Maximum fanin = %d.\n", Abc_NtkGetFaninMax(pNtkNew) ); - - // make sure everything is okay - if ( fCheck && !Abc_NtkCheck( pNtkNew ) ) - { - printf( "Abc_NtkRenode: The network check has failed.\n" ); - Abc_NtkDelete( pNtkNew ); - return NULL; - } - return pNtkNew; -} - -/**Function************************************************************* - - Synopsis [Transforms the AIG into nodes.] - - Description [Threhold is the max number of nodes duplicated at a node.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkRenodeInt( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ) -{ - ProgressBar * pProgress; - Abc_Obj_t * pNode, * pConst1, * pNodeNew; - int i; - - // set the constant node - pConst1 = Abc_AigConst1(pNtk->pManFunc); - if ( Abc_ObjFanoutNum(pConst1) > 0 ) - { - pNodeNew = Abc_NtkCreateNode( pNtkNew ); - pNodeNew->pData = Cudd_ReadOne( pNtkNew->pManFunc ); Cudd_Ref( pNodeNew->pData ); - pConst1->pCopy = pNodeNew; - } - - // perform renoding for POs - pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCoNum(pNtk) ); - Abc_NtkForEachCo( pNtk, pNode, i ) - { - Extra_ProgressBarUpdate( pProgress, i, NULL ); - if ( Abc_ObjIsCi(Abc_ObjFanin0(pNode)) ) - continue; - Abc_NtkRenode_rec( pNtkNew, Abc_ObjFanin0(pNode) ); - } - Extra_ProgressBarStop( pProgress ); - - // clean the boundaries and data field in the old network - Abc_NtkForEachObj( pNtk, pNode, i ) - { - pNode->fMarkA = 0; - pNode->pData = NULL; - } -} - -/**Function************************************************************* - - Synopsis [Find the best multi-input node rooted at the given node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_NtkRenode_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNodeOld ) -{ - Vec_Ptr_t * vCone; - Abc_Obj_t * pNodeNew; - int i; - - assert( !Abc_ObjIsComplement(pNodeOld) ); - // return if the result if known - if ( pNodeOld->pCopy ) - return pNodeOld->pCopy; - assert( Abc_ObjIsNode(pNodeOld) ); - assert( !Abc_NodeIsConst(pNodeOld) ); - assert( pNodeOld->fMarkA ); - - // collect the renoding cone - vCone = Vec_PtrAlloc( 10 ); - Abc_NtkRenodeCone( pNodeOld, vCone ); - - // create a new node - pNodeNew = Abc_NtkCreateNode( pNtkNew ); - for ( i = 0; i < vCone->nSize; i++ ) - Abc_ObjAddFanin( pNodeNew, Abc_NtkRenode_rec(pNtkNew, vCone->pArray[i]) ); - - // derive the function of this node - pNodeNew->pData = Abc_NtkRenodeDeriveBdd( pNtkNew->pManFunc, pNodeOld, vCone ); - Cudd_Ref( pNodeNew->pData ); - Vec_PtrFree( vCone ); - - // remember the node - pNodeOld->pCopy = pNodeNew; - return pNodeOld->pCopy; -} - - -/**Function************************************************************* - - Synopsis [Derives the local BDD of the node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -DdNode * Abc_NtkRenodeDeriveBdd( DdManager * dd, Abc_Obj_t * pNodeOld, Vec_Ptr_t * vFaninsOld ) -{ - Abc_Obj_t * pFaninOld; - DdNode * bFunc; - int i; - assert( !Abc_NodeIsConst(pNodeOld) ); - assert( Abc_ObjIsNode(pNodeOld) ); - // set the elementary BDD variables for the input nodes - for ( i = 0; i < vFaninsOld->nSize; i++ ) - { - pFaninOld = vFaninsOld->pArray[i]; - pFaninOld->pData = Cudd_bddIthVar( dd, i ); Cudd_Ref( pFaninOld->pData ); - pFaninOld->fMarkC = 1; - } - // call the recursive BDD computation - bFunc = Abc_NtkRenodeDeriveBdd_rec( dd, pNodeOld, vFaninsOld ); Cudd_Ref( bFunc ); - // dereference the intermediate nodes - for ( i = 0; i < vFaninsOld->nSize; i++ ) - { - pFaninOld = vFaninsOld->pArray[i]; - Cudd_RecursiveDeref( dd, pFaninOld->pData ); - pFaninOld->fMarkC = 0; - } - Cudd_Deref( bFunc ); - return bFunc; -} - -/**Function************************************************************* - - Synopsis [Derives the local BDD of the node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -DdNode * Abc_NtkRenodeDeriveBdd_rec( DdManager * dd, Abc_Obj_t * pNode, Vec_Ptr_t * vFanins ) -{ - DdNode * bFunc, * bFunc0, * bFunc1; - assert( !Abc_ObjIsComplement(pNode) ); - // if the result is available return - if ( pNode->fMarkC ) - { - assert( pNode->pData ); // network has a cycle - return pNode->pData; - } - // mark the node as visited - pNode->fMarkC = 1; - Vec_PtrPush( vFanins, pNode ); - // compute the result for both branches - bFunc0 = Abc_NtkRenodeDeriveBdd_rec( dd, Abc_ObjFanin(pNode,0), vFanins ); Cudd_Ref( bFunc0 ); - bFunc1 = Abc_NtkRenodeDeriveBdd_rec( dd, Abc_ObjFanin(pNode,1), vFanins ); Cudd_Ref( bFunc1 ); - bFunc0 = Cudd_NotCond( bFunc0, Abc_ObjFaninC0(pNode) ); - bFunc1 = Cudd_NotCond( bFunc1, Abc_ObjFaninC1(pNode) ); - // get the final result - bFunc = Cudd_bddAnd( dd, bFunc0, bFunc1 ); Cudd_Ref( bFunc ); - Cudd_RecursiveDeref( dd, bFunc0 ); - Cudd_RecursiveDeref( dd, bFunc1 ); - // set the result - pNode->pData = bFunc; - assert( pNode->pData ); - return bFunc; -} - - - -/**Function************************************************************* - - Synopsis [Limits the cones to be no more than the given size.] - - Description [Returns 1 if the last cone was limited. Returns 0 if no changes.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkRenodeLimit_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vCone, int nFaninMax, int fCanStop, int fFirst ) -{ - int nNodes0, nNodes1; - assert( !Abc_ObjIsComplement(pNode) ); - // check if the node should be added to the fanins - if ( !fFirst && (pNode->fMarkA || !Abc_ObjIsNode(pNode)) ) - { - Vec_PtrPushUnique( vCone, pNode ); - return 0; - } - // if we cannot stop in this branch, collect all nodes - if ( !fCanStop ) - { - Abc_NtkRenodeLimit_rec( Abc_ObjFanin(pNode,0), vCone, nFaninMax, 0, 0 ); - Abc_NtkRenodeLimit_rec( Abc_ObjFanin(pNode,1), vCone, nFaninMax, 0, 0 ); - return 0; - } - // if we can stop, try the left branch first, and return if we stopped - assert( vCone->nSize == 0 ); - if ( Abc_NtkRenodeLimit_rec( Abc_ObjFanin(pNode,0), vCone, nFaninMax, 1, 0 ) ) - return 1; - // save the number of nodes in the left branch and call for the right branch - nNodes0 = vCone->nSize; - assert( nNodes0 <= nFaninMax ); - Abc_NtkRenodeLimit_rec( Abc_ObjFanin(pNode,1), vCone, nFaninMax, 0, 0 ); - // check the number of nodes - if ( vCone->nSize <= nFaninMax ) - return 0; - // the number of nodes exceeds the limit - - // get the number of nodes in the right branch - vCone->nSize = 0; - Abc_NtkRenodeLimit_rec( Abc_ObjFanin(pNode,1), vCone, nFaninMax, 0, 0 ); - // if this number exceeds the limit, solve the problem for this branch - if ( vCone->nSize > nFaninMax ) - { - int RetValue; - vCone->nSize = 0; - RetValue = Abc_NtkRenodeLimit_rec( Abc_ObjFanin(pNode,1), vCone, nFaninMax, 1, 0 ); - assert( RetValue == 1 ); - return 1; - } - - nNodes1 = vCone->nSize; - assert( nNodes1 <= nFaninMax ); - if ( nNodes0 >= nNodes1 ) - { // the left branch is larger - cut it - assert( Abc_ObjFanin(pNode,0)->fMarkA == 0 ); - Abc_ObjFanin(pNode,0)->fMarkA = 1; - } - else - { // the right branch is larger - cut it - assert( Abc_ObjFanin(pNode,1)->fMarkA == 0 ); - Abc_ObjFanin(pNode,1)->fMarkA = 1; - } - return 1; -} - -/**Function************************************************************* - - Synopsis [Limits the cones to be no more than the given size.] - - Description [Returns 1 if the last cone was limited. Returns 0 if no changes.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkRenodeLimit( Abc_Obj_t * pNode, Vec_Ptr_t * vCone, int nFaninMax ) -{ - vCone->nSize = 0; - return Abc_NtkRenodeLimit_rec( pNode, vCone, nFaninMax, 1, 1 ); -} - -/**Function************************************************************* - - Synopsis [Sets the expansion boundary for multi-input nodes.] - - Description [The boundary includes the set of PIs and all nodes such that - when expanding over the node we duplicate no more than nThresh nodes.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkRenodeSetBounds( Abc_Ntk_t * pNtk, int nThresh, int nFaninMax ) -{ - Vec_Ptr_t * vCone = pNtk->vPtrTemp; - Abc_Obj_t * pNode; - int i, nFanouts, nConeSize; - - // make sure the mark is not set - Abc_NtkForEachObj( pNtk, pNode, i ) - assert( pNode->fMarkA == 0 ); - - // mark the nodes where expansion stops using pNode->fMarkA - Abc_NtkForEachNode( pNtk, pNode, i ) - { - // skip PI/PO nodes - if ( Abc_NodeIsConst(pNode) ) - continue; - // mark the nodes with multiple fanouts - nFanouts = Abc_ObjFanoutNum(pNode); - nConeSize = Abc_NodeMffcSize(pNode); - if ( (nFanouts - 1) * nConeSize > nThresh ) - pNode->fMarkA = 1; - } - - // mark the PO drivers - Abc_NtkForEachCo( pNtk, pNode, i ) - Abc_ObjFanin0(pNode)->fMarkA = 1; - - // make sure the fanin limit is met - Abc_NtkForEachNode( pNtk, pNode, i ) - { - // skip PI/PO nodes - if ( Abc_NodeIsConst(pNode) ) - continue; - if ( pNode->fMarkA == 0 ) - continue; - // continue cutting branches ntil it meets the fanin limit - while ( Abc_NtkRenodeLimit(pNode, vCone, nFaninMax) ); - assert( vCone->nSize <= nFaninMax ); - } -/* - // make sure the fanin limit is met - Abc_NtkForEachNode( pNtk, pNode, i ) - { - // skip PI/PO nodes - if ( Abc_NodeIsConst(pNode) ) - continue; - if ( pNode->fMarkA == 0 ) - continue; - Abc_NtkRenodeCone( pNode, vCone ); - assert( vCone->nSize <= nFaninMax ); - } -*/ -} - -/**Function************************************************************* - - Synopsis [Sets the expansion boundary for conversion into CNF.] - - Description [The boundary includes the set of PIs, the roots of MUXes, - the nodes with multiple fanouts and the nodes with complemented outputs.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkRenodeSetBoundsCnf( Abc_Ntk_t * pNtk ) -{ - Abc_Obj_t * pNode; - int i, nMuxes; - - // make sure the mark is not set - Abc_NtkForEachObj( pNtk, pNode, i ) - assert( pNode->fMarkA == 0 ); - - // mark the nodes where expansion stops using pNode->fMarkA - Abc_NtkForEachNode( pNtk, pNode, i ) - { - // skip PI/PO nodes - if ( Abc_NodeIsConst(pNode) ) - continue; - // mark the nodes with multiple fanouts - if ( Abc_ObjFanoutNum(pNode) > 1 ) - pNode->fMarkA = 1; - // mark the nodes that are roots of MUXes - if ( Abc_NodeIsMuxType( pNode ) ) - { - pNode->fMarkA = 1; - Abc_ObjFanin0( Abc_ObjFanin0(pNode) )->fMarkA = 1; - Abc_ObjFanin0( Abc_ObjFanin1(pNode) )->fMarkA = 1; - Abc_ObjFanin1( Abc_ObjFanin0(pNode) )->fMarkA = 1; - Abc_ObjFanin1( Abc_ObjFanin1(pNode) )->fMarkA = 1; - } - else // mark the complemented edges - { - if ( Abc_ObjFaninC0(pNode) ) - Abc_ObjFanin0(pNode)->fMarkA = 1; - if ( Abc_ObjFaninC1(pNode) ) - Abc_ObjFanin1(pNode)->fMarkA = 1; - } - } - - // mark the PO drivers - Abc_NtkForEachCo( pNtk, pNode, i ) - Abc_ObjFanin0(pNode)->fMarkA = 1; - - // count the number of MUXes - nMuxes = 0; - Abc_NtkForEachNode( pNtk, pNode, i ) - { - // skip PI/PO nodes - if ( Abc_NodeIsConst(pNode) ) - continue; - if ( Abc_NodeIsMuxType(pNode) && - Abc_ObjFanin0(pNode)->fMarkA == 0 && - Abc_ObjFanin1(pNode)->fMarkA == 0 ) - nMuxes++; - } - printf( "The number of MUXes detected = %d (%5.2f %% of logic).\n", nMuxes, 300.0*nMuxes/Abc_NtkNodeNum(pNtk) ); -} - -/**Function************************************************************* - - Synopsis [Sets the expansion boundary for conversion into multi-input AND graph.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkRenodeSetBoundsMulti( Abc_Ntk_t * pNtk, int nThresh ) -{ - Abc_Obj_t * pNode; - int i, nFanouts, nConeSize; - - // make sure the mark is not set - Abc_NtkForEachObj( pNtk, pNode, i ) - assert( pNode->fMarkA == 0 ); - - // mark the nodes where expansion stops using pNode->fMarkA - Abc_NtkForEachNode( pNtk, pNode, i ) - { - // skip PI/PO nodes - if ( Abc_NodeIsConst(pNode) ) - continue; - // mark the nodes with multiple fanouts -// if ( Abc_ObjFanoutNum(pNode) > 1 ) -// pNode->fMarkA = 1; - // mark the nodes with multiple fanouts - nFanouts = Abc_ObjFanoutNum(pNode); - nConeSize = Abc_NodeMffcSizeStop(pNode); - if ( (nFanouts - 1) * nConeSize > nThresh ) - pNode->fMarkA = 1; - // mark the children if they are pointed by the complemented edges - if ( Abc_ObjFaninC0(pNode) ) - Abc_ObjFanin0(pNode)->fMarkA = 1; - if ( Abc_ObjFaninC1(pNode) ) - Abc_ObjFanin1(pNode)->fMarkA = 1; - } - - // mark the PO drivers - Abc_NtkForEachCo( pNtk, pNode, i ) - Abc_ObjFanin0(pNode)->fMarkA = 1; -} - -/**Function************************************************************* - - Synopsis [Sets a simple boundary.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkRenodeSetBoundsSimple( Abc_Ntk_t * pNtk ) -{ - Abc_Obj_t * pNode; - int i; - // make sure the mark is not set - Abc_NtkForEachObj( pNtk, pNode, i ) - assert( pNode->fMarkA == 0 ); - // mark the nodes where expansion stops using pNode->fMarkA - Abc_NtkForEachNode( pNtk, pNode, i ) - pNode->fMarkA = 1; -} - -/**Function************************************************************* - - Synopsis [Collects the fanins of a large node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkRenodeCone_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vCone ) -{ - assert( !Abc_ObjIsComplement(pNode) ); - if ( pNode->fMarkA || !Abc_ObjIsNode(pNode) ) - { - Vec_PtrPushUnique( vCone, pNode ); - return; - } - Abc_NtkRenodeCone_rec( Abc_ObjFanin(pNode,0), vCone ); - Abc_NtkRenodeCone_rec( Abc_ObjFanin(pNode,1), vCone ); -} - -/**Function************************************************************* - - Synopsis [Collects the fanins of a large node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkRenodeCone( Abc_Obj_t * pNode, Vec_Ptr_t * vCone ) -{ - assert( !Abc_ObjIsComplement(pNode) ); - assert( Abc_ObjIsNode(pNode) ); - vCone->nSize = 0; - Abc_NtkRenodeCone_rec( Abc_ObjFanin(pNode,0), vCone ); - Abc_NtkRenodeCone_rec( Abc_ObjFanin(pNode,1), vCone ); -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/base/abc/abcRewrite.c b/src/base/abc/abcRewrite.c deleted file mode 100644 index 75fe1627..00000000 --- a/src/base/abc/abcRewrite.c +++ /dev/null @@ -1,184 +0,0 @@ -/**CFile**************************************************************** - - FileName [abcRes.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Network and node package.] - - Synopsis [Technology-independent resynthesis of the AIG.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: abcRes.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" -#include "rwr.h" -#include "dec.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static Cut_Man_t * Abc_NtkStartCutManForRewrite( Abc_Ntk_t * pNtk, int fDrop ); -static void Abc_NodePrintCuts( Abc_Obj_t * pNode ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Performs incremental rewriting of the AIG.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkRewrite( Abc_Ntk_t * pNtk, int fUseZeros, int fVerbose ) -{ - int fCheck = 1; - int fDrop = 0; - ProgressBar * pProgress; - Cut_Man_t * pManCut; - Rwr_Man_t * pManRwr; - Abc_Obj_t * pNode; - int i, nNodes, nGain; - int clk, clkStart = clock(); - - assert( Abc_NtkIsStrash(pNtk) ); - // cleanup the AIG - Abc_AigCleanup(pNtk->pManFunc); - // start the rewriting manager - pManRwr = Rwr_ManStart( 0 ); - if ( pManRwr == NULL ) - return 0; - Abc_NtkStartReverseLevels( pNtk ); - // start the cut manager -clk = clock(); - pManCut = Abc_NtkStartCutManForRewrite( pNtk, fDrop ); -Rwr_ManAddTimeCuts( pManRwr, clock() - clk ); - pNtk->pManCut = pManCut; - - // resynthesize each node once - nNodes = Abc_NtkObjNumMax(pNtk); - pProgress = Extra_ProgressBarStart( stdout, nNodes ); - Abc_NtkForEachNode( pNtk, pNode, i ) - { - Extra_ProgressBarUpdate( pProgress, i, NULL ); - // stop if all nodes have been tried once - if ( i >= nNodes ) - break; - // skip the constant node - if ( Abc_NodeIsConst(pNode) ) - continue; - // for each cut, try to resynthesize it - nGain = Rwr_NodeRewrite( pManRwr, pManCut, pNode, fUseZeros ); - if ( nGain > 0 || nGain == 0 && fUseZeros ) - { - Dec_Graph_t * pGraph = Rwr_ManReadDecs(pManRwr); - int fCompl = Rwr_ManReadCompl(pManRwr); - // complement the FF if needed - if ( fCompl ) Dec_GraphComplement( pGraph ); - Dec_GraphUpdateNetwork( pNode, pGraph, nGain ); - if ( fCompl ) Dec_GraphComplement( pGraph ); - } - } - Extra_ProgressBarStop( pProgress ); -Rwr_ManAddTimeTotal( pManRwr, clock() - clkStart ); - // print stats - if ( fVerbose ) - Rwr_ManPrintStats( pManRwr ); - // delete the managers - Rwr_ManStop( pManRwr ); - Cut_ManStop( pManCut ); - pNtk->pManCut = NULL; - Abc_NtkStopReverseLevels( pNtk ); - // check - if ( fCheck && !Abc_NtkCheck( pNtk ) ) - { - printf( "Abc_NtkRewrite: The network check has failed.\n" ); - return 0; - } - return 1; -} - - -/**Function************************************************************* - - Synopsis [Starts the cut manager for rewriting.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Cut_Man_t * Abc_NtkStartCutManForRewrite( Abc_Ntk_t * pNtk, int fDrop ) -{ - static Cut_Params_t Params, * pParams = &Params; - Cut_Man_t * pManCut; - Abc_Obj_t * pObj; - int i; - // start the cut manager - memset( pParams, 0, sizeof(Cut_Params_t) ); - pParams->nVarsMax = 4; // the max cut size ("k" of the k-feasible cuts) - pParams->nKeepMax = 250; // the max number of cuts kept at a node - pParams->fTruth = 1; // compute truth tables - pParams->fHash = 1; // hash cuts to detect unique - pParams->fFilter = 0; // filter dominated cuts - pParams->fSeq = 0; // compute sequential cuts - pParams->fDrop = fDrop; // drop cuts on the fly - pParams->fVerbose = 0; // the verbosiness flag - pParams->nIdsMax = Abc_NtkObjNumMax( pNtk ); - pManCut = Cut_ManStart( pParams ); - if ( pParams->fDrop ) - Cut_ManSetFanoutCounts( pManCut, Abc_NtkFanoutCounts(pNtk) ); - // set cuts for PIs - Abc_NtkForEachCi( pNtk, pObj, i ) - if ( Abc_ObjFanoutNum(pObj) > 0 ) - Cut_NodeSetTriv( pManCut, pObj->Id ); - return pManCut; -} - -/**Function************************************************************* - - Synopsis [Prints the cuts at the nodes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NodePrintCuts( Abc_Obj_t * pNode ) -{ - Cut_Cut_t * pCut; - unsigned uTruth; - printf( "\nNode %s\n", Abc_ObjName(pNode) ); - for ( pCut = (Cut_Cut_t *)pNode->pCopy; pCut; pCut = pCut->pNext ) - { - uTruth = pCut->uTruth; - Extra_PrintBinary( stdout, &uTruth, 16 ); - printf( " " ); - Cut_CutPrint( pCut ); - printf( "\n" ); - } -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/base/abc/abcSat.c b/src/base/abc/abcSat.c deleted file mode 100644 index 4fb059e5..00000000 --- a/src/base/abc/abcSat.c +++ /dev/null @@ -1,252 +0,0 @@ -/**CFile**************************************************************** - - FileName [abcSat.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Network and node package.] - - Synopsis [Procedures to solve the miter using the internal SAT solver.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: abcSat.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static void Abc_NodeAddClauses( solver * pSat, char * pSop0, char * pSop1, Abc_Obj_t * pNode, Vec_Int_t * vVars ); -static void Abc_NodeAddClausesTop( solver * pSat, Abc_Obj_t * pNode, Vec_Int_t * vVars ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Attempts to solve the miter using an internal SAT solver.] - - Description [Returns 1 if the miter is SAT.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -bool Abc_NtkMiterSat( Abc_Ntk_t * pNtk, int fVerbose ) -{ - solver * pSat; - lbool status; - int clk; - - assert( Abc_NtkIsBddLogic(pNtk) ); - assert( Abc_NtkLatchNum(pNtk) == 0 ); - - if ( Abc_NtkPoNum(pNtk) > 1 ) - fprintf( stdout, "Warning: The miter has more than 1 output. SAT will try to prove all of them.\n" ); - - // load clauses into the solver - clk = clock(); - pSat = Abc_NtkMiterSatCreate( pNtk ); -// printf( "Created SAT problem with %d variable and %d clauses. ", -// solver_nvars(pSat), solver_nclauses(pSat) ); -// PRT( "Time", clock() - clk ); - - // simplify the problem - clk = clock(); - status = solver_simplify(pSat); -// printf( "Simplified the problem to %d variables and %d clauses. ", -// solver_nvars(pSat), solver_nclauses(pSat) ); -// PRT( "Time", clock() - clk ); - if ( status == l_False ) - { - solver_delete( pSat ); - printf( "The problem is UNSAT after simplification.\n" ); - return 0; - } - - // solve the miter - clk = clock(); - if ( fVerbose ) - pSat->verbosity = 1; - status = solver_solve( pSat, NULL, NULL ); -// if ( fVerbose ) -// { - printf( "The problem is %5s. ", (status == l_True)? "SAT" : "UNSAT" ); - PRT( "SAT solver time", clock() - clk ); -// } - // free the solver - solver_delete( pSat ); - return status == l_True; -} - -/**Function************************************************************* - - Synopsis [Sets up the SAT solver.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -solver * Abc_NtkMiterSatCreate( Abc_Ntk_t * pNtk ) -{ - solver * pSat; - Extra_MmFlex_t * pMmFlex; - Abc_Obj_t * pNode; - Vec_Str_t * vCube; - Vec_Int_t * vVars; - char * pSop0, * pSop1; - int i; - - assert( Abc_NtkIsBddLogic(pNtk) ); - - // start the data structures - pSat = solver_new(); - pMmFlex = Extra_MmFlexStart(); - vCube = Vec_StrAlloc( 100 ); - vVars = Vec_IntAlloc( 100 ); - - // add clauses for each internal nodes - Abc_NtkForEachNode( pNtk, pNode, i ) - { - // derive SOPs for both phases of the node - Abc_NodeBddToCnf( pNode, pMmFlex, vCube, &pSop0, &pSop1 ); - // add the clauses to the solver - Abc_NodeAddClauses( pSat, pSop0, pSop1, pNode, vVars ); - } - // add clauses for each PO - Abc_NtkForEachPo( pNtk, pNode, i ) - Abc_NodeAddClausesTop( pSat, pNode, vVars ); - - // delete - Vec_StrFree( vCube ); - Vec_IntFree( vVars ); - Extra_MmFlexStop( pMmFlex, 0 ); - return pSat; -} - -/**Function************************************************************* - - Synopsis [Adds clauses for the internal node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NodeAddClauses( solver * pSat, char * pSop0, char * pSop1, Abc_Obj_t * pNode, Vec_Int_t * vVars ) -{ - Abc_Obj_t * pFanin; - int i, c, nFanins; - char * pCube; - - nFanins = Abc_ObjFaninNum( pNode ); - assert( nFanins == Abc_SopGetVarNum( pSop0 ) ); - - // add clauses for the negative phase - for ( c = 0; ; c++ ) - { - // get the cube - pCube = pSop0 + c * (nFanins + 3); - if ( *pCube == 0 ) - break; - // add the clause - vVars->nSize = 0; - Abc_ObjForEachFanin( pNode, pFanin, i ) - { - if ( pCube[i] == '0' ) - Vec_IntPush( vVars, toLit(pFanin->Id) ); - else if ( pCube[i] == '1' ) - Vec_IntPush( vVars, neg(toLit(pFanin->Id)) ); - } - Vec_IntPush( vVars, neg(toLit(pNode->Id)) ); - solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize ); - } - - // add clauses for the positive phase - for ( c = 0; ; c++ ) - { - // get the cube - pCube = pSop1 + c * (nFanins + 3); - if ( *pCube == 0 ) - break; - // add the clause - vVars->nSize = 0; - Abc_ObjForEachFanin( pNode, pFanin, i ) - { - if ( pCube[i] == '0' ) - Vec_IntPush( vVars, toLit(pFanin->Id) ); - else if ( pCube[i] == '1' ) - Vec_IntPush( vVars, neg(toLit(pFanin->Id)) ); - } - Vec_IntPush( vVars, toLit(pNode->Id) ); - solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize ); - } -} - -/**Function************************************************************* - - Synopsis [Adds clauses for the PO node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NodeAddClausesTop( solver * pSat, Abc_Obj_t * pNode, Vec_Int_t * vVars ) -{ - Abc_Obj_t * pFanin; - - pFanin = Abc_ObjFanin0(pNode); - if ( Abc_ObjFaninC0(pNode) ) - { - vVars->nSize = 0; - Vec_IntPush( vVars, toLit(pFanin->Id) ); - Vec_IntPush( vVars, toLit(pNode->Id) ); - solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize ); - - vVars->nSize = 0; - Vec_IntPush( vVars, neg(toLit(pFanin->Id)) ); - Vec_IntPush( vVars, neg(toLit(pNode->Id)) ); - solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize ); - } - else - { - vVars->nSize = 0; - Vec_IntPush( vVars, neg(toLit(pFanin->Id)) ); - Vec_IntPush( vVars, toLit(pNode->Id) ); - solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize ); - - vVars->nSize = 0; - Vec_IntPush( vVars, toLit(pFanin->Id) ); - Vec_IntPush( vVars, neg(toLit(pNode->Id)) ); - solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize ); - } - - vVars->nSize = 0; - Vec_IntPush( vVars, toLit(pNode->Id) ); - solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize ); -} - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/base/abc/abcSeq.c b/src/base/abc/abcSeq.c deleted file mode 100644 index d6b1b8e5..00000000 --- a/src/base/abc/abcSeq.c +++ /dev/null @@ -1,644 +0,0 @@ -/**CFile**************************************************************** - - FileName [abcSeq.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: abcSeq.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" - -/* - A sequential network is an AIG whose edges have number-of-latches attributes, - in addition to the complemented attibutes. - - The sets of PIs/POs remain the same as in logic network. - Constant 1 node can only be used as a fanin of a PO node and the reset node. - The reset node produces sequence (01111...). It is used to create the - initialization logic of all latches. - The latches do not have explicit initial state but they are implicitly - reset by the reset node. - -*/ - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static Vec_Int_t * Abc_NtkSeqCountLatches( Abc_Ntk_t * pNtk ); -static void Abc_NodeSeqCountLatches( Abc_Obj_t * pObj, Vec_Int_t * vNumbers ); - -static void Abc_NtkSeqCreateLatches( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ); -static void Abc_NodeSeqCreateLatches( Abc_Obj_t * pObj, int nLatches ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Converts a normal AIG into a sequential AIG.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_NtkAigToSeq( Abc_Ntk_t * pNtk ) -{ - int fCheck = 1; - Abc_Ntk_t * pNtkNew; - Abc_Aig_t * pManNew; - Vec_Ptr_t * vNodes; - Abc_Obj_t * pObj, * pConst, * pFanout, * pFaninNew, * pLatch; - int i, k, fChange, Counter; - - assert( Abc_NtkIsStrash(pNtk) ); - // start the network - pNtkNew = Abc_NtkStartFrom( pNtk, ABC_TYPE_SEQ, ABC_FUNC_AIG ); - pManNew = pNtkNew->pManFunc; - - // set mapping of the constant nodes - Abc_AigConst1(pNtk->pManFunc)->pCopy = Abc_AigConst1( pManNew ); - Abc_AigReset(pNtk->pManFunc)->pCopy = Abc_AigReset( pManNew ); - - // get rid of initial states - Abc_NtkForEachLatch( pNtk, pObj, i ) - { - pObj->pNext = pObj->pCopy; - if ( Abc_LatchIsInit0(pObj) ) - pObj->pCopy = Abc_AigAnd( pManNew, pObj->pCopy, Abc_AigReset(pManNew) ); - else if ( Abc_LatchIsInit1(pObj) ) - pObj->pCopy = Abc_AigOr( pManNew, pObj->pCopy, Abc_ObjNot( Abc_AigReset(pManNew) ) ); - } - - // copy internal nodes - vNodes = Abc_AigDfs( pNtk, 1, 0 ); - Vec_PtrForEachEntry( vNodes, pObj, i ) - if ( Abc_ObjFaninNum(pObj) == 2 ) - pObj->pCopy = Abc_AigAnd( pManNew, Abc_ObjChild0Copy(pObj), Abc_ObjChild1Copy(pObj) ); - Vec_PtrFree( vNodes ); - - // relink the CO nodes - Abc_NtkForEachPo( pNtk, pObj, i ) - Abc_ObjAddFanin( pObj->pCopy, Abc_ObjChild0Copy(pObj) ); - Abc_NtkForEachLatch( pNtk, pObj, i ) - Abc_ObjAddFanin( pObj->pNext, Abc_ObjChild0Copy(pObj) ); - - // propagate constant input latches in the new network - Counter = 0; - fChange = 1; - while ( fChange ) - { - fChange = 0; - Abc_NtkForEachLatch( pNtkNew, pLatch, i ) - { - if ( Abc_ObjFanoutNum(pLatch) == 0 ) - continue; - pFaninNew = Abc_ObjFanin0(pLatch); - if ( Abc_ObjIsCi(pFaninNew) || !Abc_NodeIsConst(pFaninNew) ) - continue; - pConst = Abc_ObjNotCond( Abc_AigConst1(pManNew), Abc_ObjFaninC0(pLatch) ); - Abc_AigReplace( pManNew, pLatch, pConst ); - fChange = 1; - Counter++; - } - } - if ( Counter ) - fprintf( stdout, "Latch sweeping removed %d latches (out of %d).\n", Counter, Abc_NtkLatchNum(pNtk) ); - - // redirect fanouts of each latch to the latch fanins - vNodes = Vec_PtrAlloc( 100 ); - Abc_NtkForEachLatch( pNtkNew, pLatch, i ) - { -//printf( "Latch %s. Fanouts = %d.\n", Abc_ObjName(pLatch), Abc_ObjFanoutNum(pLatch) ); - - Abc_NodeCollectFanouts( pLatch, vNodes ); - Vec_PtrForEachEntry( vNodes, pFanout, k ) - { - if ( Abc_ObjFaninId0(pFanout) == Abc_ObjFaninId1(pFanout)) - printf( " ******* Identical fanins!!! ******* \n" ); - - if ( Abc_ObjFaninId0(pFanout) == (int)pLatch->Id ) - { -// pFaninNew = Abc_ObjNotCond( Abc_ObjChild0(pLatch), Abc_ObjFaninC0(pFanout) ); - pFaninNew = Abc_ObjChild0(pLatch); - Abc_ObjPatchFanin( pFanout, pLatch, pFaninNew ); - Abc_ObjAddFaninL0( pFanout, 1 ); - } - else if ( Abc_ObjFaninId1(pFanout) == (int)pLatch->Id ) - { -// pFaninNew = Abc_ObjNotCond( Abc_ObjChild0(pLatch), Abc_ObjFaninC1(pFanout) ); - pFaninNew = Abc_ObjChild0(pLatch); - Abc_ObjPatchFanin( pFanout, pLatch, pFaninNew ); - Abc_ObjAddFaninL1( pFanout, 1 ); - } - else - assert( 0 ); - } - assert( Abc_ObjFanoutNum(pLatch) == 0 ); - Abc_NtkDeleteObj( pLatch ); - } - Vec_PtrFree( vNodes ); - // get rid of latches altogether -// Abc_NtkForEachLatch( pNtkNew, pObj, i ) -// Abc_NtkDeleteObj( pObj ); - assert( pNtkNew->nLatches == 0 ); - Vec_PtrClear( pNtkNew->vLats ); - Vec_PtrShrink( pNtkNew->vCis, pNtk->nPis ); - Vec_PtrShrink( pNtkNew->vCos, pNtk->nPos ); - -/* -///////////////////////////////////////////// -Abc_NtkForEachNode( pNtkNew, pObj, i ) - if ( !Abc_NodeIsConst(pObj) ) - if ( Abc_ObjFaninL0(pObj) + Abc_ObjFaninL1(pObj) > 20 ) - printf( "(%d,%d) ", Abc_ObjFaninL0(pObj), Abc_ObjFaninL1(pObj) ); -Abc_NtkForEachCo( pNtkNew, pObj, i ) - printf( "(%d) ", Abc_ObjFaninL0(pObj) ); -///////////////////////////////////////////// -printf( "\n" ); -*/ - - if ( pNtk->pExdc ) - fprintf( stdout, "Warning: EXDC is dropped when converting to sequential AIG.\n" ); - if ( fCheck && !Abc_NtkCheck( pNtkNew ) ) - fprintf( stdout, "Abc_NtkAigToSeq(): Network check has failed.\n" ); - return pNtkNew; -} - -/**Function************************************************************* - - Synopsis [Converts a sequential AIG into a logic SOP network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_NtkSeqToLogicSop( Abc_Ntk_t * pNtk ) -{ - int fCheck = 1; - Abc_Ntk_t * pNtkNew; - Abc_Obj_t * pObj, * pFanin, * pFaninNew; - int i, k, c; - assert( Abc_NtkIsSeq(pNtk) ); - // start the network - pNtkNew = Abc_NtkStartFrom( pNtk, ABC_TYPE_LOGIC, ABC_FUNC_SOP ); - // create the constant and reset nodes - Abc_NtkDupConst1( pNtk, pNtkNew ); - Abc_NtkDupReset( pNtk, pNtkNew ); - // duplicate the nodes, create node functions and latches - Abc_NtkForEachNode( pNtk, pObj, i ) - { - if ( Abc_NodeIsConst(pObj) ) - continue; - Abc_NtkDupObj(pNtkNew, pObj); - pObj->pCopy->pData = Abc_SopCreateAnd2( pNtkNew->pManFunc, Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj) ); - } - // create latches for the new nodes - Abc_NtkSeqCreateLatches( pNtk, pNtkNew ); - // connect the objects - Abc_NtkForEachObj( pNtk, pObj, i ) - Abc_ObjForEachFanin( pObj, pFanin, k ) - { - // find the fanin - pFaninNew = pFanin->pCopy; - for ( c = 0; c < Abc_ObjFaninL(pObj, k); c++ ) - pFaninNew = pFaninNew->pCopy; - Abc_ObjAddFanin( pObj->pCopy, pFaninNew ); - } - // set the complemented attributed of CO edges (to be fixed by making simple COs) - Abc_NtkForEachPo( pNtk, pObj, i ) - if ( Abc_ObjFaninC0(pObj) ) - Abc_ObjSetFaninC( pObj->pCopy, 0 ); - // fix the problem with complemented and duplicated CO edges - Abc_NtkLogicMakeSimpleCos( pNtkNew, 0 ); - // duplicate the EXDC network - if ( pNtk->pExdc ) - fprintf( stdout, "Warning: EXDC network is not copied.\n" ); - if ( fCheck && !Abc_NtkCheck( pNtkNew ) ) - fprintf( stdout, "Abc_NtkSeqToLogic(): Network check has failed.\n" ); - return pNtkNew; -} - - - - -/**Function************************************************************* - - Synopsis [Finds max number of latches on the fanout edges of each node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Abc_NtkSeqCountLatches( Abc_Ntk_t * pNtk ) -{ - Vec_Int_t * vNumbers; - Abc_Obj_t * pObj; - int i; - assert( Abc_NtkIsSeq( pNtk ) ); - // start the array of counters - vNumbers = Vec_IntAlloc( 0 ); - Vec_IntFill( vNumbers, Abc_NtkObjNumMax(pNtk), 0 ); - // count for each edge - Abc_NtkForEachObj( pNtk, pObj, i ) - Abc_NodeSeqCountLatches( pObj, vNumbers ); - return vNumbers; -} - -/**Function************************************************************* - - Synopsis [Countes the latch numbers due to the fanins edges of the given node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NodeSeqCountLatches( Abc_Obj_t * pObj, Vec_Int_t * vNumbers ) -{ - Abc_Obj_t * pFanin; - int k, nLatches; - // go through each fanin edge - Abc_ObjForEachFanin( pObj, pFanin, k ) - { - nLatches = Abc_ObjFaninL( pObj, k ); - if ( nLatches == 0 ) - continue; - if ( Vec_IntEntry( vNumbers, pFanin->Id ) < nLatches ) - Vec_IntWriteEntry( vNumbers, pFanin->Id, nLatches ); - } -} - - - -/**Function************************************************************* - - Synopsis [Creates latches.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkSeqCreateLatches( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ) -{ - Vec_Int_t * vNumbers; - Abc_Obj_t * pObj; - int i; - assert( Abc_NtkIsSeq( pNtk ) ); - // create latches for each new object according to the counters - vNumbers = Abc_NtkSeqCountLatches( pNtk ); - Abc_NtkForEachObj( pNtk, pObj, i ) - { - if ( pObj->pCopy == NULL ) - continue; - Abc_NodeSeqCreateLatches( pObj->pCopy, Vec_IntEntry(vNumbers, (int)pObj->Id) ); - } - Vec_IntFree( vNumbers ); - // add latch to the PI/PO lists, create latch names - Abc_NtkFinalizeLatches( pNtkNew ); -} - -/**Function************************************************************* - - Synopsis [Creates the given number of latches for this object.] - - Description [The latches are attached to the node and to each other - through the pCopy field.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NodeSeqCreateLatches( Abc_Obj_t * pObj, int nLatches ) -{ - Abc_Ntk_t * pNtk = pObj->pNtk; - Abc_Obj_t * pLatch, * pFanin; - int i; - pFanin = pObj; - for ( i = 0, pFanin = pObj; i < nLatches; pFanin = pLatch, i++ ) - { - pLatch = Abc_NtkCreateLatch( pNtk ); - Abc_LatchSetInitDc(pLatch); - Abc_ObjAddFanin( pLatch, pFanin ); - pFanin->pCopy = pLatch; - } -} - -/**Function************************************************************* - - Synopsis [Counters the number of latches in the sequential AIG.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkSeqLatchNum( Abc_Ntk_t * pNtk ) -{ - Vec_Int_t * vNumbers; - Abc_Obj_t * pObj; - int i, Counter; - assert( Abc_NtkIsSeq( pNtk ) ); - // create latches for each new object according to the counters - Counter = 0; - vNumbers = Abc_NtkSeqCountLatches( pNtk ); - Abc_NtkForEachPi( pNtk, pObj, i ) - { - assert( Abc_ObjFanoutLMax(pObj) == Vec_IntEntry(vNumbers, (int)pObj->Id) ); - Counter += Vec_IntEntry(vNumbers, (int)pObj->Id); - } - Abc_NtkForEachNode( pNtk, pObj, i ) - { - if ( Abc_NodeIsConst(pObj) ) - continue; - assert( Abc_ObjFanoutLMax(pObj) == Vec_IntEntry(vNumbers, (int)pObj->Id) ); - Counter += Vec_IntEntry(vNumbers, (int)pObj->Id); - } - Vec_IntFree( vNumbers ); - if ( Abc_ObjFanoutNum( Abc_AigReset(pNtk->pManFunc) ) > 0 ) - Counter++; - return Counter; -} - - - - - - -/**Function************************************************************* - - Synopsis [Performs forward retiming of the sequential AIG.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkSeqRetimeForward( Abc_Ntk_t * pNtk ) -{ - Vec_Ptr_t * vNodes; - Abc_Obj_t * pNode, * pFanout; - int i, k, nLatches; - assert( Abc_NtkIsSeq( pNtk ) ); - // assume that all nodes can be retimed - vNodes = Vec_PtrAlloc( 100 ); - Abc_NtkForEachNode( pNtk, pNode, i ) - { - if ( Abc_NodeIsConst(pNode) ) - continue; - Vec_PtrPush( vNodes, pNode ); - pNode->fMarkA = 1; - } - // process the nodes - Vec_PtrForEachEntry( vNodes, pNode, i ) - { -// printf( "(%d,%d) ", Abc_ObjFaninL0(pNode), Abc_ObjFaninL0(pNode) ); - // get the number of latches to retime - nLatches = Abc_ObjFaninLMin(pNode); - if ( nLatches == 0 ) - continue; - assert( nLatches > 0 ); - // subtract these latches on the fanin side - Abc_ObjAddFaninL0( pNode, -nLatches ); - Abc_ObjAddFaninL1( pNode, -nLatches ); - // add these latches on the fanout size - Abc_ObjForEachFanout( pNode, pFanout, k ) - { - Abc_ObjAddFanoutL( pNode, pFanout, nLatches ); - if ( pFanout->fMarkA == 0 ) - { // schedule the node for updating - Vec_PtrPush( vNodes, pFanout ); - pFanout->fMarkA = 1; - } - } - // unmark the node as processed - pNode->fMarkA = 0; - } - Vec_PtrFree( vNodes ); - // clean the marks - Abc_NtkForEachNode( pNtk, pNode, i ) - { - pNode->fMarkA = 0; - if ( Abc_NodeIsConst(pNode) ) - continue; - assert( Abc_ObjFaninLMin(pNode) == 0 ); - } -} - -/**Function************************************************************* - - Synopsis [Performs forward retiming of the sequential AIG.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkSeqRetimeBackward( Abc_Ntk_t * pNtk ) -{ - Vec_Ptr_t * vNodes; - Abc_Obj_t * pNode, * pFanin, * pFanout; - int i, k, nLatches; - assert( Abc_NtkIsSeq( pNtk ) ); - // assume that all nodes can be retimed - vNodes = Vec_PtrAlloc( 100 ); - Abc_NtkForEachNode( pNtk, pNode, i ) - { - if ( Abc_NodeIsConst(pNode) ) - continue; - Vec_PtrPush( vNodes, pNode ); - pNode->fMarkA = 1; - } - // process the nodes - Vec_PtrForEachEntry( vNodes, pNode, i ) - { - // get the number of latches to retime - nLatches = Abc_ObjFanoutLMin(pNode); - if ( nLatches == 0 ) - continue; - assert( nLatches > 0 ); - // subtract these latches on the fanout side - Abc_ObjForEachFanout( pNode, pFanout, k ) - Abc_ObjAddFanoutL( pNode, pFanout, -nLatches ); - // add these latches on the fanin size - Abc_ObjForEachFanin( pNode, pFanin, k ) - { - Abc_ObjAddFaninL( pNode, k, nLatches ); - if ( Abc_ObjIsPi(pFanin) || Abc_NodeIsConst(pFanin) ) - continue; - if ( pFanin->fMarkA == 0 ) - { // schedule the node for updating - Vec_PtrPush( vNodes, pFanin ); - pFanin->fMarkA = 1; - } - } - // unmark the node as processed - pNode->fMarkA = 0; - } - Vec_PtrFree( vNodes ); - // clean the marks - Abc_NtkForEachNode( pNtk, pNode, i ) - { - pNode->fMarkA = 0; - if ( Abc_NodeIsConst(pNode) ) - continue; -// assert( Abc_ObjFanoutLMin(pNode) == 0 ); - } -} - - - - -/**Function************************************************************* - - Synopsis [Returns the latch number of the fanout.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_ObjFanoutL( Abc_Obj_t * pObj, Abc_Obj_t * pFanout ) -{ - assert( Abc_NtkIsSeq(pObj->pNtk) ); - if ( Abc_ObjFaninId0(pFanout) == (int)pObj->Id ) - return Abc_ObjFaninL0(pFanout); - else if ( Abc_ObjFaninId1(pFanout) == (int)pObj->Id ) - return Abc_ObjFaninL1(pFanout); - else - assert( 0 ); - return 0; -} - -/**Function************************************************************* - - Synopsis [Sets the latch number of the fanout.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_ObjSetFanoutL( Abc_Obj_t * pObj, Abc_Obj_t * pFanout, int nLats ) -{ - assert( Abc_NtkIsSeq(pObj->pNtk) ); - if ( Abc_ObjFaninId0(pFanout) == (int)pObj->Id ) - Abc_ObjSetFaninL0(pFanout, nLats); - else if ( Abc_ObjFaninId1(pFanout) == (int)pObj->Id ) - Abc_ObjSetFaninL1(pFanout, nLats); - else - assert( 0 ); -} - -/**Function************************************************************* - - Synopsis [Adds to the latch number of the fanout.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_ObjAddFanoutL( Abc_Obj_t * pObj, Abc_Obj_t * pFanout, int nLats ) -{ - assert( Abc_NtkIsSeq(pObj->pNtk) ); - if ( Abc_ObjFaninId0(pFanout) == (int)pObj->Id ) - Abc_ObjAddFaninL0(pFanout, nLats); - else if ( Abc_ObjFaninId1(pFanout) == (int)pObj->Id ) - Abc_ObjAddFaninL1(pFanout, nLats); - else - assert( 0 ); -} - -/**Function************************************************************* - - Synopsis [Returns the latch number of the fanout.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_ObjFanoutLMax( Abc_Obj_t * pObj ) -{ - Abc_Obj_t * pFanout; - int i, nLatch, nLatchRes; - nLatchRes = 0; - Abc_ObjForEachFanout( pObj, pFanout, i ) - if ( nLatchRes < (nLatch = Abc_ObjFanoutL(pObj, pFanout)) ) - nLatchRes = nLatch; - assert( nLatchRes >= 0 ); - return nLatchRes; -} - -/**Function************************************************************* - - Synopsis [Returns the latch number of the fanout.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_ObjFanoutLMin( Abc_Obj_t * pObj ) -{ - Abc_Obj_t * pFanout; - int i, nLatch, nLatchRes; - nLatchRes = ABC_INFINITY; - Abc_ObjForEachFanout( pObj, pFanout, i ) - if ( nLatchRes > (nLatch = Abc_ObjFanoutL(pObj, pFanout)) ) - nLatchRes = nLatch; - assert( nLatchRes < ABC_INFINITY ); - return nLatchRes; -} - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/base/abc/abcSeqRetime.c b/src/base/abc/abcSeqRetime.c deleted file mode 100644 index 13b8a926..00000000 --- a/src/base/abc/abcSeqRetime.c +++ /dev/null @@ -1,203 +0,0 @@ -/**CFile**************************************************************** - - FileName [abcSeqRetime.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Network and node package.] - - Synopsis [Peforms retiming for optimal clock cycle.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: abcSeqRetime.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -// storing arrival times in the nodes -static inline int Abc_NodeReadLValue( Abc_Obj_t * pNode ) { return Vec_IntEntry( (pNode)->pNtk->pData, (pNode)->Id ); } -static inline void Abc_NodeSetLValue( Abc_Obj_t * pNode, int Value ) { Vec_IntWriteEntry( (pNode)->pNtk->pData, (pNode)->Id, (Value) ); } - -// the internal procedures -static int Abc_NtkRetimeSearch_rec( Abc_Ntk_t * pNtk, int FiMin, int FiMax ); -static int Abc_NtkRetimeForPeriod( Abc_Ntk_t * pNtk, int Fi ); -static int Abc_NodeUpdateLValue( Abc_Obj_t * pObj, int Fi ); - -// node status after updating its arrival time -enum { ABC_UPDATE_FAIL, ABC_UPDATE_NO, ABC_UPDATE_YES }; - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Retimes AIG for optimal delay.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkSeqRetimeDelay( Abc_Ntk_t * pNtk ) -{ - int FiMax, FiBest; - assert( Abc_NtkIsSeq( pNtk ) ); - - // start storage for sequential arrival times - assert( pNtk->pData == NULL ); - pNtk->pData = Vec_IntAlloc( 0 ); - - // get the maximum possible clock - FiMax = Abc_NtkNodeNum(pNtk); - - // make sure this clock period is feasible - assert( Abc_NtkRetimeForPeriod( pNtk, FiMax ) ); - - // search for the optimal clock period between 0 and nLevelMax - FiBest = Abc_NtkRetimeSearch_rec( pNtk, 0, FiMax ); - // print the result - printf( "The best clock period is %3d.\n", FiBest ); - - // free storage - Vec_IntFree( pNtk->pData ); - pNtk->pData = NULL; -} - -/**Function************************************************************* - - Synopsis [Performs binary search for the optimal clock period.] - - Description [Assumes that FiMin is infeasible while FiMax is feasible.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkRetimeSearch_rec( Abc_Ntk_t * pNtk, int FiMin, int FiMax ) -{ - int Median; - - assert( FiMin < FiMax ); - if ( FiMin + 1 == FiMax ) - return FiMax; - - Median = FiMin + (FiMax - FiMin)/2; - - if ( Abc_NtkRetimeForPeriod( pNtk, Median ) ) - return Abc_NtkRetimeSearch_rec( pNtk, FiMin, Median ); // Median is feasible - else - return Abc_NtkRetimeSearch_rec( pNtk, Median, FiMax ); // Median is infeasible -} - -/**Function************************************************************* - - Synopsis [Returns 1 if retiming with this clock period is feasible.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkRetimeForPeriod( Abc_Ntk_t * pNtk, int Fi ) -{ - Vec_Ptr_t * vFrontier; - Abc_Obj_t * pObj, * pFanout; - int RetValue, i, k; - - // set l-values of all nodes to be minus infinity - Vec_IntFill( pNtk->pData, Abc_NtkObjNumMax(pNtk), -ABC_INFINITY ); - - // start the frontier by including PI fanouts - vFrontier = Vec_PtrAlloc( 100 ); - Abc_NtkForEachPi( pNtk, pObj, i ) - { - Abc_NodeSetLValue( pObj, 0 ); - Abc_ObjForEachFanout( pObj, pFanout, k ) - if ( pFanout->fMarkA == 0 ) - { - Vec_PtrPush( vFrontier, pFanout ); - pFanout->fMarkA = 1; - } - } - - // iterate until convergence - Vec_PtrForEachEntry( vFrontier, pObj, i ) - { - RetValue = Abc_NodeUpdateLValue( pObj, Fi ); - if ( RetValue == ABC_UPDATE_FAIL ) - break; - // unmark the node as processed - pObj->fMarkA = 0; - if ( RetValue == ABC_UPDATE_NO ) - continue; - assert( RetValue == ABC_UPDATE_YES ); - // arrival times have changed - add fanouts to the frontier - Abc_ObjForEachFanout( pObj, pFanout, k ) - if ( pFanout->fMarkA == 0 ) - { - Vec_PtrPush( vFrontier, pFanout ); - pFanout->fMarkA = 1; - } - } - // clean the nodes - Vec_PtrForEachEntryStart( vFrontier, pObj, k, i ) - pObj->fMarkA = 0; - - // report the results - if ( RetValue == ABC_UPDATE_FAIL ) - printf( "Period = %3d. Updated nodes = %6d. Infeasible\n", Fi, vFrontier->nSize ); - else - printf( "Period = %3d. Updated nodes = %6d. Feasible\n", Fi, vFrontier->nSize ); - Vec_PtrFree( vFrontier ); - return RetValue != ABC_UPDATE_FAIL; -} - -/**Function************************************************************* - - Synopsis [Computes the l-value of the node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NodeUpdateLValue( Abc_Obj_t * pObj, int Fi ) -{ - int lValueNew, lValue0, lValue1; - assert( !Abc_ObjIsPi(pObj) ); - lValue0 = Abc_NodeReadLValue(Abc_ObjFanin0(pObj)) - Fi * Abc_ObjFaninL0(pObj); - if ( Abc_ObjFaninNum(pObj) == 2 ) - lValue1 = Abc_NodeReadLValue(Abc_ObjFanin1(pObj)) - Fi * Abc_ObjFaninL1(pObj); - else - lValue1 = -ABC_INFINITY; - lValueNew = 1 + ABC_MAX( lValue0, lValue1 ); - if ( Abc_ObjIsPo(pObj) && lValueNew > Fi ) - return ABC_UPDATE_FAIL; - if ( lValueNew == Abc_NodeReadLValue(pObj) ) - return ABC_UPDATE_NO; - Abc_NodeSetLValue( pObj, lValueNew ); - return ABC_UPDATE_YES; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - diff --git a/src/base/abc/abcStrash.c b/src/base/abc/abcStrash.c deleted file mode 100644 index 935f1300..00000000 --- a/src/base/abc/abcStrash.c +++ /dev/null @@ -1,287 +0,0 @@ -/**CFile**************************************************************** - - FileName [aigStrash.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Network and node package.] - - Synopsis [Strashing of the current network.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: aigStrash.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" -#include "extra.h" -#include "dec.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -// static functions -static void Abc_NtkStrashPerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkAig, bool fAllNodes ); -static Abc_Obj_t * Abc_NodeStrashSop( Abc_Aig_t * pMan, Abc_Obj_t * pNode, char * pSop ); -static Abc_Obj_t * Abc_NodeStrashFactor( Abc_Aig_t * pMan, Abc_Obj_t * pNode, char * pSop ); - -extern char * Mio_GateReadSop( void * pGate ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Creates the strashed AIG network.] - - Description [Converts the logic network or the AIG into a - structurally hashed AIG.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_NtkStrash( Abc_Ntk_t * pNtk, bool fAllNodes, bool fCleanup ) -{ - int fCheck = 1; - Abc_Ntk_t * pNtkAig; - int nNodes; - - assert( !Abc_NtkIsNetlist(pNtk) ); - if ( Abc_NtkIsBddLogic(pNtk) ) - Abc_NtkBddToSop(pNtk); - // print warning about choice nodes - if ( Abc_NtkGetChoiceNum( pNtk ) ) - printf( "Warning: The choice nodes in the initial AIG are removed by strashing.\n" ); - // perform strashing - pNtkAig = Abc_NtkStartFrom( pNtk, ABC_TYPE_STRASH, ABC_FUNC_AIG ); - Abc_NtkStrashPerform( pNtk, pNtkAig, fAllNodes ); - Abc_NtkFinalize( pNtk, pNtkAig ); - // print warning about self-feed latches - if ( Abc_NtkCountSelfFeedLatches(pNtkAig) ) - printf( "The network has %d self-feeding latches.\n", Abc_NtkCountSelfFeedLatches(pNtkAig) ); - if ( fCleanup && (nNodes = Abc_AigCleanup(pNtkAig->pManFunc)) ) - printf( "Cleanup has removed %d nodes.\n", nNodes ); - // duplicate EXDC - if ( pNtk->pExdc ) - pNtkAig->pExdc = Abc_NtkStrash( pNtk->pExdc, 0, 1 ); - // make sure everything is okay - if ( fCheck && !Abc_NtkCheck( pNtkAig ) ) - { - printf( "Abc_NtkStrash: The network check has failed.\n" ); - Abc_NtkDelete( pNtkAig ); - return NULL; - } - return pNtkAig; -} - -/**Function************************************************************* - - Synopsis [Appends the second network to the first.] - - Description [Modifies the first network by adding the logic of the second. - Performs structural hashing while appending the networks. Does not add - the COs of the second. Does not change the second network. Returns 0 - if the appending failed, 1 otherise.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkAppend( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2 ) -{ - int fCheck = 1; - Abc_Obj_t * pObj; - int i; - // the first network should be an AIG - assert( Abc_NtkIsStrash(pNtk1) ); - assert( Abc_NtkIsLogic(pNtk2) || Abc_NtkIsStrash(pNtk2) ); - if ( Abc_NtkIsBddLogic(pNtk2) ) - Abc_NtkBddToSop(pNtk2); - // check that the networks have the same PIs - // reorder PIs of pNtk2 according to pNtk1 - if ( !Abc_NtkCompareSignals( pNtk1, pNtk2, 1 ) ) - return 0; - // perform strashing - Abc_NtkCleanCopy( pNtk2 ); - Abc_NtkForEachCi( pNtk2, pObj, i ) - pObj->pCopy = Abc_NtkCi(pNtk1, i); - // add pNtk2 to pNtk1 while strashing - Abc_NtkStrashPerform( pNtk2, pNtk1, 1 ); - // make sure that everything is okay - if ( fCheck && !Abc_NtkCheck( pNtk1 ) ) - { - printf( "Abc_NtkAppend: The network check has failed.\n" ); - return 0; - } - return 1; -} - - -/**Function************************************************************* - - Synopsis [Prepares the network for strashing.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkStrashPerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew, bool fAllNodes ) -{ - ProgressBar * pProgress; - Abc_Aig_t * pMan = pNtkNew->pManFunc; - Vec_Ptr_t * vNodes; - Abc_Obj_t * pNode, * pNodeNew, * pObj; - int i; - - // perform strashing - vNodes = Abc_NtkDfs( pNtk, fAllNodes ); - pProgress = Extra_ProgressBarStart( stdout, vNodes->nSize ); - Vec_PtrForEachEntry( vNodes, pNode, i ) - { - Extra_ProgressBarUpdate( pProgress, i, NULL ); - // get the node - assert( Abc_ObjIsNode(pNode) ); - // strash the node - pNodeNew = Abc_NodeStrash( pMan, pNode ); - // get the old object - pObj = Abc_ObjFanout0Ntk( pNode ); - // make sure the node is not yet strashed - assert( pObj->pCopy == NULL ); - // mark the old object with the new AIG node - pObj->pCopy = pNodeNew; - } - Vec_PtrFree( vNodes ); - Extra_ProgressBarStop( pProgress ); -} - -/**Function************************************************************* - - Synopsis [Strashes one logic node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_NodeStrash( Abc_Aig_t * pMan, Abc_Obj_t * pNode ) -{ - int fUseFactor = 1; - char * pSop; - - assert( Abc_ObjIsNode(pNode) ); - - // consider the case when the graph is an AIG - if ( Abc_NtkIsStrash(pNode->pNtk) ) - { - if ( Abc_NodeIsConst(pNode) ) - return Abc_AigConst1(pMan); - return Abc_AigAnd( pMan, Abc_ObjChild0Copy(pNode), Abc_ObjChild1Copy(pNode) ); - } - - // get the SOP of the node - if ( Abc_NtkHasMapping(pNode->pNtk) ) - pSop = Mio_GateReadSop(pNode->pData); - else - pSop = pNode->pData; - - // consider the constant node - if ( Abc_NodeIsConst(pNode) ) - return Abc_ObjNotCond( Abc_AigConst1(pMan), Abc_SopIsConst0(pSop) ); - - // decide when to use factoring - if ( fUseFactor && Abc_ObjFaninNum(pNode) > 2 && Abc_SopGetCubeNum(pSop) > 1 ) - return Abc_NodeStrashFactor( pMan, pNode, pSop ); - return Abc_NodeStrashSop( pMan, pNode, pSop ); -} - -/**Function************************************************************* - - Synopsis [Strashes one logic node using its SOP.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_NodeStrashSop( Abc_Aig_t * pMan, Abc_Obj_t * pNode, char * pSop ) -{ - Abc_Obj_t * pFanin, * pAnd, * pSum; - Abc_Obj_t * pConst1 = Abc_AigConst1(pMan); - char * pCube; - int i, nFanins; - - // get the number of node's fanins - nFanins = Abc_ObjFaninNum( pNode ); - assert( nFanins == Abc_SopGetVarNum(pSop) ); - // go through the cubes of the node's SOP - pSum = Abc_ObjNot(pConst1); - Abc_SopForEachCube( pSop, nFanins, pCube ) - { - // create the AND of literals - pAnd = pConst1; - Abc_ObjForEachFanin( pNode, pFanin, i ) // pFanin can be a net - { - if ( pCube[i] == '1' ) - pAnd = Abc_AigAnd( pMan, pAnd, pFanin->pCopy ); - else if ( pCube[i] == '0' ) - pAnd = Abc_AigAnd( pMan, pAnd, Abc_ObjNot(pFanin->pCopy) ); - } - // add to the sum of cubes - pSum = Abc_AigOr( pMan, pSum, pAnd ); - } - // decide whether to complement the result - if ( Abc_SopIsComplement(pSop) ) - pSum = Abc_ObjNot(pSum); - return pSum; -} - -/**Function************************************************************* - - Synopsis [Strashes one logic node using its SOP.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_NodeStrashFactor( Abc_Aig_t * pMan, Abc_Obj_t * pRoot, char * pSop ) -{ - Dec_Graph_t * pFForm; - Dec_Node_t * pNode; - Abc_Obj_t * pAnd; - int i; - // perform factoring - pFForm = Dec_Factor( pSop ); - // collect the fanins - Dec_GraphForEachLeaf( pFForm, pNode, i ) - pNode->pFunc = Abc_ObjFanin(pRoot,i)->pCopy; - // perform strashing - pAnd = Dec_GraphToNetwork( pMan, pFForm ); - Dec_GraphFree( pFForm ); - return pAnd; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/base/abc/abcSweep.c b/src/base/abc/abcSweep.c deleted file mode 100644 index ca9bd34e..00000000 --- a/src/base/abc/abcSweep.c +++ /dev/null @@ -1,607 +0,0 @@ -/**CFile**************************************************************** - - FileName [abcDsd.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Network and node package.] - - Synopsis [Technology dependent sweep.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: abcDsd.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" -#include "fraig.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -extern Fraig_Man_t * Abc_NtkToFraig( Abc_Ntk_t * pNtk, Fraig_Params_t * pParams, int fAllNodes ); - -static stmm_table * Abc_NtkFraigEquiv( Fraig_Man_t * p, Abc_Ntk_t * pNtk, int fUseInv, bool fVerbose ); -static void Abc_NtkFraigTransform( Abc_Ntk_t * pNtk, stmm_table * tEquiv, int fUseInv, bool fVerbose ); -static void Abc_NtkFraigMergeClassMapped( Abc_Ntk_t * pNtk, Abc_Obj_t * pChain, int fVerbose, int fUseInv ); -static void Abc_NtkFraigMergeClass( Abc_Ntk_t * pNtk, Abc_Obj_t * pChain, int fVerbose, int fUseInv ); -static int Abc_NodeDroppingCost( Abc_Obj_t * pNode ); - -static void Abc_NodeSweep( Abc_Obj_t * pNode, int fVerbose ); -static void Abc_NodeConstantInput( Abc_Obj_t * pNode, Abc_Obj_t * pFanin, bool fConst0 ); -static void Abc_NodeComplementInput( Abc_Obj_t * pNode, Abc_Obj_t * pFanin ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Sweping functionally equivalence nodes.] - - Description [Removes gates with equivalent functionality. Works for - both technology-independent and mapped networks. If the flag is set, - allows adding inverters at the gate outputs.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -bool Abc_NtkFraigSweep( Abc_Ntk_t * pNtk, int fUseInv, int fVerbose ) -{ - int fCheck = 1; - Fraig_Params_t Params; - Abc_Ntk_t * pNtkAig; - Fraig_Man_t * pMan; - stmm_table * tEquiv; - - assert( !Abc_NtkIsStrash(pNtk) ); - - // derive the AIG - pNtkAig = Abc_NtkStrash( pNtk, 0, 1 ); - // perform fraiging of the AIG - Fraig_ParamsSetDefault( &Params ); - pMan = Abc_NtkToFraig( pNtkAig, &Params, 0 ); - // collect the classes of equivalent nets - tEquiv = Abc_NtkFraigEquiv( pMan, pNtk, fUseInv, fVerbose ); - - // transform the network into the equivalent one - Abc_NtkFraigTransform( pNtk, tEquiv, fUseInv, fVerbose ); - stmm_free_table( tEquiv ); - - // free the manager - Fraig_ManFree( pMan ); - Abc_NtkDelete( pNtkAig ); - - // cleanup the dangling nodes - Abc_NtkCleanup( pNtk, fVerbose ); - // check - if ( fCheck && !Abc_NtkCheck( pNtk ) ) - { - printf( "Abc_NtkFraigSweep: The network check has failed.\n" ); - return 0; - } - return 1; -} - -/**Function************************************************************* - - Synopsis [Collects equivalence classses of node in the network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -stmm_table * Abc_NtkFraigEquiv( Fraig_Man_t * p, Abc_Ntk_t * pNtk, int fUseInv, bool fVerbose ) -{ - Abc_Obj_t * pList, * pNode, * pNodeAig; - Fraig_Node_t * gNode; - Abc_Obj_t ** ppSlot; - stmm_table * tStrash2Net; - stmm_table * tResult; - stmm_generator * gen; - int c, Counter; - - // create mapping of strashed nodes into the corresponding network nodes - tStrash2Net = stmm_init_table(stmm_ptrcmp,stmm_ptrhash); - Abc_NtkForEachNode( pNtk, pNode, c ) - { - // get the strashed node - pNodeAig = pNode->pCopy; - // skip the dangling nodes - if ( pNodeAig == NULL ) - continue; - // skip the constant input nodes - if ( Abc_ObjFaninNum(pNode) == 0 ) - continue; - // skip the nodes that fanout into POs - if ( Abc_NodeHasUniqueCoFanout(pNode) ) - continue; - // get the FRAIG node - gNode = Fraig_NotCond( Abc_ObjRegular(pNodeAig)->pCopy, Abc_ObjIsComplement(pNodeAig) ); - if ( !stmm_find_or_add( tStrash2Net, (char *)Fraig_Regular(gNode), (char ***)&ppSlot ) ) - *ppSlot = NULL; - // add the node to the list - pNode->pNext = *ppSlot; - *ppSlot = pNode; - // mark the node if it is complemented - pNode->fPhase = Fraig_IsComplement(gNode); - } - - // print the classes - c = 0; - Counter = 0; - tResult = stmm_init_table(stmm_ptrcmp,stmm_ptrhash); - stmm_foreach_item( tStrash2Net, gen, (char **)&gNode, (char **)&pList ) - { - // skip the trival classes - if ( pList == NULL || pList->pNext == NULL ) - continue; - // add the non-trival class - stmm_insert( tResult, (char *)pList, NULL ); - // count nodes in the non-trival classes - for ( pNode = pList; pNode; pNode = pNode->pNext ) - Counter++; -/* - if ( fVerbose ) - { - printf( "Class %2d : {", c ); - for ( pNode = pList; pNode; pNode = pNode->pNext ) - { - pNode->pCopy = NULL; - printf( " %s", Abc_ObjName(pNode) ); - if ( pNode->fPhase ) printf( "(*)" ); - } - printf( " }\n" ); - c++; - } -*/ - } - if ( fVerbose ) - { - printf( "Sweeping stats for network \"%s\":\n", pNtk->pName ); - printf( "Internal nodes = %d. Different functions (up to compl) = %d.\n", Abc_NtkNodeNum(pNtk), stmm_count(tStrash2Net) ); - printf( "Non-trivial classes = %d. Nodes in non-trivial classes = %d.\n", stmm_count(tResult), Counter ); - } - stmm_free_table( tStrash2Net ); - return tResult; -} - - -/**Function************************************************************* - - Synopsis [Transforms the network using the equivalence relation on nodes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkFraigTransform( Abc_Ntk_t * pNtk, stmm_table * tEquiv, int fUseInv, bool fVerbose ) -{ - stmm_generator * gen; - Abc_Obj_t * pList; - if ( stmm_count(tEquiv) == 0 ) - return; - // assign levels to the nodes of the network - Abc_NtkGetLevelNum( pNtk ); - // merge nodes in the classes - if ( Abc_NtkHasMapping( pNtk ) ) - { - Abc_NtkDelayTrace( pNtk ); - stmm_foreach_item( tEquiv, gen, (char **)&pList, NULL ) - Abc_NtkFraigMergeClassMapped( pNtk, pList, fUseInv, fVerbose ); - } - else - { - stmm_foreach_item( tEquiv, gen, (char **)&pList, NULL ) - Abc_NtkFraigMergeClass( pNtk, pList, fUseInv, fVerbose ); - } -} - - -/**Function************************************************************* - - Synopsis [Transforms the list of one-phase equivalent nodes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkFraigMergeClassMapped( Abc_Ntk_t * pNtk, Abc_Obj_t * pChain, int fUseInv, int fVerbose ) -{ - Abc_Obj_t * pListDir, * pListInv; - Abc_Obj_t * pNodeMin, * pNode, * pNext; - float Arrival1, Arrival2; - - assert( pChain ); - assert( pChain->pNext ); - - // divide the nodes into two parts: - // those that need the invertor and those that don't need - pListDir = pListInv = NULL; - for ( pNode = pChain, pNext = pChain->pNext; - pNode; - pNode = pNext, pNext = pNode? pNode->pNext : NULL ) - { - // check to which class the node belongs - if ( pNode->fPhase == 1 ) - { - pNode->pNext = pListDir; - pListDir = pNode; - } - else - { - pNode->pNext = pListInv; - pListInv = pNode; - } - } - - // find the node with the smallest number of logic levels - pNodeMin = pListDir; - for ( pNode = pListDir; pNode; pNode = pNode->pNext ) - { - Arrival1 = Abc_NodeReadArrival(pNodeMin)->Worst; - Arrival2 = Abc_NodeReadArrival(pNode )->Worst; - assert( Abc_ObjIsCi(pNodeMin) || Arrival1 > 0 ); - assert( Abc_ObjIsCi(pNode) || Arrival2 > 0 ); - if ( Arrival1 > Arrival2 || - Arrival1 == Arrival2 && pNodeMin->Level > pNode->Level || - Arrival1 == Arrival2 && pNodeMin->Level == pNode->Level && - Abc_NodeDroppingCost(pNodeMin) < Abc_NodeDroppingCost(pNode) ) - pNodeMin = pNode; - } - - // move the fanouts of the direct nodes - for ( pNode = pListDir; pNode; pNode = pNode->pNext ) - if ( pNode != pNodeMin ) - Abc_ObjTransferFanout( pNode, pNodeMin ); - - // find the node with the smallest number of logic levels - pNodeMin = pListInv; - for ( pNode = pListInv; pNode; pNode = pNode->pNext ) - { - Arrival1 = Abc_NodeReadArrival(pNodeMin)->Worst; - Arrival2 = Abc_NodeReadArrival(pNode )->Worst; - assert( Abc_ObjIsCi(pNodeMin) || Arrival1 > 0 ); - assert( Abc_ObjIsCi(pNode) || Arrival2 > 0 ); - if ( Arrival1 > Arrival2 || - Arrival1 == Arrival2 && pNodeMin->Level > pNode->Level || - Arrival1 == Arrival2 && pNodeMin->Level == pNode->Level && - Abc_NodeDroppingCost(pNodeMin) < Abc_NodeDroppingCost(pNode) ) - pNodeMin = pNode; - } - - // move the fanouts of the direct nodes - for ( pNode = pListInv; pNode; pNode = pNode->pNext ) - if ( pNode != pNodeMin ) - Abc_ObjTransferFanout( pNode, pNodeMin ); -} - -/**Function************************************************************* - - Synopsis [Process one equivalence class of nodes.] - - Description [This function does not remove the nodes. It only switches - around the connections.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkFraigMergeClass( Abc_Ntk_t * pNtk, Abc_Obj_t * pChain, int fUseInv, int fVerbose ) -{ - Abc_Obj_t * pListDir, * pListInv; - Abc_Obj_t * pNodeMin, * pNodeMinInv; - Abc_Obj_t * pNode, * pNext; - - assert( pChain ); - assert( pChain->pNext ); - - // find the node with the smallest number of logic levels - pNodeMin = pChain; - for ( pNode = pChain->pNext; pNode; pNode = pNode->pNext ) - if ( pNodeMin->Level > pNode->Level || - ( pNodeMin->Level == pNode->Level && - Abc_NodeDroppingCost(pNodeMin) < Abc_NodeDroppingCost(pNode) ) ) - pNodeMin = pNode; - - // divide the nodes into two parts: - // those that need the invertor and those that don't need - pListDir = pListInv = NULL; - for ( pNode = pChain, pNext = pChain->pNext; - pNode; - pNode = pNext, pNext = pNode? pNode->pNext : NULL ) - { - if ( pNode == pNodeMin ) - continue; - // check to which class the node belongs - if ( pNodeMin->fPhase == pNode->fPhase ) - { - pNode->pNext = pListDir; - pListDir = pNode; - } - else - { - pNode->pNext = pListInv; - pListInv = pNode; - } - } - - // move the fanouts of the direct nodes - for ( pNode = pListDir; pNode; pNode = pNode->pNext ) - Abc_ObjTransferFanout( pNode, pNodeMin ); - - // skip if there are no inverted nodes - if ( pListInv == NULL ) - return; - - // add the invertor - pNodeMinInv = Abc_NodeCreateInv( pNtk, pNodeMin ); - - // move the fanouts of the inverted nodes - for ( pNode = pListInv; pNode; pNode = pNode->pNext ) - Abc_ObjTransferFanout( pNode, pNodeMinInv ); -} - - -/**Function************************************************************* - - Synopsis [Returns the number of literals saved if this node becomes useless.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NodeDroppingCost( Abc_Obj_t * pNode ) -{ - return 1; -} - - - - - -/**Function************************************************************* - - Synopsis [Removes dangling nodes.] - - Description [Returns the number of nodes removed.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkCleanup( Abc_Ntk_t * pNtk, int fVerbose ) -{ - int fCheck = 1; - Vec_Ptr_t * vNodes; - Abc_Obj_t * pNode; - int i, Counter; - // mark the nodes reachable from the POs - vNodes = Abc_NtkDfs( pNtk, 0 ); - for ( i = 0; i < vNodes->nSize; i++ ) - { - pNode = vNodes->pArray[i]; - pNode->fMarkA = 1; - } - Vec_PtrFree( vNodes ); - // if it is an AIG, also mark the constant 1 node - if ( Abc_NtkIsStrash(pNtk) ) - Abc_AigConst1(pNtk->pManFunc)->fMarkA = 1; - // remove the non-marked nodes - Counter = 0; - Abc_NtkForEachNode( pNtk, pNode, i ) - if ( pNode->fMarkA == 0 ) - { - Abc_NtkDeleteObj( pNode ); - Counter++; - } - // unmark the remaining nodes - Abc_NtkForEachNode( pNtk, pNode, i ) - pNode->fMarkA = 0; - if ( fVerbose ) - printf( "Cleanup removed %d dangling nodes.\n", Counter ); - // check - if ( fCheck && !Abc_NtkCheck( pNtk ) ) - { - printf( "Abc_NtkCleanup: The network check has failed.\n" ); - return -1; - } - return Counter; -} - - - - -/**Function************************************************************* - - Synopsis [Tranditional sweep of the network.] - - Description [Propagates constant and single-input node, removes dangling nodes.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkSweep( Abc_Ntk_t * pNtk, int fVerbose ) -{ - int fCheck = 1; - Abc_Obj_t * pNode; - int i, fConvert, nSwept, nSweptNew; - assert( Abc_NtkIsSopLogic(pNtk) || Abc_NtkIsBddLogic(pNtk) ); - // convert to the BDD representation - fConvert = 0; - if ( Abc_NtkIsSopLogic(pNtk) ) - Abc_NtkSopToBdd(pNtk), fConvert = 1; - // perform cleanup to get rid of dangling nodes - nSwept = Abc_NtkCleanup( pNtk, 0 ); - // make the network minimum base - Abc_NtkRemoveDupFanins(pNtk); - Abc_NtkMinimumBase(pNtk); - do - { - // sweep constants and single-input nodes - Abc_NtkForEachNode( pNtk, pNode, i ) - if ( Abc_ObjFaninNum(pNode) < 2 ) - Abc_NodeSweep( pNode, fVerbose ); - // make the network minimum base - Abc_NtkRemoveDupFanins(pNtk); - Abc_NtkMinimumBase(pNtk); - // perform final clean up (in case new danglies are created) - nSweptNew = Abc_NtkCleanup( pNtk, 0 ); - nSwept += nSweptNew; - } - while ( nSweptNew ); - // conver back to BDD - if ( fConvert ) - Abc_NtkBddToSop(pNtk); - // report - if ( fVerbose ) - printf( "Sweep removed %d nodes.\n", nSwept ); - // check - if ( fCheck && !Abc_NtkCheck( pNtk ) ) - { - printf( "Abc_NtkSweep: The network check has failed.\n" ); - return -1; - } - return nSwept; -} - -/**Function************************************************************* - - Synopsis [Tranditional sweep of the network.] - - Description [Propagates constant and single-input node, removes dangling nodes.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NodeSweep( Abc_Obj_t * pNode, int fVerbose ) -{ - Vec_Ptr_t * vFanout = pNode->pNtk->vPtrTemp; - Abc_Obj_t * pFanout, * pDriver; - int i; - assert( Abc_ObjFaninNum(pNode) < 2 ); - assert( Abc_ObjFanoutNum(pNode) > 0 ); - // iterate through the fanouts - Abc_NodeCollectFanouts( pNode, vFanout ); - Vec_PtrForEachEntry( vFanout, pFanout, i ) - { - if ( Abc_ObjIsCo(pFanout) ) - { - if ( Abc_ObjFaninNum(pNode) == 1 ) - { - pDriver = Abc_ObjFanin0(pNode); - if ( Abc_ObjIsCi(pDriver) || Abc_ObjFanoutNum(pDriver) > 1 || Abc_ObjFanoutNum(pNode) > 1 ) - continue; - // the driver is a node and its only fanout is this node - if ( Abc_NodeIsInv(pNode) ) - pDriver->pData = Cudd_Not(pDriver->pData); - // replace the fanin of the fanout - Abc_ObjPatchFanin( pFanout, pNode, pDriver ); - } - continue; - } - // the fanout is a regular node - if ( Abc_ObjFaninNum(pNode) == 0 ) - Abc_NodeConstantInput( pFanout, pNode, Abc_NodeIsConst0(pNode) ); - else - { - assert( Abc_ObjFaninNum(pNode) == 1 ); - pDriver = Abc_ObjFanin0(pNode); - if ( Abc_NodeIsInv(pNode) ) - Abc_NodeComplementInput( pFanout, pNode ); - Abc_ObjPatchFanin( pFanout, pNode, pDriver ); - } - } -} - -/**Function************************************************************* - - Synopsis [Replaces the local function by its cofactor.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NodeConstantInput( Abc_Obj_t * pNode, Abc_Obj_t * pFanin, bool fConst0 ) -{ - DdManager * dd = pNode->pNtk->pManFunc; - DdNode * bVar, * bTemp; - int iFanin; - assert( Abc_NtkIsBddLogic(pNode->pNtk) ); - if ( (iFanin = Vec_FanFindEntry( &pNode->vFanins, pFanin->Id )) == -1 ) - { - printf( "Node %s should be among", Abc_ObjName(pFanin) ); - printf( " the fanins of node %s...\n", Abc_ObjName(pNode) ); - return; - } - bVar = Cudd_NotCond( Cudd_bddIthVar(dd, iFanin), fConst0 ); - pNode->pData = Cudd_Cofactor( dd, bTemp = pNode->pData, bVar ); Cudd_Ref( pNode->pData ); - Cudd_RecursiveDeref( dd, bTemp ); -} - -/**Function************************************************************* - - Synopsis [Changes the polarity of one fanin.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NodeComplementInput( Abc_Obj_t * pNode, Abc_Obj_t * pFanin ) -{ - DdManager * dd = pNode->pNtk->pManFunc; - DdNode * bVar, * bCof0, * bCof1; - int iFanin; - assert( Abc_NtkIsBddLogic(pNode->pNtk) ); - if ( (iFanin = Vec_FanFindEntry( &pNode->vFanins, pFanin->Id )) == -1 ) - { - printf( "Node %s should be among", Abc_ObjName(pFanin) ); - printf( " the fanins of node %s...\n", Abc_ObjName(pNode) ); - return; - } - bVar = Cudd_bddIthVar( dd, iFanin ); - bCof0 = Cudd_Cofactor( dd, pNode->pData, Cudd_Not(bVar) ); Cudd_Ref( bCof0 ); - bCof1 = Cudd_Cofactor( dd, pNode->pData, bVar ); Cudd_Ref( bCof1 ); - Cudd_RecursiveDeref( dd, pNode->pData ); - pNode->pData = Cudd_bddIte( dd, bVar, bCof0, bCof1 ); Cudd_Ref( pNode->pData ); - Cudd_RecursiveDeref( dd, bCof0 ); - Cudd_RecursiveDeref( dd, bCof1 ); -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/base/abc/abcSymm.c b/src/base/abc/abcSymm.c deleted file mode 100644 index 8df3a837..00000000 --- a/src/base/abc/abcSymm.c +++ /dev/null @@ -1,202 +0,0 @@ -/**CFile**************************************************************** - - FileName [abcSymm.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Network and node package.] - - Synopsis [Computation of two-variable symmetries.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: abcSymm.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static void Abc_NtkSymmetriesUsingBdds( Abc_Ntk_t * pNtk, int fNaive, int fVerbose ); -static void Ntk_NetworkSymmsBdd( DdManager * dd, Abc_Ntk_t * pNtk, int fNaive, int fVerbose ); -static void Ntk_NetworkSymmsPrint( Abc_Ntk_t * pNtk, Extra_SymmInfo_t * pSymms ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [The top level procedure to compute symmetries.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkSymmetries( Abc_Ntk_t * pNtk, int fUseBdds, int fNaive, int fVerbose ) -{ - if ( fUseBdds || fNaive ) - Abc_NtkSymmetriesUsingBdds( pNtk, fNaive, fVerbose ); - else - printf( "This option is currently not implemented.\n" ); -} - -/**Function************************************************************* - - Synopsis [Symmetry computation using BDDs (both naive and smart).] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkSymmetriesUsingBdds( Abc_Ntk_t * pNtk, int fNaive, int fVerbose ) -{ - DdManager * dd; - int clk, clkBdd, clkSym; - - // compute the global functions -clk = clock(); - dd = Abc_NtkGlobalBdds( pNtk, 0 ); - Cudd_AutodynDisable( dd ); - Cudd_zddVarsFromBddVars( dd, 2 ); -clkBdd = clock() - clk; - // create the collapsed network -clk = clock(); - Ntk_NetworkSymmsBdd( dd, pNtk, fNaive, fVerbose ); -clkSym = clock() - clk; - // undo the global functions - Abc_NtkFreeGlobalBdds( pNtk ); - Extra_StopManager( dd ); - pNtk->pManGlob = NULL; - -PRT( "Constructing BDDs", clkBdd ); -PRT( "Computing symms ", clkSym ); -PRT( "TOTAL ", clkBdd + clkSym ); -} - -/**Function************************************************************* - - Synopsis [Symmetry computation using BDDs (both naive and smart).] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ntk_NetworkSymmsBdd( DdManager * dd, Abc_Ntk_t * pNtk, int fNaive, int fVerbose ) -{ - Extra_SymmInfo_t * pSymms; - Abc_Obj_t * pNode; - DdNode * bFunc; - int nSymms = 0; - int i; - - // compute symmetry info for each PO - Abc_NtkForEachCo( pNtk, pNode, i ) - { - bFunc = pNtk->vFuncsGlob->pArray[i]; - if ( Cudd_IsConstant(bFunc) ) - continue; - if ( fNaive ) - pSymms = Extra_SymmPairsComputeNaive( dd, bFunc ); - else - pSymms = Extra_SymmPairsCompute( dd, bFunc ); - nSymms += pSymms->nSymms; - if ( fVerbose ) - { - printf( "Output %6s (%d): ", Abc_ObjName(pNode), pSymms->nSymms ); - Ntk_NetworkSymmsPrint( pNtk, pSymms ); - } -//Extra_SymmPairsPrint( pSymms ); - Extra_SymmPairsDissolve( pSymms ); - } - printf( "The total number of symmetries is %d.\n", nSymms ); -} - -/**Function************************************************************* - - Synopsis [Printing symmetry groups from the symmetry data structure.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Ntk_NetworkSymmsPrint( Abc_Ntk_t * pNtk, Extra_SymmInfo_t * pSymms ) -{ - char ** pInputNames; - int * pVarTaken; - int i, k, nVars, nSize, fStart; - - // get variable names - nVars = Abc_NtkCiNum(pNtk); - pInputNames = Abc_NtkCollectCioNames( pNtk, 0 ); - - // alloc the array of marks - pVarTaken = ALLOC( int, nVars ); - memset( pVarTaken, 0, sizeof(int) * nVars ); - - // print the groups - fStart = 1; - nSize = pSymms->nVars; - for ( i = 0; i < nSize; i++ ) - { - // skip the variable already considered - if ( pVarTaken[i] ) - continue; - // find all the vars symmetric with this one - for ( k = 0; k < nSize; k++ ) - { - if ( k == i ) - continue; - if ( pSymms->pSymms[i][k] == 0 ) - continue; - // vars i and k are symmetric - assert( pVarTaken[k] == 0 ); - // there is a new symmetry pair - if ( fStart == 1 ) - { // start a new symmetry class - fStart = 0; - printf( " { %s", pInputNames[ pSymms->pVars[i] ] ); - // mark the var as taken - pVarTaken[i] = 1; - } - printf( " %s", pInputNames[ pSymms->pVars[k] ] ); - // mark the var as taken - pVarTaken[k] = 1; - } - if ( fStart == 0 ) - { - printf( " }" ); - fStart = 1; - } - } - printf( "\n" ); - - free( pInputNames ); - free( pVarTaken ); -} - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/base/abc/abcTiming.c b/src/base/abc/abcTiming.c deleted file mode 100644 index b8524bd5..00000000 --- a/src/base/abc/abcTiming.c +++ /dev/null @@ -1,755 +0,0 @@ -/**CFile**************************************************************** - - FileName [abcTiming.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Network and node package.] - - Synopsis [Computation of timing info for mapped circuits.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: abcTiming.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" -#include "main.h" -#include "mio.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -struct Abc_ManTime_t_ -{ - Abc_Time_t tArrDef; - Abc_Time_t tReqDef; - Vec_Ptr_t * vArrs; - Vec_Ptr_t * vReqs; -}; - -// static functions -static Abc_ManTime_t * Abc_ManTimeStart(); -static void Abc_ManTimeExpand( Abc_ManTime_t * p, int nSize, int fProgressive ); -static void Abc_NtkTimePrepare( Abc_Ntk_t * pNtk ); - -static void Abc_NodeDelayTraceArrival( Abc_Obj_t * pNode ); - -// accessing the arrival and required times of a node -static inline Abc_Time_t * Abc_NodeArrival( Abc_Obj_t * pNode ) { return pNode->pNtk->pManTime->vArrs->pArray[pNode->Id]; } -static inline Abc_Time_t * Abc_NodeRequired( Abc_Obj_t * pNode ) { return pNode->pNtk->pManTime->vReqs->pArray[pNode->Id]; } - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Reads the arrival time of the node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Time_t * Abc_NodeReadArrival( Abc_Obj_t * pNode ) -{ - assert( pNode->pNtk->pManTime ); - return Abc_NodeArrival(pNode); -} - -/**Function************************************************************* - - Synopsis [Reads the arrival time of the node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Time_t * Abc_NodeReadRequired( Abc_Obj_t * pNode ) -{ - assert( pNode->pNtk->pManTime ); - return Abc_NodeRequired(pNode); -} - -/**Function************************************************************* - - Synopsis [Reads the arrival time of the node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Time_t * Abc_NtkReadDefaultArrival( Abc_Ntk_t * pNtk ) -{ - assert( pNtk->pManTime ); - return &pNtk->pManTime->tArrDef; -} - -/**Function************************************************************* - - Synopsis [Reads the arrival time of the node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Time_t * Abc_NtkReadDefaultRequired( Abc_Ntk_t * pNtk ) -{ - assert( pNtk->pManTime ); - return &pNtk->pManTime->tReqDef; -} - -/**Function************************************************************* - - Synopsis [Sets the default arrival time for the network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkTimeSetDefaultArrival( Abc_Ntk_t * pNtk, float Rise, float Fall ) -{ - if ( Rise == 0.0 && Fall == 0.0 ) - return; - if ( pNtk->pManTime == NULL ) - pNtk->pManTime = Abc_ManTimeStart(); - pNtk->pManTime->tArrDef.Rise = Rise; - pNtk->pManTime->tArrDef.Fall = Fall; - pNtk->pManTime->tArrDef.Worst = ABC_MAX( Rise, Fall ); -} - -/**Function************************************************************* - - Synopsis [Sets the default arrival time for the network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkTimeSetDefaultRequired( Abc_Ntk_t * pNtk, float Rise, float Fall ) -{ - if ( Rise == 0.0 && Fall == 0.0 ) - return; - if ( pNtk->pManTime == NULL ) - pNtk->pManTime = Abc_ManTimeStart(); - pNtk->pManTime->tReqDef.Rise = Rise; - pNtk->pManTime->tReqDef.Rise = Fall; - pNtk->pManTime->tReqDef.Worst = ABC_MAX( Rise, Fall ); -} - -/**Function************************************************************* - - Synopsis [Sets the arrival time for an object.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkTimeSetArrival( Abc_Ntk_t * pNtk, int ObjId, float Rise, float Fall ) -{ - Vec_Ptr_t * vTimes; - Abc_Time_t * pTime; - if ( pNtk->pManTime == NULL ) - pNtk->pManTime = Abc_ManTimeStart(); - if ( pNtk->pManTime->tArrDef.Rise == Rise && pNtk->pManTime->tArrDef.Fall == Fall ) - return; - Abc_ManTimeExpand( pNtk->pManTime, ObjId + 1, 1 ); - // set the arrival time - vTimes = pNtk->pManTime->vArrs; - pTime = vTimes->pArray[ObjId]; - pTime->Rise = Rise; - pTime->Fall = Rise; - pTime->Worst = ABC_MAX( Rise, Fall ); -} - -/**Function************************************************************* - - Synopsis [Sets the arrival time for an object.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkTimeSetRequired( Abc_Ntk_t * pNtk, int ObjId, float Rise, float Fall ) -{ - Vec_Ptr_t * vTimes; - Abc_Time_t * pTime; - if ( pNtk->pManTime == NULL ) - pNtk->pManTime = Abc_ManTimeStart(); - if ( pNtk->pManTime->tReqDef.Rise == Rise && pNtk->pManTime->tReqDef.Fall == Fall ) - return; - Abc_ManTimeExpand( pNtk->pManTime, ObjId + 1, 1 ); - // set the required time - vTimes = pNtk->pManTime->vReqs; - pTime = vTimes->pArray[ObjId]; - pTime->Rise = Rise; - pTime->Fall = Rise; - pTime->Worst = ABC_MAX( Rise, Fall ); -} - -/**Function************************************************************* - - Synopsis [Finalizes the timing manager after setting arr/req times.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkTimeInitialize( Abc_Ntk_t * pNtk ) -{ - Abc_Obj_t * pObj; - Abc_Time_t ** ppTimes, * pTime; - int i; - if ( pNtk->pManTime == NULL ) - return; - Abc_ManTimeExpand( pNtk->pManTime, Abc_NtkObjNumMax(pNtk), 0 ); - // set the default timing - ppTimes = (Abc_Time_t **)pNtk->pManTime->vArrs->pArray; - Abc_NtkForEachPi( pNtk, pObj, i ) - { - pTime = ppTimes[pObj->Id]; - if ( pTime->Worst != -ABC_INFINITY ) - continue; - *pTime = pNtk->pManTime->tArrDef; - } - // set the default timing - ppTimes = (Abc_Time_t **)pNtk->pManTime->vReqs->pArray; - Abc_NtkForEachPo( pNtk, pObj, i ) - { - pTime = ppTimes[pObj->Id]; - if ( pTime->Worst != -ABC_INFINITY ) - continue; - *pTime = pNtk->pManTime->tReqDef; - } - // set the 0 arrival times for latches and constant nodes - ppTimes = (Abc_Time_t **)pNtk->pManTime->vArrs->pArray; - Abc_NtkForEachLatch( pNtk, pObj, i ) - { - pTime = ppTimes[pObj->Id]; - pTime->Fall = pTime->Rise = pTime->Worst = 0.0; - } -} - -/**Function************************************************************* - - Synopsis [Prepares the timing manager for delay trace.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkTimePrepare( Abc_Ntk_t * pNtk ) -{ - Abc_Obj_t * pObj; - Abc_Time_t ** ppTimes, * pTime; - int i; - // if there is no timing manager, allocate and initialize - if ( pNtk->pManTime == NULL ) - { - pNtk->pManTime = Abc_ManTimeStart(); - Abc_NtkTimeInitialize( pNtk ); - return; - } - // if timing manager is given, expand it if necessary - Abc_ManTimeExpand( pNtk->pManTime, Abc_NtkObjNumMax(pNtk), 0 ); - // clean arrivals except for PIs - ppTimes = (Abc_Time_t **)pNtk->pManTime->vArrs->pArray; - Abc_NtkForEachNode( pNtk, pObj, i ) - { - pTime = ppTimes[pObj->Id]; - pTime->Fall = pTime->Rise = pTime->Worst = -ABC_INFINITY; - } - Abc_NtkForEachPo( pNtk, pObj, i ) - { - pTime = ppTimes[pObj->Id]; - pTime->Fall = pTime->Rise = pTime->Worst = -ABC_INFINITY; - } - // clean required except for POs -} - - - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_ManTime_t * Abc_ManTimeStart() -{ - Abc_ManTime_t * p; - p = ALLOC( Abc_ManTime_t, 1 ); - memset( p, 0, sizeof(Abc_ManTime_t) ); - p->vArrs = Vec_PtrAlloc( 0 ); - p->vReqs = Vec_PtrAlloc( 0 ); - return p; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_ManTimeStop( Abc_ManTime_t * p ) -{ - if ( p->vArrs->nSize > 0 ) - { - free( p->vArrs->pArray[0] ); - Vec_PtrFree( p->vArrs ); - } - if ( p->vReqs->nSize > 0 ) - { - free( p->vReqs->pArray[0] ); - Vec_PtrFree( p->vReqs ); - } - free( p ); -} - -/**Function************************************************************* - - Synopsis [Duplicates the timing manager with the PI/PO timing info.] - - Description [The PIs/POs of the new network should be allocated.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_ManTimeDup( Abc_Ntk_t * pNtkOld, Abc_Ntk_t * pNtkNew ) -{ - Abc_Obj_t * pObj; - Abc_Time_t ** ppTimesOld, ** ppTimesNew; - int i; - if ( pNtkOld->pManTime == NULL ) - return; - assert( Abc_NtkPiNum(pNtkOld) == Abc_NtkPiNum(pNtkNew) ); - assert( Abc_NtkPoNum(pNtkOld) == Abc_NtkPoNum(pNtkNew) ); - assert( Abc_NtkLatchNum(pNtkOld) == Abc_NtkLatchNum(pNtkNew) ); - // create the new timing manager - pNtkNew->pManTime = Abc_ManTimeStart(); - Abc_ManTimeExpand( pNtkNew->pManTime, Abc_NtkObjNumMax(pNtkNew), 0 ); - // set the default timing - pNtkNew->pManTime->tArrDef = pNtkOld->pManTime->tArrDef; - pNtkNew->pManTime->tReqDef = pNtkOld->pManTime->tReqDef; - // set the CI timing - ppTimesOld = (Abc_Time_t **)pNtkOld->pManTime->vArrs->pArray; - ppTimesNew = (Abc_Time_t **)pNtkNew->pManTime->vArrs->pArray; - Abc_NtkForEachCi( pNtkOld, pObj, i ) - *ppTimesNew[ Abc_NtkCi(pNtkNew,i)->Id ] = *ppTimesOld[ pObj->Id ]; - // set the CO timing - ppTimesOld = (Abc_Time_t **)pNtkOld->pManTime->vReqs->pArray; - ppTimesNew = (Abc_Time_t **)pNtkNew->pManTime->vReqs->pArray; - Abc_NtkForEachCo( pNtkOld, pObj, i ) - *ppTimesNew[ Abc_NtkCo(pNtkNew,i)->Id ] = *ppTimesOld[ pObj->Id ]; -} - -/**Function************************************************************* - - Synopsis [Expends the storage for timing information.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_ManTimeExpand( Abc_ManTime_t * p, int nSize, int fProgressive ) -{ - Vec_Ptr_t * vTimes; - Abc_Time_t * ppTimes, * ppTimesOld, * pTime; - int nSizeOld, nSizeNew, i; - - nSizeOld = p->vArrs->nSize; - if ( nSizeOld >= nSize ) - return; - nSizeNew = fProgressive? 2 * nSize : nSize; - if ( nSizeNew < 100 ) - nSizeNew = 100; - - vTimes = p->vArrs; - Vec_PtrGrow( vTimes, nSizeNew ); - vTimes->nSize = nSizeNew; - ppTimesOld = ( nSizeOld == 0 )? NULL : vTimes->pArray[0]; - ppTimes = REALLOC( Abc_Time_t, ppTimesOld, nSizeNew ); - for ( i = 0; i < nSizeNew; i++ ) - vTimes->pArray[i] = ppTimes + i; - for ( i = nSizeOld; i < nSizeNew; i++ ) - { - pTime = vTimes->pArray[i]; - pTime->Rise = -ABC_INFINITY; - pTime->Fall = -ABC_INFINITY; - pTime->Worst = -ABC_INFINITY; - } - - vTimes = p->vReqs; - Vec_PtrGrow( vTimes, nSizeNew ); - vTimes->nSize = nSizeNew; - ppTimesOld = ( nSizeOld == 0 )? NULL : vTimes->pArray[0]; - ppTimes = REALLOC( Abc_Time_t, ppTimesOld, nSizeNew ); - for ( i = 0; i < nSizeNew; i++ ) - vTimes->pArray[i] = ppTimes + i; - for ( i = nSizeOld; i < nSizeNew; i++ ) - { - pTime = vTimes->pArray[i]; - pTime->Rise = -ABC_INFINITY; - pTime->Fall = -ABC_INFINITY; - pTime->Worst = -ABC_INFINITY; - } -} - - - - - - -/**Function************************************************************* - - Synopsis [Sets the CI node levels according to the arrival info.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkSetNodeLevelsArrival( Abc_Ntk_t * pNtkOld ) -{ - Abc_Obj_t * pNodeOld, * pNodeNew; - float tAndDelay; - int i; - if ( pNtkOld->pManTime == NULL ) - return; - if ( Mio_LibraryReadNand2(Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame())) == NULL ) - return; - tAndDelay = Mio_LibraryReadDelayNand2Max(Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame())); - Abc_NtkForEachPi( pNtkOld, pNodeOld, i ) - { - pNodeNew = pNodeOld->pCopy; - pNodeNew->Level = (int)(Abc_NodeArrival(pNodeOld)->Worst / tAndDelay); - } -} - -/**Function************************************************************* - - Synopsis [Sets the CI node levels according to the arrival info.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Time_t * Abc_NtkGetCiArrivalTimes( Abc_Ntk_t * pNtk ) -{ - Abc_Time_t * p; - Abc_Obj_t * pNode; - int i; - p = ALLOC( Abc_Time_t, Abc_NtkCiNum(pNtk) ); - memset( p, 0, sizeof(Abc_Time_t) * Abc_NtkCiNum(pNtk) ); - if ( pNtk->pManTime == NULL ) - return p; - // set the PI arrival times - Abc_NtkForEachPi( pNtk, pNode, i ) - p[i] = *Abc_NodeArrival(pNode); - return p; -} - - -/**Function************************************************************* - - Synopsis [Sets the CI node levels according to the arrival info.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -float * Abc_NtkGetCiArrivalFloats( Abc_Ntk_t * pNtk ) -{ - float * p; - Abc_Obj_t * pNode; - int i; - p = ALLOC( float, Abc_NtkCiNum(pNtk) ); - memset( p, 0, sizeof(float) * Abc_NtkCiNum(pNtk) ); - if ( pNtk->pManTime == NULL ) - return p; - // set the PI arrival times - Abc_NtkForEachPi( pNtk, pNode, i ) - p[i] = Abc_NodeArrival(pNode)->Worst; - return p; -} - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -float Abc_NtkDelayTrace( Abc_Ntk_t * pNtk ) -{ - Abc_Obj_t * pNode, * pDriver; - Vec_Ptr_t * vNodes; - Abc_Time_t * pTime; - float tArrivalMax; - int i; - - assert( Abc_NtkIsMappedLogic(pNtk) ); - - Abc_NtkTimePrepare( pNtk ); - vNodes = Abc_NtkDfs( pNtk, 1 ); - for ( i = 0; i < vNodes->nSize; i++ ) - Abc_NodeDelayTraceArrival( vNodes->pArray[i] ); - Vec_PtrFree( vNodes ); - - // get the latest arrival times - tArrivalMax = -ABC_INFINITY; - Abc_NtkForEachCo( pNtk, pNode, i ) - { - pDriver = Abc_ObjFanin0(pNode); - pTime = Abc_NodeArrival(pDriver); - if ( tArrivalMax < pTime->Worst ) - tArrivalMax = pTime->Worst; - } - return tArrivalMax; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NodeDelayTraceArrival( Abc_Obj_t * pNode ) -{ - Abc_Obj_t * pFanin; - Abc_Time_t * pTimeIn, * pTimeOut; - float tDelayBlockRise, tDelayBlockFall; - Mio_PinPhase_t PinPhase; - Mio_Pin_t * pPin; - int i; - - // start the arrival time of the node - pTimeOut = Abc_NodeArrival(pNode); - pTimeOut->Rise = pTimeOut->Fall = 0; - // go through the pins of the gate - pPin = Mio_GateReadPins(pNode->pData); - Abc_ObjForEachFanin( pNode, pFanin, i ) - { - pTimeIn = Abc_NodeArrival(pFanin); - assert( pTimeIn->Worst != -ABC_INFINITY ); - // get the interesting parameters of this pin - PinPhase = Mio_PinReadPhase(pPin); - tDelayBlockRise = (float)Mio_PinReadDelayBlockRise( pPin ); - tDelayBlockFall = (float)Mio_PinReadDelayBlockFall( pPin ); - // compute the arrival times of the positive phase - if ( PinPhase != MIO_PHASE_INV ) // NONINV phase is present - { - if ( pTimeOut->Rise < pTimeIn->Rise + tDelayBlockRise ) - pTimeOut->Rise = pTimeIn->Rise + tDelayBlockRise; - if ( pTimeOut->Fall < pTimeIn->Fall + tDelayBlockFall ) - pTimeOut->Fall = pTimeIn->Fall + tDelayBlockFall; - } - if ( PinPhase != MIO_PHASE_NONINV ) // INV phase is present - { - if ( pTimeOut->Rise < pTimeIn->Fall + tDelayBlockRise ) - pTimeOut->Rise = pTimeIn->Fall + tDelayBlockRise; - if ( pTimeOut->Fall < pTimeIn->Rise + tDelayBlockFall ) - pTimeOut->Fall = pTimeIn->Rise + tDelayBlockFall; - } - pPin = Mio_PinReadNext(pPin); - } - pTimeOut->Worst = ABC_MAX( pTimeOut->Rise, pTimeOut->Fall ); -} - - - - -/**Function************************************************************* - - Synopsis [Prepares the AIG for the comptuation of required levels.] - - Description [This procedure should be called before the required times - are used. It starts internal data structures, which records the level - from the COs of the AIG nodes in reverse topologogical order.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkStartReverseLevels( Abc_Ntk_t * pNtk ) -{ - Vec_Ptr_t * vNodes; - Abc_Obj_t * pObj, * pFanout; - int i, k, nLevelsCur; - assert( Abc_NtkIsStrash(pNtk) ); - // remember the maximum number of direct levels - pNtk->LevelMax = Abc_AigGetLevelNum(pNtk); - // start the reverse levels - pNtk->vLevelsR = Vec_IntAlloc( 0 ); - Vec_IntFill( pNtk->vLevelsR, Abc_NtkObjNumMax(pNtk), 0 ); - // compute levels in reverse topological order - vNodes = Abc_NtkDfsReverse( pNtk ); - Vec_PtrForEachEntry( vNodes, pObj, i ) - { - nLevelsCur = 0; - Abc_ObjForEachFanout( pObj, pFanout, k ) - if ( nLevelsCur < Vec_IntEntry(pNtk->vLevelsR, pFanout->Id) ) - nLevelsCur = Vec_IntEntry(pNtk->vLevelsR, pFanout->Id); - Vec_IntWriteEntry( pNtk->vLevelsR, pObj->Id, nLevelsCur + 1 ); - } - Vec_PtrFree( vNodes ); -} - -/**Function************************************************************* - - Synopsis [Cleans the data structures used to compute required levels.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkStopReverseLevels( Abc_Ntk_t * pNtk ) -{ - assert( pNtk->vLevelsR ); - Vec_IntFree( pNtk->vLevelsR ); - pNtk->vLevelsR = NULL; - pNtk->LevelMax = 0; - -} - -/**Function************************************************************* - - Synopsis [Sets the reverse level of the node.] - - Description [The reverse level is the level of the node in reverse - topological order, starting from the COs.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NodeSetReverseLevel( Abc_Obj_t * pObj, int LevelR ) -{ - Abc_Ntk_t * pNtk = pObj->pNtk; - assert( Abc_NtkIsStrash(pNtk) ); - assert( pNtk->vLevelsR ); - Vec_IntFillExtra( pNtk->vLevelsR, pObj->Id + 1, 0 ); - Vec_IntWriteEntry( pNtk->vLevelsR, pObj->Id, LevelR ); -} - -/**Function************************************************************* - - Synopsis [Returns the reverse level of the node.] - - Description [The reverse level is the level of the node in reverse - topological order, starting from the COs.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NodeReadReverseLevel( Abc_Obj_t * pObj ) -{ - Abc_Ntk_t * pNtk = pObj->pNtk; - assert( Abc_NtkIsStrash(pNtk) ); - assert( pNtk->vLevelsR ); - Vec_IntFillExtra( pNtk->vLevelsR, pObj->Id + 1, 0 ); - return Vec_IntEntry(pNtk->vLevelsR, pObj->Id); -} - -/**Function************************************************************* - - Synopsis [Returns required level of the node.] - - Description [Converts the reverse levels of the node into its required - level as follows: ReqLevel(Node) = MaxLevels(Ntk) + 1 - LevelR(Node).] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NodeReadRequiredLevel( Abc_Obj_t * pObj ) -{ - Abc_Ntk_t * pNtk = pObj->pNtk; - assert( Abc_NtkIsStrash(pNtk) ); - assert( pNtk->vLevelsR ); - return pNtk->LevelMax + 1 - Vec_IntEntry(pNtk->vLevelsR, pObj->Id); -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/base/abc/abcUnreach.c b/src/base/abc/abcUnreach.c deleted file mode 100644 index 0fe3ec63..00000000 --- a/src/base/abc/abcUnreach.c +++ /dev/null @@ -1,336 +0,0 @@ -/**CFile**************************************************************** - - FileName [abcUnreach.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Network and node package.] - - Synopsis [Computes unreachable states for small benchmarks.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: abcUnreach.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static DdNode * Abc_NtkTransitionRelation( DdManager * dd, Abc_Ntk_t * pNtk, int fVerbose ); -static DdNode * Abc_NtkInitStateAndVarMap( DdManager * dd, Abc_Ntk_t * pNtk, int fVerbose ); -static DdNode * Abc_NtkComputeUnreachable( DdManager * dd, Abc_Ntk_t * pNtk, DdNode * bRelation, DdNode * bInitial, bool fVerbose ); -static Abc_Ntk_t * Abc_NtkConstructExdc ( DdManager * dd, Abc_Ntk_t * pNtk, DdNode * bUnreach ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Extracts sequential DCs of the network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkExtractSequentialDcs( Abc_Ntk_t * pNtk, bool fVerbose ) -{ - int fCheck = 1; - int fReorder = 1; - DdManager * dd; - DdNode * bRelation, * bInitial, * bUnreach; - - // remove EXDC network if present - if ( pNtk->pExdc ) - { - Abc_NtkDelete( pNtk->pExdc ); - pNtk->pExdc = NULL; - } - - // compute the global BDDs of the latches - dd = Abc_NtkGlobalBdds( pNtk, 1 ); - if ( dd == NULL ) - return 0; - if ( fVerbose ) - printf( "The shared BDD size is %d nodes.\n", Cudd_ReadKeys(dd) - Cudd_ReadDead(dd) ); - - // create the transition relation (dereferenced global BDDs) - bRelation = Abc_NtkTransitionRelation( dd, pNtk, fVerbose ); Cudd_Ref( bRelation ); - // create the initial state and the variable map - bInitial = Abc_NtkInitStateAndVarMap( dd, pNtk, fVerbose ); Cudd_Ref( bInitial ); - // compute the unreachable states - bUnreach = Abc_NtkComputeUnreachable( dd, pNtk, bRelation, bInitial, fVerbose ); Cudd_Ref( bUnreach ); - Cudd_RecursiveDeref( dd, bRelation ); - Cudd_RecursiveDeref( dd, bInitial ); - - // reorder and disable reordering - if ( fReorder ) - { - if ( fVerbose ) - fprintf( stdout, "BDD nodes in the unreachable states before reordering %d.\n", Cudd_DagSize(bUnreach) ); - Cudd_ReduceHeap( dd, CUDD_REORDER_SYMM_SIFT, 1 ); - Cudd_AutodynDisable( dd ); - if ( fVerbose ) - fprintf( stdout, "BDD nodes in the unreachable states after reordering %d.\n", Cudd_DagSize(bUnreach) ); - } - - // allocate ZDD variables - Cudd_zddVarsFromBddVars( dd, 2 ); - // create the EXDC network representing the unreachable states - pNtk->pExdc = Abc_NtkConstructExdc( dd, pNtk, bUnreach ); - Cudd_RecursiveDeref( dd, bUnreach ); - Extra_StopManager( dd ); - pNtk->pManGlob = NULL; - - // make sure that everything is okay - if ( fCheck && !Abc_NtkCheck( pNtk->pExdc ) ) - { - printf( "Abc_NtkExtractSequentialDcs: The network check has failed.\n" ); - Abc_NtkDelete( pNtk->pExdc ); - return 0; - } - return 1; -} - -/**Function************************************************************* - - Synopsis [Computes the transition relation of the network.] - - Description [Assumes that the global BDDs are computed.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -DdNode * Abc_NtkTransitionRelation( DdManager * dd, Abc_Ntk_t * pNtk, int fVerbose ) -{ - DdNode * bRel, * bTemp, * bProd, * bVar, * bInputs; - Abc_Obj_t * pNode; - int fReorder = 1; - int i; - - // extand the BDD manager to represent NS variables - assert( dd->size == Abc_NtkCiNum(pNtk) ); - Cudd_bddIthVar( dd, Abc_NtkCiNum(pNtk) + Abc_NtkLatchNum(pNtk) - 1 ); - - // enable reordering - if ( fReorder ) - Cudd_AutodynEnable( dd, CUDD_REORDER_SYMM_SIFT ); - else - Cudd_AutodynDisable( dd ); - - // compute the transition relation - bRel = b1; Cudd_Ref( bRel ); - Abc_NtkForEachLatch( pNtk, pNode, i ) - { - bVar = Cudd_bddIthVar( dd, Abc_NtkCiNum(pNtk) + i ); - bProd = Cudd_bddXnor( dd, bVar, pNtk->vFuncsGlob->pArray[i] ); Cudd_Ref( bProd ); - bRel = Cudd_bddAnd( dd, bTemp = bRel, bProd ); Cudd_Ref( bRel ); - Cudd_RecursiveDeref( dd, bTemp ); - Cudd_RecursiveDeref( dd, bProd ); - } - // free the global BDDs - Abc_NtkFreeGlobalBdds( pNtk ); - - // quantify the PI variables - bInputs = Extra_bddComputeRangeCube( dd, 0, Abc_NtkPiNum(pNtk) ); Cudd_Ref( bInputs ); - bRel = Cudd_bddExistAbstract( dd, bTemp = bRel, bInputs ); Cudd_Ref( bRel ); - Cudd_RecursiveDeref( dd, bTemp ); - Cudd_RecursiveDeref( dd, bInputs ); - - // reorder and disable reordering - if ( fReorder ) - { - if ( fVerbose ) - fprintf( stdout, "BDD nodes in the transition relation before reordering %d.\n", Cudd_DagSize(bRel) ); - Cudd_ReduceHeap( dd, CUDD_REORDER_SYMM_SIFT, 100 ); - Cudd_AutodynDisable( dd ); - if ( fVerbose ) - fprintf( stdout, "BDD nodes in the transition relation after reordering %d.\n", Cudd_DagSize(bRel) ); - } - Cudd_Deref( bRel ); - return bRel; -} - -/**Function************************************************************* - - Synopsis [Computes the initial state and sets up the variable map.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -DdNode * Abc_NtkInitStateAndVarMap( DdManager * dd, Abc_Ntk_t * pNtk, int fVerbose ) -{ - DdNode ** pbVarsX, ** pbVarsY; - DdNode * bTemp, * bProd, * bVar; - Abc_Obj_t * pLatch; - int i; - - // set the variable mapping for Cudd_bddVarMap() - pbVarsX = ALLOC( DdNode *, dd->size ); - pbVarsY = ALLOC( DdNode *, dd->size ); - bProd = b1; Cudd_Ref( bProd ); - Abc_NtkForEachLatch( pNtk, pLatch, i ) - { - pbVarsX[i] = dd->vars[ Abc_NtkPiNum(pNtk) + i ]; - pbVarsY[i] = dd->vars[ Abc_NtkCiNum(pNtk) + i ]; - // get the initial value of the latch - bVar = Cudd_NotCond( pbVarsX[i], !Abc_LatchIsInit1(pLatch) ); - bProd = Cudd_bddAnd( dd, bTemp = bProd, bVar ); Cudd_Ref( bProd ); - Cudd_RecursiveDeref( dd, bTemp ); - } - Cudd_SetVarMap( dd, pbVarsX, pbVarsY, Abc_NtkLatchNum(pNtk) ); - FREE( pbVarsX ); - FREE( pbVarsY ); - - Cudd_Deref( bProd ); - return bProd; -} - -/**Function************************************************************* - - Synopsis [Computes the set of unreachable states.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -DdNode * Abc_NtkComputeUnreachable( DdManager * dd, Abc_Ntk_t * pNtk, DdNode * bTrans, DdNode * bInitial, bool fVerbose ) -{ - DdNode * bRelation, * bReached, * bCubeCs; - DdNode * bCurrent, * bNext, * bTemp; - int nIters; - - // perform reachability analisys - bCurrent = bInitial; Cudd_Ref( bCurrent ); - bReached = bInitial; Cudd_Ref( bReached ); - bRelation = bTrans; Cudd_Ref( bRelation ); - bCubeCs = Extra_bddComputeRangeCube( dd, Abc_NtkPiNum(pNtk), Abc_NtkCiNum(pNtk) ); Cudd_Ref( bCubeCs ); - for ( nIters = 1; ; nIters++ ) - { - // compute the next states - bNext = Cudd_bddAndAbstract( dd, bRelation, bCurrent, bCubeCs ); Cudd_Ref( bNext ); - Cudd_RecursiveDeref( dd, bCurrent ); - // remap these states into the current state vars - bNext = Cudd_bddVarMap( dd, bTemp = bNext ); Cudd_Ref( bNext ); - Cudd_RecursiveDeref( dd, bTemp ); - // check if there are any new states - if ( Cudd_bddLeq( dd, bNext, bReached ) ) - break; - // get the new states - bCurrent = Cudd_bddAnd( dd, bNext, Cudd_Not(bReached) ); Cudd_Ref( bCurrent ); - // minimize the new states with the reached states -// bCurrent = Cudd_bddConstrain( dd, bTemp = bCurrent, Cudd_Not(bReached) ); Cudd_Ref( bCurrent ); -// Cudd_RecursiveDeref( dd, bTemp ); - // add to the reached states - bReached = Cudd_bddOr( dd, bTemp = bReached, bNext ); Cudd_Ref( bReached ); - Cudd_RecursiveDeref( dd, bTemp ); - Cudd_RecursiveDeref( dd, bNext ); - // minimize the transition relation -// bRelation = Cudd_bddConstrain( dd, bTemp = bRelation, Cudd_Not(bReached) ); Cudd_Ref( bRelation ); -// Cudd_RecursiveDeref( dd, bTemp ); - } - Cudd_RecursiveDeref( dd, bRelation ); - Cudd_RecursiveDeref( dd, bCubeCs ); - Cudd_RecursiveDeref( dd, bNext ); - // report the stats - if ( fVerbose ) - { - fprintf( stdout, "Reachability analysis completed in %d iterations.\n", nIters ); - fprintf( stdout, "The number of minterms in the reachable state set = %d.\n", - (int)Cudd_CountMinterm(dd, bReached, Abc_NtkLatchNum(pNtk) ) ); - } -//PRB( dd, bReached ); - Cudd_Deref( bReached ); - return Cudd_Not( bReached ); -} - -/**Function************************************************************* - - Synopsis [Creates the EXDC network.] - - Description [The set of unreachable states depends on CS variables.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_NtkConstructExdc( DdManager * dd, Abc_Ntk_t * pNtk, DdNode * bUnreach ) -{ - Abc_Ntk_t * pNtkNew; - Abc_Obj_t * pNode, * pNodeNew; - int * pPermute; - int i; - - // start the new network - pNtkNew = Abc_NtkAlloc( ABC_TYPE_LOGIC, ABC_FUNC_BDD ); - // create PIs corresponding to LOs - Abc_NtkForEachLatch( pNtk, pNode, i ) - pNode->pCopy = Abc_NtkCreatePi(pNtkNew); - - // create a new node - pNodeNew = Abc_NtkCreateNode(pNtkNew); - // add the fanins corresponding to latch outputs - Abc_NtkForEachLatch( pNtk, pNode, i ) - Abc_ObjAddFanin( pNodeNew, pNode->pCopy ); - - // create the logic function - pPermute = ALLOC( int, dd->size ); - for ( i = 0; i < dd->size; i++ ) - pPermute[i] = -1; - Abc_NtkForEachLatch( pNtk, pNode, i ) - pPermute[Abc_NtkPiNum(pNtk) + i] = i; - // remap the functions - pNodeNew->pData = Extra_TransferPermute( dd, pNtkNew->pManFunc, bUnreach, pPermute ); Cudd_Ref( pNodeNew->pData ); - free( pPermute ); - Abc_NodeMinimumBase( pNodeNew ); - - // make the new node drive all the COs - Abc_NtkForEachCo( pNtk, pNode, i ) - Abc_ObjAddFanin( Abc_NtkCreatePo(pNtkNew), pNodeNew ); - - // store the PI names of the EXDC network - Abc_NtkForEachLatch( pNtk, pNode, i ) - Abc_NtkLogicStoreName( Abc_NtkPi(pNtkNew,i), Abc_ObjName(pNode) ); - // store the PO names of the EXDC network - Abc_NtkForEachPo( pNtk, pNode, i ) - Abc_NtkLogicStoreName( Abc_NtkPo(pNtkNew,i), Abc_ObjName(pNode) ); - Abc_NtkForEachLatch( pNtk, pNode, i ) - Abc_NtkLogicStoreName( Abc_NtkCo(pNtkNew,Abc_NtkPoNum(pNtk) + i), Abc_ObjNameSuffix(pNode, "_in") ); - - // make the network minimum base - Abc_NtkMinimumBase( pNtkNew ); - - // fix the problem with complemented and duplicated CO edges - Abc_NtkLogicMakeSimpleCos( pNtkNew, 0 ); - - // transform the network to the SOP representation - Abc_NtkBddToSop( pNtkNew ); - return pNtkNew; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/base/abc/abcVerify.c b/src/base/abc/abcVerify.c deleted file mode 100644 index 55d6cf7d..00000000 --- a/src/base/abc/abcVerify.c +++ /dev/null @@ -1,311 +0,0 @@ -/**CFile**************************************************************** - - FileName [abcVerify.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Network and node package.] - - Synopsis [Combinational and sequential verification for two networks.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: abcVerify.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" -#include "fraig.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Verifies combinational equivalence by brute-force SAT.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkCecSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2 ) -{ - Abc_Ntk_t * pMiter; - Abc_Ntk_t * pCnf; - int RetValue; - - // get the miter of the two networks - pMiter = Abc_NtkMiter( pNtk1, pNtk2, 1 ); - if ( pMiter == NULL ) - { - printf( "Miter computation has failed.\n" ); - return; - } - RetValue = Abc_NtkMiterIsConstant( pMiter ); - if ( RetValue == 1 ) - { - Abc_NtkDelete( pMiter ); - printf( "Networks are NOT EQUIVALENT after structural hashing.\n" ); - return; - } - if ( RetValue == 0 ) - { - Abc_NtkDelete( pMiter ); - printf( "Networks are equivalent after structural hashing.\n" ); - return; - } - - // convert the miter into a CNF - pCnf = Abc_NtkRenode( pMiter, 0, 100, 1, 0, 0 ); - Abc_NtkDelete( pMiter ); - if ( pCnf == NULL ) - { - printf( "Renoding for CNF has failed.\n" ); - return; - } - - // solve the CNF using the SAT solver - if ( Abc_NtkMiterSat( pCnf, 0 ) ) - printf( "Networks are NOT EQUIVALENT after SAT.\n" ); - else - printf( "Networks are equivalent after SAT.\n" ); - Abc_NtkDelete( pCnf ); -} - - -/**Function************************************************************* - - Synopsis [Verifies sequential equivalence by fraiging followed by SAT.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkCecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fVerbose ) -{ - Fraig_Params_t Params; - Abc_Ntk_t * pMiter; - Abc_Ntk_t * pFraig; - int RetValue; - - // get the miter of the two networks - pMiter = Abc_NtkMiter( pNtk1, pNtk2, 1 ); - if ( pMiter == NULL ) - { - printf( "Miter computation has failed.\n" ); - return; - } - RetValue = Abc_NtkMiterIsConstant( pMiter ); - if ( RetValue == 1 ) - { - Abc_NtkDelete( pMiter ); - printf( "Networks are NOT EQUIVALENT after structural hashing.\n" ); - return; - } - if ( RetValue == 0 ) - { - Abc_NtkDelete( pMiter ); - printf( "Networks are equivalent after structural hashing.\n" ); - return; - } - - // convert the miter into a FRAIG - Fraig_ParamsSetDefault( &Params ); - Params.fVerbose = fVerbose; - pFraig = Abc_NtkFraig( pMiter, &Params, 0 ); - Abc_NtkDelete( pMiter ); - if ( pFraig == NULL ) - { - printf( "Fraiging has failed.\n" ); - return; - } - RetValue = Abc_NtkMiterIsConstant( pFraig ); - Abc_NtkDelete( pFraig ); - if ( RetValue == 0 ) - { - printf( "Networks are equivalent after fraiging.\n" ); - return; - } - printf( "Networks are NOT EQUIVALENT after fraiging.\n" ); -} - -/**Function************************************************************* - - Synopsis [Verifies sequential equivalence by brute-force SAT.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkSecSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nFrames ) -{ - Abc_Ntk_t * pMiter; - Abc_Ntk_t * pFrames; - Abc_Ntk_t * pCnf; - int RetValue; - - // get the miter of the two networks - pMiter = Abc_NtkMiter( pNtk1, pNtk2, 0 ); - if ( pMiter == NULL ) - { - printf( "Miter computation has failed.\n" ); - return; - } - RetValue = Abc_NtkMiterIsConstant( pMiter ); - if ( RetValue == 1 ) - { - Abc_NtkDelete( pMiter ); - printf( "Networks are NOT EQUIVALENT after structural hashing.\n" ); - return; - } - if ( RetValue == 0 ) - { - Abc_NtkDelete( pMiter ); - printf( "Networks are equivalent after structural hashing.\n" ); - return; - } - - // create the timeframes - pFrames = Abc_NtkFrames( pMiter, nFrames, 1 ); - Abc_NtkDelete( pMiter ); - if ( pFrames == NULL ) - { - printf( "Frames computation has failed.\n" ); - return; - } - RetValue = Abc_NtkMiterIsConstant( pFrames ); - if ( RetValue == 1 ) - { - Abc_NtkDelete( pFrames ); - printf( "Networks are NOT EQUIVALENT after framing.\n" ); - return; - } - if ( RetValue == 0 ) - { - Abc_NtkDelete( pFrames ); - printf( "Networks are equivalent after framing.\n" ); - return; - } - - // convert the miter into a CNF - pCnf = Abc_NtkRenode( pFrames, 0, 100, 1, 0, 0 ); - Abc_NtkDelete( pFrames ); - if ( pCnf == NULL ) - { - printf( "Renoding for CNF has failed.\n" ); - return; - } - - // solve the CNF using the SAT solver - if ( Abc_NtkMiterSat( pCnf, 0 ) ) - printf( "Networks are NOT EQUIVALENT after SAT.\n" ); - else - printf( "Networks are equivalent after SAT.\n" ); - Abc_NtkDelete( pCnf ); -} - -/**Function************************************************************* - - Synopsis [Verifies combinational equivalence by fraiging followed by SAT] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkSecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nFrames ) -{ - Fraig_Params_t Params; - Abc_Ntk_t * pMiter; - Abc_Ntk_t * pFraig; - Abc_Ntk_t * pFrames; - int RetValue; - - // get the miter of the two networks - pMiter = Abc_NtkMiter( pNtk1, pNtk2, 0 ); - if ( pMiter == NULL ) - { - printf( "Miter computation has failed.\n" ); - return; - } - RetValue = Abc_NtkMiterIsConstant( pMiter ); - if ( RetValue == 1 ) - { - Abc_NtkDelete( pMiter ); - printf( "Networks are NOT EQUIVALENT after structural hashing.\n" ); - return; - } - if ( RetValue == 0 ) - { - Abc_NtkDelete( pMiter ); - printf( "Networks are equivalent after structural hashing.\n" ); - return; - } - - // create the timeframes - pFrames = Abc_NtkFrames( pMiter, nFrames, 1 ); - Abc_NtkDelete( pMiter ); - if ( pFrames == NULL ) - { - printf( "Frames computation has failed.\n" ); - return; - } - RetValue = Abc_NtkMiterIsConstant( pFrames ); - if ( RetValue == 1 ) - { - Abc_NtkDelete( pFrames ); - printf( "Networks are NOT EQUIVALENT after framing.\n" ); - return; - } - if ( RetValue == 0 ) - { - Abc_NtkDelete( pFrames ); - printf( "Networks are equivalent after framing.\n" ); - return; - } - - // convert the miter into a FRAIG - Fraig_ParamsSetDefault( &Params ); - pFraig = Abc_NtkFraig( pFrames, &Params, 0 ); - Abc_NtkDelete( pFrames ); - if ( pFraig == NULL ) - { - printf( "Fraiging has failed.\n" ); - return; - } - RetValue = Abc_NtkMiterIsConstant( pFraig ); - Abc_NtkDelete( pFraig ); - if ( RetValue == 0 ) - { - printf( "Networks are equivalent after fraiging.\n" ); - return; - } - printf( "Networks are NOT EQUIVALENT after fraiging.\n" ); -} - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/base/abc/module.make b/src/base/abc/module.make index 695e056b..649e71a2 100644 --- a/src/base/abc/module.make +++ b/src/base/abc/module.make @@ -1,40 +1,15 @@ -SRC += src/base/abc/abc.c \ - src/base/abc/abcAig.c \ - src/base/abc/abcAttach.c \ - src/base/abc/abcBalance.c \ +SRC += src/base/abc/abcAig.c \ src/base/abc/abcCheck.c \ - src/base/abc/abcCollapse.c \ - src/base/abc/abcCreate.c \ - src/base/abc/abcCut.c \ src/base/abc/abcDfs.c \ - src/base/abc/abcDsd.c \ src/base/abc/abcFanio.c \ - src/base/abc/abcFpga.c \ - src/base/abc/abcFraig.c \ src/base/abc/abcFunc.c \ - src/base/abc/abcFxu.c \ src/base/abc/abcLatch.c \ - src/base/abc/abcMap.c \ src/base/abc/abcMinBase.c \ - src/base/abc/abcMiter.c \ src/base/abc/abcNames.c \ src/base/abc/abcNetlist.c \ - src/base/abc/abcNtbdd.c \ - src/base/abc/abcPrint.c \ - src/base/abc/abcReconv.c \ - src/base/abc/abcRefactor.c \ + src/base/abc/abcNtk.c \ + src/base/abc/abcObj.c \ src/base/abc/abcRefs.c \ - src/base/abc/abcRenode.c \ - src/base/abc/abcRewrite.c \ - src/base/abc/abcSat.c \ - src/base/abc/abcSeq.c \ - src/base/abc/abcSeqRetime.c \ src/base/abc/abcShow.c \ src/base/abc/abcSop.c \ - src/base/abc/abcStrash.c \ - src/base/abc/abcSweep.c \ - src/base/abc/abcSymm.c \ - src/base/abc/abcTiming.c \ - src/base/abc/abcUnreach.c \ - src/base/abc/abcUtil.c \ - src/base/abc/abcVerify.c + src/base/abc/abcUtil.c diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c new file mode 100644 index 00000000..30047d23 --- /dev/null +++ b/src/base/abci/abc.c @@ -0,0 +1,4058 @@ +/**CFile**************************************************************** + + FileName [abc.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Network and node package.] + + Synopsis [Command file.] + + 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" +#include "mainInt.h" +#include "fraig.h" +#include "fxu.h" +#include "cut.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static int Abc_CommandPrintStats ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandPrintIo ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandPrintLatch ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandPrintFanio ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandPrintFactor ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandPrintLevel ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandPrintSupport ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandPrintSymms ( Abc_Frame_t * pAbc, int argc, char ** argv ); + +static int Abc_CommandShowBdd ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandShowCut ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandShowAig ( Abc_Frame_t * pAbc, int argc, char ** argv ); + +static int Abc_CommandCollapse ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandStrash ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandBalance ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandRenode ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandCleanup ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandSweep ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandFastExtract ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandDisjoint ( Abc_Frame_t * pAbc, int argc, char ** argv ); + +static int Abc_CommandRewrite ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandRefactor ( Abc_Frame_t * pAbc, int argc, char ** argv ); + +static int Abc_CommandLogic ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandMiter ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandFrames ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandSop ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandBdd ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandMuxes ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandSat ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandExtSeqDcs ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandOneOutput ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandOneNode ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandShortNames ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandCut ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandTest ( Abc_Frame_t * pAbc, int argc, char ** argv ); + +static int Abc_CommandFraig ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandFraigTrust ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandFraigStore ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandFraigRestore ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandFraigClean ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandFraigSweep ( Abc_Frame_t * pAbc, int argc, char ** argv ); + +static int Abc_CommandMap ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandUnmap ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAttach ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandSuperChoice ( Abc_Frame_t * pAbc, int argc, char ** argv ); + +static int Abc_CommandFpga ( Abc_Frame_t * pAbc, int argc, char ** argv ); + +static int Abc_CommandSeq ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandRetime ( Abc_Frame_t * pAbc, int argc, char ** argv ); + +static int Abc_CommandCec ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandSec ( Abc_Frame_t * pAbc, int argc, char ** argv ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_Init( Abc_Frame_t * pAbc ) +{ + Cmd_CommandAdd( pAbc, "Printing", "print_stats", Abc_CommandPrintStats, 0 ); + Cmd_CommandAdd( pAbc, "Printing", "print_io", Abc_CommandPrintIo, 0 ); + Cmd_CommandAdd( pAbc, "Printing", "print_latch", Abc_CommandPrintLatch, 0 ); + Cmd_CommandAdd( pAbc, "Printing", "print_fanio", Abc_CommandPrintFanio, 0 ); + Cmd_CommandAdd( pAbc, "Printing", "print_factor", Abc_CommandPrintFactor, 0 ); + Cmd_CommandAdd( pAbc, "Printing", "print_level", Abc_CommandPrintLevel, 0 ); + Cmd_CommandAdd( pAbc, "Printing", "print_supp", Abc_CommandPrintSupport, 0 ); + Cmd_CommandAdd( pAbc, "Printing", "print_symm", Abc_CommandPrintSymms, 0 ); + + Cmd_CommandAdd( pAbc, "Printing", "show_bdd", Abc_CommandShowBdd, 0 ); + Cmd_CommandAdd( pAbc, "Printing", "show_cut", Abc_CommandShowCut, 0 ); + Cmd_CommandAdd( pAbc, "Printing", "show_aig", Abc_CommandShowAig, 0 ); + + Cmd_CommandAdd( pAbc, "Synthesis", "collapse", Abc_CommandCollapse, 1 ); + Cmd_CommandAdd( pAbc, "Synthesis", "strash", Abc_CommandStrash, 1 ); + Cmd_CommandAdd( pAbc, "Synthesis", "balance", Abc_CommandBalance, 1 ); + Cmd_CommandAdd( pAbc, "Synthesis", "renode", Abc_CommandRenode, 1 ); + Cmd_CommandAdd( pAbc, "Synthesis", "cleanup", Abc_CommandCleanup, 1 ); + Cmd_CommandAdd( pAbc, "Synthesis", "sweep", Abc_CommandSweep, 1 ); + Cmd_CommandAdd( pAbc, "Synthesis", "fx", Abc_CommandFastExtract, 1 ); + Cmd_CommandAdd( pAbc, "Synthesis", "dsd", Abc_CommandDisjoint, 1 ); + + Cmd_CommandAdd( pAbc, "Synthesis", "rewrite", Abc_CommandRewrite, 1 ); + Cmd_CommandAdd( pAbc, "Synthesis", "refactor", Abc_CommandRefactor, 1 ); + + Cmd_CommandAdd( pAbc, "Various", "logic", Abc_CommandLogic, 1 ); + Cmd_CommandAdd( pAbc, "Various", "miter", Abc_CommandMiter, 1 ); + Cmd_CommandAdd( pAbc, "Various", "frames", Abc_CommandFrames, 1 ); + Cmd_CommandAdd( pAbc, "Various", "sop", Abc_CommandSop, 0 ); + Cmd_CommandAdd( pAbc, "Various", "bdd", Abc_CommandBdd, 0 ); + Cmd_CommandAdd( pAbc, "Various", "muxes", Abc_CommandMuxes, 1 ); + Cmd_CommandAdd( pAbc, "Various", "sat", Abc_CommandSat, 0 ); + Cmd_CommandAdd( pAbc, "Various", "ext_seq_dcs", Abc_CommandExtSeqDcs, 0 ); + Cmd_CommandAdd( pAbc, "Various", "one_output", Abc_CommandOneOutput, 1 ); + Cmd_CommandAdd( pAbc, "Various", "one_node", Abc_CommandOneNode, 1 ); + Cmd_CommandAdd( pAbc, "Various", "short_names", Abc_CommandShortNames, 0 ); + Cmd_CommandAdd( pAbc, "Various", "cut", Abc_CommandCut, 0 ); + Cmd_CommandAdd( pAbc, "Various", "test", Abc_CommandTest, 0 ); + + Cmd_CommandAdd( pAbc, "Fraiging", "fraig", Abc_CommandFraig, 1 ); + Cmd_CommandAdd( pAbc, "Fraiging", "fraig_trust", Abc_CommandFraigTrust, 1 ); + Cmd_CommandAdd( pAbc, "Fraiging", "fraig_store", Abc_CommandFraigStore, 0 ); + Cmd_CommandAdd( pAbc, "Fraiging", "fraig_restore", Abc_CommandFraigRestore, 1 ); + Cmd_CommandAdd( pAbc, "Fraiging", "fraig_clean", Abc_CommandFraigClean, 0 ); + Cmd_CommandAdd( pAbc, "Fraiging", "fraig_sweep", Abc_CommandFraigSweep, 1 ); + + Cmd_CommandAdd( pAbc, "SC mapping", "map", Abc_CommandMap, 1 ); + Cmd_CommandAdd( pAbc, "SC mapping", "unmap", Abc_CommandUnmap, 1 ); + Cmd_CommandAdd( pAbc, "SC mapping", "attach", Abc_CommandAttach, 1 ); + Cmd_CommandAdd( pAbc, "SC mapping", "sc", Abc_CommandSuperChoice, 1 ); + + Cmd_CommandAdd( pAbc, "FPGA mapping", "fpga", Abc_CommandFpga, 1 ); + + Cmd_CommandAdd( pAbc, "Sequential", "seq", Abc_CommandSeq, 1 ); + Cmd_CommandAdd( pAbc, "Sequential", "retime", Abc_CommandRetime, 1 ); + + Cmd_CommandAdd( pAbc, "Verification", "cec", Abc_CommandCec, 0 ); + Cmd_CommandAdd( pAbc, "Verification", "sec", Abc_CommandSec, 0 ); + +// Rwt_Man4ExploreStart(); +// Map_Var3Print(); +// Map_Var4Test(); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_End() +{ + Abc_NtkFraigStoreClean(); +// Rwt_Man4ExplorePrint(); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandPrintStats( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk; + bool fShort; + int c; + int fFactor; + + pNtk = Abc_FrameReadNet(pAbc); + pOut = Abc_FrameReadOut(pAbc); + pErr = Abc_FrameReadErr(pAbc); + + // set the defaults + fShort = 1; + fFactor = 0; + util_getopt_reset(); + while ( ( c = util_getopt( argc, argv, "sfh" ) ) != EOF ) + { + switch ( c ) + { + case 's': + fShort ^= 1; + break; + case 'f': + fFactor ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + + if ( pNtk == NULL ) + { + fprintf( Abc_FrameReadErr(pAbc), "Empty network\n" ); + return 1; + } + Abc_NtkPrintStats( pOut, pNtk, fFactor ); + return 0; + +usage: + fprintf( pErr, "usage: print_stats [-fh]\n" ); + fprintf( pErr, "\t prints the network statistics and\n" ); + fprintf( pErr, "\t-f : toggles printing the literal count in the factored forms [default = %s]\n", fFactor? "yes": "no" ); + fprintf( pErr, "\t-h : print the command usage\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandPrintIo( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk; + Abc_Obj_t * pNode; + int c; + + 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 ( argc > util_optind + 1 ) + { + fprintf( pErr, "Wrong number of auguments.\n" ); + goto usage; + } + + if ( argc == util_optind + 1 ) + { + pNode = Abc_NtkFindNode( pNtk, argv[util_optind] ); + if ( pNode == NULL ) + { + fprintf( pErr, "Cannot find node \"%s\".\n", argv[util_optind] ); + return 1; + } + Abc_NodePrintFanio( pOut, pNode ); + return 0; + } + // print the nodes + Abc_NtkPrintIo( pOut, pNtk ); + return 0; + +usage: + fprintf( pErr, "usage: print_io [-h] \n" ); + fprintf( pErr, "\t prints the PIs/POs or fanins/fanouts of a node\n" ); + fprintf( pErr, "\t-h : print the command usage\n"); + fprintf( pErr, "\tnode : the node to print fanins/fanouts\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandPrintLatch( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk; + int c; + + 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; + } + // print the nodes + Abc_NtkPrintLatch( pOut, pNtk ); + return 0; + +usage: + fprintf( pErr, "usage: print_latch [-h]\n" ); + fprintf( pErr, "\t prints information about latches\n" ); + fprintf( pErr, "\t-h : print the command usage\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandPrintFanio( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk; + int c; + + 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; + } + + // print the nodes + Abc_NtkPrintFanio( pOut, pNtk ); + return 0; + +usage: + fprintf( pErr, "usage: print_fanio [-h]\n" ); + fprintf( pErr, "\t prints the statistics about fanins/fanouts of all nodes\n" ); + fprintf( pErr, "\t-h : print the command usage\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandPrintFactor( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk; + Abc_Obj_t * pNode; + int c; + int fUseRealNames; + + pNtk = Abc_FrameReadNet(pAbc); + pOut = Abc_FrameReadOut(pAbc); + pErr = Abc_FrameReadErr(pAbc); + + // set defaults + fUseRealNames = 1; + util_getopt_reset(); + while ( ( c = util_getopt( argc, argv, "nh" ) ) != EOF ) + { + switch ( c ) + { + case 'n': + fUseRealNames ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + + if ( pNtk == NULL ) + { + fprintf( pErr, "Empty network.\n" ); + return 1; + } + + if ( !Abc_NtkIsSopLogic(pNtk) ) + { + fprintf( pErr, "Printing factored forms can be done for SOP networks.\n" ); + return 1; + } + + if ( argc > util_optind + 1 ) + { + fprintf( pErr, "Wrong number of auguments.\n" ); + goto usage; + } + + if ( argc == util_optind + 1 ) + { + pNode = Abc_NtkFindNode( pNtk, argv[util_optind] ); + if ( pNode == NULL ) + { + fprintf( pErr, "Cannot find node \"%s\".\n", argv[util_optind] ); + return 1; + } + Abc_NodePrintFactor( pOut, pNode, fUseRealNames ); + return 0; + } + // print the nodes + Abc_NtkPrintFactor( pOut, pNtk, fUseRealNames ); + return 0; + +usage: + fprintf( pErr, "usage: print_factor [-nh] \n" ); + fprintf( pErr, "\t prints the factored forms of nodes\n" ); + fprintf( pErr, "\t-n : toggles real/dummy fanin names [default = %s]\n", fUseRealNames? "real": "dummy" ); + fprintf( pErr, "\t-h : print the command usage\n"); + fprintf( pErr, "\tnode : (optional) one node to consider\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandPrintLevel( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk; + Abc_Obj_t * pNode; + int c; + int fProfile; + + pNtk = Abc_FrameReadNet(pAbc); + pOut = Abc_FrameReadOut(pAbc); + pErr = Abc_FrameReadErr(pAbc); + + // set defaults + fProfile = 1; + util_getopt_reset(); + while ( ( c = util_getopt( argc, argv, "ph" ) ) != EOF ) + { + switch ( c ) + { + case 'p': + fProfile ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + + if ( pNtk == NULL ) + { + fprintf( pErr, "Empty network.\n" ); + return 1; + } + + if ( !fProfile && !Abc_NtkIsStrash(pNtk) ) + { + fprintf( pErr, "This command works only for AIGs.\n" ); + return 1; + } + + if ( argc > util_optind + 1 ) + { + fprintf( pErr, "Wrong number of auguments.\n" ); + goto usage; + } + + if ( argc == util_optind + 1 ) + { + pNode = Abc_NtkFindNode( pNtk, argv[util_optind] ); + if ( pNode == NULL ) + { + fprintf( pErr, "Cannot find node \"%s\".\n", argv[util_optind] ); + return 1; + } + Abc_NodePrintLevel( pOut, pNode ); + return 0; + } + // process all COs + Abc_NtkPrintLevel( pOut, pNtk, fProfile ); + return 0; + +usage: + fprintf( pErr, "usage: print_level [-ph] \n" ); + fprintf( pErr, "\t prints information about node level and cone size\n" ); + fprintf( pErr, "\t-p : toggles printing level profile [default = %s]\n", fProfile? "yes": "no" ); + fprintf( pErr, "\t-h : print the command usage\n"); + fprintf( pErr, "\tnode : (optional) one node to consider\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandPrintSupport( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + Vec_Ptr_t * vSuppFun; + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk; + int c; + extern Vec_Ptr_t * Sim_ComputeFunSupp( 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_NtkIsComb(pNtk) ) + { + fprintf( pErr, "This command works only for combinational networks.\n" ); + return 1; + } + + if ( !Abc_NtkIsStrash(pNtk) ) + { + fprintf( pErr, "This command works only for AIGs.\n" ); + return 1; + } + vSuppFun = Sim_ComputeFunSupp( pNtk ); + free( vSuppFun->pArray[0] ); + Vec_PtrFree( vSuppFun ); + return 0; + +usage: + fprintf( pErr, "usage: print_supp [-h]\n" ); + fprintf( pErr, "\t prints the supports of the CO nodes\n" ); + fprintf( pErr, "\t-h : print the command usage\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandPrintSymms( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk; + int c; + int fUseBdds; + int fNaive; + int fVerbose; + extern void Abc_NtkSymmetries( Abc_Ntk_t * pNtk, int fUseBdds, int fNaive, int fVerbose ); + + pNtk = Abc_FrameReadNet(pAbc); + pOut = Abc_FrameReadOut(pAbc); + pErr = Abc_FrameReadErr(pAbc); + + // set defaults + fUseBdds = 0; + fNaive = 0; + fVerbose = 0; + util_getopt_reset(); + while ( ( c = util_getopt( argc, argv, "bnvh" ) ) != EOF ) + { + switch ( c ) + { + case 'b': + fUseBdds ^= 1; + break; + case 'n': + fNaive ^= 1; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pNtk == NULL ) + { + fprintf( pErr, "Empty network.\n" ); + return 1; + } + if ( !Abc_NtkIsComb(pNtk) ) + { + fprintf( pErr, "This command works only for combinational networks.\n" ); + return 1; + } + if ( !Abc_NtkIsStrash(pNtk) ) + { + fprintf( pErr, "This command works only for AIGs.\n" ); + return 1; + } + Abc_NtkSymmetries( pNtk, fUseBdds, fNaive, fVerbose ); + return 0; + +usage: + fprintf( pErr, "usage: print_symm [-nbvh]\n" ); + fprintf( pErr, "\t computes symmetries of the PO functions\n" ); + fprintf( pErr, "\t-b : enable efficient BDD-based computation [default = %s].\n", fUseBdds? "yes": "no" ); + fprintf( pErr, "\t-n : enable naive BDD-based computation [default = %s].\n", fNaive? "yes": "no" ); + fprintf( pErr, "\t-v : enable verbose output [default = %s].\n", fVerbose? "yes": "no" ); + fprintf( pErr, "\t-h : print the command usage\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandShowBdd( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk; + Abc_Obj_t * pNode; + int c; + extern void Abc_NodeShowBdd( Abc_Obj_t * pNode ); + + 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_NtkIsBddLogic(pNtk) ) + { + fprintf( pErr, "Visualizing BDDs can only be done for logic BDD networks.\n" ); + return 1; + } + + if ( argc != util_optind + 1 ) + { + fprintf( pErr, "Wrong number of auguments.\n" ); + goto usage; + } + + pNode = Abc_NtkFindNode( pNtk, argv[util_optind] ); + if ( pNode == NULL ) + { + fprintf( pErr, "Cannot find node \"%s\".\n", argv[util_optind] ); + return 1; + } + Abc_NodeShowBdd( pNode ); + return 0; + +usage: + fprintf( pErr, "usage: show_bdd [-h] \n" ); + fprintf( pErr, " visualizes the BDD of a node using DOT and GSVIEW\n" ); +#ifdef WIN32 + fprintf( pErr, " \"dot.exe\" and \"gsview32.exe\" should be set in the paths\n" ); + fprintf( pErr, " (\"gsview32.exe\" may be in \"C:\\Program Files\\Ghostgum\\gsview\\\")\n" ); +#endif + fprintf( pErr, "\tnode : the node to consider\n"); + fprintf( pErr, "\t-h : print the command usage\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandShowCut( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk; + Abc_Obj_t * pNode; + int c; + int nNodeSizeMax; + int nConeSizeMax; + extern void Abc_NodeShowCut( Abc_Obj_t * pNode, int nNodeSizeMax, int nConeSizeMax ); + + pNtk = Abc_FrameReadNet(pAbc); + pOut = Abc_FrameReadOut(pAbc); + pErr = Abc_FrameReadErr(pAbc); + + // set defaults + nNodeSizeMax = 10; + nConeSizeMax = ABC_INFINITY; + util_getopt_reset(); + while ( ( c = util_getopt( argc, argv, "NCh" ) ) != EOF ) + { + switch ( c ) + { + case 'N': + if ( util_optind >= argc ) + { + fprintf( pErr, "Command line switch \"-N\" should be followed by an integer.\n" ); + goto usage; + } + nNodeSizeMax = atoi(argv[util_optind]); + util_optind++; + if ( nNodeSizeMax < 0 ) + goto usage; + break; + case 'C': + if ( util_optind >= argc ) + { + fprintf( pErr, "Command line switch \"-C\" should be followed by an integer.\n" ); + goto usage; + } + nConeSizeMax = atoi(argv[util_optind]); + util_optind++; + if ( nConeSizeMax < 0 ) + goto usage; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + + if ( pNtk == NULL ) + { + fprintf( pErr, "Empty network.\n" ); + return 1; + } + + if ( !Abc_NtkIsStrash(pNtk) ) + { + fprintf( pErr, "Visualizing cuts only works for AIGs.\n" ); + return 1; + } + if ( argc != util_optind + 1 ) + { + fprintf( pErr, "Wrong number of auguments.\n" ); + goto usage; + } + + pNode = Abc_NtkFindNode( pNtk, argv[util_optind] ); + if ( pNode == NULL ) + { + fprintf( pErr, "Cannot find node \"%s\".\n", argv[util_optind] ); + return 1; + } + Abc_NodeShowCut( pNode, nNodeSizeMax, nConeSizeMax ); + return 0; + +usage: + fprintf( pErr, "usage: show_cut [-N num] [-C num] [-h] \n" ); + fprintf( pErr, " visualizes the cut of a node using DOT and GSVIEW\n" ); +#ifdef WIN32 + fprintf( pErr, " \"dot.exe\" and \"gsview32.exe\" should be set in the paths\n" ); + fprintf( pErr, " (\"gsview32.exe\" may be in \"C:\\Program Files\\Ghostgum\\gsview\\\")\n" ); +#endif + fprintf( pErr, "\t-N num : the max size of the cut to be computed [default = %d]\n", nNodeSizeMax ); + fprintf( pErr, "\t-C num : the max support of the containing cone [default = %d]\n", nConeSizeMax ); + fprintf( pErr, "\tnode : the node to consider\n"); + fprintf( pErr, "\t-h : print the command usage\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandShowAig( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk; + int c; + extern void Abc_NtkShowAig( 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_NtkIsStrash(pNtk) ) + { + fprintf( pErr, "Visualizing AIG can only be done for AIGs.\n" ); + return 1; + } + Abc_NtkShowAig( pNtk ); + return 0; + +usage: + fprintf( pErr, "usage: show_aig [-h]\n" ); + fprintf( pErr, " visualizes the AIG with choices using DOT and GSVIEW\n" ); +#ifdef WIN32 + fprintf( pErr, " \"dot.exe\" and \"gsview32.exe\" should be set in the paths\n" ); + fprintf( pErr, " (\"gsview32.exe\" may be in \"C:\\Program Files\\Ghostgum\\gsview\\\")\n" ); +#endif + fprintf( pErr, "\t-h : print the command usage\n"); + return 1; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandCollapse( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk, * pNtkRes; + int c; + + 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_NtkIsLogic(pNtk) && !Abc_NtkIsStrash(pNtk) ) + { + fprintf( pErr, "Can only collapse a logic network.\n" ); + return 1; + } + + // get the new network + if ( Abc_NtkIsStrash(pNtk) ) + pNtkRes = Abc_NtkCollapse( pNtk, 1 ); + else + { + pNtk = Abc_NtkStrash( pNtk, 0, 0 ); + pNtkRes = Abc_NtkCollapse( pNtk, 1 ); + Abc_NtkDelete( pNtk ); + } + if ( pNtkRes == NULL ) + { + fprintf( pErr, "Collapsing has failed.\n" ); + return 1; + } + // replace the current network + Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); + return 0; + +usage: + fprintf( pErr, "usage: collapse [-h]\n" ); + fprintf( pErr, "\t collapses the network by constructing global BDDs\n" ); + fprintf( pErr, "\t-h : print the command usage\n"); + return 1; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandStrash( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk, * pNtkRes; + int c; + int fAllNodes; + int fCleanup; + + pNtk = Abc_FrameReadNet(pAbc); + pOut = Abc_FrameReadOut(pAbc); + pErr = Abc_FrameReadErr(pAbc); + + // set defaults + fAllNodes = 0; + fCleanup = 1; + util_getopt_reset(); + while ( ( c = util_getopt( argc, argv, "ach" ) ) != EOF ) + { + switch ( c ) + { + case 'a': + fAllNodes ^= 1; + break; + case 'c': + fCleanup ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + + if ( pNtk == NULL ) + { + fprintf( pErr, "Empty network.\n" ); + return 1; + } + + // get the new network + pNtkRes = Abc_NtkStrash( pNtk, fAllNodes, fCleanup ); + if ( pNtkRes == NULL ) + { + fprintf( pErr, "Strashing has failed.\n" ); + return 1; + } + // replace the current network + Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); + return 0; + +usage: + fprintf( pErr, "usage: strash [-ach]\n" ); + fprintf( pErr, "\t transforms combinational logic into an AIG\n" ); + fprintf( pErr, "\t-a : toggles between using all nodes and DFS nodes [default = %s]\n", fAllNodes? "all": "DFS" ); + fprintf( pErr, "\t-c : toggles cleanup to remove the dagling AIG nodes [default = %s]\n", fCleanup? "all": "DFS" ); + fprintf( pErr, "\t-h : print the command usage\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandBalance( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk, * pNtkRes, * pNtkTemp; + int c; + int fDuplicate; + + pNtk = Abc_FrameReadNet(pAbc); + pOut = Abc_FrameReadOut(pAbc); + pErr = Abc_FrameReadErr(pAbc); + + // set defaults + fDuplicate = 0; + util_getopt_reset(); + while ( ( c = util_getopt( argc, argv, "dh" ) ) != EOF ) + { + switch ( c ) + { + case 'd': + fDuplicate ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + + if ( pNtk == NULL ) + { + fprintf( pErr, "Empty network.\n" ); + return 1; + } + + // get the new network + if ( Abc_NtkIsStrash(pNtk) ) + { + pNtkRes = Abc_NtkBalance( pNtk, fDuplicate ); + } + else + { + pNtkTemp = Abc_NtkStrash( pNtk, 0, 0 ); + if ( pNtkTemp == NULL ) + { + fprintf( pErr, "Strashing before balancing has failed.\n" ); + return 1; + } + pNtkRes = Abc_NtkBalance( pNtkTemp, fDuplicate ); + Abc_NtkDelete( pNtkTemp ); + } + + // check if balancing worked + if ( pNtkRes == NULL ) + { + fprintf( pErr, "Balancing has failed.\n" ); + return 1; + } + // replace the current network + Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); + return 0; + +usage: + fprintf( pErr, "usage: balance [-dh]\n" ); + fprintf( pErr, "\t transforms the current network into a well-balanced AIG\n" ); + fprintf( pErr, "\t-d : toggle duplication of logic [default = %s]\n", fDuplicate? "yes": "no" ); + fprintf( pErr, "\t-h : print the command usage\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandRenode( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk, * pNtkRes; + int nThresh, nFaninMax, c; + int fCnf; + int fMulti; + int fSimple; + + pNtk = Abc_FrameReadNet(pAbc); + pOut = Abc_FrameReadOut(pAbc); + pErr = Abc_FrameReadErr(pAbc); + + // set defaults + nThresh = 1; + nFaninMax = 20; + fCnf = 0; + fMulti = 0; + fSimple = 0; + util_getopt_reset(); + while ( ( c = util_getopt( argc, argv, "TFmcsh" ) ) != EOF ) + { + switch ( c ) + { + case 'T': + if ( util_optind >= argc ) + { + fprintf( pErr, "Command line switch \"-T\" should be followed by an integer.\n" ); + goto usage; + } + nThresh = atoi(argv[util_optind]); + util_optind++; + if ( nThresh < 0 ) + goto usage; + break; + case 'F': + if ( util_optind >= argc ) + { + fprintf( pErr, "Command line switch \"-F\" should be followed by an integer.\n" ); + goto usage; + } + nFaninMax = atoi(argv[util_optind]); + util_optind++; + if ( nFaninMax < 0 ) + goto usage; + break; + case 'c': + fCnf ^= 1; + break; + case 'm': + fMulti ^= 1; + break; + case 's': + fSimple ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + + if ( pNtk == NULL ) + { + fprintf( pErr, "Empty network.\n" ); + return 1; + } + if ( !Abc_NtkIsStrash(pNtk) ) + { + fprintf( pErr, "Cannot renode a network that is not an AIG.\n" ); + return 1; + } + + // get the new network + pNtkRes = Abc_NtkRenode( pNtk, nThresh, nFaninMax, fCnf, fMulti, fSimple ); + if ( pNtkRes == NULL ) + { + fprintf( pErr, "Renoding has failed.\n" ); + return 1; + } + // replace the current network + Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); + return 0; + +usage: + fprintf( pErr, "usage: renode [-T num] [-F num] [-cmsh]\n" ); + fprintf( pErr, "\t transforms an AIG into a logic network by creating larger nodes\n" ); + fprintf( pErr, "\t-F num : the maximum fanin size after renoding [default = %d]\n", nFaninMax ); + fprintf( pErr, "\t-T num : the threshold for AIG node duplication [default = %d]\n", nThresh ); + fprintf( pErr, "\t (an AIG node is the root of a new node after renoding\n" ); + fprintf( pErr, "\t if doing so prevents duplication of more than %d AIG nodes,\n", nThresh ); + fprintf( pErr, "\t that is, if [(numFanouts(Node)-1) * size(MFFC(Node))] > %d)\n", nThresh ); + fprintf( pErr, "\t-m : creates multi-input AND graph [default = %s]\n", fMulti? "yes": "no" ); + fprintf( pErr, "\t-s : creates a simple AIG (no renoding) [default = %s]\n", fSimple? "yes": "no" ); + fprintf( pErr, "\t-c : performs renoding to derive the CNF [default = %s]\n", fCnf? "yes": "no" ); + fprintf( pErr, "\t-h : print the command usage\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandCleanup( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk; + int c; + + 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_NtkIsStrash(pNtk) ) + { + fprintf( pErr, "Cleanup cannot be performed on the AIG.\n" ); + return 1; + } + // modify the current network + Abc_NtkCleanup( pNtk, 0 ); + return 0; + +usage: + fprintf( pErr, "usage: cleanup [-h]\n" ); + fprintf( pErr, "\t removes dangling nodes\n" ); + fprintf( pErr, "\t-h : print the command usage\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandSweep( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk; + int c; + + 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_NtkIsSopLogic(pNtk) && !Abc_NtkIsBddLogic(pNtk) ) + { + fprintf( pErr, "Sweep cannot be performed on an AIG or a mapped network (unmap it first).\n" ); + return 1; + } + // modify the current network + Abc_NtkSweep( pNtk, 0 ); + return 0; + +usage: + fprintf( pErr, "usage: sweep [-h]\n" ); + fprintf( pErr, "\t removes dangling nodes; propagates constant, buffers, inverters\n" ); + fprintf( pErr, "\t-h : print the command usage\n"); + return 1; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandFastExtract( 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; + } + + if ( !Abc_NtkIsLogic(pNtk) ) + { + fprintf( pErr, "Fast extract can only be applied to a logic network.\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 [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandDisjoint( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk, * pNtkRes, * pNtkNew; + int fGlobal, fRecursive, fVerbose, fPrint, fShort, c; + + extern Abc_Ntk_t * Abc_NtkDsdGlobal( Abc_Ntk_t * pNtk, bool fVerbose, bool fPrint, bool fShort ); + extern int Abc_NtkDsdLocal( Abc_Ntk_t * pNtk, bool fVerbose, bool fRecursive ); + + pNtk = Abc_FrameReadNet(pAbc); + pOut = Abc_FrameReadOut(pAbc); + pErr = Abc_FrameReadErr(pAbc); + + // set defaults + fGlobal = 1; + fRecursive = 0; + fVerbose = 0; + fPrint = 0; + fShort = 0; + util_getopt_reset(); + while ( ( c = util_getopt( argc, argv, "grvpsh" ) ) != EOF ) + { + switch ( c ) + { + case 'g': + fGlobal ^= 1; + break; + case 'r': + fRecursive ^= 1; + break; + case 'v': + fVerbose ^= 1; + break; + case 'p': + fPrint ^= 1; + break; + case 's': + fShort ^= 1; + break; + case 'h': + goto usage; + break; + default: + goto usage; + } + } + + if ( pNtk == NULL ) + { + fprintf( pErr, "Empty network.\n" ); + return 1; + } + + if ( fGlobal ) + { +// fprintf( stdout, "Performing DSD of global functions of the network.\n" ); + // get the new network + if ( !Abc_NtkIsStrash(pNtk) ) + { + pNtkNew = Abc_NtkStrash( pNtk, 0, 0 ); + pNtkRes = Abc_NtkDsdGlobal( pNtkNew, fVerbose, fPrint, fShort ); + Abc_NtkDelete( pNtkNew ); + } + else + { + pNtkRes = Abc_NtkDsdGlobal( pNtk, fVerbose, fPrint, fShort ); + } + if ( pNtkRes == NULL ) + { + fprintf( pErr, "Global DSD has failed.\n" ); + return 1; + } + // replace the current network + Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); + } + else if ( fRecursive ) + { + if ( !Abc_NtkIsBddLogic( pNtk ) ) + { + fprintf( pErr, "This command is only applicable to logic BDD networks.\n" ); + return 1; + } + fprintf( stdout, "Performing recursive DSD and MUX decomposition of local functions.\n" ); + if ( !Abc_NtkDsdLocal( pNtk, fVerbose, fRecursive ) ) + fprintf( pErr, "Recursive DSD has failed.\n" ); + } + else + { + if ( !Abc_NtkIsBddLogic( pNtk ) ) + { + fprintf( pErr, "This command is only applicable to logic BDD networks.\n" ); + return 1; + } + fprintf( stdout, "Performing simple non-recursive DSD of local functions.\n" ); + if ( !Abc_NtkDsdLocal( pNtk, fVerbose, fRecursive ) ) + fprintf( pErr, "Simple DSD of local functions has failed.\n" ); + } + return 0; + +usage: + fprintf( pErr, "usage: dsd [-grvpsh]\n" ); + fprintf( pErr, "\t decomposes the network using disjoint-support decomposition\n" ); + fprintf( pErr, "\t-g : toggle DSD of global and local functions [default = %s]\n", fGlobal? "global": "local" ); + fprintf( pErr, "\t-r : toggle recursive DSD/MUX and simple DSD [default = %s]\n", fRecursive? "recursive DSD/MUX": "simple DSD" ); + fprintf( pErr, "\t-v : prints DSD statistics and runtime [default = %s]\n", fVerbose? "yes": "no" ); + fprintf( pErr, "\t-p : prints DSD structure to the standard output [default = %s]\n", fPrint? "yes": "no" ); + fprintf( pErr, "\t-s : use short PI names when printing DSD structure [default = %s]\n", fShort? "yes": "no" ); + fprintf( pErr, "\t-h : print the command usage\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandRewrite( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk; + int c; + bool fPrecompute; + bool fUseZeros; + bool fVerbose; + // external functions + extern void Rwr_Precompute(); + extern int Abc_NtkRewrite( Abc_Ntk_t * pNtk, int fUseZeros, int fVerbose ); + + pNtk = Abc_FrameReadNet(pAbc); + pOut = Abc_FrameReadOut(pAbc); + pErr = Abc_FrameReadErr(pAbc); + + // set defaults + fPrecompute = 0; + fUseZeros = 0; + fVerbose = 0; + util_getopt_reset(); + while ( ( c = util_getopt( argc, argv, "xzvh" ) ) != EOF ) + { + switch ( c ) + { + case 'x': + fPrecompute ^= 1; + break; + case 'z': + fUseZeros ^= 1; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + + if ( fPrecompute ) + { + Rwr_Precompute(); + return 0; + } + + if ( pNtk == NULL ) + { + fprintf( pErr, "Empty network.\n" ); + return 1; + } + if ( !Abc_NtkIsStrash(pNtk) ) + { + fprintf( pErr, "This command can only be applied to an AIG.\n" ); + return 1; + } + if ( Abc_NtkGetChoiceNum(pNtk) ) + { + fprintf( pErr, "AIG resynthesis cannot be applied to AIGs with choice nodes.\n" ); + return 1; + } + + // modify the current network + if ( !Abc_NtkRewrite( pNtk, fUseZeros, fVerbose ) ) + { + fprintf( pErr, "Rewriting has failed.\n" ); + return 1; + } + return 0; + +usage: + fprintf( pErr, "usage: rewrite [-zvh]\n" ); + fprintf( pErr, "\t performs technology-independent rewriting of the AIG\n" ); + fprintf( pErr, "\t-z : toggle using zero-cost replacements [default = %s]\n", fUseZeros? "yes": "no" ); + fprintf( pErr, "\t-v : toggle verbose printout [default = %s]\n", fVerbose? "yes": "no" ); + fprintf( pErr, "\t-h : print the command usage\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandRefactor( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk; + int c; + int nNodeSizeMax; + int nConeSizeMax; + bool fUseZeros; + bool fUseDcs; + bool fVerbose; + extern int Abc_NtkRefactor( Abc_Ntk_t * pNtk, int nNodeSizeMax, int nConeSizeMax, bool fUseZeros, bool fUseDcs, bool fVerbose ); + + pNtk = Abc_FrameReadNet(pAbc); + pOut = Abc_FrameReadOut(pAbc); + pErr = Abc_FrameReadErr(pAbc); + + // set defaults + nNodeSizeMax = 10; + nConeSizeMax = 16; + fUseZeros = 0; + fUseDcs = 0; + fVerbose = 0; + util_getopt_reset(); + while ( ( c = util_getopt( argc, argv, "NCzdvh" ) ) != EOF ) + { + switch ( c ) + { + case 'N': + if ( util_optind >= argc ) + { + fprintf( pErr, "Command line switch \"-N\" should be followed by an integer.\n" ); + goto usage; + } + nNodeSizeMax = atoi(argv[util_optind]); + util_optind++; + if ( nNodeSizeMax < 0 ) + goto usage; + break; + case 'C': + if ( util_optind >= argc ) + { + fprintf( pErr, "Command line switch \"-C\" should be followed by an integer.\n" ); + goto usage; + } + nConeSizeMax = atoi(argv[util_optind]); + util_optind++; + if ( nConeSizeMax < 0 ) + goto usage; + break; + case 'z': + fUseZeros ^= 1; + break; + case 'd': + fUseDcs ^= 1; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + + if ( pNtk == NULL ) + { + fprintf( pErr, "Empty network.\n" ); + return 1; + } + if ( !Abc_NtkIsStrash(pNtk) ) + { + fprintf( pErr, "This command can only be applied to an AIG.\n" ); + return 1; + } + if ( Abc_NtkGetChoiceNum(pNtk) ) + { + fprintf( pErr, "AIG resynthesis cannot be applied to AIGs with choice nodes.\n" ); + return 1; + } + + if ( fUseDcs && nNodeSizeMax >= nConeSizeMax ) + { + fprintf( pErr, "For don't-care to work, containing cone should be larger than collapsed node.\n" ); + return 1; + } + + // modify the current network + if ( !Abc_NtkRefactor( pNtk, nNodeSizeMax, nConeSizeMax, fUseZeros, fUseDcs, fVerbose ) ) + { + fprintf( pErr, "Refactoring has failed.\n" ); + return 1; + } + return 0; + +usage: + fprintf( pErr, "usage: refactor [-N num] [-C num] [-zdvh]\n" ); + fprintf( pErr, "\t performs technology-independent refactoring of the AIG\n" ); + fprintf( pErr, "\t-N num : the max support of the collapsed node [default = %d]\n", nNodeSizeMax ); + fprintf( pErr, "\t-C num : the max support of the containing cone [default = %d]\n", nConeSizeMax ); + fprintf( pErr, "\t-z : toggle using zero-cost replacements [default = %s]\n", fUseZeros? "yes": "no" ); + fprintf( pErr, "\t-d : toggle using don't-cares [default = %s]\n", fUseDcs? "yes": "no" ); + fprintf( pErr, "\t-v : toggle verbose printout [default = %s]\n", fVerbose? "yes": "no" ); + fprintf( pErr, "\t-h : print the command usage\n"); + return 1; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandLogic( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk, * pNtkRes; + int c; + + 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_NtkIsNetlist( pNtk ) ) + { + fprintf( pErr, "This command is only applicable to netlists.\n" ); + return 1; + } + + // get the new network + pNtkRes = Abc_NtkNetlistToLogic( pNtk ); + if ( pNtkRes == NULL ) + { + fprintf( pErr, "Converting to a logic network has failed.\n" ); + return 1; + } + // replace the current network + Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); + return 0; + +usage: + fprintf( pErr, "usage: logic [-h]\n" ); + fprintf( pErr, "\t transforms a netlist into a logic network\n" ); + fprintf( pErr, "\t-h : print the command usage\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandMiter( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk, * pNtk1, * pNtk2, * pNtkRes; + int fDelete1, fDelete2; + char ** pArgvNew; + int nArgcNew; + int c; + int fCheck; + int fComb; + + pNtk = Abc_FrameReadNet(pAbc); + pOut = Abc_FrameReadOut(pAbc); + pErr = Abc_FrameReadErr(pAbc); + + // set defaults + fComb = 1; + fCheck = 1; + util_getopt_reset(); + while ( ( c = util_getopt( argc, argv, "ch" ) ) != EOF ) + { + switch ( c ) + { + case 'c': + fComb ^= 1; + break; + default: + goto usage; + } + } + + pArgvNew = argv + util_optind; + nArgcNew = argc - util_optind; + if ( !Abc_NtkPrepareTwoNtks( pErr, pNtk, pArgvNew, nArgcNew, &pNtk1, &pNtk2, &fDelete1, &fDelete2 ) ) + return 1; + + // compute the miter + pNtkRes = Abc_NtkMiter( pNtk1, pNtk2, fComb ); + if ( fDelete1 ) Abc_NtkDelete( pNtk1 ); + if ( fDelete2 ) Abc_NtkDelete( pNtk2 ); + + // get the new network + if ( pNtkRes == NULL ) + { + fprintf( pErr, "Miter computation has failed.\n" ); + return 1; + } + // replace the current network + Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); + return 0; + +usage: + fprintf( pErr, "usage: miter [-ch] \n" ); + fprintf( pErr, "\t computes the miter of the two circuits\n" ); + fprintf( pErr, "\t-c : computes combinational miter (latches as POs) [default = %s]\n", fComb? "yes": "no" ); + fprintf( pErr, "\t-h : print the command usage\n"); + fprintf( pErr, "\tfile1 : (optional) the file with the first network\n"); + fprintf( pErr, "\tfile2 : (optional) the file with the second network\n"); + fprintf( pErr, "\t if no files are given, uses the current network and its spec\n"); + fprintf( pErr, "\t if one file is given, uses the current network and the file\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandFrames( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk, * pNtkTemp, * pNtkRes; + int fInitial; + int nFrames; + int c; + + pNtk = Abc_FrameReadNet(pAbc); + pOut = Abc_FrameReadOut(pAbc); + pErr = Abc_FrameReadErr(pAbc); + + // set defaults + fInitial = 0; + nFrames = 5; + util_getopt_reset(); + while ( ( c = util_getopt( argc, argv, "Fih" ) ) != EOF ) + { + switch ( c ) + { + case 'F': + if ( util_optind >= argc ) + { + fprintf( pErr, "Command line switch \"-F\" should be followed by an integer.\n" ); + goto usage; + } + nFrames = atoi(argv[util_optind]); + util_optind++; + if ( nFrames < 0 ) + goto usage; + break; + case 'i': + fInitial ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + + if ( pNtk == NULL ) + { + fprintf( pErr, "Empty network.\n" ); + return 1; + } + + // get the new network + if ( !Abc_NtkIsStrash(pNtk) ) + { + pNtkTemp = Abc_NtkStrash( pNtk, 0, 0 ); + pNtkRes = Abc_NtkFrames( pNtkTemp, nFrames, fInitial ); + Abc_NtkDelete( pNtkTemp ); + } + else + pNtkRes = Abc_NtkFrames( pNtk, nFrames, fInitial ); + if ( pNtkRes == NULL ) + { + fprintf( pErr, "Unrolling the network has failed.\n" ); + return 1; + } + // replace the current network + Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); + return 0; + +usage: + fprintf( pErr, "usage: frames [-F num] [-ih]\n" ); + fprintf( pErr, "\t unrolls the network for a number of time frames\n" ); + fprintf( pErr, "\t-F num : the number of frames to unroll [default = %d]\n", nFrames ); + fprintf( pErr, "\t-i : toggles initializing the first frame [default = %s]\n", fInitial? "yes": "no" ); + fprintf( pErr, "\t-h : print the command usage\n"); + return 1; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandSop( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk; + int c; + + 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; + } + + // get the new network + if ( !Abc_NtkIsBddLogic(pNtk) ) + { + fprintf( pErr, "Converting to SOP is possible when node functions are BDDs.\n" ); + return 1; + } + if ( !Abc_NtkBddToSop( pNtk ) ) + { + fprintf( pErr, "Converting to SOP has failed.\n" ); + return 1; + } + return 0; + +usage: + fprintf( pErr, "usage: sop [-h]\n" ); + fprintf( pErr, "\t converts node functions from BDD to SOP\n" ); + fprintf( pErr, "\t-h : print the command usage\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandBdd( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk; + int c; + + 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; + } + + // get the new network + if ( !Abc_NtkIsSopLogic(pNtk) ) + { + fprintf( pErr, "Converting to BDD is possible when node functions are SOPs.\n" ); + return 1; + } + if ( !Abc_NtkSopToBdd( pNtk ) ) + { + fprintf( pErr, "Converting to BDD has failed.\n" ); + return 1; + } + return 0; + +usage: + fprintf( pErr, "usage: bdd [-h]\n" ); + fprintf( pErr, "\t converts node functions from SOP to BDD\n" ); + fprintf( pErr, "\t-h : print the command usage\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandMuxes( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk, * pNtkRes; + int c; + + 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_NtkIsBddLogic(pNtk) ) + { + fprintf( pErr, "Only a BDD logic network can be converted to MUXes.\n" ); + return 1; + } + + // get the new network + pNtkRes = Abc_NtkBddToMuxes( pNtk ); + if ( pNtkRes == NULL ) + { + fprintf( pErr, "Converting to MUXes has failed.\n" ); + return 1; + } + // replace the current network + Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); + return 0; + +usage: + fprintf( pErr, "usage: muxes [-h]\n" ); + fprintf( pErr, "\t converts the current network by a network derived by\n" ); + fprintf( pErr, "\t replacing all nodes by DAGs isomorphic to the local BDDs\n" ); + fprintf( pErr, "\t-h : print the command usage\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandSat( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk; + int c; + int fVerbose; + + pNtk = Abc_FrameReadNet(pAbc); + pOut = Abc_FrameReadOut(pAbc); + pErr = Abc_FrameReadErr(pAbc); + + // set defaults + fVerbose = 0; + util_getopt_reset(); + while ( ( c = util_getopt( argc, argv, "vh" ) ) != EOF ) + { + switch ( c ) + { + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + + if ( pNtk == NULL ) + { + fprintf( pErr, "Empty network.\n" ); + return 1; + } + if ( Abc_NtkLatchNum(pNtk) > 0 ) + { + fprintf( stdout, "Currently can only solve the miter for combinational circuits.\n" ); + return 0; + } + if ( !Abc_NtkIsLogic(pNtk) ) + { + fprintf( stdout, "This command can only be applied to logic network.\n" ); + return 0; + } + if ( Abc_NtkIsMappedLogic(pNtk) ) + Abc_NtkUnmap(pNtk); + if ( Abc_NtkIsSopLogic(pNtk) ) + Abc_NtkSopToBdd(pNtk); + + if ( Abc_NtkMiterSat( pNtk, fVerbose ) ) + printf( "The miter is satisfiable.\n" ); + else + printf( "The miter is unsatisfiable.\n" ); + return 0; + +usage: + fprintf( pErr, "usage: sat [-vh]\n" ); + fprintf( pErr, "\t solves the miter\n" ); + fprintf( pErr, "\t-v : prints verbose information [default = %s]\n", fVerbose? "yes": "no" ); + fprintf( pErr, "\t-h : print the command usage\n"); + return 1; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandExtSeqDcs( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk; + int c; + int fVerbose; + extern int Abc_NtkExtractSequentialDcs( Abc_Ntk_t * pNet, bool fVerbose ); + + pNtk = Abc_FrameReadNet(pAbc); + pOut = Abc_FrameReadOut(pAbc); + pErr = Abc_FrameReadErr(pAbc); + + // set defaults + fVerbose = 0; + util_getopt_reset(); + while ( ( c = util_getopt( argc, argv, "vh" ) ) != EOF ) + { + switch ( c ) + { + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + + if ( pNtk == NULL ) + { + fprintf( pErr, "Empty network.\n" ); + return 1; + } + if ( Abc_NtkLatchNum(pNtk) == 0 ) + { + fprintf( stdout, "The current network has no latches.\n" ); + return 0; + } + if ( !Abc_NtkIsStrash(pNtk) ) + { + fprintf( stdout, "This command works only for AIGs.\n" ); + return 0; + } + if ( !Abc_NtkExtractSequentialDcs( pNtk, fVerbose ) ) + { + fprintf( stdout, "Extracting sequential don't-cares has failed.\n" ); + return 1; + } + return 0; + +usage: + fprintf( pErr, "usage: ext_seq_dcs [-vh]\n" ); + fprintf( pErr, "\t create EXDC network using unreachable states\n" ); + fprintf( pErr, "\t-v : prints verbose information [default = %s]\n", fVerbose? "yes": "no" ); + fprintf( pErr, "\t-h : print the command usage\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandOneOutput( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk, * pNtkRes; + Abc_Obj_t * pNode; + int c; + int fUseAllCis; + int Output; + + pNtk = Abc_FrameReadNet(pAbc); + pOut = Abc_FrameReadOut(pAbc); + pErr = Abc_FrameReadErr(pAbc); + + // set defaults + fUseAllCis = 0; + Output = -1; + util_getopt_reset(); + while ( ( c = util_getopt( argc, argv, "Oah" ) ) != EOF ) + { + switch ( c ) + { + case 'O': + if ( util_optind >= argc ) + { + fprintf( pErr, "Command line switch \"-O\" should be followed by an integer.\n" ); + goto usage; + } + Output = atoi(argv[util_optind]); + util_optind++; + if ( Output < 0 ) + goto usage; + break; + case 'a': + fUseAllCis ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + + if ( pNtk == NULL ) + { + fprintf( pErr, "Empty network.\n" ); + return 1; + } + + if ( !Abc_NtkIsLogic(pNtk) && !Abc_NtkIsStrash(pNtk) ) + { + fprintf( pErr, "Currently can only be applied to the logic network or an AIG.\n" ); + return 1; + } + + if ( argc > util_optind + 1 ) + { + fprintf( pErr, "Wrong number of auguments.\n" ); + goto usage; + } + + if ( argc == util_optind + 1 ) + { + pNode = Abc_NtkFindCo( pNtk, argv[util_optind] ); + if ( pNode == NULL ) + { + fprintf( pErr, "Cannot find CO node \"%s\".\n", argv[util_optind] ); + return 1; + } + pNtkRes = Abc_NtkSplitOutput( pNtk, pNode, fUseAllCis ); + } + else + { + if ( Output == -1 ) + { + fprintf( pErr, "The output is not specified.\n" ); + return 1; + } + if ( Output >= Abc_NtkCoNum(pNtk) ) + { + fprintf( pErr, "The 0-based output number (%d) is larger than the number of outputs (%d).\n", Output, Abc_NtkCoNum(pNtk) ); + return 1; + } + pNtkRes = Abc_NtkSplitOutput( pNtk, Abc_NtkCo(pNtk,Output), fUseAllCis ); + } + if ( pNtkRes == NULL ) + { + fprintf( pErr, "Splitting one output has failed.\n" ); + return 1; + } + // replace the current network + Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); + return 0; + +usage: + fprintf( pErr, "usage: one_output [-O num] [-ah] \n" ); + fprintf( pErr, "\t replaces the current network by the logic cone of one output\n" ); + fprintf( pErr, "\t-a : toggle writing all CIs or structral support only [default = %s]\n", fUseAllCis? "all": "structural" ); + fprintf( pErr, "\t-h : print the command usage\n"); + fprintf( pErr, "\t-O num : (optional) the 0-based number of the output\n"); + fprintf( pErr, "\tname : (optional) the name of the output\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandOneNode( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk, * pNtkRes; + Abc_Obj_t * pNode; + int c; + + 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_NtkIsLogic(pNtk) ) + { + fprintf( pErr, "Currently can only be applied to a logic network.\n" ); + return 1; + } + + if ( argc != util_optind + 1 ) + { + fprintf( pErr, "Wrong number of auguments.\n" ); + goto usage; + } + + pNode = Abc_NtkFindNode( pNtk, argv[util_optind] ); + if ( pNode == NULL ) + { + fprintf( pErr, "Cannot find node \"%s\".\n", argv[util_optind] ); + return 1; + } + + pNtkRes = Abc_NtkSplitNode( pNtk, pNode ); +// pNtkRes = Abc_NtkDeriveFromBdd( pNtk->pManFunc, pNode->pData, NULL, NULL ); + if ( pNtkRes == NULL ) + { + fprintf( pErr, "Splitting one node has failed.\n" ); + return 1; + } + // replace the current network + Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); + return 0; + +usage: + fprintf( pErr, "usage: one_node [-h] \n" ); + fprintf( pErr, "\t replaces the current network by the network composed of one node\n" ); + fprintf( pErr, "\t-h : print the command usage\n"); + fprintf( pErr, "\tname : the node name\n"); + return 1; +} + + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandShortNames( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk; + int c; + + 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; + } + Abc_NtkShortNames( pNtk ); + return 0; + +usage: + fprintf( pErr, "usage: short_names [-h]\n" ); + fprintf( pErr, "\t replaces PI/PO/latch names by short char strings\n" ); + fprintf( pErr, "\t-h : print the command usage\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandCut( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + Cut_Params_t Params, * pParams = &Params; + Cut_Man_t * pCutMan; + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk; + int c; + extern Cut_Man_t * Abc_NtkCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams ); + + pNtk = Abc_FrameReadNet(pAbc); + pOut = Abc_FrameReadOut(pAbc); + pErr = Abc_FrameReadErr(pAbc); + + // set defaults + pParams->nVarsMax = 5; // the max cut size ("k" of the k-feasible cuts) + pParams->nKeepMax = 250; // the max number of cuts kept at a node + pParams->fTruth = 1; // compute truth tables + pParams->fHash = 0; // hash cuts to detect unique + pParams->fFilter = 0; // filter dominated cuts + pParams->fSeq = 0; // compute sequential cuts + pParams->fDrop = 0; // drop cuts on the fly + pParams->fVerbose = 0; // the verbosiness flag + util_getopt_reset(); + while ( ( c = util_getopt( argc, argv, "KMtrfsdvh" ) ) != EOF ) + { + switch ( c ) + { + case 'K': + if ( util_optind >= argc ) + { + fprintf( pErr, "Command line switch \"-K\" should be followed by an integer.\n" ); + goto usage; + } + pParams->nVarsMax = atoi(argv[util_optind]); + util_optind++; + if ( pParams->nVarsMax < 0 ) + goto usage; + break; + case 'M': + if ( util_optind >= argc ) + { + fprintf( pErr, "Command line switch \"-M\" should be followed by an integer.\n" ); + goto usage; + } + pParams->nKeepMax = atoi(argv[util_optind]); + util_optind++; + if ( pParams->nKeepMax < 0 ) + goto usage; + break; + case 't': + pParams->fTruth ^= 1; + break; + case 'r': + pParams->fHash ^= 1; + break; + case 'f': + pParams->fFilter ^= 1; + break; + case 's': + pParams->fSeq ^= 1; + break; + case 'd': + pParams->fDrop ^= 1; + break; + case 'v': + pParams->fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + + if ( pNtk == NULL ) + { + fprintf( pErr, "Empty network.\n" ); + return 1; + } + if ( !Abc_NtkIsStrash(pNtk) ) + { + fprintf( pErr, "Cut computation is available only for AIGs.\n" ); + return 1; + } + pCutMan = Abc_NtkCuts( pNtk, pParams ); + Cut_ManPrintStats( pCutMan ); + Cut_ManStop( pCutMan ); + return 0; + +usage: + fprintf( pErr, "usage: cut [-K num] [-M num] [-trfsdvh]\n" ); + fprintf( pErr, "\t computes k-feasible cuts for the AIG\n" ); + fprintf( pErr, "\t-K num : max number of leaves (4 <= num <= 6) [default = %d]\n", pParams->nVarsMax ); + fprintf( pErr, "\t-M num : max number of cuts stored at a node [default = %d]\n", pParams->nKeepMax ); + fprintf( pErr, "\t-t : toggle truth table computation [default = %s]\n", pParams->fTruth? "yes": "no" ); + fprintf( pErr, "\t-r : toggle reduction by hashing [default = %s]\n", pParams->fHash? "yes": "no" ); + fprintf( pErr, "\t-f : toggle filtering by dominance [default = %s]\n", pParams->fFilter? "yes": "no" ); + fprintf( pErr, "\t-s : toggle sequential cut computation [default = %s]\n", pParams->fSeq? "yes": "no" ); + fprintf( pErr, "\t-d : toggle dropping when fanouts are done [default = %s]\n", pParams->fDrop? "yes": "no" ); + fprintf( pErr, "\t-v : toggle printing verbose information [default = %s]\n", pParams->fVerbose? "yes": "no" ); + fprintf( pErr, "\t-h : print the command usage\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk, * pNtkRes; + int c; + + 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; + } + // run the command + pNtkRes = Abc_NtkMiterForCofactors( pNtk, 0, 0, -1 ); + if ( pNtkRes == NULL ) + { + fprintf( pErr, "Command has failed.\n" ); + return 1; + } + // replace the current network + Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); + return 0; + +usage: + fprintf( pErr, "usage: test [-h]\n" ); + fprintf( pErr, "\t testbench for new procedures\n" ); + fprintf( pErr, "\t-h : print the command usage\n"); + return 1; +} + + + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandFraig( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + char Buffer[100]; + Fraig_Params_t Params, * pParams = &Params; + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk, * pNtkRes; + int fAllNodes; + int c; + + pNtk = Abc_FrameReadNet(pAbc); + pOut = Abc_FrameReadOut(pAbc); + pErr = Abc_FrameReadErr(pAbc); + + // set defaults + fAllNodes = 0; + pParams->nPatsRand = 2048; // the number of words of random simulation info + pParams->nPatsDyna = 2048; // the number of words of dynamic simulation info + pParams->nBTLimit = 99; // the max number of backtracks to perform + pParams->fFuncRed = 1; // performs only one level hashing + pParams->fFeedBack = 1; // enables solver feedback + pParams->fDist1Pats = 1; // enables distance-1 patterns + pParams->fDoSparse = 0; // performs equiv tests for sparse functions + pParams->fChoicing = 0; // enables recording structural choices + pParams->fTryProve = 0; // tries to solve the final miter + pParams->fVerbose = 0; // the verbosiness flag + pParams->fVerboseP = 0; // the verbosiness flag + util_getopt_reset(); + while ( ( c = util_getopt( argc, argv, "RDBrscpvah" ) ) != EOF ) + { + switch ( c ) + { + + case 'R': + if ( util_optind >= argc ) + { + fprintf( pErr, "Command line switch \"-R\" should be followed by an integer.\n" ); + goto usage; + } + pParams->nPatsRand = atoi(argv[util_optind]); + util_optind++; + if ( pParams->nPatsRand < 0 ) + goto usage; + break; + case 'D': + if ( util_optind >= argc ) + { + fprintf( pErr, "Command line switch \"-D\" should be followed by an integer.\n" ); + goto usage; + } + pParams->nPatsDyna = atoi(argv[util_optind]); + util_optind++; + if ( pParams->nPatsDyna < 0 ) + goto usage; + break; + case 'B': + if ( util_optind >= argc ) + { + fprintf( pErr, "Command line switch \"-B\" should be followed by an integer.\n" ); + goto usage; + } + pParams->nBTLimit = atoi(argv[util_optind]); + util_optind++; + if ( pParams->nBTLimit < 0 ) + goto usage; + break; + + case 'r': + pParams->fFuncRed ^= 1; + break; + case 's': + pParams->fDoSparse ^= 1; + break; + case 'c': + pParams->fChoicing ^= 1; + break; + case 'p': + pParams->fTryProve ^= 1; + break; + case 'v': + pParams->fVerbose ^= 1; + break; + case 'a': + fAllNodes ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + + if ( pNtk == NULL ) + { + fprintf( pErr, "Empty network.\n" ); + return 1; + } + if ( !Abc_NtkIsLogic(pNtk) && !Abc_NtkIsStrash(pNtk) ) + { + fprintf( pErr, "Can only fraig a logic network or an AIG.\n" ); + return 1; + } + + // report the proof + pParams->fVerboseP = pParams->fTryProve; + + // get the new network + if ( Abc_NtkIsStrash(pNtk) ) + pNtkRes = Abc_NtkFraig( pNtk, &Params, fAllNodes ); + else + { + pNtk = Abc_NtkStrash( pNtk, fAllNodes, !fAllNodes ); + pNtkRes = Abc_NtkFraig( pNtk, &Params, fAllNodes ); + Abc_NtkDelete( pNtk ); + } + if ( pNtkRes == NULL ) + { + fprintf( pErr, "Fraiging has failed.\n" ); + return 1; + } + + if ( pParams->fTryProve ) // report the result + Abc_NtkMiterReport( pNtkRes ); + + // replace the current network + Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); + return 0; + +usage: + sprintf( Buffer, "%d", pParams->nBTLimit ); + 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", pParams->nPatsRand ); + fprintf( pErr, "\t-D num : number of systematic patterns (127 < num < 32769) [default = %d]\n", pParams->nPatsDyna ); + fprintf( pErr, "\t-B num : number of backtracks for one SAT problem [default = %s]\n", pParams->nBTLimit==-1? "infinity" : Buffer ); + fprintf( pErr, "\t-r : toggle functional reduction [default = %s]\n", pParams->fFuncRed? "yes": "no" ); + fprintf( pErr, "\t-s : toggle considering sparse functions [default = %s]\n", pParams->fDoSparse? "yes": "no" ); + fprintf( pErr, "\t-c : toggle accumulation of choices [default = %s]\n", pParams->fChoicing? "yes": "no" ); + fprintf( pErr, "\t-p : toggle proving the final miter [default = %s]\n", pParams->fTryProve? "yes": "no" ); + fprintf( pErr, "\t-v : toggle verbose output [default = %s]\n", pParams->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; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandFraigTrust( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk, * pNtkRes; + int c; + int fDuplicate; + + pNtk = Abc_FrameReadNet(pAbc); + pOut = Abc_FrameReadOut(pAbc); + pErr = Abc_FrameReadErr(pAbc); + + // set defaults + fDuplicate = 0; + util_getopt_reset(); + while ( ( c = util_getopt( argc, argv, "dh" ) ) != EOF ) + { + switch ( c ) + { + case 'd': + fDuplicate ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + + if ( pNtk == NULL ) + { + fprintf( pErr, "Empty network.\n" ); + return 1; + } + + // get the new network + pNtkRes = Abc_NtkFraigTrust( pNtk ); + if ( pNtkRes == NULL ) + { + fprintf( pErr, "Fraiging in the trust mode has failed.\n" ); + return 1; + } + // replace the current network + Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); + return 0; + +usage: + fprintf( pErr, "usage: fraig_trust [-h]\n" ); + fprintf( pErr, "\t transforms the current network into an AIG assuming it is FRAIG with choices\n" ); +// fprintf( pErr, "\t-d : toggle duplication of logic [default = %s]\n", fDuplicate? "yes": "no" ); + fprintf( pErr, "\t-h : print the command usage\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandFraigStore( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk; + int c; + int fDuplicate; + + pNtk = Abc_FrameReadNet(pAbc); + pOut = Abc_FrameReadOut(pAbc); + pErr = Abc_FrameReadErr(pAbc); + + // set defaults + fDuplicate = 0; + util_getopt_reset(); + while ( ( c = util_getopt( argc, argv, "dh" ) ) != EOF ) + { + switch ( c ) + { + case 'd': + fDuplicate ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + + if ( pNtk == NULL ) + { + fprintf( pErr, "Empty network.\n" ); + return 1; + } + + // get the new network + if ( !Abc_NtkFraigStore( pNtk ) ) + { + fprintf( pErr, "Fraig storing has failed.\n" ); + return 1; + } + return 0; + +usage: + fprintf( pErr, "usage: fraig_store [-h]\n" ); + fprintf( pErr, "\t saves the current network in the AIG database\n" ); +// fprintf( pErr, "\t-d : toggle duplication of logic [default = %s]\n", fDuplicate? "yes": "no" ); + fprintf( pErr, "\t-h : print the command usage\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandFraigRestore( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk, * pNtkRes; + int c; + int fDuplicate; + + pNtk = Abc_FrameReadNet(pAbc); + pOut = Abc_FrameReadOut(pAbc); + pErr = Abc_FrameReadErr(pAbc); + + // set defaults + fDuplicate = 0; + util_getopt_reset(); + while ( ( c = util_getopt( argc, argv, "dh" ) ) != EOF ) + { + switch ( c ) + { + case 'd': + fDuplicate ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + + if ( pNtk == NULL ) + { + fprintf( pErr, "Empty network.\n" ); + return 1; + } + + // get the new network + pNtkRes = Abc_NtkFraigRestore(); + if ( pNtkRes == NULL ) + { + fprintf( pErr, "Fraig restoring has failed.\n" ); + return 1; + } + // replace the current network + Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); + return 0; + +usage: + fprintf( pErr, "usage: fraig_restore [-h]\n" ); + fprintf( pErr, "\t makes the current network by fraiging the AIG database\n" ); +// fprintf( pErr, "\t-d : toggle duplication of logic [default = %s]\n", fDuplicate? "yes": "no" ); + fprintf( pErr, "\t-h : print the command usage\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandFraigClean( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk; + int c; + int fDuplicate; + + pNtk = Abc_FrameReadNet(pAbc); + pOut = Abc_FrameReadOut(pAbc); + pErr = Abc_FrameReadErr(pAbc); + + // set defaults + fDuplicate = 0; + util_getopt_reset(); + while ( ( c = util_getopt( argc, argv, "dh" ) ) != EOF ) + { + switch ( c ) + { + case 'd': + fDuplicate ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + Abc_NtkFraigStoreClean(); + return 0; + +usage: + fprintf( pErr, "usage: fraig_clean [-h]\n" ); + fprintf( pErr, "\t cleans the internal FRAIG storage\n" ); +// fprintf( pErr, "\t-d : toggle duplication of logic [default = %s]\n", fDuplicate? "yes": "no" ); + fprintf( pErr, "\t-h : print the command usage\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandFraigSweep( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk; + int c; + int fUseInv; + int fVerbose; + + pNtk = Abc_FrameReadNet(pAbc); + pOut = Abc_FrameReadOut(pAbc); + pErr = Abc_FrameReadErr(pAbc); + + // set defaults + fUseInv = 1; + fVerbose = 0; + util_getopt_reset(); + while ( ( c = util_getopt( argc, argv, "ivh" ) ) != EOF ) + { + switch ( c ) + { + case 'i': + fUseInv ^= 1; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + + if ( pNtk == NULL ) + { + fprintf( pErr, "Empty network.\n" ); + return 1; + } + if ( Abc_NtkIsStrash(pNtk) ) + { + fprintf( pErr, "Cannot sweep AIGs (use \"fraig\").\n" ); + return 1; + } + if ( !Abc_NtkIsLogic(pNtk) ) + { + fprintf( pErr, "Transform the current network into a logic network.\n" ); + return 1; + } + // modify the current network + if ( !Abc_NtkFraigSweep( pNtk, fUseInv, fVerbose ) ) + { + fprintf( pErr, "Sweeping has failed.\n" ); + return 1; + } + return 0; + +usage: + fprintf( pErr, "usage: fraig_sweep [-vh]\n" ); + fprintf( pErr, "\t performs technology-dependent sweep\n" ); +// fprintf( pErr, "\t-i : toggle using inverter for complemented nodes [default = %s]\n", fUseInv? "yes": "no" ); + fprintf( pErr, "\t-v : prints verbose information [default = %s]\n", fVerbose? "yes": "no" ); + fprintf( pErr, "\t-h : print the command usage\n"); + return 1; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandMap( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk, * pNtkRes; + char Buffer[100]; + double DelayTarget; + int fRecovery; + int fSweep; + int fSwitching; + int fVerbose; + int c; + extern Abc_Ntk_t * Abc_NtkMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, int fSwitching, int fVerbose ); + + pNtk = Abc_FrameReadNet(pAbc); + pOut = Abc_FrameReadOut(pAbc); + pErr = Abc_FrameReadErr(pAbc); + + // set defaults + DelayTarget =-1; + fRecovery = 1; + fSweep = 1; + fSwitching = 0; + fVerbose = 0; + util_getopt_reset(); + while ( ( c = util_getopt( argc, argv, "Daspvh" ) ) != EOF ) + { + switch ( c ) + { + case 'D': + if ( util_optind >= argc ) + { + fprintf( pErr, "Command line switch \"-D\" should be followed by a floating point number.\n" ); + goto usage; + } + DelayTarget = (float)atof(argv[util_optind]); + util_optind++; + if ( DelayTarget <= 0.0 ) + goto usage; + break; + case 'a': + fRecovery ^= 1; + break; + case 's': + fSweep ^= 1; + break; + case 'p': + fSwitching ^= 1; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + + if ( pNtk == NULL ) + { + fprintf( pErr, "Empty network.\n" ); + return 1; + } + + if ( !Abc_NtkIsStrash(pNtk) ) + { + pNtk = Abc_NtkStrash( pNtk, 0, 0 ); + if ( pNtk == NULL ) + { + fprintf( pErr, "Strashing before mapping has failed.\n" ); + return 1; + } + pNtk = Abc_NtkBalance( pNtkRes = pNtk, 0 ); + Abc_NtkDelete( pNtkRes ); + if ( pNtk == NULL ) + { + fprintf( pErr, "Balancing before mapping has failed.\n" ); + return 1; + } + fprintf( pOut, "The network was strashed and balanced before mapping.\n" ); + // get the new network + pNtkRes = Abc_NtkMap( pNtk, DelayTarget, fRecovery, fSwitching, fVerbose ); + if ( pNtkRes == NULL ) + { + Abc_NtkDelete( pNtk ); + fprintf( pErr, "Mapping has failed.\n" ); + return 1; + } + Abc_NtkDelete( pNtk ); + } + else + { + // get the new network + pNtkRes = Abc_NtkMap( pNtk, DelayTarget, fRecovery, fSwitching, fVerbose ); + if ( pNtkRes == NULL ) + { + fprintf( pErr, "Mapping has failed.\n" ); + return 1; + } + } + + if ( fSweep ) + Abc_NtkFraigSweep( pNtkRes, 0, 0 ); + + // replace the current network + Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); + return 0; + +usage: + if ( DelayTarget == -1 ) + sprintf( Buffer, "not used" ); + else + sprintf( Buffer, "%.3f", DelayTarget ); + fprintf( pErr, "usage: map [-D num] [-aspvh]\n" ); + fprintf( pErr, "\t performs standard cell mapping of the current network\n" ); + fprintf( pErr, "\t-D num : sets the global required times [default = %s]\n", Buffer ); + fprintf( pErr, "\t-a : toggles area recovery [default = %s]\n", fRecovery? "yes": "no" ); + fprintf( pErr, "\t-s : toggles sweep after mapping [default = %s]\n", fSweep? "yes": "no" ); + fprintf( pErr, "\t-p : optimizes power by minimizing switching activity [default = %s]\n", fSwitching? "yes": "no" ); + fprintf( pErr, "\t-v : toggles verbose output [default = %s]\n", fVerbose? "yes": "no" ); + fprintf( pErr, "\t-h : print the command usage\n"); + return 1; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandUnmap( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk; + int c; + extern int Abc_NtkUnmap( 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_NtkHasMapping(pNtk) ) + { + fprintf( pErr, "Cannot unmap the network that is not mapped.\n" ); + return 1; + } + + // get the new network + if ( !Abc_NtkUnmap( pNtk ) ) + { + fprintf( pErr, "Unmapping has failed.\n" ); + return 1; + } + return 0; + +usage: + fprintf( pErr, "usage: unmap [-h]\n" ); + fprintf( pErr, "\t replaces the library gates by the logic nodes represented using SOPs\n" ); + fprintf( pErr, "\t-h : print the command usage\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandAttach( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk; + int c; + extern int Abc_NtkUnmap( 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_NtkIsSopLogic(pNtk) ) + { + fprintf( pErr, "Can only attach gates if the nodes have SOP representations.\n" ); + return 1; + } + + // get the new network + if ( !Abc_NtkAttach( pNtk ) ) + { + fprintf( pErr, "Attaching gates has failed.\n" ); + return 1; + } + return 0; + +usage: + fprintf( pErr, "usage: attach [-h]\n" ); + fprintf( pErr, "\t replaces the SOP functions by the gates from the library\n" ); + fprintf( pErr, "\t-h : print the command usage\n"); + return 1; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_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_NtkIsStrash(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 (accumulate: \"r file.blif; rsup; b; sc; f -ac; wb file_sc.blif\")\n" ); + fprintf( pErr, "\t (map without supergate library: \"r file_sc.blif; ft; map\")\n" ); + fprintf( pErr, "\t-h : print the command usage\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandFpga( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk, * pNtkRes; + int c; + int fRecovery; + int fSwitching; + int fVerbose; + extern Abc_Ntk_t * Abc_NtkFpga( Abc_Ntk_t * pNtk, int fRecovery, int fSwitching, int fVerbose ); + + pNtk = Abc_FrameReadNet(pAbc); + pOut = Abc_FrameReadOut(pAbc); + pErr = Abc_FrameReadErr(pAbc); + + // set defaults + fRecovery = 1; + fSwitching = 0; + fVerbose = 0; + util_getopt_reset(); + while ( ( c = util_getopt( argc, argv, "apvh" ) ) != EOF ) + { + switch ( c ) + { + case 'a': + fRecovery ^= 1; + break; + case 'p': + fSwitching ^= 1; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + + if ( pNtk == NULL ) + { + fprintf( pErr, "Empty network.\n" ); + return 1; + } + + if ( !Abc_NtkIsStrash(pNtk) ) + { + // strash and balance the network + pNtk = Abc_NtkStrash( pNtk, 0, 0 ); + if ( pNtk == NULL ) + { + fprintf( pErr, "Strashing before FPGA mapping has failed.\n" ); + return 1; + } + pNtk = Abc_NtkBalance( pNtkRes = pNtk, 0 ); + Abc_NtkDelete( pNtkRes ); + if ( pNtk == NULL ) + { + fprintf( pErr, "Balancing before FPGA mapping has failed.\n" ); + return 1; + } + fprintf( pOut, "The network was strashed and balanced before FPGA mapping.\n" ); + // get the new network + pNtkRes = Abc_NtkFpga( pNtk, fRecovery, fSwitching, fVerbose ); + if ( pNtkRes == NULL ) + { + Abc_NtkDelete( pNtk ); + fprintf( pErr, "FPGA mapping has failed.\n" ); + return 1; + } + Abc_NtkDelete( pNtk ); + } + else + { + // get the new network + pNtkRes = Abc_NtkFpga( pNtk, fRecovery, fSwitching, fVerbose ); + if ( pNtkRes == NULL ) + { + fprintf( pErr, "FPGA mapping has failed.\n" ); + return 1; + } + } + // replace the current network + Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); + return 0; + +usage: + fprintf( pErr, "usage: fpga [-apvh]\n" ); + fprintf( pErr, "\t performs FPGA mapping of the current network\n" ); + fprintf( pErr, "\t-a : toggles area recovery [default = %s]\n", fRecovery? "yes": "no" ); + fprintf( pErr, "\t-p : optimizes power by minimizing switching activity [default = %s]\n", fSwitching? "yes": "no" ); + fprintf( pErr, "\t-v : toggles verbose output [default = %s]\n", fVerbose? "yes": "no" ); + fprintf( pErr, "\t-h : prints the command usage\n"); + return 1; +} + + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandSeq( 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; + } + + printf( "This command is not yet implemented.\n" ); + return 0; + + if ( !Abc_NtkIsStrash(pNtk) ) + { + fprintf( pErr, "Works only for AIG.\n" ); + return 1; + } + + // get the new network + pNtkRes = Abc_NtkAigToSeq( pNtk ); + if ( pNtkRes == NULL ) + { + fprintf( pErr, "Converting to sequential AIG has failed.\n" ); + return 1; + } + // replace the current network + Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); + return 0; + +usage: + fprintf( pErr, "usage: seq [-h]\n" ); + fprintf( pErr, "\t converts AIG into sequential AIG (while sweeping latches)\n" ); + fprintf( pErr, "\t-h : print the command usage\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandRetime( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk; + int c; + int fForward; + int fBackward; + + extern Abc_Ntk_t * Abc_NtkSuperChoice( Abc_Ntk_t * pNtk ); + + pNtk = Abc_FrameReadNet(pAbc); + pOut = Abc_FrameReadOut(pAbc); + pErr = Abc_FrameReadErr(pAbc); + + // set defaults + fForward = 0; + fBackward = 0; + util_getopt_reset(); + while ( ( c = util_getopt( argc, argv, "fbh" ) ) != EOF ) + { + switch ( c ) + { + case 'f': + fForward ^= 1; + break; + case 'b': + fBackward ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + + if ( pNtk == NULL ) + { + fprintf( pErr, "Empty network.\n" ); + return 1; + } + + printf( "This command is not yet implemented.\n" ); + return 0; + + + if ( !Abc_NtkIsSeq(pNtk) ) + { + fprintf( pErr, "Works only for sequential AIG.\n" ); + return 1; + } + + // get the new network + if ( fForward ) + Abc_NtkSeqRetimeForward( pNtk ); + else if ( fBackward ) + Abc_NtkSeqRetimeBackward( pNtk ); + else + Abc_NtkSeqRetimeDelay( pNtk ); + return 0; + +usage: + fprintf( pErr, "usage: retime [-fbh]\n" ); + fprintf( pErr, "\t retimes sequential AIG (default is Pan's algorithm)\n" ); + fprintf( pErr, "\t-f : toggle forward retiming [default = %s]\n", fForward? "yes": "no" ); + fprintf( pErr, "\t-b : toggle backward retiming [default = %s]\n", fBackward? "yes": "no" ); + fprintf( pErr, "\t-h : print the command usage\n"); + return 1; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandCec( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk, * pNtk1, * pNtk2; + int fDelete1, fDelete2; + char ** pArgvNew; + int nArgcNew; + int c; + int fSat; + int fVerbose; + + extern void Abc_NtkCecSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2 ); + extern void Abc_NtkCecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fVerbose ); + + + pNtk = Abc_FrameReadNet(pAbc); + pOut = Abc_FrameReadOut(pAbc); + pErr = Abc_FrameReadErr(pAbc); + + // set defaults + fSat = 0; + fVerbose = 0; + util_getopt_reset(); + while ( ( c = util_getopt( argc, argv, "svh" ) ) != EOF ) + { + switch ( c ) + { + case 's': + fSat ^= 1; + break; + case 'v': + fVerbose ^= 1; + break; + default: + goto usage; + } + } + + pArgvNew = argv + util_optind; + nArgcNew = argc - util_optind; + if ( !Abc_NtkPrepareTwoNtks( pErr, pNtk, pArgvNew, nArgcNew, &pNtk1, &pNtk2, &fDelete1, &fDelete2 ) ) + return 1; + + // perform equivalence checking + if ( fSat ) + Abc_NtkCecSat( pNtk1, pNtk2 ); + else + Abc_NtkCecFraig( pNtk1, pNtk2, fVerbose ); + + if ( fDelete1 ) Abc_NtkDelete( pNtk1 ); + if ( fDelete2 ) Abc_NtkDelete( pNtk2 ); + return 0; + +usage: + fprintf( pErr, "usage: cec [-svh] \n" ); + fprintf( pErr, "\t performs combinational equivalence checking\n" ); + fprintf( pErr, "\t-s : toggle \"SAT only\" and \"FRAIG + SAT\" [default = %s]\n", fSat? "SAT only": "FRAIG + SAT" ); + fprintf( pErr, "\t-v : toggles verbose output [default = %s]\n", fVerbose? "yes": "no" ); + fprintf( pErr, "\t-h : print the command usage\n"); + fprintf( pErr, "\tfile1 : (optional) the file with the first network\n"); + fprintf( pErr, "\tfile2 : (optional) the file with the second network\n"); + fprintf( pErr, "\t if no files are given, uses the current network and its spec\n"); + fprintf( pErr, "\t if one file is given, uses the current network and the file\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandSec( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk, * pNtk1, * pNtk2; + int fDelete1, fDelete2; + char ** pArgvNew; + int nArgcNew; + int c; + int fSat; + int nFrames; + + extern void Abc_NtkSecSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nFrames ); + extern void Abc_NtkSecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nFrames ); + + + pNtk = Abc_FrameReadNet(pAbc); + pOut = Abc_FrameReadOut(pAbc); + pErr = Abc_FrameReadErr(pAbc); + + // set defaults + nFrames = 3; + fSat = 0; + util_getopt_reset(); + while ( ( c = util_getopt( argc, argv, "Fsh" ) ) != EOF ) + { + switch ( c ) + { + case 'F': + if ( util_optind >= argc ) + { + fprintf( pErr, "Command line switch \"-F\" should be followed by an integer.\n" ); + goto usage; + } + nFrames = atoi(argv[util_optind]); + util_optind++; + if ( nFrames < 0 ) + goto usage; + break; + case 's': + fSat ^= 1; + break; + default: + goto usage; + } + } + + pArgvNew = argv + util_optind; + nArgcNew = argc - util_optind; + if ( !Abc_NtkPrepareTwoNtks( pErr, pNtk, pArgvNew, nArgcNew, &pNtk1, &pNtk2, &fDelete1, &fDelete2 ) ) + return 1; + + // perform equivalence checking + if ( fSat ) + Abc_NtkSecSat( pNtk1, pNtk2, nFrames ); + else + Abc_NtkSecFraig( pNtk1, pNtk2, nFrames ); + + if ( fDelete1 ) Abc_NtkDelete( pNtk1 ); + if ( fDelete2 ) Abc_NtkDelete( pNtk2 ); + return 0; + +usage: + fprintf( pErr, "usage: sec [-sh] [-F num] \n" ); + fprintf( pErr, "\t performs bounded sequential equivalence checking\n" ); + fprintf( pErr, "\t-s : toggle \"SAT only\" and \"FRAIG + SAT\" [default = %s]\n", fSat? "SAT only": "FRAIG + SAT" ); + fprintf( pErr, "\t-h : print the command usage\n"); + fprintf( pErr, "\t-F num : the number of time frames to use [default = %d]\n", nFrames ); + fprintf( pErr, "\tfile1 : (optional) the file with the first network\n"); + fprintf( pErr, "\tfile2 : (optional) the file with the second network\n"); + fprintf( pErr, "\t if no files are given, uses the current network and its spec\n"); + fprintf( pErr, "\t if one file is given, uses the current network and the file\n"); + return 1; +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/base/abci/abcAttach.c b/src/base/abci/abcAttach.c new file mode 100644 index 00000000..a8e06555 --- /dev/null +++ b/src/base/abci/abcAttach.c @@ -0,0 +1,405 @@ +/**CFile**************************************************************** + + FileName [abcAttach.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Network and node package.] + + Synopsis [Attaches the library gates to the current network.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: abcAttach.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abc.h" +#include "main.h" +#include "mio.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +#define ATTACH_FULL (~((unsigned)0)) +#define ATTACH_MASK(n) ((~((unsigned)0)) >> (32-(n))) + +static void Abc_AttachSetupTruthTables( unsigned uTruths[][2] ); +static void Abc_AttachComputeTruth( char * pSop, unsigned uTruthsIn[][2], unsigned * uTruthNode ); +static Mio_Gate_t * Abc_AttachFind( Mio_Gate_t ** ppGates, unsigned ** puTruthGates, int nGates, unsigned * uTruthNode, int * Perm ); +static int Abc_AttachCompare( unsigned ** puTruthGates, int nGates, unsigned * uTruthNode ); +static int Abc_NodeAttach( Abc_Obj_t * pNode, Mio_Gate_t ** ppGates, unsigned ** puTruthGates, int nGates, unsigned uTruths[][2] ); +static void Abc_TruthPermute( char * pPerm, int nVars, unsigned * uTruthNode, unsigned * uTruthPerm ); + +static char ** s_pPerms = NULL; +static int s_nPerms; + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Attaches gates from the current library to the internal nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NtkAttach( Abc_Ntk_t * pNtk ) +{ + int fCheck = 1; + Mio_Library_t * pGenlib; + unsigned ** puTruthGates; + unsigned uTruths[6][2]; + Abc_Obj_t * pNode; + Mio_Gate_t ** ppGates; + int nGates, nFanins, i; + + assert( Abc_NtkIsSopLogic(pNtk) ); + + // check that the library is available + pGenlib = Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()); + if ( pGenlib == NULL ) + { + printf( "The current library is not available.\n" ); + return 0; + } + + // start the truth tables + Abc_AttachSetupTruthTables( uTruths ); + + // collect all the gates + ppGates = Mio_CollectRoots( pGenlib, 6, (float)1.0e+20, 1, &nGates ); + + // derive the gate truth tables + puTruthGates = ALLOC( unsigned *, nGates ); + puTruthGates[0] = ALLOC( unsigned, 2 * nGates ); + for ( i = 1; i < nGates; i++ ) + puTruthGates[i] = puTruthGates[i-1] + 2; + for ( i = 0; i < nGates; i++ ) + Mio_DeriveTruthTable( ppGates[i], uTruths, Mio_GateReadInputs(ppGates[i]), 6, puTruthGates[i] ); + + // assign the gates to pNode->pCopy + Abc_NtkCleanCopy( pNtk ); + Abc_NtkForEachNode( pNtk, pNode, i ) + { + nFanins = Abc_ObjFaninNum(pNode); + if ( nFanins == 0 ) + { + if ( Abc_SopIsConst1(pNode->pData) ) + pNode->pCopy = (Abc_Obj_t *)Mio_LibraryReadConst1(pGenlib); + else + pNode->pCopy = (Abc_Obj_t *)Mio_LibraryReadConst0(pGenlib); + } + else if ( nFanins == 1 ) + { + if ( Abc_SopIsBuf(pNode->pData) ) + pNode->pCopy = (Abc_Obj_t *)Mio_LibraryReadBuf(pGenlib); + else + pNode->pCopy = (Abc_Obj_t *)Mio_LibraryReadInv(pGenlib); + } + else if ( nFanins > 6 ) + { + printf( "Cannot attach gate with more than 6 inputs to node %s.\n", Abc_ObjName(pNode) ); + free( puTruthGates[0] ); + free( puTruthGates ); + free( ppGates ); + return 0; + } + else if ( !Abc_NodeAttach( pNode, ppGates, puTruthGates, nGates, uTruths ) ) + { + printf( "Could not attach the library gate to node %s.\n", Abc_ObjName(pNode) ); + free( puTruthGates[0] ); + free( puTruthGates ); + free( ppGates ); + return 0; + } + } + free( puTruthGates[0] ); + free( puTruthGates ); + free( ppGates ); + FREE( s_pPerms ); + + // perform the final transformation + Abc_NtkForEachNode( pNtk, pNode, i ) + { + if ( pNode->pCopy == NULL ) + { + printf( "Some elementary gates (constant, buffer, or inverter) are missing in the library.\n" ); + return 0; + } + } + + // replace SOP representation by the gate representation + Abc_NtkForEachNode( pNtk, pNode, i ) + pNode->pData = pNode->pCopy, pNode->pCopy = NULL; + pNtk->ntkFunc = ABC_FUNC_MAP; + Extra_MmFlexStop( pNtk->pManFunc, 0 ); + pNtk->pManFunc = pGenlib; + + printf( "Library gates are successfully attached to the nodes.\n" ); + + // make sure that everything is okay + if ( fCheck && !Abc_NtkCheck( pNtk ) ) + { + printf( "Abc_NtkAttach: The network check has failed.\n" ); + return 0; + } + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NodeAttach( Abc_Obj_t * pNode, Mio_Gate_t ** ppGates, unsigned ** puTruthGates, int nGates, unsigned uTruths[][2] ) +{ + int Perm[10]; + int pTempInts[10]; + unsigned uTruthNode[2]; + Abc_Obj_t * pFanin; + Mio_Gate_t * pGate; + int nFanins, i; + + // compute the node's truth table + Abc_AttachComputeTruth( pNode->pData, uTruths, uTruthNode ); + // find the matching gate and permutation + pGate = Abc_AttachFind( ppGates, puTruthGates, nGates, uTruthNode, Perm ); + if ( pGate == NULL ) + return 0; + // permute the fanins + nFanins = Abc_ObjFaninNum(pNode); + Abc_ObjForEachFanin( pNode, pFanin, i ) + pTempInts[i] = pFanin->Id; + for ( i = 0; i < nFanins; i++ ) + pNode->vFanins.pArray[Perm[i]].iFan = pTempInts[i]; + // set the gate + pNode->pCopy = (Abc_Obj_t *)pGate; + return 1; +} + +/**Function************************************************************* + + Synopsis [Sets up the truth tables.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_AttachSetupTruthTables( unsigned uTruths[][2] ) +{ + int m, v; + for ( v = 0; v < 5; v++ ) + uTruths[v][0] = 0; + // set up the truth tables + for ( m = 0; m < 32; m++ ) + for ( v = 0; v < 5; v++ ) + if ( m & (1 << v) ) + uTruths[v][0] |= (1 << m); + // make adjustments for the case of 6 variables + for ( v = 0; v < 5; v++ ) + uTruths[v][1] = uTruths[v][0]; + uTruths[5][0] = 0; + uTruths[5][1] = ATTACH_FULL; +} + +/**Function************************************************************* + + Synopsis [Compute the truth table of the node's cover.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_AttachComputeTruth( char * pSop, unsigned uTruthsIn[][2], unsigned * uTruthRes ) +{ +// Mvc_Cube_t * pCube; + unsigned uSignCube[2]; + int Value; +// int nInputs = pCover->nBits/2; + int nInputs = 6; + int nFanins = Abc_SopGetVarNum(pSop); + char * pCube; + int k; + + // make sure that the number of input truth tables in equal to the number of gate inputs + assert( nInputs < 7 ); + + // clean the resulting truth table + uTruthRes[0] = 0; + uTruthRes[1] = 0; + if ( nInputs < 6 ) + { + // consider the case when only one unsigned can be used +// Mvc_CoverForEachCube( pCover, pCube ) + Abc_SopForEachCube( pSop, nFanins, pCube ) + { + uSignCube[0] = ATTACH_FULL; +// Mvc_CubeForEachVarValue( pCover, pCube, Var, Value ) + Abc_CubeForEachVar( pCube, Value, k ) + { + if ( Value == '0' ) + uSignCube[0] &= ~uTruthsIn[k][0]; + else if ( Value == '1' ) + uSignCube[0] &= uTruthsIn[k][0]; + } + uTruthRes[0] |= uSignCube[0]; + } + if ( Abc_SopGetPhase(pSop) == 0 ) + uTruthRes[0] = ~uTruthRes[0]; + if ( nInputs < 5 ) + uTruthRes[0] &= ATTACH_MASK(1<= 0 ) + { + for ( v = 0; v < 6; v++ ) + Perm[v] = v; + return ppGates[iNum]; + } + // get permutations + if ( s_pPerms == NULL ) + { + s_pPerms = Extra_Permutations( 6 ); + s_nPerms = Extra_Factorial( 6 ); + } + // try permutations + for ( i = 0; i < s_nPerms; i++ ) + { + Abc_TruthPermute( s_pPerms[i], 6, uTruthNode, uTruthPerm ); + if ( (iNum = Abc_AttachCompare( puTruthGates, nGates, uTruthPerm )) >= 0 ) + { + for ( v = 0; v < 6; v++ ) + Perm[v] = (int)s_pPerms[i][v]; + return ppGates[iNum]; + } + } + return NULL; +} + +/**Function************************************************************* + + Synopsis [Find the gate by truth table.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_AttachCompare( unsigned ** puTruthGates, int nGates, unsigned * uTruthNode ) +{ + int i; + for ( i = 0; i < nGates; i++ ) + if ( puTruthGates[i][0] == uTruthNode[0] && puTruthGates[i][1] == uTruthNode[1] ) + return i; + return -1; +} + +/**Function************************************************************* + + Synopsis [Permutes the 6-input truth table.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_TruthPermute( char * pPerm, int nVars, unsigned * uTruthNode, unsigned * uTruthPerm ) +{ + int nMints, iMintPerm, iMint, v; + uTruthPerm[0] = uTruthPerm[1] = 0; + nMints = (1 << nVars); + for ( iMint = 0; iMint < nMints; iMint++ ) + { + if ( (uTruthNode[iMint/32] & (1 << (iMint%32))) == 0 ) + continue; + iMintPerm = 0; + for ( v = 0; v < nVars; v++ ) + if ( iMint & (1 << v) ) + iMintPerm |= (1 << pPerm[v]); + uTruthPerm[iMintPerm/32] |= (1 << (iMintPerm%32)); + } +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/base/abci/abcBalance.c b/src/base/abci/abcBalance.c new file mode 100644 index 00000000..5042d0d5 --- /dev/null +++ b/src/base/abci/abcBalance.c @@ -0,0 +1,239 @@ +/**CFile**************************************************************** + + FileName [abcBalance.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Network and node package.] + + Synopsis [Performs global balancing of the AIG by the number of levels.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: abcBalance.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abc.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static void Abc_NtkBalancePerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkAig, bool fDuplicate ); +static Abc_Obj_t * Abc_NodeBalance_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode, Vec_Vec_t * vStorage, bool fDuplicate ); +static Vec_Ptr_t * Abc_NodeBalanceCone( Abc_Obj_t * pNode, Vec_Vec_t * vSuper, int fDuplicate ); +static int Abc_NodeBalanceCone_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vSuper, bool fFirst, bool fDuplicate ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Balances the AIG network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkBalance( Abc_Ntk_t * pNtk, bool fDuplicate ) +{ + int fCheck = 1; + Abc_Ntk_t * pNtkAig; + assert( Abc_NtkIsStrash(pNtk) ); + // perform balancing + pNtkAig = Abc_NtkStartFrom( pNtk, ABC_TYPE_STRASH, ABC_FUNC_AIG ); + Abc_NtkBalancePerform( pNtk, pNtkAig, fDuplicate ); + Abc_NtkFinalize( pNtk, pNtkAig ); + // make sure everything is okay + if ( fCheck && !Abc_NtkCheck( pNtkAig ) ) + { + printf( "Abc_NtkBalance: The network check has failed.\n" ); + Abc_NtkDelete( pNtkAig ); + return NULL; + } + return pNtkAig; +} + +/**Function************************************************************* + + Synopsis [Balances the AIG network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkBalancePerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkAig, bool fDuplicate ) +{ + int fCheck = 1; + ProgressBar * pProgress; + Vec_Vec_t * vStorage; + Abc_Obj_t * pNode, * pDriver; + int i; + + // copy the constant node + Abc_AigConst1(pNtk->pManFunc)->pCopy = Abc_AigConst1(pNtkAig->pManFunc); + // set the level of PIs of AIG according to the arrival times of the old network + Abc_NtkSetNodeLevelsArrival( pNtk ); + // allocate temporary storage for supergates + vStorage = Vec_VecStart( Abc_AigGetLevelNum(pNtk) + 1 ); + // perform balancing of POs + pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCoNum(pNtk) ); + Abc_NtkForEachCo( pNtk, pNode, i ) + { + Extra_ProgressBarUpdate( pProgress, i, NULL ); + // strash the driver node + pDriver = Abc_ObjFanin0(pNode); + Abc_NodeBalance_rec( pNtkAig, pDriver, vStorage, fDuplicate ); + } + Extra_ProgressBarStop( pProgress ); + Vec_VecFree( vStorage ); +} + +/**Function************************************************************* + + Synopsis [Rebalances the multi-input node rooted at pNodeOld.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Abc_NodeBalance_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNodeOld, Vec_Vec_t * vStorage, bool fDuplicate ) +{ + Abc_Aig_t * pMan = pNtkNew->pManFunc; + Abc_Obj_t * pNodeNew, * pNode1, * pNode2; + Vec_Ptr_t * vSuper; + int i; + assert( !Abc_ObjIsComplement(pNodeOld) ); + // return if the result if known + if ( pNodeOld->pCopy ) + return pNodeOld->pCopy; + assert( Abc_ObjIsNode(pNodeOld) ); + // get the implication supergate + vSuper = Abc_NodeBalanceCone( pNodeOld, vStorage, fDuplicate ); + if ( vSuper->nSize == 0 ) + { // it means that the supergate contains two nodes in the opposite polarity + pNodeOld->pCopy = Abc_ObjNot(Abc_AigConst1(pMan)); + return pNodeOld->pCopy; + } + // for each old node, derive the new well-balanced node + for ( i = 0; i < vSuper->nSize; i++ ) + { + pNodeNew = Abc_NodeBalance_rec( pNtkNew, Abc_ObjRegular(vSuper->pArray[i]), vStorage, fDuplicate ); + vSuper->pArray[i] = Abc_ObjNotCond( pNodeNew, Abc_ObjIsComplement(vSuper->pArray[i]) ); + } + // sort the new nodes by level in the decreasing order + Vec_PtrSort( vSuper, Abc_NodeCompareLevelsDecrease ); + // balance the nodes + assert( vSuper->nSize > 1 ); + while ( vSuper->nSize > 1 ) + { + pNode1 = Vec_PtrPop(vSuper); + pNode2 = Vec_PtrPop(vSuper); + Abc_VecObjPushUniqueOrderByLevel( vSuper, Abc_AigAnd(pMan, pNode1, pNode2) ); + } + // make sure the balanced node is not assigned + assert( pNodeOld->pCopy == NULL ); + // mark the old node with the new node + pNodeOld->pCopy = vSuper->pArray[0]; + return pNodeOld->pCopy; +} + +/**Function************************************************************* + + Synopsis [Collects the nodes in the cone delimited by fMarkA==1.] + + Description [Returns -1 if the AND-cone has the same node in both polarities. + Returns 1 if the AND-cone has the same node in the same polarity. Returns 0 + if the AND-cone has no repeated nodes.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Abc_NodeBalanceCone( Abc_Obj_t * pNode, Vec_Vec_t * vStorage, int fDuplicate ) +{ + Vec_Ptr_t * vNodes; + int RetValue, i; + assert( !Abc_ObjIsComplement(pNode) ); + vNodes = Vec_VecEntry( vStorage, pNode->Level ); + Vec_PtrClear( vNodes ); + RetValue = Abc_NodeBalanceCone_rec( pNode, vNodes, 1, fDuplicate ); + assert( vNodes->nSize > 0 ); + for ( i = 0; i < vNodes->nSize; i++ ) + Abc_ObjRegular((Abc_Obj_t *)vNodes->pArray[i])->fMarkB = 0; + if ( RetValue == -1 ) + vNodes->nSize = 0; + return vNodes; +} + + +/**Function************************************************************* + + Synopsis [Collects the nodes in the cone delimited by fMarkA==1.] + + Description [Returns -1 if the AND-cone has the same node in both polarities. + Returns 1 if the AND-cone has the same node in the same polarity. Returns 0 + if the AND-cone has no repeated nodes.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NodeBalanceCone_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vSuper, bool fFirst, bool fDuplicate ) +{ + int RetValue1, RetValue2, i; + // check if the node is visited + if ( Abc_ObjRegular(pNode)->fMarkB ) + { + // check if the node occurs in the same polarity + for ( i = 0; i < vSuper->nSize; i++ ) + if ( vSuper->pArray[i] == pNode ) + return 1; + // check if the node is present in the opposite polarity + for ( i = 0; i < vSuper->nSize; i++ ) + if ( vSuper->pArray[i] == Abc_ObjNot(pNode) ) + return -1; + assert( 0 ); + return 0; + } + // if the new node is complemented or a PI, another gate begins + if ( !fFirst && (Abc_ObjIsComplement(pNode) || !Abc_ObjIsNode(pNode) || !fDuplicate && (Abc_ObjFanoutNum(pNode) > 1)) ) + { + Vec_PtrPush( vSuper, pNode ); + Abc_ObjRegular(pNode)->fMarkB = 1; + return 0; + } + assert( !Abc_ObjIsComplement(pNode) ); + assert( Abc_ObjIsNode(pNode) ); + // go through the branches + RetValue1 = Abc_NodeBalanceCone_rec( Abc_ObjChild0(pNode), vSuper, 0, fDuplicate ); + RetValue2 = Abc_NodeBalanceCone_rec( Abc_ObjChild1(pNode), vSuper, 0, fDuplicate ); + if ( RetValue1 == -1 || RetValue2 == -1 ) + return -1; + // return 1 if at least one branch has a duplicate + return RetValue1 || RetValue2; +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/base/abci/abcCollapse.c b/src/base/abci/abcCollapse.c new file mode 100644 index 00000000..4e359506 --- /dev/null +++ b/src/base/abci/abcCollapse.c @@ -0,0 +1,147 @@ +/**CFile**************************************************************** + + FileName [abcCollapse.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Network and node package.] + + Synopsis [Collapsing the network into two-levels.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: abcCollapse.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abc.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static Abc_Ntk_t * Abc_NtkFromGlobalBdds( Abc_Ntk_t * pNtk ); +static Abc_Obj_t * Abc_NodeFromGlobalBdds( Abc_Ntk_t * pNtkNew, DdManager * dd, DdNode * bFunc ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Collapses the network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkCollapse( Abc_Ntk_t * pNtk, int fVerbose ) +{ + int fCheck = 1; + Abc_Ntk_t * pNtkNew; + + assert( Abc_NtkIsStrash(pNtk) ); + + // compute the global BDDs + if ( Abc_NtkGlobalBdds(pNtk, 0) == NULL ) + return NULL; + if ( fVerbose ) + printf( "The shared BDD size is %d nodes.\n", Cudd_ReadKeys(pNtk->pManGlob) - Cudd_ReadDead(pNtk->pManGlob) ); + + // create the new network + pNtkNew = Abc_NtkFromGlobalBdds( pNtk ); + Abc_NtkFreeGlobalBdds( pNtk ); + if ( pNtkNew == NULL ) + { + Cudd_Quit( pNtk->pManGlob ); + pNtk->pManGlob = NULL; + return NULL; + } + Extra_StopManager( pNtk->pManGlob ); + pNtk->pManGlob = NULL; + + // make the network minimum base + Abc_NtkMinimumBase( pNtkNew ); + + // make sure that everything is okay + if ( fCheck && !Abc_NtkCheck( pNtkNew ) ) + { + printf( "Abc_NtkCollapse: The network check has failed.\n" ); + Abc_NtkDelete( pNtkNew ); + return NULL; + } + return pNtkNew; +} + +/**Function************************************************************* + + Synopsis [Derives the network with the given global BDD.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkFromGlobalBdds( Abc_Ntk_t * pNtk ) +{ + ProgressBar * pProgress; + Abc_Ntk_t * pNtkNew; + Abc_Obj_t * pNode, * pNodeNew; + DdManager * dd = pNtk->pManGlob; + int i; + // start the new network + pNtkNew = Abc_NtkStartFrom( pNtk, ABC_TYPE_LOGIC, ABC_FUNC_BDD ); + // make sure the new manager has the same number of inputs + Cudd_bddIthVar( pNtkNew->pManFunc, dd->size-1 ); + // process the POs + pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCoNum(pNtk) ); + Abc_NtkForEachCo( pNtk, pNode, i ) + { + Extra_ProgressBarUpdate( pProgress, i, NULL ); + pNodeNew = Abc_NodeFromGlobalBdds( pNtkNew, dd, Vec_PtrEntry(pNtk->vFuncsGlob, i) ); + Abc_ObjAddFanin( pNode->pCopy, pNodeNew ); + } + Extra_ProgressBarStop( pProgress ); + return pNtkNew; +} + +/**Function************************************************************* + + Synopsis [Derives the network with the given global BDD.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Abc_NodeFromGlobalBdds( Abc_Ntk_t * pNtkNew, DdManager * dd, DdNode * bFunc ) +{ + Abc_Obj_t * pNodeNew, * pTemp; + int i; + // create a new node + pNodeNew = Abc_NtkCreateNode( pNtkNew ); + // add the fanins in the order, in which they appear in the reordered manager + Abc_NtkForEachCi( pNtkNew, pTemp, i ) + Abc_ObjAddFanin( pNodeNew, Abc_NtkCi(pNtkNew, dd->invperm[i]) ); + // transfer the function + pNodeNew->pData = Extra_TransferLevelByLevel( dd, pNtkNew->pManFunc, bFunc ); Cudd_Ref( pNodeNew->pData ); + return pNodeNew; +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/base/abci/abcCut.c b/src/base/abci/abcCut.c new file mode 100644 index 00000000..f487bd1b --- /dev/null +++ b/src/base/abci/abcCut.c @@ -0,0 +1,190 @@ +/**CFile**************************************************************** + + FileName [abcCut.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Network and node package.] + + Synopsis [Interface to cut computation.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: abcCut.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abc.h" +#include "cut.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Computes the cuts for the network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Cut_Man_t * Abc_NtkCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams ) +{ + Cut_Man_t * p; + Abc_Obj_t * pObj, * pDriver, * pNode; + Vec_Ptr_t * vNodes; + Vec_Int_t * vChoices; + int i; + int clk = clock(); + + assert( Abc_NtkIsStrash(pNtk) ); + + // start the manager + pParams->nIdsMax = Abc_NtkObjNumMax( pNtk ); + p = Cut_ManStart( pParams ); + if ( pParams->fDrop ) + Cut_ManSetFanoutCounts( p, Abc_NtkFanoutCounts(pNtk) ); + // set cuts for PIs + Abc_NtkForEachCi( pNtk, pObj, i ) + if ( Abc_ObjFanoutNum(pObj) > 0 ) + Cut_NodeSetTriv( p, pObj->Id ); + // compute cuts for internal nodes + vNodes = Abc_AigDfs( pNtk, 0, 1 ); + vChoices = Vec_IntAlloc( 100 ); + Vec_PtrForEachEntry( vNodes, pObj, i ) + { + // when we reached a CO, it is time to deallocate the cuts + if ( Abc_ObjIsCo(pObj) ) + { + if ( pParams->fDrop ) + Cut_NodeTryDroppingCuts( p, Abc_ObjFaninId0(pObj) ); + continue; + } + // skip constant node, it has no cuts + if ( Abc_NodeIsConst(pObj) ) + continue; + // compute the cuts to the internal node + Abc_NodeGetCuts( p, pObj ); + // add cuts due to choices + if ( Abc_NodeIsAigChoice(pObj) ) + { + Vec_IntClear( vChoices ); + for ( pNode = pObj; pNode; pNode = pNode->pData ) + Vec_IntPush( vChoices, pNode->Id ); + Cut_NodeUnionCuts( p, vChoices ); + } + } + if ( !pParams->fSeq ) + { + Vec_PtrFree( vNodes ); + Vec_IntFree( vChoices ); +PRT( "Total", clock() - clk ); + return p; + } + assert( 0 ); + + // compute sequential cuts + Abc_NtkIncrementTravId( pNtk ); + Abc_NtkForEachLatch( pNtk, pObj, i ) + { + pDriver = Abc_ObjFanin0(pObj); + if ( !Abc_ObjIsNode(pDriver) ) + continue; + if ( Abc_NodeIsTravIdCurrent(pDriver) ) + continue; + Abc_NodeSetTravIdCurrent(pDriver); + Cut_NodeSetComputedAsNew( p, pDriver->Id ); + } + // compute as long as new cuts appear + + + return p; +} + +/**Function************************************************************* + + Synopsis [Computes the cuts for the network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void * Abc_NodeGetCutsRecursive( void * p, Abc_Obj_t * pObj ) +{ + void * pList; + if ( pList = Abc_NodeReadCuts( p, pObj ) ) + return pList; + Abc_NodeGetCutsRecursive( p, Abc_ObjFanin0(pObj) ); + Abc_NodeGetCutsRecursive( p, Abc_ObjFanin1(pObj) ); + return Abc_NodeGetCuts( p, pObj ); +} + +/**Function************************************************************* + + Synopsis [Computes the cuts for the network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void * Abc_NodeGetCuts( void * p, Abc_Obj_t * pObj ) +{ + return Cut_NodeComputeCuts( p, pObj->Id, Abc_ObjFaninId0(pObj), Abc_ObjFaninId1(pObj), + Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj) ); +} + +/**Function************************************************************* + + Synopsis [Computes the cuts for the network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void * Abc_NodeReadCuts( void * p, Abc_Obj_t * pObj ) +{ + return Cut_NodeReadCuts( p, pObj->Id ); +} + +/**Function************************************************************* + + Synopsis [Computes the cuts for the network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NodeFreeCuts( void * p, Abc_Obj_t * pObj ) +{ + Cut_NodeFreeCuts( p, pObj->Id ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/base/abci/abcDsd.c b/src/base/abci/abcDsd.c new file mode 100644 index 00000000..013b7ac4 --- /dev/null +++ b/src/base/abci/abcDsd.c @@ -0,0 +1,539 @@ +/**CFile**************************************************************** + + FileName [abcDsd.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Network and node package.] + + Synopsis [Decomposes the network using disjoint-support decomposition.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: abcDsd.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abc.h" +#include "dsd.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static Abc_Ntk_t * Abc_NtkDsdInternal( Abc_Ntk_t * pNtk, bool fVerbose, bool fPrint, bool fShort ); +static void Abc_NtkDsdConstruct( Dsd_Manager_t * pManDsd, Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ); +static Abc_Obj_t * Abc_NtkDsdConstructNode( Dsd_Manager_t * pManDsd, Dsd_Node_t * pNodeDsd, Abc_Ntk_t * pNtkNew ); + +static Vec_Ptr_t * Abc_NtkCollectNodesForDsd( Abc_Ntk_t * pNtk ); +static void Abc_NodeDecompDsdAndMux( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes, Dsd_Manager_t * pManDsd, bool fRecursive ); +static bool Abc_NodeIsForDsd( Abc_Obj_t * pNode ); +static int Abc_NodeFindMuxVar( DdManager * dd, DdNode * bFunc, int nVars ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Derives the DSD network.] + + Description [Takes the strashed network (pNtk), derives global BDDs for + the combinational outputs of this network, and decomposes these BDDs using + disjoint support decomposition. Finally, constructs and return a new + network, which is topologically equivalent to the decomposition tree. + Allocates and frees a new BDD manager and a new DSD manager.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkDsdGlobal( Abc_Ntk_t * pNtk, bool fVerbose, bool fPrint, bool fShort ) +{ + int fCheck = 1; + Abc_Ntk_t * pNtkNew; + + assert( Abc_NtkIsStrash(pNtk) ); + + // perform FPGA mapping + if ( Abc_NtkGlobalBdds(pNtk, 0) == NULL ) + return NULL; + if ( fVerbose ) + printf( "The shared BDD size is %d nodes.\n", Cudd_ReadKeys(pNtk->pManGlob) - Cudd_ReadDead(pNtk->pManGlob) ); + + // transform the result of mapping into a BDD network + pNtkNew = Abc_NtkDsdInternal( pNtk, fVerbose, fPrint, fShort ); + if ( pNtkNew == NULL ) + { + Cudd_Quit( pNtk->pManGlob ); + pNtk->pManGlob = NULL; + return NULL; + } + Extra_StopManager( pNtk->pManGlob ); + pNtk->pManGlob = NULL; + + // make sure that everything is okay + if ( fCheck && !Abc_NtkCheck( pNtkNew ) ) + { + printf( "Abc_NtkDsdGlobal: The network check has failed.\n" ); + Abc_NtkDelete( pNtkNew ); + return NULL; + } + return pNtkNew; +} + +/**Function************************************************************* + + Synopsis [Constructs the decomposed network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkDsdInternal( Abc_Ntk_t * pNtk, bool fVerbose, bool fPrint, bool fShort ) +{ + DdManager * dd = pNtk->pManGlob; + Dsd_Manager_t * pManDsd; + Abc_Ntk_t * pNtkNew; + DdNode * bFunc; + char ** ppNamesCi, ** ppNamesCo; + Abc_Obj_t * pObj; + int i; + + // complement the global functions + Abc_NtkForEachCo( pNtk, pObj, i ) + { + bFunc = Vec_PtrEntry(pNtk->vFuncsGlob, i); + Vec_PtrWriteEntry(pNtk->vFuncsGlob, i, Cudd_NotCond(bFunc, Abc_ObjFaninC0(pObj)) ); + } + + // perform the decomposition + assert( Vec_PtrSize(pNtk->vFuncsGlob) == Abc_NtkCoNum(pNtk) ); + pManDsd = Dsd_ManagerStart( dd, Abc_NtkCiNum(pNtk), fVerbose ); + Dsd_Decompose( pManDsd, (DdNode **)pNtk->vFuncsGlob->pArray, Abc_NtkCoNum(pNtk) ); + Abc_NtkFreeGlobalBdds( pNtk ); + if ( pManDsd == NULL ) + { + Cudd_Quit( dd ); + return NULL; + } + + // start the new network + pNtkNew = Abc_NtkStartFrom( pNtk, ABC_TYPE_LOGIC, ABC_FUNC_BDD ); + // make sure the new manager has enough inputs + Cudd_bddIthVar( pNtkNew->pManFunc, dd->size-1 ); + // put the results into the new network (save new CO drivers in old CO drivers) + Abc_NtkDsdConstruct( pManDsd, pNtk, pNtkNew ); + // finalize the new network + Abc_NtkFinalize( pNtk, pNtkNew ); + // fix the problem with complemented and duplicated CO edges + Abc_NtkLogicMakeSimpleCos( pNtkNew, 0 ); + + if ( fPrint ) + { + ppNamesCi = Abc_NtkCollectCioNames( pNtk, 0 ); + ppNamesCo = Abc_NtkCollectCioNames( pNtk, 1 ); + Dsd_TreePrint( stdout, pManDsd, ppNamesCi, ppNamesCo, fShort, -1 ); + free( ppNamesCi ); + free( ppNamesCo ); + } + + // stop the DSD manager + Dsd_ManagerStop( pManDsd ); + return pNtkNew; +} + +/**Function************************************************************* + + Synopsis [Constructs the decomposed network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkDsdConstruct( Dsd_Manager_t * pManDsd, Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ) +{ + Dsd_Node_t ** ppNodesDsd; + Dsd_Node_t * pNodeDsd; + Abc_Obj_t * pNode, * pNodeNew, * pDriver, * pConst1; + int i, nNodesDsd; + + // save the CI nodes in the DSD nodes + Abc_NtkForEachCi( pNtk, pNode, i ) + { + pNodeDsd = Dsd_ManagerReadInput( pManDsd, i ); + Dsd_NodeSetMark( pNodeDsd, (int)pNode->pCopy ); + } + // set the constant node + pConst1 = Abc_AigConst1(pNtk->pManFunc); + if ( Abc_ObjFanoutNum(pConst1) > 0 ) + pConst1->pCopy = Abc_NodeCreateConst1(pNtkNew); + + // collect DSD nodes in DFS order (leaves and const1 are not collected) + ppNodesDsd = Dsd_TreeCollectNodesDfs( pManDsd, &nNodesDsd ); + for ( i = 0; i < nNodesDsd; i++ ) + Abc_NtkDsdConstructNode( pManDsd, ppNodesDsd[i], pNtkNew ); + free( ppNodesDsd ); + + // set the pointers to the CO drivers + Abc_NtkForEachCo( pNtk, pNode, i ) + { + pDriver = Abc_ObjFanin0( pNode ); + if ( !Abc_ObjIsNode(pDriver) ) + continue; + if ( !Abc_NodeIsAigAnd(pDriver) ) + continue; + pNodeDsd = Dsd_ManagerReadRoot( pManDsd, i ); + pNodeNew = (Abc_Obj_t *)Dsd_NodeReadMark( Dsd_Regular(pNodeDsd) ); + assert( !Abc_ObjIsComplement(pNodeNew) ); + pDriver->pCopy = Abc_ObjNotCond( pNodeNew, Dsd_IsComplement(pNodeDsd) ); + } +} + +/**Function************************************************************* + + Synopsis [Performs DSD using the manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Abc_NtkDsdConstructNode( Dsd_Manager_t * pManDsd, Dsd_Node_t * pNodeDsd, Abc_Ntk_t * pNtkNew ) +{ + DdManager * ddDsd = Dsd_ManagerReadDd( pManDsd ); + DdManager * ddNew = pNtkNew->pManFunc; + Dsd_Node_t * pFaninDsd; + Abc_Obj_t * pNodeNew, * pFanin; + DdNode * bLocal, * bTemp, * bVar; + Dsd_Type_t Type; + int i, nDecs; + + // create the new node + pNodeNew = Abc_NtkCreateNode( pNtkNew ); + // add the fanins + Type = Dsd_NodeReadType( pNodeDsd ); + nDecs = Dsd_NodeReadDecsNum( pNodeDsd ); + assert( nDecs > 1 ); + for ( i = 0; i < nDecs; i++ ) + { + pFaninDsd = Dsd_NodeReadDec( pNodeDsd, i ); + pFanin = (Abc_Obj_t *)Dsd_NodeReadMark(Dsd_Regular(pFaninDsd)); + Abc_ObjAddFanin( pNodeNew, pFanin ); + assert( Type == DSD_NODE_OR || !Dsd_IsComplement(pFaninDsd) ); + } + + // create the local function depending on the type of the node + ddNew = pNtkNew->pManFunc; + switch ( Type ) + { + case DSD_NODE_CONST1: + { + bLocal = ddNew->one; Cudd_Ref( bLocal ); + break; + } + case DSD_NODE_OR: + { + bLocal = Cudd_Not(ddNew->one); Cudd_Ref( bLocal ); + for ( i = 0; i < nDecs; i++ ) + { + pFaninDsd = Dsd_NodeReadDec( pNodeDsd, i ); + bVar = Cudd_NotCond( ddNew->vars[i], Dsd_IsComplement(pFaninDsd) ); + bLocal = Cudd_bddOr( ddNew, bTemp = bLocal, bVar ); Cudd_Ref( bLocal ); + Cudd_RecursiveDeref( ddNew, bTemp ); + } + break; + } + case DSD_NODE_EXOR: + { + bLocal = Cudd_Not(ddNew->one); Cudd_Ref( bLocal ); + for ( i = 0; i < nDecs; i++ ) + { + bLocal = Cudd_bddXor( ddNew, bTemp = bLocal, ddNew->vars[i] ); Cudd_Ref( bLocal ); + Cudd_RecursiveDeref( ddNew, bTemp ); + } + break; + } + case DSD_NODE_PRIME: + { + bLocal = Dsd_TreeGetPrimeFunction( ddDsd, pNodeDsd ); Cudd_Ref( bLocal ); + bLocal = Extra_TransferLevelByLevel( ddDsd, ddNew, bTemp = bLocal ); Cudd_Ref( bLocal ); + Cudd_RecursiveDeref( ddDsd, bTemp ); + // bLocal is now in the new BDD manager + break; + } + default: + { + assert( 0 ); + break; + } + } + pNodeNew->pData = bLocal; + Dsd_NodeSetMark( pNodeDsd, (int)pNodeNew ); + return pNodeNew; +} + + + + + + +/**Function************************************************************* + + Synopsis [Recursively decomposes internal nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NtkDsdLocal( Abc_Ntk_t * pNtk, bool fVerbose, bool fRecursive ) +{ + int fCheck = 1; + Dsd_Manager_t * pManDsd; + DdManager * dd = pNtk->pManFunc; + Vec_Ptr_t * vNodes; + int i; + + assert( Abc_NtkIsBddLogic(pNtk) ); + + // make the network minimum base + Abc_NtkMinimumBase( pNtk ); + + // start the DSD manager + pManDsd = Dsd_ManagerStart( dd, dd->size, 0 ); + + // collect nodes for decomposition + vNodes = Abc_NtkCollectNodesForDsd( pNtk ); + for ( i = 0; i < vNodes->nSize; i++ ) + Abc_NodeDecompDsdAndMux( vNodes->pArray[i], vNodes, pManDsd, fRecursive ); + Vec_PtrFree( vNodes ); + + // stop the DSD manager + Dsd_ManagerStop( pManDsd ); + + // make sure everything is okay + if ( fCheck && !Abc_NtkCheck( pNtk ) ) + { + printf( "Abc_NtkDsdRecursive: The network check has failed.\n" ); + return 0; + } + return 1; +} + +/**Function************************************************************* + + Synopsis [Collects the nodes that may need decomposition.] + + Description [The nodes that do not need decomposition are those + whose BDD has more internal nodes than the support size.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Abc_NtkCollectNodesForDsd( Abc_Ntk_t * pNtk ) +{ + Vec_Ptr_t * vNodes; + Abc_Obj_t * pNode; + int i; + vNodes = Vec_PtrAlloc( 100 ); + Abc_NtkForEachNode( pNtk, pNode, i ) + { + if ( Abc_NodeIsForDsd(pNode) ) + Vec_PtrPush( vNodes, pNode ); + } + return vNodes; +} + +/**Function************************************************************* + + Synopsis [Performs decomposition of one node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NodeDecompDsdAndMux( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes, Dsd_Manager_t * pManDsd, bool fRecursive ) +{ + DdManager * dd = pNode->pNtk->pManFunc; + Abc_Obj_t * pRoot, * pFanin, * pNode1, * pNode2, * pNodeC; + Dsd_Node_t ** ppNodesDsd, * pNodeDsd, * pFaninDsd; + int i, nNodesDsd, iVar, fCompl; + + // try disjoint support decomposition + pNodeDsd = Dsd_DecomposeOne( pManDsd, pNode->pData ); + fCompl = Dsd_IsComplement( pNodeDsd ); + pNodeDsd = Dsd_Regular( pNodeDsd ); + + // determine what decomposition to use + if ( !fRecursive || Dsd_NodeReadDecsNum(pNodeDsd) != Abc_ObjFaninNum(pNode) ) + { // perform DSD + + // set the inputs + Abc_ObjForEachFanin( pNode, pFanin, i ) + { + pFaninDsd = Dsd_ManagerReadInput( pManDsd, i ); + Dsd_NodeSetMark( pFaninDsd, (int)pFanin ); + } + + // construct the intermediate nodes + ppNodesDsd = Dsd_TreeCollectNodesDfsOne( pManDsd, pNodeDsd, &nNodesDsd ); + for ( i = 0; i < nNodesDsd; i++ ) + { + pRoot = Abc_NtkDsdConstructNode( pManDsd, ppNodesDsd[i], pNode->pNtk ); + if ( Abc_NodeIsForDsd(pRoot) && fRecursive ) + Vec_PtrPush( vNodes, pRoot ); + } + free( ppNodesDsd ); + + // remove the current fanins + Abc_ObjRemoveFanins( pNode ); + // add fanin to the root + Abc_ObjAddFanin( pNode, pRoot ); + // update the function to be that of buffer + Cudd_RecursiveDeref( dd, pNode->pData ); + pNode->pData = Cudd_NotCond( dd->vars[0], fCompl ); Cudd_Ref( pNode->pData ); + } + else // perform MUX-decomposition + { + // get the cofactoring variable + iVar = Abc_NodeFindMuxVar( dd, pNode->pData, Abc_ObjFaninNum(pNode) ); + pNodeC = Abc_ObjFanin( pNode, iVar ); + + // get the negative cofactor + pNode1 = Abc_NodeClone( pNode ); + pNode1->pData = Cudd_Cofactor( dd, pNode->pData, Cudd_Not(dd->vars[iVar]) ); Cudd_Ref( pNode1->pData ); + Abc_NodeMinimumBase( pNode1 ); + if ( Abc_NodeIsForDsd(pNode1) ) + Vec_PtrPush( vNodes, pNode1 ); + + // get the positive cofactor + pNode2 = Abc_NodeClone( pNode ); + pNode2->pData = Cudd_Cofactor( dd, pNode->pData, dd->vars[iVar] ); Cudd_Ref( pNode2->pData ); + Abc_NodeMinimumBase( pNode2 ); + if ( Abc_NodeIsForDsd(pNode2) ) + Vec_PtrPush( vNodes, pNode2 ); + + // remove the current fanins + Abc_ObjRemoveFanins( pNode ); + // add new fanins + Abc_ObjAddFanin( pNode, pNodeC ); + Abc_ObjAddFanin( pNode, pNode2 ); + Abc_ObjAddFanin( pNode, pNode1 ); + // update the function to be that of MUX + Cudd_RecursiveDeref( dd, pNode->pData ); + pNode->pData = Cudd_bddIte( dd, dd->vars[0], dd->vars[1], dd->vars[2] ); Cudd_Ref( pNode->pData ); + } +} + +/**Function************************************************************* + + Synopsis [Performs decomposition of one node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +bool Abc_NodeIsForDsd( Abc_Obj_t * pNode ) +{ + DdManager * dd = pNode->pNtk->pManFunc; + DdNode * bFunc, * bFunc0, * bFunc1; + assert( Abc_ObjIsNode(pNode) ); +// if ( Cudd_DagSize(pNode->pData)-1 > Abc_ObjFaninNum(pNode) ) +// return 1; +// return 0; + + for ( bFunc = Cudd_Regular(pNode->pData); !cuddIsConstant(bFunc); ) + { + bFunc0 = Cudd_Regular( cuddE(bFunc) ); + bFunc1 = cuddT(bFunc); + if ( bFunc0 == b1 ) + bFunc = bFunc1; + else if ( bFunc1 == b1 || bFunc0 == bFunc1 ) + bFunc = bFunc0; + else + return 1; + } + return 0; +} + +/**Function************************************************************* + + Synopsis [Determines a cofactoring variable.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NodeFindMuxVar( DdManager * dd, DdNode * bFunc, int nVars ) +{ + DdNode * bVar, * bCof0, * bCof1; + int SuppSumMin = 1000000; + int i, nSSD, nSSQ, iVar; + +// printf( "\n\nCofactors:\n\n" ); + iVar = -1; + for ( i = 0; i < nVars; i++ ) + { + bVar = dd->vars[i]; + + bCof0 = Cudd_Cofactor( dd, bFunc, Cudd_Not(bVar) ); Cudd_Ref( bCof0 ); + bCof1 = Cudd_Cofactor( dd, bFunc, bVar ); Cudd_Ref( bCof1 ); + +// nodD = Cudd_DagSize(bCof0); +// nodQ = Cudd_DagSize(bCof1); +// printf( "+%02d: D=%2d. Q=%2d. ", i, nodD, nodQ ); +// printf( "S=%2d. D=%2d. ", nodD + nodQ, abs(nodD-nodQ) ); + + nSSD = Cudd_SupportSize( dd, bCof0 ); + nSSQ = Cudd_SupportSize( dd, bCof1 ); + +// printf( "SD=%2d. SQ=%2d. ", nSSD, nSSQ ); +// printf( "S=%2d. D=%2d. ", nSSD + nSSQ, abs(nSSD - nSSQ) ); +// printf( "Cost=%3d. ", Cost(nodD,nodQ,nSSD,nSSQ) ); +// printf( "\n" ); + + Cudd_RecursiveDeref( dd, bCof0 ); + Cudd_RecursiveDeref( dd, bCof1 ); + + if ( SuppSumMin > nSSD + nSSQ ) + { + SuppSumMin = nSSD + nSSQ; + iVar = i; + } + } + return iVar; +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/base/abci/abcFpga.c b/src/base/abci/abcFpga.c new file mode 100644 index 00000000..f30325c0 --- /dev/null +++ b/src/base/abci/abcFpga.c @@ -0,0 +1,267 @@ +/**CFile**************************************************************** + + FileName [abcFpga.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Network and node package.] + + Synopsis [Interface with the FPGA mapping package.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: abcFpga.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abc.h" +#include "fpgaInt.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static Fpga_Man_t * Abc_NtkToFpga( Abc_Ntk_t * pNtk, int fRecovery, float * pSwitching, int fVerbose ); +static Abc_Ntk_t * Abc_NtkFromFpga( Fpga_Man_t * pMan, Abc_Ntk_t * pNtk ); +static Abc_Obj_t * Abc_NodeFromFpga_rec( Abc_Ntk_t * pNtkNew, Fpga_Node_t * pNodeFpga ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Interface with the FPGA mapping package.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkFpga( Abc_Ntk_t * pNtk, int fRecovery, int fSwitching, int fVerbose ) +{ + int fCheck = 1; + Abc_Ntk_t * pNtkNew; + Fpga_Man_t * pMan; + Vec_Int_t * vSwitching; + float * pSwitching = NULL; + int fShowSwitching = 0; + + assert( Abc_NtkIsStrash(pNtk) ); + + // print a warning about choice nodes + if ( Abc_NtkGetChoiceNum( pNtk ) ) + printf( "Performing FPGA mapping with choices.\n" ); + + // compute switching activity + fShowSwitching |= fSwitching; + if ( fShowSwitching ) + { + extern Vec_Int_t * Sim_NtkComputeSwitching( Abc_Ntk_t * pNtk, int nPatterns ); + vSwitching = Sim_NtkComputeSwitching( pNtk, 4096 ); + pSwitching = (float *)vSwitching->pArray; + } + + // perform FPGA mapping + pMan = Abc_NtkToFpga( pNtk, fRecovery, pSwitching, fVerbose ); + if ( pSwitching ) Vec_IntFree( vSwitching ); + if ( pMan == NULL ) + return NULL; + Fpga_ManSetSwitching( pMan, fSwitching ); + if ( !Fpga_Mapping( pMan ) ) + { + Fpga_ManFree( pMan ); + return NULL; + } + + // transform the result of mapping into a BDD network + pNtkNew = Abc_NtkFromFpga( pMan, pNtk ); + if ( pNtkNew == NULL ) + return NULL; + Fpga_ManFree( pMan ); + + // make the network minimum base + Abc_NtkMinimumBase( pNtkNew ); + + // make sure that everything is okay + if ( fCheck && !Abc_NtkCheck( pNtkNew ) ) + { + printf( "Abc_NtkFpga: The network check has failed.\n" ); + Abc_NtkDelete( pNtkNew ); + return NULL; + } + return pNtkNew; +} + +/**Function************************************************************* + + Synopsis [Load the network into FPGA manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Fpga_Man_t * Abc_NtkToFpga( Abc_Ntk_t * pNtk, int fRecovery, float * pSwitching, int fVerbose ) +{ + Fpga_Man_t * pMan; + ProgressBar * pProgress; + Fpga_Node_t * pNodeFpga; + Vec_Ptr_t * vNodes; + Abc_Obj_t * pNode, * pFanin, * pPrev; + int i; + + assert( Abc_NtkIsStrash(pNtk) ); + + // start the mapping manager and set its parameters + pMan = Fpga_ManCreate( Abc_NtkCiNum(pNtk), Abc_NtkCoNum(pNtk), fVerbose ); + if ( pMan == NULL ) + return NULL; + Fpga_ManSetAreaRecovery( pMan, fRecovery ); + Fpga_ManSetOutputNames( pMan, Abc_NtkCollectCioNames(pNtk, 1) ); + Fpga_ManSetInputArrivals( pMan, Abc_NtkGetCiArrivalFloats(pNtk) ); + + // create PIs and remember them in the old nodes + Abc_NtkCleanCopy( pNtk ); + Abc_NtkForEachCi( pNtk, pNode, i ) + { + pNodeFpga = Fpga_ManReadInputs(pMan)[i]; + pNode->pCopy = (Abc_Obj_t *)pNodeFpga; + if ( pSwitching ) + Fpga_NodeSetSwitching( pNodeFpga, pSwitching[pNode->Id] ); + } + + // load the AIG into the mapper + vNodes = Abc_AigDfs( pNtk, 0, 0 ); + pProgress = Extra_ProgressBarStart( stdout, vNodes->nSize ); + Vec_PtrForEachEntry( vNodes, pNode, i ) + { + Extra_ProgressBarUpdate( pProgress, i, NULL ); + // consider the case of a constant + if ( Abc_NodeIsConst(pNode) ) + { + Abc_AigConst1(pNtk->pManFunc)->pCopy = (Abc_Obj_t *)Fpga_ManReadConst1(pMan); + continue; + } + // add the node to the mapper + pNodeFpga = Fpga_NodeAnd( pMan, + Fpga_NotCond( Abc_ObjFanin0(pNode)->pCopy, Abc_ObjFaninC0(pNode) ), + Fpga_NotCond( Abc_ObjFanin1(pNode)->pCopy, Abc_ObjFaninC1(pNode) ) ); + assert( pNode->pCopy == NULL ); + // remember the node + pNode->pCopy = (Abc_Obj_t *)pNodeFpga; + if ( pSwitching ) + Fpga_NodeSetSwitching( pNodeFpga, pSwitching[pNode->Id] ); + // set up the choice node + if ( Abc_NodeIsAigChoice( pNode ) ) + for ( pPrev = pNode, pFanin = pNode->pData; pFanin; pPrev = pFanin, pFanin = pFanin->pData ) + { + Fpga_NodeSetNextE( (Fpga_Node_t *)pPrev->pCopy, (Fpga_Node_t *)pFanin->pCopy ); + Fpga_NodeSetRepr( (Fpga_Node_t *)pFanin->pCopy, (Fpga_Node_t *)pNode->pCopy ); + } + } + Extra_ProgressBarStop( pProgress ); + Vec_PtrFree( vNodes ); + + // set the primary outputs without copying the phase + Abc_NtkForEachCo( pNtk, pNode, i ) + Fpga_ManReadOutputs(pMan)[i] = (Fpga_Node_t *)Abc_ObjFanin0(pNode)->pCopy; + return pMan; +} + +/**Function************************************************************* + + Synopsis [Creates the mapped network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkFromFpga( Fpga_Man_t * pMan, Abc_Ntk_t * pNtk ) +{ + ProgressBar * pProgress; + Abc_Ntk_t * pNtkNew; + Abc_Obj_t * pNode, * pNodeNew; + int i, nDupGates; + // create the new network + pNtkNew = Abc_NtkStartFrom( pNtk, ABC_TYPE_LOGIC, ABC_FUNC_BDD ); + // make the mapper point to the new network + Fpga_CutsCleanSign( pMan ); + Fpga_ManCleanData0( pMan ); + Abc_NtkForEachCi( pNtk, pNode, i ) + Fpga_NodeSetData0( Fpga_ManReadInputs(pMan)[i], (char *)pNode->pCopy ); + // set the constant node + if ( Abc_ObjFanoutNum( Abc_AigConst1(pNtk->pManFunc) ) > 0 ) + Fpga_NodeSetData0( Fpga_ManReadConst1(pMan), (char *)Abc_NodeCreateConst1(pNtkNew) ); + // process the nodes in topological order + pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCoNum(pNtk) ); + Abc_NtkForEachCo( pNtk, pNode, i ) + { + Extra_ProgressBarUpdate( pProgress, i, NULL ); + pNodeNew = Abc_NodeFromFpga_rec( pNtkNew, Fpga_ManReadOutputs(pMan)[i] ); + assert( !Abc_ObjIsComplement(pNodeNew) ); + Abc_ObjFanin0(pNode)->pCopy = pNodeNew; + } + Extra_ProgressBarStop( pProgress ); + // finalize the new network + Abc_NtkFinalize( pNtk, pNtkNew ); + // decouple the PO driver nodes to reduce the number of levels + nDupGates = Abc_NtkLogicMakeSimpleCos( pNtkNew, 1 ); +// if ( nDupGates && Fpga_ManReadVerbose(pMan) ) +// printf( "Duplicated %d gates to decouple the CO drivers.\n", nDupGates ); + return pNtkNew; +} + +/**Function************************************************************* + + Synopsis [Derive one node after FPGA mapping.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Abc_NodeFromFpga_rec( Abc_Ntk_t * pNtkNew, Fpga_Node_t * pNodeFpga ) +{ + Fpga_Cut_t * pCutBest; + Fpga_Node_t ** ppLeaves; + Abc_Obj_t * pNodeNew; + int i, nLeaves; + assert( !Fpga_IsComplement(pNodeFpga) ); + // return if the result if known + pNodeNew = (Abc_Obj_t *)Fpga_NodeReadData0( pNodeFpga ); + if ( pNodeNew ) + return pNodeNew; + assert( Fpga_NodeIsAnd(pNodeFpga) ); + // get the parameters of the best cut + pCutBest = Fpga_NodeReadCutBest( pNodeFpga ); + ppLeaves = Fpga_CutReadLeaves( pCutBest ); + nLeaves = Fpga_CutReadLeavesNum( pCutBest ); + // create a new node + pNodeNew = Abc_NtkCreateNode( pNtkNew ); + for ( i = 0; i < nLeaves; i++ ) + Abc_ObjAddFanin( pNodeNew, Abc_NodeFromFpga_rec(pNtkNew, ppLeaves[i]) ); + // derive the function of this node + pNodeNew->pData = Fpga_TruthsCutBdd( pNtkNew->pManFunc, pCutBest ); Cudd_Ref( pNodeNew->pData ); + Fpga_NodeSetData0( pNodeFpga, (char *)pNodeNew ); + return pNodeNew; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/base/abci/abcFraig.c b/src/base/abci/abcFraig.c new file mode 100644 index 00000000..fbe676a3 --- /dev/null +++ b/src/base/abci/abcFraig.c @@ -0,0 +1,586 @@ +/**CFile**************************************************************** + + FileName [abcFraig.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Network and node package.] + + Synopsis [Procedures interfacing with the FRAIG package.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: abcFraig.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abc.h" +#include "fraig.h" +#include "main.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +extern Fraig_Man_t * Abc_NtkToFraig( Abc_Ntk_t * pNtk, Fraig_Params_t * pParams, int fAllNodes ); +static Abc_Ntk_t * Abc_NtkFromFraig( Fraig_Man_t * pMan, Abc_Ntk_t * pNtk ); +static Abc_Obj_t * Abc_NodeFromFraig_rec( Abc_Ntk_t * pNtkNew, Fraig_Node_t * pNodeFraig ); + +static int Abc_NtkFraigTrustCheck( Abc_Ntk_t * pNtk ); +static void Abc_NtkFraigTrustOne( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ); +static Abc_Obj_t * Abc_NodeFraigTrust( Abc_Aig_t * pMan, Abc_Obj_t * pNode ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Interfaces the network with the FRAIG package.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkFraig( Abc_Ntk_t * pNtk, void * pParams, int fAllNodes ) +{ + int fCheck = 1; + Fraig_Params_t * pPars = pParams; + Abc_Ntk_t * pNtkNew; + Fraig_Man_t * pMan; + // perform fraiging + pMan = Abc_NtkToFraig( pNtk, pParams, fAllNodes ); + // prove the miter if asked to + if ( pPars->fTryProve ) + Fraig_ManProveMiter( pMan ); + // reconstruct FRAIG in the new network + pNtkNew = Abc_NtkFromFraig( pMan, pNtk ); + Fraig_ManFree( pMan ); + // make sure that everything is okay + if ( fCheck && !Abc_NtkCheck( pNtkNew ) ) + { + printf( "Abc_NtkFraig: The network check has failed.\n" ); + Abc_NtkDelete( pNtkNew ); + return NULL; + } + return pNtkNew; +} + +/**Function************************************************************* + + Synopsis [Transforms the strashed network into FRAIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Fraig_Man_t * Abc_NtkToFraig( Abc_Ntk_t * pNtk, Fraig_Params_t * pParams, int fAllNodes ) +{ + Fraig_Man_t * pMan; + ProgressBar * pProgress; + Fraig_Node_t * pNodeFraig; + Vec_Ptr_t * vNodes; + Abc_Obj_t * pNode, * pConst1, * pReset; + int i; + + assert( Abc_NtkIsStrash(pNtk) ); + + // create the FRAIG manager + pMan = Fraig_ManCreate( pParams ); + + // create PIs and remember them in the old nodes + Abc_NtkCleanCopy( pNtk ); + Abc_NtkForEachCi( pNtk, pNode, i ) + pNode->pCopy = (Abc_Obj_t *)Fraig_ManReadIthVar(pMan, i); + pConst1 = Abc_AigConst1( pNtk->pManFunc ); + pReset = Abc_AigReset( pNtk->pManFunc ); + + // perform strashing + vNodes = Abc_AigDfs( pNtk, fAllNodes, 0 ); + if ( !pParams->fInternal ) + pProgress = Extra_ProgressBarStart( stdout, vNodes->nSize ); + Vec_PtrForEachEntry( vNodes, pNode, i ) + { + if ( !pParams->fInternal ) + Extra_ProgressBarUpdate( pProgress, i, NULL ); + if ( pNode == pConst1 ) + pNodeFraig = Fraig_ManReadConst1(pMan); + else if ( pNode == pReset ) + continue; + else + pNodeFraig = Fraig_NodeAnd( pMan, + Fraig_NotCond( Abc_ObjFanin0(pNode)->pCopy, Abc_ObjFaninC0(pNode) ), + Fraig_NotCond( Abc_ObjFanin1(pNode)->pCopy, Abc_ObjFaninC1(pNode) ) ); + assert( pNode->pCopy == NULL ); + pNode->pCopy = (Abc_Obj_t *)pNodeFraig; + } + if ( !pParams->fInternal ) + Extra_ProgressBarStop( pProgress ); + Vec_PtrFree( vNodes ); + + // set the primary outputs + Abc_NtkForEachCo( pNtk, pNode, i ) + Fraig_ManSetPo( pMan, (Fraig_Node_t *)Abc_ObjNotCond( Abc_ObjFanin0(pNode)->pCopy, Abc_ObjFaninC0(pNode) ) ); + return pMan; +} + +/**Function************************************************************* + + Synopsis [Transforms FRAIG into what looks like a strashed network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkFromFraig( Fraig_Man_t * pMan, Abc_Ntk_t * pNtk ) +{ + ProgressBar * pProgress; + Abc_Ntk_t * pNtkNew; + Abc_Obj_t * pNode, * pNodeNew; + int i; + // create the new network + pNtkNew = Abc_NtkStartFrom( pNtk, ABC_TYPE_STRASH, ABC_FUNC_AIG ); + // make the mapper point to the new network + Abc_NtkForEachCi( pNtk, pNode, i ) + Fraig_NodeSetData1( Fraig_ManReadIthVar(pMan, i), (Fraig_Node_t *)pNode->pCopy ); + // set the constant node + Fraig_NodeSetData1( Fraig_ManReadConst1(pMan), (Fraig_Node_t *)Abc_AigConst1(pNtkNew->pManFunc) ); + // process the nodes in topological order + pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCoNum(pNtk) ); + Abc_NtkForEachCo( pNtk, pNode, i ) + { + Extra_ProgressBarUpdate( pProgress, i, NULL ); + pNodeNew = Abc_NodeFromFraig_rec( pNtkNew, Fraig_ManReadOutputs(pMan)[i] ); + Abc_ObjAddFanin( pNode->pCopy, pNodeNew ); + } + Extra_ProgressBarStop( pProgress ); + return pNtkNew; +} + +/**Function************************************************************* + + Synopsis [Transforms into AIG one node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Abc_NodeFromFraig_rec( Abc_Ntk_t * pNtkNew, Fraig_Node_t * pNodeFraig ) +{ + Abc_Obj_t * pRes, * pRes0, * pRes1, * pResMin, * pResCur; + Fraig_Node_t * pNodeTemp, * pNodeFraigR = Fraig_Regular(pNodeFraig); + void ** ppTail; + // check if the node was already considered + if ( pRes = (Abc_Obj_t *)Fraig_NodeReadData1(pNodeFraigR) ) + return Abc_ObjNotCond( pRes, Fraig_IsComplement(pNodeFraig) ); + // solve the children + pRes0 = Abc_NodeFromFraig_rec( pNtkNew, Fraig_NodeReadOne(pNodeFraigR) ); + pRes1 = Abc_NodeFromFraig_rec( pNtkNew, Fraig_NodeReadTwo(pNodeFraigR) ); + // derive the new node + pRes = Abc_AigAnd( pNtkNew->pManFunc, pRes0, pRes1 ); + pRes->fPhase = Fraig_NodeReadSimInv( pNodeFraigR ); + // if the node has an equivalence class, find its representative + if ( Fraig_NodeReadRepr(pNodeFraigR) == NULL && Fraig_NodeReadNextE(pNodeFraigR) != NULL ) + { + // go through the FRAIG nodes belonging to this equivalence class + // and find the representative node (the node with the smallest level) + pResMin = pRes; + for ( pNodeTemp = Fraig_NodeReadNextE(pNodeFraigR); pNodeTemp; pNodeTemp = Fraig_NodeReadNextE(pNodeTemp) ) + { + assert( Fraig_NodeReadData1(pNodeTemp) == NULL ); + pResCur = Abc_NodeFromFraig_rec( pNtkNew, pNodeTemp ); + if ( pResMin->Level > pResCur->Level ) + pResMin = pResCur; + } + // link the nodes in such a way that representative goes first + ppTail = &pResMin->pData; + if ( pRes != pResMin ) + { + *ppTail = pRes; + ppTail = &pRes->pData; + } + for ( pNodeTemp = Fraig_NodeReadNextE(pNodeFraigR); pNodeTemp; pNodeTemp = Fraig_NodeReadNextE(pNodeTemp) ) + { + pResCur = (Abc_Obj_t *)Fraig_NodeReadData1(pNodeTemp); + assert( pResCur ); + if ( pResMin == pResCur ) + continue; + *ppTail = pResCur; + ppTail = &pResCur->pData; + } + assert( *ppTail == NULL ); + + // update the phase of the node + pRes = Abc_ObjNotCond( pResMin, (pRes->fPhase ^ pResMin->fPhase) ); + } + Fraig_NodeSetData1( pNodeFraigR, (Fraig_Node_t *)pRes ); + return Abc_ObjNotCond( pRes, Fraig_IsComplement(pNodeFraig) ); +} + + + + +/**Function************************************************************* + + Synopsis [Interfaces the network with the FRAIG package.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkFraigTrust( Abc_Ntk_t * pNtk ) +{ + int fCheck = 1; + Abc_Ntk_t * pNtkNew; + + if ( !Abc_NtkIsSopLogic(pNtk) ) + { + printf( "Abc_NtkFraigTrust: Trust mode works for netlists and logic SOP networks.\n" ); + return NULL; + } + + if ( !Abc_NtkFraigTrustCheck(pNtk) ) + { + printf( "Abc_NtkFraigTrust: The network does not look like an AIG with choice nodes.\n" ); + return NULL; + } + + // perform strashing + pNtkNew = Abc_NtkStartFrom( pNtk, ABC_TYPE_STRASH, ABC_FUNC_AIG ); + Abc_NtkFraigTrustOne( pNtk, pNtkNew ); + Abc_NtkFinalize( pNtk, pNtkNew ); + + // print a warning about choice nodes + printf( "Warning: The resulting AIG contains %d choice nodes.\n", Abc_NtkGetChoiceNum( pNtkNew ) ); + + // make sure that everything is okay + if ( fCheck && !Abc_NtkCheck( pNtkNew ) ) + { + printf( "Abc_NtkFraigTrust: The network check has failed.\n" ); + Abc_NtkDelete( pNtkNew ); + return NULL; + } + return pNtkNew; +} + +/**Function************************************************************* + + Synopsis [Checks whether the node can be processed in the trust mode.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NtkFraigTrustCheck( Abc_Ntk_t * pNtk ) +{ + Abc_Obj_t * pNode; + int i, nFanins; + Abc_NtkForEachNode( pNtk, pNode, i ) + { + nFanins = Abc_ObjFaninNum(pNode); + if ( nFanins < 2 ) + continue; + if ( nFanins == 2 && Abc_SopIsAndType(pNode->pData) ) + continue; + if ( !Abc_SopIsOrType(pNode->pData) ) + return 0; + } + return 1; +} + +/**Function************************************************************* + + Synopsis [Interfaces the network with the FRAIG package.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkFraigTrustOne( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ) +{ + ProgressBar * pProgress; + Abc_Aig_t * pMan = pNtkNew->pManFunc; + Vec_Ptr_t * vNodes; + Abc_Obj_t * pNode, * pNodeNew, * pObj; + int i; + + // perform strashing + vNodes = Abc_NtkDfs( pNtk, 0 ); + pProgress = Extra_ProgressBarStart( stdout, vNodes->nSize ); + Vec_PtrForEachEntry( vNodes, pNode, i ) + { + Extra_ProgressBarUpdate( pProgress, i, NULL ); + // get the node + assert( Abc_ObjIsNode(pNode) ); + // strash the node + pNodeNew = Abc_NodeFraigTrust( pMan, pNode ); + // get the old object + if ( Abc_NtkIsNetlist(pNtk) ) + pObj = Abc_ObjFanout0( pNode ); // the fanout net + else + pObj = pNode; // the node itself + // make sure the node is not yet strashed + assert( pObj->pCopy == NULL ); + // mark the old object with the new AIG node + pObj->pCopy = pNodeNew; + } + Vec_PtrFree( vNodes ); + Extra_ProgressBarStop( pProgress ); +} + +/**Function************************************************************* + + Synopsis [Transforms one node into a FRAIG in the trust mode.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Abc_NodeFraigTrust( Abc_Aig_t * pMan, Abc_Obj_t * pNode ) +{ + Abc_Obj_t * pSum, * pFanin; + Abc_Obj_t * pConst1 = Abc_AigConst1(pMan); + void ** ppTail; + int i, nFanins, fCompl; + + assert( Abc_ObjIsNode(pNode) ); + // get the number of node's fanins + nFanins = Abc_ObjFaninNum( pNode ); + assert( nFanins == Abc_SopGetVarNum(pNode->pData) ); + // check if it is a constant + if ( nFanins == 0 ) + return Abc_ObjNotCond( pConst1, Abc_SopIsConst0(pNode->pData) ); + if ( nFanins == 1 ) + return Abc_ObjNotCond( Abc_ObjFanin0(pNode)->pCopy, Abc_SopIsInv(pNode->pData) ); + if ( nFanins == 2 && Abc_SopIsAndType(pNode->pData) ) + return Abc_AigAnd( pMan, + Abc_ObjNotCond( Abc_ObjFanin0(pNode)->pCopy, !Abc_SopGetIthCareLit(pNode->pData,0) ), + Abc_ObjNotCond( Abc_ObjFanin1(pNode)->pCopy, !Abc_SopGetIthCareLit(pNode->pData,1) ) ); + assert( Abc_SopIsOrType(pNode->pData) ); + fCompl = Abc_SopGetIthCareLit(pNode->pData,0); + // get the root of the choice node (the first fanin) + pSum = Abc_ObjFanin0(pNode)->pCopy; + // connect other fanins + ppTail = &pSum->pData; + Abc_ObjForEachFanin( pNode, pFanin, i ) + { + if ( i == 0 ) + continue; + *ppTail = pFanin->pCopy; + ppTail = &pFanin->pCopy->pData; + // set the complemented bit of this cut + if ( fCompl ^ Abc_SopGetIthCareLit(pNode->pData, i) ) + pFanin->pCopy->fPhase = 1; + } + assert( *ppTail == NULL ); + return pSum; +} + + + + +/**Function************************************************************* + + Synopsis [Interfaces the network with the FRAIG package.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NtkFraigStore( Abc_Ntk_t * pNtk ) +{ + Abc_Frame_t * p; + Abc_Ntk_t * pStore; + int nAndsOld; + + if ( !Abc_NtkIsLogic(pNtk) && !Abc_NtkIsStrash(pNtk) ) + { + printf( "The netlist need to be converted into a logic network before adding it to storage.\n" ); + return 0; + } + + // get the network currently stored + p = Abc_FrameGetGlobalFrame(); + pStore = Abc_FrameReadNtkStore(p); + if ( pStore == NULL ) + { + // start the stored network + pStore = Abc_NtkStrash( pNtk, 0, 0 ); + if ( pStore == NULL ) + { + printf( "Abc_NtkFraigStore: Initial strashing has failed.\n" ); + return 0; + } + // save the parameters + Abc_FrameSetNtkStore( p, pStore ); + Abc_FrameSetNtkStoreSize( p, 1 ); + nAndsOld = 0; + } + else + { + // add the new network to storage + nAndsOld = Abc_NtkNodeNum( pStore ); + if ( !Abc_NtkAppend( pStore, pNtk ) ) + { + printf( "The current network cannot be appended to the stored network.\n" ); + return 0; + } + // set the number of networks stored + Abc_FrameSetNtkStoreSize( p, Abc_FrameReadNtkStoreSize(p) + 1 ); + } + printf( "The number of AIG nodes added to storage = %5d.\n", Abc_NtkNodeNum(pStore) - nAndsOld ); + return 1; +} + +/**Function************************************************************* + + Synopsis [Interfaces the network with the FRAIG package.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkFraigRestore() +{ + Abc_Frame_t * p; + Fraig_Params_t Params; + Abc_Ntk_t * pStore, * pFraig; + int nWords1, nWords2, nWordsMin; + + // get the stored network + p = Abc_FrameGetGlobalFrame(); + pStore = Abc_FrameReadNtkStore(p); + Abc_FrameSetNtkStore( p, NULL ); + if ( pStore == NULL ) + { + printf( "There are no network currently in storage.\n" ); + return NULL; + } + printf( "Currently stored %d networks with %d nodes will be fraiged.\n", + Abc_FrameReadNtkStoreSize(p), Abc_NtkNodeNum(pStore) ); + + // to determine the number of simulation patterns + // use the following strategy + // at least 64 words (32 words random and 32 words dynamic) + // no more than 256M for one circuit (128M + 128M) + nWords1 = 32; + nWords2 = (1<<27) / (Abc_NtkNodeNum(pStore) + Abc_NtkCiNum(pStore)); + nWordsMin = ABC_MIN( nWords1, nWords2 ); + + // set parameters for fraiging + Fraig_ParamsSetDefault( &Params ); + Params.nPatsRand = nWordsMin * 32; // the number of words of random simulation info + Params.nPatsDyna = nWordsMin * 32; // the number of words of dynamic simulation info + Params.nBTLimit = 99; // the max number of backtracks to perform + Params.fFuncRed = 1; // performs only one level hashing + Params.fFeedBack = 1; // enables solver feedback + Params.fDist1Pats = 1; // enables distance-1 patterns + Params.fDoSparse = 1; // performs equiv tests for sparse functions + Params.fChoicing = 1; // enables recording structural choices + Params.fTryProve = 0; // tries to solve the final miter + Params.fVerbose = 0; // the verbosiness flag + +// Fraig_ManReportChoices( p ); + // transform it into FRAIG + pFraig = Abc_NtkFraig( pStore, &Params, 1 ); + if ( pFraig == NULL ) + return NULL; + Abc_NtkDelete( pStore ); + return pFraig; +} + +/**Function************************************************************* + + Synopsis [Interfaces the network with the FRAIG package.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkFraigStoreClean() +{ + Abc_Frame_t * p; + Abc_Ntk_t * pStore; + // get the stored network + p = Abc_FrameGetGlobalFrame(); + pStore = Abc_FrameReadNtkStore(p); + if ( pStore ) + Abc_NtkDelete( pStore ); + Abc_FrameSetNtkStore( p, NULL ); +} + +/**Function************************************************************* + + Synopsis [Checks the correctness of stored networks.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkFraigStoreCheck( Abc_Ntk_t * pFraig ) +{ + Abc_Obj_t * pNode0, * pNode1; + int nPoOrig, nPoFinal, nStored; + int i, k; + // check that the PO functions are correct + nPoFinal = Abc_NtkPoNum(pFraig); + nStored = Abc_FrameReadNtkStoreSize(Abc_FrameGetGlobalFrame()); + assert( nPoFinal % nStored == 0 ); + nPoOrig = nPoFinal / nStored; + for ( i = 0; i < nPoOrig; i++ ) + { + pNode0 = Abc_ObjFanin0( Abc_NtkPo(pFraig, i) ); + for ( k = 1; k < nStored; k++ ) + { + pNode1 = Abc_ObjFanin0( Abc_NtkPo(pFraig, k*nPoOrig+i) ); + if ( pNode0 != pNode1 ) + printf( "Verification for PO #%d of network #%d has failed. The PO function is not used.\n", i+1, k+1 ); + } + } +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/base/abci/abcFxu.c b/src/base/abci/abcFxu.c new file mode 100644 index 00000000..0c8994e1 --- /dev/null +++ b/src/base/abci/abcFxu.c @@ -0,0 +1,259 @@ +/**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 ) +{ + int fCheck = 1; + + assert( Abc_NtkIsLogic(pNtk) ); + // convert nodes to SOPs + if ( Abc_NtkIsMappedLogic(pNtk) ) + Abc_NtkUnmap(pNtk); + else if ( Abc_NtkIsBddLogic(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 + Abc_NtkFxuCollectInfo( pNtk, p ); + // call the fast extract procedure + if ( Fxu_FastExtract(p) > 0 ) + { + // update the network + Abc_NtkFxuReconstruct( pNtk, p ); + // make sure everything is okay + if ( fCheck && !Abc_NtkCheck( pNtk ) ) + printf( "Abc_NtkFastExtract: The network check has failed.\n" ); + return 1; + } + else + printf( "Warning: The network has not been changed by \"fx\".\n" ); + 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, Abc_NtkObjNumMax(pNtk), NULL ); + Vec_PtrFill( p->vFanins, Abc_NtkObjNumMax(pNtk), NULL ); + Vec_PtrFill( p->vSopsNew, Abc_NtkObjNumMax(pNtk) + p->nNodesExt, NULL ); + Vec_PtrFill( p->vFaninsNew, Abc_NtkObjNumMax(pNtk) + 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 = Abc_NtkObjNumMax(pNtk); +} + +/**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_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 ); + Abc_ObjRemoveFanins( pNode ); + // add new fanins + vFanins = p->vFaninsNew->pArray[i]; + for ( k = 0; k < vFanins->nSize; k++ ) + { + pFanin = Abc_NtkObj( pNtk, vFanins->pArray[k] ); + Abc_ObjAddFanin( pNode, pFanin ); + } + pNode->pData = p->vSopsNew->pArray[i]; + assert( pNode->pData != NULL ); + } + // set up the new nodes + for ( i = p->vFanins->nSize; i < p->vFanins->nSize + p->nNodesNew; i++ ) + { + // get the new node + pNode = Abc_NtkObj( pNtk, i ); + // add the fanins + vFanins = p->vFaninsNew->pArray[i]; + for ( k = 0; k < vFanins->nSize; k++ ) + { + pFanin = Abc_NtkObj( pNtk, vFanins->pArray[k] ); + Abc_ObjAddFanin( pNode, pFanin ); + } + pNode->pData = p->vSopsNew->pArray[i]; + assert( pNode->pData != NULL ); + } +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/base/abci/abcMap.c b/src/base/abci/abcMap.c new file mode 100644 index 00000000..45f600ed --- /dev/null +++ b/src/base/abci/abcMap.c @@ -0,0 +1,689 @@ +/**CFile**************************************************************** + + FileName [abcMap.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Network and node package.] + + Synopsis [Interface with the SC mapping package.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: abcMap.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abc.h" +#include "main.h" +#include "mio.h" +#include "mapper.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static Map_Man_t * Abc_NtkToMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, float * pSwitching, int fVerbose ); +static Abc_Ntk_t * Abc_NtkFromMap( Map_Man_t * pMan, Abc_Ntk_t * pNtk ); +static Abc_Obj_t * Abc_NodeFromMap_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, int fPhase ); +static Abc_Obj_t * Abc_NodeFromMapPhase_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, int fPhase ); +static Abc_Obj_t * Abc_NodeFromMapSuper_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, Map_Super_t * pSuper, Abc_Obj_t * pNodePis[], int nNodePis ); + +static Abc_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 /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Interface with the mapping package.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, int fSwitching, int fVerbose ) +{ + int fCheck = 1; + Abc_Ntk_t * pNtkNew; + Map_Man_t * pMan; + Vec_Int_t * vSwitching; + float * pSwitching = NULL; + int fShowSwitching = 0; + int clk; + + assert( Abc_NtkIsStrash(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_NtkGetChoiceNum( pNtk ) ) + printf( "Performing mapping with choices.\n" ); + + // compute switching activity + fShowSwitching |= fSwitching; + if ( fShowSwitching ) + { + extern Vec_Int_t * Sim_NtkComputeSwitching( Abc_Ntk_t * pNtk, int nPatterns ); + vSwitching = Sim_NtkComputeSwitching( pNtk, 4096 ); + pSwitching = (float *)vSwitching->pArray; + } + + // perform the mapping + pMan = Abc_NtkToMap( pNtk, DelayTarget, fRecovery, pSwitching, fVerbose ); + if ( pSwitching ) Vec_IntFree( vSwitching ); + if ( pMan == NULL ) + return NULL; +clk = clock(); + Map_ManSetSwitching( pMan, fSwitching ); + 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 ); + 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 [Load the network into manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Map_Man_t * Abc_NtkToMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, float * pSwitching, int fVerbose ) +{ + Map_Man_t * pMan; + ProgressBar * pProgress; + Map_Node_t * pNodeMap; + Vec_Ptr_t * vNodes; + Abc_Obj_t * pNode, * pFanin, * pPrev; + int i; + + assert( Abc_NtkIsStrash(pNtk) ); + + // start the mapping manager and set its parameters + pMan = Map_ManCreate( Abc_NtkPiNum(pNtk) + Abc_NtkLatchNum(pNtk), Abc_NtkPoNum(pNtk) + Abc_NtkLatchNum(pNtk), fVerbose ); + if ( pMan == NULL ) + return NULL; + Map_ManSetAreaRecovery( pMan, fRecovery ); + Map_ManSetOutputNames( pMan, Abc_NtkCollectCioNames(pNtk, 1) ); + Map_ManSetDelayTarget( pMan, (float)DelayTarget ); + Map_ManSetInputArrivals( pMan, (Map_Time_t *)Abc_NtkGetCiArrivalTimes(pNtk) ); + + // create PIs and remember them in the old nodes + Abc_NtkCleanCopy( pNtk ); + Abc_NtkForEachCi( pNtk, pNode, i ) + { + pNodeMap = Map_ManReadInputs(pMan)[i]; + pNode->pCopy = (Abc_Obj_t *)pNodeMap; + if ( pSwitching ) + Map_NodeSetSwitching( pNodeMap, pSwitching[pNode->Id] ); + } + + // load the AIG into the mapper + vNodes = Abc_AigDfs( pNtk, 0, 0 ); + pProgress = Extra_ProgressBarStart( stdout, vNodes->nSize ); + Vec_PtrForEachEntry( vNodes, pNode, i ) + { + Extra_ProgressBarUpdate( pProgress, i, NULL ); + // consider the case of a constant + if ( Abc_NodeIsConst(pNode) ) + { + Abc_AigConst1(pNtk->pManFunc)->pCopy = (Abc_Obj_t *)Map_ManReadConst1(pMan); + continue; + } + // add the node to the mapper + pNodeMap = Map_NodeAnd( pMan, + Map_NotCond( Abc_ObjFanin0(pNode)->pCopy, Abc_ObjFaninC0(pNode) ), + Map_NotCond( Abc_ObjFanin1(pNode)->pCopy, Abc_ObjFaninC1(pNode) ) ); + assert( pNode->pCopy == NULL ); + // remember the node + pNode->pCopy = (Abc_Obj_t *)pNodeMap; + if ( pSwitching ) + Map_NodeSetSwitching( pNodeMap, pSwitching[pNode->Id] ); + // set up the choice node + if ( Abc_NodeIsAigChoice( pNode ) ) + for ( pPrev = pNode, pFanin = pNode->pData; pFanin; pPrev = pFanin, pFanin = pFanin->pData ) + { + Map_NodeSetNextE( (Map_Node_t *)pPrev->pCopy, (Map_Node_t *)pFanin->pCopy ); + Map_NodeSetRepr( (Map_Node_t *)pFanin->pCopy, (Map_Node_t *)pNode->pCopy ); + } + } + Extra_ProgressBarStop( pProgress ); + Vec_PtrFree( vNodes ); + + // set the primary outputs in the required phase + Abc_NtkForEachCo( pNtk, pNode, i ) + Map_ManReadOutputs(pMan)[i] = Map_NotCond( (Map_Node_t *)Abc_ObjFanin0(pNode)->pCopy, Abc_ObjFaninC0(pNode) ); + return pMan; +} + +/**Function************************************************************* + + Synopsis [Creates the mapped network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkFromMap( Map_Man_t * pMan, Abc_Ntk_t * pNtk ) +{ + ProgressBar * pProgress; + Abc_Ntk_t * pNtkNew; + Map_Node_t * pNodeMap; + Abc_Obj_t * pNode, * pNodeNew; + int i, nDupGates; + + // create the new network + pNtkNew = Abc_NtkStartFrom( pNtk, ABC_TYPE_LOGIC, ABC_FUNC_MAP ); + // make the mapper point to the new network + Map_ManCleanData( pMan ); + Abc_NtkForEachCi( pNtk, pNode, i ) + Map_NodeSetData( Map_ManReadInputs(pMan)[i], 1, (char *)pNode->pCopy ); + // set the constant node + if ( Abc_ObjFanoutNum( Abc_AigConst1(pNtk->pManFunc) ) > 0 ) + Map_NodeSetData( Map_ManReadConst1(pMan), 1, (char *)Abc_NodeCreateConst1(pNtkNew) ); + + // assign the mapping of the required phase to the POs + pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCoNum(pNtk) ); + Abc_NtkForEachCo( pNtk, pNode, i ) + { + Extra_ProgressBarUpdate( pProgress, i, NULL ); + pNodeMap = Map_ManReadOutputs(pMan)[i]; + pNodeNew = Abc_NodeFromMap_rec( pNtkNew, Map_Regular(pNodeMap), !Map_IsComplement(pNodeMap) ); + assert( !Abc_ObjIsComplement(pNodeNew) ); + Abc_ObjAddFanin( pNode->pCopy, pNodeNew ); + } + Extra_ProgressBarStop( pProgress ); + // decouple the PO driver nodes to reduce the number of levels + nDupGates = Abc_NtkLogicMakeSimpleCos( pNtkNew, 1 ); +// if ( nDupGates && Map_ManReadVerbose(pMan) ) +// printf( "Duplicated %d gates to decouple the CO drivers.\n", nDupGates ); + return pNtkNew; +} + +/**Function************************************************************* + + Synopsis [Constructs the nodes corrresponding to one node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Abc_NodeFromMap_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, int fPhase ) +{ + Abc_Obj_t * pNodeNew, * pNodeInv; + + // check if the phase is already implemented + pNodeNew = (Abc_Obj_t *)Map_NodeReadData( pNodeMap, fPhase ); + if ( pNodeNew ) + return pNodeNew; + + // implement the node if the best cut is assigned + if ( Map_NodeReadCutBest(pNodeMap, fPhase) != NULL ) + return Abc_NodeFromMapPhase_rec( pNtkNew, pNodeMap, fPhase ); + + // if the cut is not assigned, implement the node + assert( Map_NodeReadCutBest(pNodeMap, !fPhase) != NULL || Map_NodeIsConst(pNodeMap) ); + pNodeNew = Abc_NodeFromMapPhase_rec( pNtkNew, pNodeMap, !fPhase ); + + // add the inverter + pNodeInv = Abc_NtkCreateNode( pNtkNew ); + Abc_ObjAddFanin( pNodeInv, pNodeNew ); + pNodeInv->pData = Mio_LibraryReadInv(Map_ManReadGenLib(Map_NodeReadMan(pNodeMap))); + + // set the inverter + Map_NodeSetData( pNodeMap, fPhase, (char *)pNodeInv ); + return pNodeInv; +} + +/**Function************************************************************* + + Synopsis [Constructs the nodes corrresponding to one node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Abc_NodeFromMapPhase_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, int fPhase ) +{ + Abc_Obj_t * pNodePIs[10]; + Abc_Obj_t * pNodeNew; + Map_Node_t ** ppLeaves; + Map_Cut_t * pCutBest; + Map_Super_t * pSuperBest; + unsigned uPhaseBest; + int i, fInvPin, nLeaves; + + // make sure the node can be implemented in this phase + assert( Map_NodeReadCutBest(pNodeMap, fPhase) != NULL || Map_NodeIsConst(pNodeMap) ); + // check if the phase is already implemented + pNodeNew = (Abc_Obj_t *)Map_NodeReadData( pNodeMap, fPhase ); + if ( pNodeNew ) + return pNodeNew; + + // get the information about the best cut + pCutBest = Map_NodeReadCutBest( pNodeMap, fPhase ); + pSuperBest = Map_CutReadSuperBest( pCutBest, fPhase ); + uPhaseBest = Map_CutReadPhaseBest( pCutBest, fPhase ); + nLeaves = Map_CutReadLeavesNum( pCutBest ); + ppLeaves = Map_CutReadLeaves( pCutBest ); + + // collect the PI nodes + for ( i = 0; i < nLeaves; i++ ) + { + fInvPin = ((uPhaseBest & (1 << i)) > 0); + pNodePIs[i] = Abc_NodeFromMap_rec( pNtkNew, ppLeaves[i], !fInvPin ); + assert( pNodePIs[i] != NULL ); + } + + // implement the supergate + pNodeNew = Abc_NodeFromMapSuper_rec( pNtkNew, pNodeMap, pSuperBest, pNodePIs, nLeaves ); + Map_NodeSetData( pNodeMap, fPhase, (char *)pNodeNew ); + return pNodeNew; +} + +/**Function************************************************************* + + Synopsis [Constructs the nodes corrresponding to one supergate.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Abc_NodeFromMapSuper_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, 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_NodeFromMapSuper_rec( pNtkNew, pNodeMap, ppFanins[i], pNodePis, nNodePis ); + Abc_ObjAddFanin( pNodeNew, pNodeFanin ); + } + pNodeNew->pData = pRoot; + return pNodeNew; +} + + +/**Function************************************************************* + + Synopsis [Unmaps the network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NtkUnmap( Abc_Ntk_t * pNtk ) +{ + Abc_Obj_t * pNode; + char * pSop; + int i; + + assert( Abc_NtkIsMappedLogic(pNtk) ); + // update the functionality manager + assert( pNtk->pManFunc == Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()) ); + pNtk->pManFunc = Extra_MmFlexStart(); + pNtk->ntkFunc = ABC_FUNC_SOP; + // update the nodes + Abc_NtkForEachNode( pNtk, pNode, i ) + { + pSop = Mio_GateReadSop(pNode->pData); + assert( Abc_SopGetVarNum(pSop) == Abc_ObjFaninNum(pNode) ); + pNode->pData = Abc_SopRegister( pNtk->pManFunc, pSop ); + } + return 1; +} + + + + +/**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_NtkIsStrash(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_NtkGetChoiceNum( pNtk ) ) + printf( "Performing mapping with choices.\n" ); + + // perform the mapping + pMan = Abc_NtkToMap( pNtk, -1, 1, NULL, 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_NtkObjNumMax(pNtk) ); + Abc_NtkForEachNode( pNtk, pNode, i ) + { + Extra_ProgressBarUpdate( pProgress, i, NULL ); + if ( Abc_NodeIsConst(pNode) ) + continue; + Abc_NodeSuperChoice( pNtkNew, pNode ); + } + Extra_ProgressBarStop( pProgress ); + return pNtkNew; +} + + +/**Function************************************************************* + + Synopsis [Creates the mapped network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NodeSuperChoice( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode ) +{ + Map_Node_t * pMapNode = (Map_Node_t *)pNode->pNext; + Map_Cut_t * pCuts, * pTemp; + + pCuts = Map_NodeReadCuts(pMapNode); + for ( pTemp = Map_CutReadNext(pCuts); pTemp; pTemp = Map_CutReadNext(pTemp) ) + { + Abc_NodeFromMapCutPhase( pNtkNew, pTemp, 0 ); + Abc_NodeFromMapCutPhase( pNtkNew, pTemp, 1 ); + } +} + + +/**Function************************************************************* + + Synopsis [Constructs the nodes corrresponding to one node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NodeFromMapCutPhase( Abc_Ntk_t * pNtkNew, Map_Cut_t * pCut, int fPhase ) +{ + Abc_Obj_t * pNodePIs[10]; + Map_Node_t ** ppLeaves; + Map_Super_t * pSuperBest; + unsigned uPhaseBest; + int i, fInvPin, nLeaves; + + pSuperBest = Map_CutReadSuperBest( pCut, fPhase ); + if ( pSuperBest == NULL ) + return; + + // get the information about the best cut + uPhaseBest = Map_CutReadPhaseBest( pCut, fPhase ); + nLeaves = Map_CutReadLeavesNum( pCut ); + ppLeaves = Map_CutReadLeaves( pCut ); + + // collect the PI nodes + for ( i = 0; i < nLeaves; i++ ) + { + fInvPin = ((uPhaseBest & (1 << i)) > 0); + pNodePIs[i] = (Abc_Obj_t *)Map_NodeReadData( ppLeaves[i], !fInvPin ); + assert( pNodePIs[i] != NULL ); + } + + // implement the supergate + Abc_NodeFromMapSuperChoice_rec( pNtkNew, pSuperBest, pNodePIs, nLeaves ); +} + + +/**Function************************************************************* + + Synopsis [Constructs the nodes corrresponding to one supergate.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Abc_NodeFromMapSuperChoice_rec( Abc_Ntk_t * pNtkNew, Map_Super_t * pSuper, Abc_Obj_t * pNodePis[], int nNodePis ) +{ + Mio_Gate_t * pRoot; + Map_Super_t ** ppFanins; + Abc_Obj_t * pNodeNew, * pNodeFanin; + int nFanins, Number, i; + + // get the parameters of the supergate + pRoot = Map_SuperReadRoot(pSuper); + if ( pRoot == NULL ) + { + Number = Map_SuperReadNum(pSuper); + if ( Number < nNodePis ) + { + return pNodePis[Number]; + } + else + { +// assert( 0 ); + /* It might happen that a super gate with 5 inputs is constructed that + * actually depends only on the first four variables; i.e the fifth is a + * don't care -- in that case we connect constant node for the fifth + * (since the cut only has 4 variables). An interesting question is what + * if the first variable (and not the fifth one is the redundant one; + * can that happen?) */ + return Abc_NodeCreateConst0(pNtkNew); + } + } + + // get information about the fanins of the supergate + nFanins = Map_SuperReadFaninNum( pSuper ); + ppFanins = Map_SuperReadFanins( pSuper ); + // create a new node with these fanins + pNodeNew = Abc_NtkCreateNode( pNtkNew ); + for ( i = 0; i < nFanins; i++ ) + { + pNodeFanin = Abc_NodeFromMapSuperChoice_rec( pNtkNew, ppFanins[i], pNodePis, nNodePis ); + Abc_ObjAddFanin( pNodeNew, pNodeFanin ); + } + pNodeNew->pData = Abc_SopRegister( pNtkNew->pManFunc, Mio_GateReadSop(pRoot) ); + return pNodeNew; +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/base/abci/abcMiter.c b/src/base/abci/abcMiter.c new file mode 100644 index 00000000..0d75ba1f --- /dev/null +++ b/src/base/abci/abcMiter.c @@ -0,0 +1,600 @@ +/**CFile**************************************************************** + + FileName [abcMiter.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Network and node package.] + + Synopsis [Procedures to derive the miter of two circuits.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: abcMiter.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abc.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static Abc_Ntk_t * Abc_NtkMiterInt( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb ); +static void Abc_NtkMiterPrepare( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, Abc_Ntk_t * pNtkMiter, int fComb ); +static void Abc_NtkMiterAddOne( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkMiter ); +static void Abc_NtkMiterAddCone( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkMiter, Abc_Obj_t * pNode ); +static void Abc_NtkMiterFinalize( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, Abc_Ntk_t * pNtkMiter, int fComb ); +static void Abc_NtkAddFrame( Abc_Ntk_t * pNetNew, Abc_Ntk_t * pNet, int iFrame, Vec_Ptr_t * vNodes ); + + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Derives the miter of two networks.] + + Description [Preprocesses the networks to make sure that they are strashed.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkMiter( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb ) +{ + Abc_Ntk_t * pTemp = NULL; + int fRemove1, fRemove2; + // check that the networks have the same PIs/POs/latches + if ( !Abc_NtkCompareSignals( pNtk1, pNtk2, fComb ) ) + return NULL; + // make sure the circuits are strashed + fRemove1 = (!Abc_NtkIsStrash(pNtk1)) && (pNtk1 = Abc_NtkStrash(pNtk1, 0, 0)); + fRemove2 = (!Abc_NtkIsStrash(pNtk2)) && (pNtk2 = Abc_NtkStrash(pNtk2, 0, 0)); + if ( pNtk1 && pNtk2 ) + pTemp = Abc_NtkMiterInt( pNtk1, pNtk2, fComb ); + if ( fRemove1 ) Abc_NtkDelete( pNtk1 ); + if ( fRemove2 ) Abc_NtkDelete( pNtk2 ); + return pTemp; +} + +/**Function************************************************************* + + Synopsis [Derives the miter of two sequential networks.] + + Description [Assumes that the networks are strashed.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkMiterInt( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb ) +{ + int fCheck = 1; + char Buffer[100]; + Abc_Ntk_t * pNtkMiter; + + assert( Abc_NtkIsStrash(pNtk1) ); + assert( Abc_NtkIsStrash(pNtk2) ); + + // start the new network + pNtkMiter = Abc_NtkAlloc( ABC_TYPE_STRASH, ABC_FUNC_AIG ); + sprintf( Buffer, "%s_%s_miter", pNtk1->pName, pNtk2->pName ); + pNtkMiter->pName = util_strsav(Buffer); + + // perform strashing + Abc_NtkMiterPrepare( pNtk1, pNtk2, pNtkMiter, fComb ); + Abc_NtkMiterAddOne( pNtk1, pNtkMiter ); + Abc_NtkMiterAddOne( pNtk2, pNtkMiter ); + Abc_NtkMiterFinalize( pNtk1, pNtk2, pNtkMiter, fComb ); + + // make sure that everything is okay + if ( fCheck && !Abc_NtkCheck( pNtkMiter ) ) + { + printf( "Abc_NtkMiter: The network check has failed.\n" ); + Abc_NtkDelete( pNtkMiter ); + return NULL; + } + return pNtkMiter; +} + +/**Function************************************************************* + + Synopsis [Prepares the network for mitering.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkMiterPrepare( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, Abc_Ntk_t * pNtkMiter, int fComb ) +{ + Abc_Obj_t * pObj, * pObjNew; + int i; + // clean the copy field in all objects +// Abc_NtkCleanCopy( pNtk1 ); +// Abc_NtkCleanCopy( pNtk2 ); + if ( fComb ) + { + // create new PIs and remember them in the old PIs + Abc_NtkForEachCi( pNtk1, pObj, i ) + { + pObjNew = Abc_NtkCreatePi( pNtkMiter ); + // remember this PI in the old PIs + pObj->pCopy = pObjNew; + pObj = Abc_NtkCi(pNtk2, i); + pObj->pCopy = pObjNew; + // add name + Abc_NtkLogicStoreName( pObjNew, Abc_ObjName(pObj) ); + } + // create the only PO + pObjNew = Abc_NtkCreatePo( pNtkMiter ); + // add the PO name + Abc_NtkLogicStoreName( pObjNew, "miter" ); + } + else + { + // create new PIs and remember them in the old PIs + Abc_NtkForEachPi( pNtk1, pObj, i ) + { + pObjNew = Abc_NtkCreatePi( pNtkMiter ); + // remember this PI in the old PIs + pObj->pCopy = pObjNew; + pObj = Abc_NtkPi(pNtk2, i); + pObj->pCopy = pObjNew; + // add name + Abc_NtkLogicStoreName( pObjNew, Abc_ObjName(pObj) ); + } + // create the only PO + pObjNew = Abc_NtkCreatePo( pNtkMiter ); + // add the PO name + Abc_NtkLogicStoreName( pObjNew, "miter" ); + // create the latches + Abc_NtkForEachLatch( pNtk1, pObj, i ) + { + pObjNew = Abc_NtkDupObj( pNtkMiter, pObj ); + Vec_PtrPush( pNtkMiter->vCis, pObjNew ); + Vec_PtrPush( pNtkMiter->vCos, pObjNew ); + // add name + Abc_NtkLogicStoreNamePlus( pObjNew, Abc_ObjName(pObj), "_1" ); + } + Abc_NtkForEachLatch( pNtk2, pObj, i ) + { + pObjNew = Abc_NtkDupObj( pNtkMiter, pObj ); + Vec_PtrPush( pNtkMiter->vCis, pObjNew ); + Vec_PtrPush( pNtkMiter->vCos, pObjNew ); + // add name + Abc_NtkLogicStoreNamePlus( pObjNew, Abc_ObjName(pObj), "_2" ); + } + } +} + +/**Function************************************************************* + + Synopsis [Performs mitering for one network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkMiterAddOne( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkMiter ) +{ + ProgressBar * pProgress; + Vec_Ptr_t * vNodes; + Abc_Obj_t * pNode, * pConst1, * pConst1New; + int i; + // get the constant nodes + pConst1 = Abc_AigConst1( pNtk->pManFunc ); + pConst1New = Abc_AigConst1( pNtkMiter->pManFunc ); + // perform strashing + vNodes = Abc_NtkDfs( pNtk, 0 ); + pProgress = Extra_ProgressBarStart( stdout, vNodes->nSize ); + Vec_PtrForEachEntry( vNodes, pNode, i ) + { + Extra_ProgressBarUpdate( pProgress, i, NULL ); + if ( pNode == pConst1 ) + pNode->pCopy = pConst1New; + else + pNode->pCopy = Abc_AigAnd( pNtkMiter->pManFunc, Abc_ObjChild0Copy(pNode), Abc_ObjChild1Copy(pNode) ); + } + Vec_PtrFree( vNodes ); + Extra_ProgressBarStop( pProgress ); +} + +/**Function************************************************************* + + Synopsis [Performs mitering for one network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkMiterAddCone( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkMiter, Abc_Obj_t * pRoot ) +{ + Vec_Ptr_t * vNodes; + Abc_Obj_t * pNode, * pNodeNew, * pConst1, * pConst1New; + int i; + // get the constant nodes + pConst1 = Abc_AigConst1( pNtk->pManFunc ); + pConst1New = Abc_AigConst1( pNtkMiter->pManFunc ); + // perform strashing + vNodes = Abc_NtkDfsNodes( pNtk, &pRoot, 1 ); + for ( i = 0; i < vNodes->nSize; i++ ) + { + pNode = vNodes->pArray[i]; + if ( pNode == pConst1 ) + pNodeNew = pConst1New; + else + pNodeNew = Abc_AigAnd( pNtkMiter->pManFunc, Abc_ObjChild0Copy(pNode), Abc_ObjChild1Copy(pNode) ); + pNode->pCopy = pNodeNew; + } + Vec_PtrFree( vNodes ); +} + + +/**Function************************************************************* + + Synopsis [Finalizes the miter by adding the output part.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkMiterFinalize( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, Abc_Ntk_t * pNtkMiter, int fComb ) +{ + Vec_Ptr_t * vPairs; + Abc_Obj_t * pMiter, * pNode; + int i; + // collect the PO pairs from both networks + vPairs = Vec_PtrAlloc( 100 ); + if ( fComb ) + { + // collect the CO nodes for the miter + Abc_NtkForEachCo( pNtk1, pNode, i ) + { + Vec_PtrPush( vPairs, Abc_ObjChild0Copy(pNode) ); + pNode = Abc_NtkCo( pNtk2, i ); + Vec_PtrPush( vPairs, Abc_ObjChild0Copy(pNode) ); + } + } + else + { + // collect the PO nodes for the miter + Abc_NtkForEachPo( pNtk1, pNode, i ) + { + Vec_PtrPush( vPairs, Abc_ObjChild0Copy(pNode) ); + pNode = Abc_NtkPo( pNtk2, i ); + Vec_PtrPush( vPairs, Abc_ObjChild0Copy(pNode) ); + } + // connect new latches + Abc_NtkForEachLatch( pNtk1, pNode, i ) + Abc_ObjAddFanin( pNode->pCopy, Abc_ObjChild0Copy(pNode) ); + Abc_NtkForEachLatch( pNtk2, pNode, i ) + Abc_ObjAddFanin( pNode->pCopy, Abc_ObjChild0Copy(pNode) ); + } + // add the miter + pMiter = Abc_AigMiter( pNtkMiter->pManFunc, vPairs ); + Abc_ObjAddFanin( Abc_NtkPo(pNtkMiter,0), pMiter ); + Vec_PtrFree( vPairs ); +} + + + + +/**Function************************************************************* + + Synopsis [Derives the miter of two cofactors of one output.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkMiterForCofactors( Abc_Ntk_t * pNtk, int Out, int In1, int In2 ) +{ + int fCheck = 1; + char Buffer[100]; + Abc_Ntk_t * pNtkMiter; + Abc_Obj_t * pRoot, * pOutput1, * pOutput2, * pMiter; + + assert( Abc_NtkIsStrash(pNtk) ); + assert( Out < Abc_NtkCoNum(pNtk) ); + assert( In1 < Abc_NtkCiNum(pNtk) ); + assert( In2 < Abc_NtkCiNum(pNtk) ); + + // start the new network + pNtkMiter = Abc_NtkAlloc( ABC_TYPE_STRASH, ABC_FUNC_AIG ); + sprintf( Buffer, "%s_miter", Abc_ObjName(Abc_NtkCo(pNtk, Out)) ); + pNtkMiter->pName = util_strsav(Buffer); + + // get the root output + pRoot = Abc_NtkCo( pNtk, Out ); + + // perform strashing + Abc_NtkMiterPrepare( pNtk, pNtk, pNtkMiter, 1 ); + // set the first cofactor + Abc_NtkCi(pNtk, In1)->pCopy = Abc_ObjNot( Abc_AigConst1(pNtkMiter->pManFunc) ); + if ( In2 >= 0 ) + Abc_NtkCi(pNtk, In2)->pCopy = Abc_AigConst1( pNtkMiter->pManFunc ); + // add the first cofactor + Abc_NtkMiterAddCone( pNtk, pNtkMiter, pRoot ); + + // save the output + pOutput1 = Abc_ObjFanin0(pRoot)->pCopy; + + // set the second cofactor + Abc_NtkCi(pNtk, In1)->pCopy = Abc_AigConst1( pNtkMiter->pManFunc ); + if ( In2 >= 0 ) + Abc_NtkCi(pNtk, In2)->pCopy = Abc_ObjNot( Abc_AigConst1(pNtkMiter->pManFunc) ); + // add the second cofactor + Abc_NtkMiterAddCone( pNtk, pNtkMiter, pRoot ); + + // save the output + pOutput2 = Abc_ObjFanin0(pRoot)->pCopy; + + // create the miter of the two outputs + pMiter = Abc_AigXor( pNtkMiter->pManFunc, pOutput1, pOutput2 ); + Abc_ObjAddFanin( Abc_NtkPo(pNtkMiter,0), pMiter ); + + // make sure that everything is okay + if ( fCheck && !Abc_NtkCheck( pNtkMiter ) ) + { + printf( "Abc_NtkMiter: The network check has failed.\n" ); + Abc_NtkDelete( pNtkMiter ); + return NULL; + } + return pNtkMiter; +} + + + + + +/**Function************************************************************* + + Synopsis [Checks the status of the miter.] + + Description [Return 1 if the miter is sat for at least one output. + Return 0 if the miter is unsat for all its outputs. Returns -1 if the + miter is undecided for some outputs.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NtkMiterIsConstant( Abc_Ntk_t * pMiter ) +{ + Abc_Obj_t * pNodePo, * pChild; + int i; + assert( Abc_NtkIsStrash(pMiter) ); + Abc_NtkForEachPo( pMiter, pNodePo, i ) + { + pChild = Abc_ObjChild0( Abc_NtkPo(pMiter,i) ); + if ( Abc_ObjIsNode(Abc_ObjRegular(pChild)) && Abc_NodeIsConst(pChild) ) + { + assert( Abc_ObjRegular(pChild) == Abc_AigConst1(pMiter->pManFunc) ); + if ( !Abc_ObjIsComplement(pChild) ) + { + // if the miter is constant 1, return immediately + printf( "MITER IS CONSTANT 1!\n" ); + return 1; + } + } + // if the miter is undecided (or satisfiable), return immediately + else + return -1; + } + // return 0, meaning all outputs are constant zero + return 0; +} + +/**Function************************************************************* + + Synopsis [Reports the status of the miter.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkMiterReport( Abc_Ntk_t * pMiter ) +{ + Abc_Obj_t * pChild, * pNode; + int i; + if ( Abc_NtkPoNum(pMiter) == 1 ) + { + pChild = Abc_ObjChild0( Abc_NtkPo(pMiter,0) ); + if ( Abc_ObjIsNode(Abc_ObjRegular(pChild)) && Abc_NodeIsConst(pChild) ) + { + if ( Abc_ObjIsComplement(pChild) ) + printf( "Unsatisfiable.\n" ); + else + printf( "Satisfiable. (Constant 1).\n" ); + } + else + printf( "Satisfiable.\n" ); + } + else + { + Abc_NtkForEachPo( pMiter, pNode, i ) + { + pChild = Abc_ObjChild0( Abc_NtkPo(pMiter,i) ); + printf( "Output #%2d : ", i ); + if ( Abc_ObjIsNode(Abc_ObjRegular(pChild)) && Abc_NodeIsConst(pChild) ) + { + if ( Abc_ObjIsComplement(pChild) ) + printf( "Unsatisfiable.\n" ); + else + printf( "Satisfiable. (Constant 1).\n" ); + } + else + printf( "Satisfiable.\n" ); + } + } +} + + +/**Function************************************************************* + + Synopsis [Derives the timeframes of the network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkFrames( Abc_Ntk_t * pNtk, int nFrames, int fInitial ) +{ + int fCheck = 1; + char Buffer[100]; + ProgressBar * pProgress; + Abc_Ntk_t * pNtkFrames; + Vec_Ptr_t * vNodes; + Abc_Obj_t * pLatch, * pLatchNew; + int i, Counter; + assert( nFrames > 0 ); + assert( Abc_NtkIsStrash(pNtk) ); + // start the new network + pNtkFrames = Abc_NtkAlloc( ABC_TYPE_STRASH, ABC_FUNC_AIG ); + sprintf( Buffer, "%s_%d_frames", pNtk->pName, nFrames ); + pNtkFrames->pName = util_strsav(Buffer); + // create new latches (or their initial values) and remember them in the new latches + if ( !fInitial ) + { + Abc_NtkForEachLatch( pNtk, pLatch, i ) + Abc_NtkDupObj( pNtkFrames, pLatch ); + } + else + { + Counter = 0; + Abc_NtkForEachLatch( pNtk, pLatch, i ) + { + if ( Abc_LatchIsInitDc(pLatch) ) // don't-care initial value - create a new PI + { + pLatch->pCopy = Abc_NtkCreatePi(pNtkFrames); + Abc_NtkLogicStoreName( pLatch->pCopy, Abc_ObjName(pLatch) ); + Counter++; + } + else + pLatch->pCopy = Abc_ObjNotCond( Abc_AigConst1(pNtkFrames->pManFunc), Abc_LatchIsInit0(pLatch) ); + } + if ( Counter ) + printf( "Warning: %d uninitialized latches are replaced by free variables.\n", Counter ); + } + + // create the timeframes + vNodes = Abc_NtkDfs( pNtk, 0 ); + pProgress = Extra_ProgressBarStart( stdout, nFrames ); + for ( i = 0; i < nFrames; i++ ) + { + Extra_ProgressBarUpdate( pProgress, i, NULL ); + Abc_NtkAddFrame( pNtkFrames, pNtk, i, vNodes ); + } + Extra_ProgressBarStop( pProgress ); + Vec_PtrFree( vNodes ); + + // connect the new latches to the outputs of the last frame + if ( !fInitial ) + { + Abc_NtkForEachLatch( pNtk, pLatch, i ) + { + pLatchNew = Abc_NtkLatch(pNtkFrames, i); + Abc_ObjAddFanin( pLatchNew, Abc_ObjFanin0(pLatch)->pCopy ); + Vec_PtrPush( pNtkFrames->vCis, pLatchNew ); + Vec_PtrPush( pNtkFrames->vCos, pLatchNew ); + Abc_NtkLogicStoreName( pLatchNew, Abc_ObjName(pLatch) ); + } + } + // make sure that everything is okay + if ( fCheck && !Abc_NtkCheck( pNtkFrames ) ) + { + printf( "Abc_NtkFrames: The network check has failed.\n" ); + Abc_NtkDelete( pNtkFrames ); + return NULL; + } + return pNtkFrames; +} + +/**Function************************************************************* + + Synopsis [Adds one time frame to the new network.] + + Description [Assumes that the latches of the old network point + to the outputs of the previous frame of the new network (pLatch->pCopy). + In the end, updates the latches of the old network to point to the + outputs of the current frame of the new network.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkAddFrame( Abc_Ntk_t * pNtkFrames, Abc_Ntk_t * pNtk, int iFrame, Vec_Ptr_t * vNodes ) +{ + char Buffer[10]; + Abc_Obj_t * pNode, * pNodeNew, * pLatch; + Abc_Obj_t * pConst1, * pConst1New; + int i; + // get the constant nodes + pConst1 = Abc_AigConst1( pNtk->pManFunc ); + pConst1New = Abc_AigConst1( pNtkFrames->pManFunc ); + // create the prefix to be added to the node names + sprintf( Buffer, "_%02d", iFrame ); + // add the new PI nodes + Abc_NtkForEachPi( pNtk, pNode, i ) + { + pNodeNew = Abc_NtkDupObj( pNtkFrames, pNode ); + Abc_NtkLogicStoreNamePlus( pNodeNew, Abc_ObjName(pNode), Buffer ); + } + // add the internal nodes + Vec_PtrForEachEntry( vNodes, pNode, i ) + { + if ( pNode == pConst1 ) + pNodeNew = pConst1New; + else + pNodeNew = Abc_AigAnd( pNtkFrames->pManFunc, Abc_ObjChild0Copy(pNode), Abc_ObjChild1Copy(pNode) ); + pNode->pCopy = pNodeNew; + } + // add the new POs + Abc_NtkForEachPo( pNtk, pNode, i ) + { + pNodeNew = Abc_NtkDupObj( pNtkFrames, pNode ); + Abc_ObjAddFanin( pNodeNew, Abc_ObjChild0Copy(pNode) ); + Abc_NtkLogicStoreNamePlus( pNodeNew, Abc_ObjName(pNode), Buffer ); + } + // transfer the implementation of the latch drivers to the latches + Abc_NtkForEachLatch( pNtk, pLatch, i ) + pLatch->pCopy = Abc_ObjChild0Copy(pLatch); +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/base/abci/abcNtbdd.c b/src/base/abci/abcNtbdd.c new file mode 100644 index 00000000..61c1a110 --- /dev/null +++ b/src/base/abci/abcNtbdd.c @@ -0,0 +1,402 @@ +/**CFile**************************************************************** + + FileName [abcNtbdd.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Network and node package.] + + Synopsis [Procedures to translate between the BDD and the network.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: abcNtbdd.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abc.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static void Abc_NtkBddToMuxesPerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ); +static Abc_Obj_t * Abc_NodeBddToMuxes( Abc_Obj_t * pNodeOld, Abc_Ntk_t * pNtkNew, Abc_Obj_t * pConst1 ); +static Abc_Obj_t * Abc_NodeBddToMuxes_rec( DdManager * dd, DdNode * bFunc, Abc_Ntk_t * pNtkNew, st_table * tBdd2Node ); +static DdNode * Abc_NodeGlobalBdds_rec( DdManager * dd, Abc_Obj_t * pNode ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Constructs the network isomorphic to the given BDD.] + + Description [Assumes that the BDD depends on the variables whose indexes + correspond to the names in the array (pNamesPi). Otherwise, returns NULL. + The resulting network comes with one node, whose functionality is + equal to the given BDD. To decompose this BDD into the network of + multiplexers use Abc_NtkBddToMuxes(). To decompose this BDD into + an And-Inverter Graph, use Abc_NtkStrash().] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkDeriveFromBdd( DdManager * dd, DdNode * bFunc, char * pNamePo, Vec_Ptr_t * vNamesPi ) +{ + Abc_Ntk_t * pNtk; + Vec_Ptr_t * vNamesPiFake = NULL; + Abc_Obj_t * pNode, * pNodePi, * pNodePo; + DdNode * bSupp, * bTemp; + char * pName; + int i; + + // supply fake names if real names are not given + if ( pNamePo == NULL ) + pNamePo = "F"; + if ( vNamesPi == NULL ) + { + vNamesPiFake = Abc_NodeGetFakeNames( dd->size ); + vNamesPi = vNamesPiFake; + } + + // make sure BDD depends on the variables whose index + // does not exceed the size of the array with PI names + bSupp = Cudd_Support( dd, bFunc ); Cudd_Ref( bSupp ); + for ( bTemp = bSupp; bTemp != Cudd_ReadOne(dd); bTemp = cuddT(bTemp) ) + if ( (int)Cudd_NodeReadIndex(bTemp) >= Vec_PtrSize(vNamesPi) ) + break; + Cudd_RecursiveDeref( dd, bSupp ); + if ( bTemp != Cudd_ReadOne(dd) ) + return NULL; + + // start the network + pNtk = Abc_NtkAlloc( ABC_TYPE_LOGIC, ABC_FUNC_BDD ); + pNtk->pName = util_strsav(pNamePo); + // make sure the new manager has enough inputs + Cudd_bddIthVar( pNtk->pManFunc, Vec_PtrSize(vNamesPi) ); + // add the PIs corresponding to the names + Vec_PtrForEachEntry( vNamesPi, pName, i ) + Abc_NtkLogicStoreName( Abc_NtkCreatePi(pNtk), pName ); + // create the node + pNode = Abc_NtkCreateNode( pNtk ); + pNode->pData = Cudd_bddTransfer( dd, pNtk->pManFunc, bFunc ); Cudd_Ref(pNode->pData); + Abc_NtkForEachPi( pNtk, pNodePi, i ) + Abc_ObjAddFanin( pNode, pNodePi ); + // create the only PO + pNodePo = Abc_NtkCreatePo( pNtk ); + Abc_ObjAddFanin( pNodePo, pNode ); + Abc_NtkLogicStoreName( pNodePo, pNamePo ); + // make the network minimum base + Abc_NtkMinimumBase( pNtk ); + if ( vNamesPiFake ) + Abc_NodeFreeNames( vNamesPiFake ); + if ( !Abc_NtkCheck( pNtk ) ) + fprintf( stdout, "Abc_NtkDeriveFromBdd(): Network check has failed.\n" ); + return pNtk; +} + + + +/**Function************************************************************* + + Synopsis [Creates the network isomorphic to the union of local BDDs of the nodes.] + + Description [The nodes of the local BDDs are converted into the network nodes + with logic functions equal to the MUX.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkBddToMuxes( Abc_Ntk_t * pNtk ) +{ + int fCheck = 1; + Abc_Ntk_t * pNtkNew; + assert( Abc_NtkIsBddLogic(pNtk) ); + pNtkNew = Abc_NtkStartFrom( pNtk, ABC_TYPE_LOGIC, ABC_FUNC_SOP ); + Abc_NtkBddToMuxesPerform( pNtk, pNtkNew ); + Abc_NtkFinalize( pNtk, pNtkNew ); + // make sure everything is okay + if ( fCheck && !Abc_NtkCheck( pNtkNew ) ) + { + printf( "Abc_NtkBddToMuxes: The network check has failed.\n" ); + Abc_NtkDelete( pNtkNew ); + return NULL; + } + return pNtkNew; +} + +/**Function************************************************************* + + Synopsis [Converts the network to MUXes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkBddToMuxesPerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ) +{ + ProgressBar * pProgress; + DdManager * dd = pNtk->pManFunc; + Abc_Obj_t * pNode, * pNodeNew, * pConst1; + Vec_Ptr_t * vNodes; + int i; + // create the constant one node + pConst1 = Abc_NodeCreateConst1( pNtkNew ); + // perform conversion in the topological order + vNodes = Abc_NtkDfs( pNtk, 0 ); + pProgress = Extra_ProgressBarStart( stdout, vNodes->nSize ); + Vec_PtrForEachEntry( vNodes, pNode, i ) + { + Extra_ProgressBarUpdate( pProgress, i, NULL ); + // convert one node + assert( Abc_ObjIsNode(pNode) ); + pNodeNew = Abc_NodeBddToMuxes( pNode, pNtkNew, pConst1 ); + // mark the old node with the new one + assert( pNode->pCopy == NULL ); + pNode->pCopy = pNodeNew; + } + Vec_PtrFree( vNodes ); + Extra_ProgressBarStop( pProgress ); +} + +/**Function************************************************************* + + Synopsis [Converts the node to MUXes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Abc_NodeBddToMuxes( Abc_Obj_t * pNodeOld, Abc_Ntk_t * pNtkNew, Abc_Obj_t * pConst1 ) +{ + DdManager * dd = pNodeOld->pNtk->pManFunc; + DdNode * bFunc = pNodeOld->pData; + Abc_Obj_t * pFaninOld, * pNodeNew; + st_table * tBdd2Node; + int i; + // create the table mapping BDD nodes into the ABC nodes + tBdd2Node = st_init_table( st_ptrcmp, st_ptrhash ); + // add the constant and the elementary vars + st_insert( tBdd2Node, (char *)b1, (char *)pConst1 ); + Abc_ObjForEachFanin( pNodeOld, pFaninOld, i ) + st_insert( tBdd2Node, (char *)Cudd_bddIthVar(dd, i), (char *)pFaninOld->pCopy ); + // create the new nodes recursively + pNodeNew = Abc_NodeBddToMuxes_rec( dd, Cudd_Regular(bFunc), pNtkNew, tBdd2Node ); + st_free_table( tBdd2Node ); + if ( Cudd_IsComplement(bFunc) ) + pNodeNew = Abc_NodeCreateInv( pNtkNew, pNodeNew ); + return pNodeNew; +} + +/**Function************************************************************* + + Synopsis [Converts the node to MUXes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Abc_NodeBddToMuxes_rec( DdManager * dd, DdNode * bFunc, Abc_Ntk_t * pNtkNew, st_table * tBdd2Node ) +{ + Abc_Obj_t * pNodeNew, * pNodeNew0, * pNodeNew1, * pNodeNewC; + assert( !Cudd_IsComplement(bFunc) ); + if ( st_lookup( tBdd2Node, (char *)bFunc, (char **)&pNodeNew ) ) + return pNodeNew; + // solve for the children nodes + pNodeNew0 = Abc_NodeBddToMuxes_rec( dd, Cudd_Regular(cuddE(bFunc)), pNtkNew, tBdd2Node ); + if ( Cudd_IsComplement(cuddE(bFunc)) ) + pNodeNew0 = Abc_NodeCreateInv( pNtkNew, pNodeNew0 ); + pNodeNew1 = Abc_NodeBddToMuxes_rec( dd, cuddT(bFunc), pNtkNew, tBdd2Node ); + if ( !st_lookup( tBdd2Node, (char *)Cudd_bddIthVar(dd, bFunc->index), (char **)&pNodeNewC ) ) + assert( 0 ); + // create the MUX node + pNodeNew = Abc_NodeCreateMux( pNtkNew, pNodeNewC, pNodeNew1, pNodeNew0 ); + st_insert( tBdd2Node, (char *)bFunc, (char *)pNodeNew ); + return pNodeNew; +} + + +/**Function************************************************************* + + Synopsis [Derives global BDDs for the COs of the network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +DdManager * Abc_NtkGlobalBdds( Abc_Ntk_t * pNtk, int fLatchOnly ) +{ + int fReorder = 1; + ProgressBar * pProgress; + Vec_Ptr_t * vFuncsGlob; + Abc_Obj_t * pNode; + DdNode * bFunc; + DdManager * dd; + int i; + + // start the manager + assert( pNtk->pManGlob == NULL ); + dd = Cudd_Init( Abc_NtkCiNum(pNtk), 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 ); + if ( fReorder ) + Cudd_AutodynEnable( dd, CUDD_REORDER_SYMM_SIFT ); + + // set the elementary variables + Abc_NtkCleanCopy( pNtk ); + Abc_NtkForEachCi( pNtk, pNode, i ) + pNode->pCopy = (Abc_Obj_t *)dd->vars[i]; + // assign the constant node BDD + pNode = Abc_AigConst1( pNtk->pManFunc ); + pNode->pCopy = (Abc_Obj_t *)dd->one; Cudd_Ref( dd->one ); + + // collect the global functions of the COs + vFuncsGlob = Vec_PtrAlloc( 100 ); + if ( fLatchOnly ) + { + // construct the BDDs + pProgress = Extra_ProgressBarStart( stdout, Abc_NtkLatchNum(pNtk) ); + Abc_NtkForEachLatch( pNtk, pNode, i ) + { + Extra_ProgressBarUpdate( pProgress, i, NULL ); + bFunc = Abc_NodeGlobalBdds_rec( dd, Abc_ObjFanin0(pNode) ); + if ( bFunc == NULL ) + { + printf( "Constructing global BDDs timed out.\n" ); + Extra_ProgressBarStop( pProgress ); + Cudd_Quit( dd ); + return NULL; + } + bFunc = Cudd_NotCond( bFunc, Abc_ObjFaninC0(pNode) ); Cudd_Ref( bFunc ); + Vec_PtrPush( vFuncsGlob, bFunc ); + } + Extra_ProgressBarStop( pProgress ); + } + else + { + // construct the BDDs + pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCoNum(pNtk) ); + Abc_NtkForEachCo( pNtk, pNode, i ) + { + Extra_ProgressBarUpdate( pProgress, i, NULL ); + bFunc = Abc_NodeGlobalBdds_rec( dd, Abc_ObjFanin0(pNode) ); + if ( bFunc == NULL ) + { + printf( "Constructing global BDDs timed out.\n" ); + Extra_ProgressBarStop( pProgress ); + Cudd_Quit( dd ); + return NULL; + } + bFunc = Cudd_NotCond( bFunc, Abc_ObjFaninC0(pNode) ); Cudd_Ref( bFunc ); + Vec_PtrPush( vFuncsGlob, bFunc ); + } + Extra_ProgressBarStop( pProgress ); + } + + // derefence the intermediate BDDs + Abc_NtkForEachNode( pNtk, pNode, i ) + if ( pNode->pCopy ) + { + Cudd_RecursiveDeref( dd, (DdNode *)pNode->pCopy ); + pNode->pCopy = NULL; + } + // reorder one more time + if ( fReorder ) + { + Cudd_ReduceHeap( dd, CUDD_REORDER_SYMM_SIFT, 1 ); + Cudd_AutodynDisable( dd ); + } + pNtk->pManGlob = dd; + pNtk->vFuncsGlob = vFuncsGlob; + return dd; +} + +/**Function************************************************************* + + Synopsis [Derives the global BDD for one AIG node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +DdNode * Abc_NodeGlobalBdds_rec( DdManager * dd, Abc_Obj_t * pNode ) +{ + DdNode * bFunc, * bFunc0, * bFunc1; + assert( !Abc_ObjIsComplement(pNode) ); + if ( Cudd_ReadKeys(dd) > 500000 ) + return NULL; + // if the result is available return + if ( pNode->pCopy ) + return (DdNode *)pNode->pCopy; + // compute the result for both branches + bFunc0 = Abc_NodeGlobalBdds_rec( dd, Abc_ObjFanin(pNode,0) ); + if ( bFunc0 == NULL ) + return NULL; + Cudd_Ref( bFunc0 ); + bFunc1 = Abc_NodeGlobalBdds_rec( dd, Abc_ObjFanin(pNode,1) ); + if ( bFunc1 == NULL ) + return NULL; + Cudd_Ref( bFunc1 ); + bFunc0 = Cudd_NotCond( bFunc0, Abc_ObjFaninC0(pNode) ); + bFunc1 = Cudd_NotCond( bFunc1, Abc_ObjFaninC1(pNode) ); + // get the final result + bFunc = Cudd_bddAnd( dd, bFunc0, bFunc1 ); Cudd_Ref( bFunc ); + Cudd_RecursiveDeref( dd, bFunc0 ); + Cudd_RecursiveDeref( dd, bFunc1 ); + // set the result + assert( pNode->pCopy == NULL ); + pNode->pCopy = (Abc_Obj_t *)bFunc; + return bFunc; +} + +/**Function************************************************************* + + Synopsis [Dereferences global BDDs of the network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkFreeGlobalBdds( Abc_Ntk_t * pNtk ) +{ + DdNode * bFunc; + int i; + assert( pNtk->pManGlob ); + assert( pNtk->vFuncsGlob ); + Vec_PtrForEachEntry( pNtk->vFuncsGlob, bFunc, i ) + Cudd_RecursiveDeref( pNtk->pManGlob, bFunc ); + Vec_PtrFree( pNtk->vFuncsGlob ); + pNtk->vFuncsGlob = NULL; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/base/abci/abcPrint.c b/src/base/abci/abcPrint.c new file mode 100644 index 00000000..41b9288e --- /dev/null +++ b/src/base/abci/abcPrint.c @@ -0,0 +1,505 @@ +/**CFile**************************************************************** + + FileName [abcPrint.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Network and node package.] + + Synopsis [Printing statistics.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: abcPrint.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abc.h" +#include "dec.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Print the vital stats of the network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkPrintStats( FILE * pFile, Abc_Ntk_t * pNtk, int fFactored ) +{ + int Num; + + fprintf( pFile, "%-13s:", pNtk->pName ); + fprintf( pFile, " i/o = %4d/%4d", Abc_NtkPiNum(pNtk), Abc_NtkPoNum(pNtk) ); + + if ( !Abc_NtkIsSeq(pNtk) ) + fprintf( pFile, " lat = %4d", Abc_NtkLatchNum(pNtk) ); + else + fprintf( pFile, " lat = %4d", Abc_NtkSeqLatchNum(pNtk) ); + + if ( Abc_NtkIsNetlist(pNtk) ) + { + fprintf( pFile, " net = %5d", Abc_NtkNetNum(pNtk) ); + fprintf( pFile, " nd = %5d", Abc_NtkNodeNum(pNtk) ); + } + else if ( Abc_NtkIsStrash(pNtk) ) + { + fprintf( pFile, " and = %5d", Abc_NtkNodeNum(pNtk) ); + if ( Num = Abc_NtkGetChoiceNum(pNtk) ) + fprintf( pFile, " (choice = %d)", Num ); + if ( Num = Abc_NtkGetExorNum(pNtk) ) + fprintf( pFile, " (exor = %d)", Num ); + } + else if ( Abc_NtkIsSeq(pNtk) ) + fprintf( pFile, " and = %5d", Abc_NtkNodeNum(pNtk) ); + else + fprintf( pFile, " nd = %5d", Abc_NtkNodeNum(pNtk) ); + + if ( Abc_NtkHasSop(pNtk) ) + { + fprintf( pFile, " cube = %5d", Abc_NtkGetCubeNum(pNtk) ); +// fprintf( pFile, " lit(sop) = %5d", Abc_NtkGetLitNum(pNtk) ); + if ( fFactored ) + fprintf( pFile, " lit(fac) = %5d", Abc_NtkGetLitFactNum(pNtk) ); + } + else if ( Abc_NtkHasBdd(pNtk) ) + fprintf( pFile, " bdd = %5d", Abc_NtkGetBddNodeNum(pNtk) ); + else if ( Abc_NtkHasMapping(pNtk) ) + { + fprintf( pFile, " area = %5.2f", Abc_NtkGetMappedArea(pNtk) ); + fprintf( pFile, " delay = %5.2f", Abc_NtkDelayTrace(pNtk) ); + } + else if ( !Abc_NtkHasAig(pNtk) ) + { + assert( 0 ); + } + + if ( Abc_NtkIsStrash(pNtk) ) + fprintf( pFile, " lev = %3d", Abc_AigGetLevelNum(pNtk) ); + else if ( !Abc_NtkIsSeq(pNtk) ) + fprintf( pFile, " lev = %3d", Abc_NtkGetLevelNum(pNtk) ); + + fprintf( pFile, "\n" ); +} + +/**Function************************************************************* + + Synopsis [Prints PIs/POs and LIs/LOs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkPrintIo( FILE * pFile, Abc_Ntk_t * pNtk ) +{ + Abc_Obj_t * pObj; + int i; + + fprintf( pFile, "Primary inputs (%d): ", Abc_NtkPiNum(pNtk) ); + Abc_NtkForEachPi( pNtk, pObj, i ) + fprintf( pFile, " %s", Abc_ObjName(pObj) ); + fprintf( pFile, "\n" ); + + fprintf( pFile, "Primary outputs (%d):", Abc_NtkPoNum(pNtk) ); + Abc_NtkForEachPo( pNtk, pObj, i ) + fprintf( pFile, " %s", Abc_ObjName(pObj) ); + fprintf( pFile, "\n" ); + + fprintf( pFile, "Latches (%d): ", Abc_NtkLatchNum(pNtk) ); + Abc_NtkForEachLatch( pNtk, pObj, i ) + fprintf( pFile, " %s", Abc_ObjName(pObj) ); + fprintf( pFile, "\n" ); +} + +/**Function************************************************************* + + Synopsis [Prints statistics about latches.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkPrintLatch( FILE * pFile, Abc_Ntk_t * pNtk ) +{ + Abc_Obj_t * pLatch, * pFanin; + int i, Counter0, Counter1, Counter2; + int Init0, Init1, Init2; + + if ( Abc_NtkLatchNum(pNtk) == 0 ) + { + fprintf( pFile, "The network is combinational.\n" ); + return; + } + + assert( !Abc_NtkIsNetlist(pNtk) ); + + Init0 = Init1 = Init2 = 0; + Counter0 = Counter1 = Counter2 = 0; + + Abc_NtkForEachLatch( pNtk, pLatch, i ) + { + if ( Abc_LatchIsInit0(pLatch) ) + Init0++; + else if ( Abc_LatchIsInit1(pLatch) ) + Init1++; + else if ( Abc_LatchIsInitDc(pLatch) ) + Init2++; + else + assert( 0 ); + + pFanin = Abc_ObjFanin0(pLatch); + if ( !Abc_ObjIsNode(pFanin) || !Abc_NodeIsConst(pFanin) ) + continue; + + // the latch input is a constant node + Counter0++; + if ( Abc_LatchIsInitDc(pLatch) ) + { + Counter1++; + continue; + } + // count the number of cases when the constant is equal to the initial value + if ( Abc_NtkIsStrash(pNtk) ) + { + if ( Abc_LatchIsInit1(pLatch) == !Abc_ObjFaninC0(pLatch) ) + Counter2++; + } + else + { + if ( Abc_LatchIsInit1(pLatch) == Abc_NodeIsConst1(pLatch) ) + Counter2++; + } + } +// fprintf( pFile, "%-15s: ", pNtk->pName ); +// fprintf( pFile, "L = %5d: 0 = %4d. 1 = %3d. DC = %4d. ", Abc_NtkLatchNum(pNtk), Init0, Init1, Init2 ); +// fprintf( pFile, "Con = %3d. DC = %3d. Mat = %3d. ", Counter0, Counter1, Counter2 ); +// fprintf( pFile, "SFeed = %2d.\n", Abc_NtkCountSelfFeedLatches(pNtk) ); + fprintf( pFile, "%-15s: ", pNtk->pName ); + fprintf( pFile, "Lat = %5d: 0 = %4d. 1 = %3d. DC = %4d. \n", Abc_NtkLatchNum(pNtk), Init0, Init1, Init2 ); + fprintf( pFile, "Con = %3d. DC = %3d. Mat = %3d. ", Counter0, Counter1, Counter2 ); + fprintf( pFile, "SFeed = %2d.\n", Abc_NtkCountSelfFeedLatches(pNtk) ); +} + +/**Function************************************************************* + + Synopsis [Prints the distribution of fanins/fanouts in the network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkPrintFanio( FILE * pFile, Abc_Ntk_t * pNtk ) +{ + Abc_Obj_t * pNode; + int i, k, nFanins, nFanouts; + Vec_Int_t * vFanins, * vFanouts; + int nOldSize, nNewSize; + + vFanins = Vec_IntAlloc( 0 ); + vFanouts = Vec_IntAlloc( 0 ); + Vec_IntFill( vFanins, 100, 0 ); + Vec_IntFill( vFanouts, 100, 0 ); + Abc_NtkForEachNode( pNtk, pNode, i ) + { + nFanins = Abc_ObjFaninNum(pNode); + if ( Abc_NtkIsNetlist(pNtk) ) + nFanouts = Abc_ObjFanoutNum( Abc_ObjFanout0(pNode) ); + else + nFanouts = Abc_ObjFanoutNum(pNode); + if ( nFanins > vFanins->nSize || nFanouts > vFanouts->nSize ) + { + nOldSize = vFanins->nSize; + nNewSize = ABC_MAX(nFanins, nFanouts) + 10; + Vec_IntGrow( vFanins, nNewSize ); + Vec_IntGrow( vFanouts, nNewSize ); + for ( k = nOldSize; k < nNewSize; k++ ) + { + Vec_IntPush( vFanins, 0 ); + Vec_IntPush( vFanouts, 0 ); + } + } + vFanins->pArray[nFanins]++; + vFanouts->pArray[nFanouts]++; + } + fprintf( pFile, "The distribution of fanins and fanouts in the network:\n" ); + fprintf( pFile, " Number Nodes with fanin Nodes with fanout\n" ); + for ( k = 0; k < vFanins->nSize; k++ ) + { + if ( vFanins->pArray[k] == 0 && vFanouts->pArray[k] == 0 ) + continue; + fprintf( pFile, "%5d : ", k ); + if ( vFanins->pArray[k] == 0 ) + fprintf( pFile, " " ); + else + fprintf( pFile, "%12d ", vFanins->pArray[k] ); + fprintf( pFile, " " ); + if ( vFanouts->pArray[k] == 0 ) + fprintf( pFile, " " ); + else + fprintf( pFile, "%12d ", vFanouts->pArray[k] ); + fprintf( pFile, "\n" ); + } + Vec_IntFree( vFanins ); + Vec_IntFree( vFanouts ); +} + +/**Function************************************************************* + + Synopsis [Prints the fanins/fanouts of a node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NodePrintFanio( FILE * pFile, Abc_Obj_t * pNode ) +{ + Abc_Obj_t * pNode2; + int i; + if ( Abc_ObjIsPo(pNode) ) + pNode = Abc_ObjFanin0(pNode); + + fprintf( pFile, "Node %s", Abc_ObjName(pNode) ); + fprintf( pFile, "\n" ); + + fprintf( pFile, "Fanins (%d): ", Abc_ObjFaninNum(pNode) ); + Abc_ObjForEachFanin( pNode, pNode2, i ) + fprintf( pFile, " %s", Abc_ObjName(pNode2) ); + fprintf( pFile, "\n" ); + + fprintf( pFile, "Fanouts (%d): ", Abc_ObjFaninNum(pNode) ); + Abc_ObjForEachFanout( pNode, pNode2, i ) + fprintf( pFile, " %s", Abc_ObjName(pNode2) ); + fprintf( pFile, "\n" ); +} + +/**Function************************************************************* + + Synopsis [Prints the factored form of one node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkPrintFactor( FILE * pFile, Abc_Ntk_t * pNtk, int fUseRealNames ) +{ + Abc_Obj_t * pNode; + int i; + assert( Abc_NtkIsSopLogic(pNtk) ); + Abc_NtkForEachNode( pNtk, pNode, i ) + Abc_NodePrintFactor( pFile, pNode, fUseRealNames ); +} + +/**Function************************************************************* + + Synopsis [Prints the factored form of one node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NodePrintFactor( FILE * pFile, Abc_Obj_t * pNode, int fUseRealNames ) +{ + Dec_Graph_t * pGraph; + Vec_Ptr_t * vNamesIn; + if ( Abc_ObjIsCo(pNode) ) + pNode = Abc_ObjFanin0(pNode); + if ( Abc_ObjIsPi(pNode) ) + { + fprintf( pFile, "Skipping the PI node.\n" ); + return; + } + if ( Abc_ObjIsLatch(pNode) ) + { + fprintf( pFile, "Skipping the latch.\n" ); + return; + } + assert( Abc_ObjIsNode(pNode) ); + pGraph = Dec_Factor( pNode->pData ); + if ( fUseRealNames ) + { + vNamesIn = Abc_NodeGetFaninNames(pNode); + Dec_GraphPrint( stdout, pGraph, (char **)vNamesIn->pArray, Abc_ObjName(pNode) ); + Abc_NodeFreeNames( vNamesIn ); + } + else + Dec_GraphPrint( stdout, pGraph, (char **)NULL, Abc_ObjName(pNode) ); + Dec_GraphFree( pGraph ); +} + + +/**Function************************************************************* + + Synopsis [Prints the level stats of the PO node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkPrintLevel( FILE * pFile, Abc_Ntk_t * pNtk, int fProfile ) +{ + Abc_Obj_t * pNode; + int i, Length; + + // print the delay profile + if ( fProfile && Abc_NtkHasMapping(pNtk) ) + { + int nIntervals = 12; + float DelayMax, DelayCur, DelayDelta; + int * pLevelCounts; + int DelayInt, nOutsSum, nOutsTotal; + + // get the max delay and delta + DelayMax = Abc_NtkDelayTrace( pNtk ); + DelayDelta = DelayMax/nIntervals; + // collect outputs by delay + pLevelCounts = ALLOC( int, nIntervals ); + memset( pLevelCounts, 0, sizeof(int) * nIntervals ); + Abc_NtkForEachCo( pNtk, pNode, i ) + { + DelayCur = Abc_NodeReadArrival( Abc_ObjFanin0(pNode) )->Worst; + DelayInt = (int)(DelayCur / DelayDelta); + if ( DelayInt >= nIntervals ) + DelayInt = nIntervals - 1; + pLevelCounts[DelayInt]++; + } + + nOutsSum = 0; + nOutsTotal = Abc_NtkCoNum(pNtk); + for ( i = 0; i < nIntervals; i++ ) + { + nOutsSum += pLevelCounts[i]; + printf( "[%8.2f - %8.2f] : COs = %4d. %5.1f %%\n", + DelayDelta * i, DelayDelta * (i+1), pLevelCounts[i], 100.0 * nOutsSum/nOutsTotal ); + } + free( pLevelCounts ); + return; + } + else if ( fProfile ) + { + int LevelMax, * pLevelCounts; + int nOutsSum, nOutsTotal; + + if ( !Abc_NtkIsStrash(pNtk) ) + Abc_NtkGetLevelNum(pNtk); + + LevelMax = 0; + Abc_NtkForEachCo( pNtk, pNode, i ) + if ( LevelMax < (int)Abc_ObjFanin0(pNode)->Level ) + LevelMax = Abc_ObjFanin0(pNode)->Level; + pLevelCounts = ALLOC( int, LevelMax + 1 ); + memset( pLevelCounts, 0, sizeof(int) * (LevelMax + 1) ); + Abc_NtkForEachCo( pNtk, pNode, i ) + pLevelCounts[Abc_ObjFanin0(pNode)->Level]++; + + nOutsSum = 0; + nOutsTotal = Abc_NtkCoNum(pNtk); + for ( i = 0; i <= LevelMax; i++ ) + if ( pLevelCounts[i] ) + { + nOutsSum += pLevelCounts[i]; + printf( "Level = %4d. COs = %4d. %5.1f %%\n", i, pLevelCounts[i], 100.0 * nOutsSum/nOutsTotal ); + } + free( pLevelCounts ); + return; + } + assert( Abc_NtkIsStrash(pNtk) ); + + // find the longest name + Length = 0; + Abc_NtkForEachCo( pNtk, pNode, i ) + if ( Length < (int)strlen(Abc_ObjName(pNode)) ) + Length = strlen(Abc_ObjName(pNode)); + if ( Length < 5 ) + Length = 5; + // print stats for each output + Abc_NtkForEachCo( pNtk, pNode, i ) + { + fprintf( pFile, "CO %4d : %*s ", i, Length, Abc_ObjName(pNode) ); + Abc_NodePrintLevel( pFile, pNode ); + } +} + +/**Function************************************************************* + + Synopsis [Prints the factored form of one node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NodePrintLevel( FILE * pFile, Abc_Obj_t * pNode ) +{ + Abc_Obj_t * pDriver; + Vec_Ptr_t * vNodes; + + pDriver = Abc_ObjIsCo(pNode)? Abc_ObjFanin0(pNode) : pNode; + if ( Abc_ObjIsPi(pDriver) ) + { + fprintf( pFile, "Primary input.\n" ); + return; + } + if ( Abc_ObjIsLatch(pDriver) ) + { + fprintf( pFile, "Latch.\n" ); + return; + } + if ( Abc_NodeIsConst(pDriver) ) + { + fprintf( pFile, "Constant %d.\n", !Abc_ObjFaninC0(pNode) ); + return; + } + // print the level + fprintf( pFile, "Level = %3d. ", pDriver->Level ); + // print the size of MFFC + fprintf( pFile, "Mffc = %5d. ", Abc_NodeMffcSize(pDriver) ); + // print the size of the shole cone + vNodes = Abc_NtkDfsNodes( pNode->pNtk, &pDriver, 1 ); + fprintf( pFile, "Cone = %5d. ", Vec_PtrSize(vNodes) ); + Vec_PtrFree( vNodes ); + fprintf( pFile, "\n" ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/base/abci/abcReconv.c b/src/base/abci/abcReconv.c new file mode 100644 index 00000000..766c14f3 --- /dev/null +++ b/src/base/abci/abcReconv.c @@ -0,0 +1,742 @@ +/**CFile**************************************************************** + + FileName [abcRes.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Network and node package.] + + Synopsis [Reconvergence=driven cut computation.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: abcRes.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abc.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +struct Abc_ManCut_t_ +{ + // user specified parameters + int nNodeSizeMax; // the limit on the size of the supernode + int nConeSizeMax; // the limit on the size of the containing cone + int nNodeFanStop; // the limit on the size of the supernode + int nConeFanStop; // the limit on the size of the containing cone + // internal parameters + Vec_Ptr_t * vNodeLeaves; // fanins of the collapsed node (the cut) + Vec_Ptr_t * vConeLeaves; // fanins of the containing cone + Vec_Ptr_t * vVisited; // the visited nodes + Vec_Vec_t * vLevels; // the data structure to compute TFO nodes + Vec_Ptr_t * vNodesTfo; // the nodes in the TFO of the cut +}; + +static int Abc_NodeBuildCutLevelOne_int( Vec_Ptr_t * vVisited, Vec_Ptr_t * vLeaves, int nSizeLimit, int nFaninLimit ); +static int Abc_NodeBuildCutLevelTwo_int( Vec_Ptr_t * vVisited, Vec_Ptr_t * vLeaves, int nFaninLimit ); +static void Abc_NodeConeMarkCollect_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vVisited ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Unmarks the TFI cone.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Abc_NodesMark( Vec_Ptr_t * vVisited ) +{ + Abc_Obj_t * pNode; + int i; + Vec_PtrForEachEntry( vVisited, pNode, i ) + pNode->fMarkA = 1; +} + +/**Function************************************************************* + + Synopsis [Unmarks the TFI cone.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Abc_NodesUnmark( Vec_Ptr_t * vVisited ) +{ + Abc_Obj_t * pNode; + int i; + Vec_PtrForEachEntry( vVisited, pNode, i ) + pNode->fMarkA = 0; +} + +/**Function************************************************************* + + Synopsis [Unmarks the TFI cone.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Abc_NodesUnmarkB( Vec_Ptr_t * vVisited ) +{ + Abc_Obj_t * pNode; + int i; + Vec_PtrForEachEntry( vVisited, pNode, i ) + pNode->fMarkB = 0; +} + +/**Function************************************************************* + + Synopsis [Evaluate the cost of removing the node from the set of leaves.] + + Description [Returns the number of new leaves that will be brought in. + Returns large number if the node cannot be removed from the set of leaves.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Abc_NodeGetLeafCostOne( Abc_Obj_t * pNode, int nFaninLimit ) +{ + int Cost; + // make sure the node is in the construction zone + assert( pNode->fMarkB == 1 ); + // cannot expand over the PI node + if ( Abc_ObjIsCi(pNode) ) + return 999; + // get the cost of the cone + Cost = (!Abc_ObjFanin0(pNode)->fMarkB) + (!Abc_ObjFanin1(pNode)->fMarkB); + // always accept if the number of leaves does not increase + if ( Cost < 2 ) + return Cost; + // skip nodes with many fanouts + if ( Abc_ObjFanoutNum(pNode) > nFaninLimit ) + return 999; + // return the number of nodes that will be on the leaves if this node is removed + return Cost; +} + +/**Function************************************************************* + + Synopsis [Evaluate the cost of removing the node from the set of leaves.] + + Description [Returns the number of new leaves that will be brought in. + Returns large number if the node cannot be removed from the set of leaves.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Abc_NodeGetLeafCostTwo( Abc_Obj_t * pNode, int nFaninLimit, + Abc_Obj_t ** ppLeafToAdd, Abc_Obj_t ** pNodeToMark1, Abc_Obj_t ** pNodeToMark2 ) +{ + Abc_Obj_t * pFanin0, * pFanin1, * pTemp; + Abc_Obj_t * pGrand, * pGrandToAdd; + // make sure the node is in the construction zone + assert( pNode->fMarkB == 1 ); + // cannot expand over the PI node + if ( Abc_ObjIsCi(pNode) ) + return 999; + // skip nodes with many fanouts +// if ( Abc_ObjFanoutNum(pNode) > nFaninLimit ) +// return 999; + // get the children + pFanin0 = Abc_ObjFanin0(pNode); + pFanin1 = Abc_ObjFanin1(pNode); + assert( !pFanin0->fMarkB && !pFanin1->fMarkB ); + // count the number of unique grandchildren that will be included + // return infinite cost if this number if more than 1 + if ( Abc_ObjIsCi(pFanin0) && Abc_ObjIsCi(pFanin1) ) + return 999; + // consider the special case when a non-CI fanin can be dropped + if ( !Abc_ObjIsCi(pFanin0) && Abc_ObjFanin0(pFanin0)->fMarkB && Abc_ObjFanin1(pFanin0)->fMarkB ) + { + *ppLeafToAdd = pFanin1; + *pNodeToMark1 = pFanin0; + *pNodeToMark2 = NULL; + return 1; + } + if ( !Abc_ObjIsCi(pFanin1) && Abc_ObjFanin0(pFanin1)->fMarkB && Abc_ObjFanin1(pFanin1)->fMarkB ) + { + *ppLeafToAdd = pFanin0; + *pNodeToMark1 = pFanin1; + *pNodeToMark2 = NULL; + return 1; + } + + // make the first node CI if any + if ( Abc_ObjIsCi(pFanin1) ) + pTemp = pFanin0, pFanin0 = pFanin1, pFanin1 = pTemp; + // consider the first node + pGrandToAdd = NULL; + if ( Abc_ObjIsCi(pFanin0) ) + { + *pNodeToMark1 = NULL; + pGrandToAdd = pFanin0; + } + else + { + *pNodeToMark1 = pFanin0; + pGrand = Abc_ObjFanin0(pFanin0); + if ( !pGrand->fMarkB ) + { + if ( pGrandToAdd && pGrandToAdd != pGrand ) + return 999; + pGrandToAdd = pGrand; + } + pGrand = Abc_ObjFanin1(pFanin0); + if ( !pGrand->fMarkB ) + { + if ( pGrandToAdd && pGrandToAdd != pGrand ) + return 999; + pGrandToAdd = pGrand; + } + } + // consider the second node + *pNodeToMark2 = pFanin1; + pGrand = Abc_ObjFanin0(pFanin1); + if ( !pGrand->fMarkB ) + { + if ( pGrandToAdd && pGrandToAdd != pGrand ) + return 999; + pGrandToAdd = pGrand; + } + pGrand = Abc_ObjFanin1(pFanin1); + if ( !pGrand->fMarkB ) + { + if ( pGrandToAdd && pGrandToAdd != pGrand ) + return 999; + pGrandToAdd = pGrand; + } + assert( pGrandToAdd != NULL ); + *ppLeafToAdd = pGrandToAdd; + return 1; +} + + +/**Function************************************************************* + + Synopsis [Finds a fanin-limited, reconvergence-driven cut for the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Abc_NodeFindCut( Abc_ManCut_t * p, Abc_Obj_t * pRoot, bool fContain ) +{ + Abc_Obj_t * pNode; + int i; + + assert( !Abc_ObjIsComplement(pRoot) ); + assert( Abc_ObjIsNode(pRoot) ); + + // start the visited nodes and mark them + Vec_PtrClear( p->vVisited ); + Vec_PtrPush( p->vVisited, pRoot ); + Vec_PtrPush( p->vVisited, Abc_ObjFanin0(pRoot) ); + Vec_PtrPush( p->vVisited, Abc_ObjFanin1(pRoot) ); + pRoot->fMarkB = 1; + Abc_ObjFanin0(pRoot)->fMarkB = 1; + Abc_ObjFanin1(pRoot)->fMarkB = 1; + + // start the cut + Vec_PtrClear( p->vNodeLeaves ); + Vec_PtrPush( p->vNodeLeaves, Abc_ObjFanin0(pRoot) ); + Vec_PtrPush( p->vNodeLeaves, Abc_ObjFanin1(pRoot) ); + + // compute the cut + while ( Abc_NodeBuildCutLevelOne_int( p->vVisited, p->vNodeLeaves, p->nNodeSizeMax, p->nNodeFanStop ) ); + assert( Vec_PtrSize(p->vNodeLeaves) <= p->nNodeSizeMax ); + + // return if containing cut is not requested + if ( !fContain ) + { + // unmark both fMarkA and fMarkB in tbe TFI + Abc_NodesUnmarkB( p->vVisited ); + return p->vNodeLeaves; + } + +//printf( "\n\n\n" ); + // compute the containing cut + assert( p->nNodeSizeMax < p->nConeSizeMax ); + // copy the current boundary + Vec_PtrClear( p->vConeLeaves ); + Vec_PtrForEachEntry( p->vNodeLeaves, pNode, i ) + Vec_PtrPush( p->vConeLeaves, pNode ); + // compute the containing cut + while ( Abc_NodeBuildCutLevelOne_int( p->vVisited, p->vConeLeaves, p->nConeSizeMax, p->nConeFanStop ) ); + assert( Vec_PtrSize(p->vConeLeaves) <= p->nConeSizeMax ); + // unmark TFI using fMarkA and fMarkB + Abc_NodesUnmarkB( p->vVisited ); + return p->vNodeLeaves; +} + +/**Function************************************************************* + + Synopsis [Builds reconvergence-driven cut by changing one leaf at a time.] + + Description [This procedure looks at the current leaves and tries to change + one leaf at a time in such a way that the cut grows as little as possible. + In evaluating the fanins, this procedure looks only at their immediate + predecessors (this is why it is called a one-level construction procedure).] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NodeBuildCutLevelOne_int( Vec_Ptr_t * vVisited, Vec_Ptr_t * vLeaves, int nSizeLimit, int nFaninLimit ) +{ + Abc_Obj_t * pNode, * pFaninBest, * pNext; + int CostBest, CostCur, i; + // find the best fanin + CostBest = 100; + pFaninBest = NULL; +//printf( "Evaluating fanins of the cut:\n" ); + Vec_PtrForEachEntry( vLeaves, pNode, i ) + { + CostCur = Abc_NodeGetLeafCostOne( pNode, nFaninLimit ); +//printf( " Fanin %s has cost %d.\n", Abc_ObjName(pNode), CostCur ); + if ( CostBest > CostCur ) + { + CostBest = CostCur; + pFaninBest = pNode; + } + if ( CostBest == 0 ) + break; + } + if ( pFaninBest == NULL ) + return 0; +// return Abc_NodeBuildCutLevelTwo_int( vVisited, vLeaves, nFaninLimit ); + + assert( CostBest < 3 ); + if ( vLeaves->nSize - 1 + CostBest > nSizeLimit ) + return 0; +// return Abc_NodeBuildCutLevelTwo_int( vVisited, vLeaves, nFaninLimit ); + + assert( Abc_ObjIsNode(pFaninBest) ); + // remove the node from the array + Vec_PtrRemove( vLeaves, pFaninBest ); +//printf( "Removing fanin %s.\n", Abc_ObjName(pFaninBest) ); + + // add the left child to the fanins + pNext = Abc_ObjFanin0(pFaninBest); + if ( !pNext->fMarkB ) + { +//printf( "Adding fanin %s.\n", Abc_ObjName(pNext) ); + pNext->fMarkB = 1; + Vec_PtrPush( vLeaves, pNext ); + Vec_PtrPush( vVisited, pNext ); + } + // add the right child to the fanins + pNext = Abc_ObjFanin1(pFaninBest); + if ( !pNext->fMarkB ) + { +//printf( "Adding fanin %s.\n", Abc_ObjName(pNext) ); + pNext->fMarkB = 1; + Vec_PtrPush( vLeaves, pNext ); + Vec_PtrPush( vVisited, pNext ); + } + assert( vLeaves->nSize <= nSizeLimit ); + // keep doing this + return 1; +} + +/**Function************************************************************* + + Synopsis [Builds reconvergence-driven cut by changing one leaf at a time.] + + Description [This procedure looks at the current leaves and tries to change + one leaf at a time in such a way that the cut grows as little as possible. + In evaluating the fanins, this procedure looks across two levels of fanins + (this is why it is called a two-level construction procedure).] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NodeBuildCutLevelTwo_int( Vec_Ptr_t * vVisited, Vec_Ptr_t * vLeaves, int nFaninLimit ) +{ + Abc_Obj_t * pNode, * pLeafToAdd, * pNodeToMark1, * pNodeToMark2; + int CostCur, i; + // find the best fanin + Vec_PtrForEachEntry( vLeaves, pNode, i ) + { + CostCur = Abc_NodeGetLeafCostTwo( pNode, nFaninLimit, &pLeafToAdd, &pNodeToMark1, &pNodeToMark2 ); + if ( CostCur < 2 ) + break; + } + if ( CostCur > 2 ) + return 0; + // remove the node from the array + Vec_PtrRemove( vLeaves, pNode ); + // add the node to the leaves + if ( pLeafToAdd ) + { + assert( !pLeafToAdd->fMarkB ); + pLeafToAdd->fMarkB = 1; + Vec_PtrPush( vLeaves, pLeafToAdd ); + Vec_PtrPush( vVisited, pLeafToAdd ); + } + // mark the other nodes + if ( pNodeToMark1 ) + { + assert( !pNodeToMark1->fMarkB ); + pNodeToMark1->fMarkB = 1; + Vec_PtrPush( vVisited, pNodeToMark1 ); + } + if ( pNodeToMark2 ) + { + assert( !pNodeToMark2->fMarkB ); + pNodeToMark2->fMarkB = 1; + Vec_PtrPush( vVisited, pNodeToMark2 ); + } + // keep doing this + return 1; +} + + +/**Function************************************************************* + + Synopsis [Get the nodes contained in the cut.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NodeConeCollect( Abc_Obj_t ** ppRoots, int nRoots, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vVisited, int fIncludeFanins ) +{ + Abc_Obj_t * pTemp; + int i; + // mark the fanins of the cone + Abc_NodesMark( vLeaves ); + // collect the nodes in the DFS order + Vec_PtrClear( vVisited ); + // add the fanins + if ( fIncludeFanins ) + Vec_PtrForEachEntry( vLeaves, pTemp, i ) + Vec_PtrPush( vVisited, pTemp ); + // add other nodes + for ( i = 0; i < nRoots; i++ ) + Abc_NodeConeMarkCollect_rec( ppRoots[i], vVisited ); + // unmark both sets + Abc_NodesUnmark( vLeaves ); + Abc_NodesUnmark( vVisited ); +} + +/**Function************************************************************* + + Synopsis [Marks the TFI cone.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NodeConeMarkCollect_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vVisited ) +{ + if ( pNode->fMarkA == 1 ) + return; + // visit transitive fanin + if ( Abc_ObjIsNode(pNode) ) + { + Abc_NodeConeMarkCollect_rec( Abc_ObjFanin0(pNode), vVisited ); + Abc_NodeConeMarkCollect_rec( Abc_ObjFanin1(pNode), vVisited ); + } + assert( pNode->fMarkA == 0 ); + pNode->fMarkA = 1; + Vec_PtrPush( vVisited, pNode ); +} + +/**Function************************************************************* + + Synopsis [Returns BDD representing the logic function of the cone.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +DdNode * Abc_NodeConeBdd( DdManager * dd, DdNode ** pbVars, Abc_Obj_t * pNode, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vVisited ) +{ + DdNode * bFunc0, * bFunc1, * bFunc; + int i; + // get the nodes in the cut without fanins in the DFS order + Abc_NodeConeCollect( &pNode, 1, vLeaves, vVisited, 0 ); + // set the elementary BDDs + Vec_PtrForEachEntry( vLeaves, pNode, i ) + pNode->pCopy = (Abc_Obj_t *)pbVars[i]; + // compute the BDDs for the collected nodes + Vec_PtrForEachEntry( vVisited, pNode, i ) + { + bFunc0 = Cudd_NotCond( Abc_ObjFanin0(pNode)->pCopy, Abc_ObjFaninC0(pNode) ); + bFunc1 = Cudd_NotCond( Abc_ObjFanin1(pNode)->pCopy, Abc_ObjFaninC1(pNode) ); + bFunc = Cudd_bddAnd( dd, bFunc0, bFunc1 ); Cudd_Ref( bFunc ); + pNode->pCopy = (Abc_Obj_t *)bFunc; + } + Cudd_Ref( bFunc ); + // dereference the intermediate ones + Vec_PtrForEachEntry( vVisited, pNode, i ) + Cudd_RecursiveDeref( dd, (DdNode *)pNode->pCopy ); + Cudd_Deref( bFunc ); + return bFunc; +} + +/**Function************************************************************* + + Synopsis [Returns BDD representing the transition relation of the cone.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +DdNode * Abc_NodeConeDcs( DdManager * dd, DdNode ** pbVarsX, DdNode ** pbVarsY, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vRoots, Vec_Ptr_t * vVisited ) +{ + DdNode * bFunc0, * bFunc1, * bFunc, * bTrans, * bTemp, * bCube, * bResult; + Abc_Obj_t * pNode; + int i; + // get the nodes in the cut without fanins in the DFS order + Abc_NodeConeCollect( (Abc_Obj_t **)vRoots->pArray, vRoots->nSize, vLeaves, vVisited, 0 ); + // set the elementary BDDs + Vec_PtrForEachEntry( vLeaves, pNode, i ) + pNode->pCopy = (Abc_Obj_t *)pbVarsX[i]; + // compute the BDDs for the collected nodes + Vec_PtrForEachEntry( vVisited, pNode, i ) + { + bFunc0 = Cudd_NotCond( Abc_ObjFanin0(pNode)->pCopy, Abc_ObjFaninC0(pNode) ); + bFunc1 = Cudd_NotCond( Abc_ObjFanin1(pNode)->pCopy, Abc_ObjFaninC1(pNode) ); + bFunc = Cudd_bddAnd( dd, bFunc0, bFunc1 ); Cudd_Ref( bFunc ); + pNode->pCopy = (Abc_Obj_t *)bFunc; + } + // compute the transition relation of the cone + bTrans = b1; Cudd_Ref( bTrans ); + Vec_PtrForEachEntry( vRoots, pNode, i ) + { + bFunc = Cudd_bddXnor( dd, (DdNode *)pNode->pCopy, pbVarsY[i] ); Cudd_Ref( bFunc ); + bTrans = Cudd_bddAnd( dd, bTemp = bTrans, bFunc ); Cudd_Ref( bTrans ); + Cudd_RecursiveDeref( dd, bTemp ); + Cudd_RecursiveDeref( dd, bFunc ); + } + // dereference the intermediate ones + Vec_PtrForEachEntry( vVisited, pNode, i ) + Cudd_RecursiveDeref( dd, (DdNode *)pNode->pCopy ); + // compute don't-cares + bCube = Extra_bddComputeRangeCube( dd, vRoots->nSize, vRoots->nSize + vLeaves->nSize ); Cudd_Ref( bCube ); + bResult = Cudd_bddExistAbstract( dd, bTrans, bCube ); Cudd_Ref( bResult ); + bResult = Cudd_Not( bResult ); + Cudd_RecursiveDeref( dd, bCube ); + Cudd_RecursiveDeref( dd, bTrans ); + Cudd_Deref( bResult ); + return bResult; +} + +/**Function************************************************************* + + Synopsis [Starts the resynthesis manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_ManCut_t * Abc_NtkManCutStart( int nNodeSizeMax, int nConeSizeMax, int nNodeFanStop, int nConeFanStop ) +{ + Abc_ManCut_t * p; + p = ALLOC( Abc_ManCut_t, 1 ); + memset( p, 0, sizeof(Abc_ManCut_t) ); + p->vNodeLeaves = Vec_PtrAlloc( 100 ); + p->vConeLeaves = Vec_PtrAlloc( 100 ); + p->vVisited = Vec_PtrAlloc( 100 ); + p->vLevels = Vec_VecAlloc( 100 ); + p->vNodesTfo = Vec_PtrAlloc( 100 ); + p->nNodeSizeMax = nNodeSizeMax; + p->nConeSizeMax = nConeSizeMax; + p->nNodeFanStop = nNodeFanStop; + p->nConeFanStop = nConeFanStop; + return p; +} + +/**Function************************************************************* + + Synopsis [Stops the resynthesis manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkManCutStop( Abc_ManCut_t * p ) +{ + Vec_PtrFree( p->vNodeLeaves ); + Vec_PtrFree( p->vConeLeaves ); + Vec_PtrFree( p->vVisited ); + Vec_VecFree( p->vLevels ); + Vec_PtrFree( p->vNodesTfo ); + free( p ); +} + +/**Function************************************************************* + + Synopsis [Returns the leaves of the cone.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Abc_NtkManCutReadCutLarge( Abc_ManCut_t * p ) +{ + return p->vConeLeaves; +} + +/**Function************************************************************* + + Synopsis [Returns the leaves of the cone.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Abc_NtkManCutReadVisited( Abc_ManCut_t * p ) +{ + return p->vVisited; +} + + + +/**Function************************************************************* + + Synopsis [Collects the TFO of the cut in the topological order.] + + Description [TFO of the cut is defined as a set of nodes, for which the cut + is a cut, that is, every path from the collected nodes to the CIs goes through + a node in the cut. The nodes are collected if their level does not exceed + the given number (LevelMax). The nodes are returned in the topological order. + If the root node is given, its MFFC is marked, so that the collected nodes + do not contain any nodes in the MFFC.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Abc_NodeCollectTfoCands( Abc_ManCut_t * p, Abc_Obj_t * pRoot, Vec_Ptr_t * vLeaves, int LevelMax ) +{ + Abc_Ntk_t * pNtk = pRoot->pNtk; + Vec_Ptr_t * vVec; + Abc_Obj_t * pNode, * pFanout; + int i, k, v, LevelMin; + assert( Abc_NtkIsStrash(pNtk) ); + + // assuming that the structure is clean + Vec_VecForEachLevel( p->vLevels, vVec, i ) + assert( vVec->nSize == 0 ); + + // put fanins into the structure while labeling them + Abc_NtkIncrementTravId( pNtk ); + LevelMin = -1; + Vec_PtrForEachEntry( vLeaves, pNode, i ) + { + if ( pNode->Level > (unsigned)LevelMax ) + continue; + Abc_NodeSetTravIdCurrent( pNode ); + Vec_VecPush( p->vLevels, pNode->Level, pNode ); + if ( LevelMin < (int)pNode->Level ) + LevelMin = pNode->Level; + } + assert( LevelMin >= 0 ); + + // mark MFFC + if ( pRoot ) + Abc_NodeMffcLabel( pRoot ); + + // go through the levels up + Vec_PtrClear( p->vNodesTfo ); + Vec_VecForEachEntryStart( p->vLevels, pNode, i, k, LevelMin ) + { + if ( i > LevelMax ) + break; + // if the node is not marked, it is not a fanin + if ( !Abc_NodeIsTravIdCurrent(pNode) ) + { + // check if it belongs to the TFO + if ( !Abc_NodeIsTravIdCurrent(Abc_ObjFanin0(pNode)) || + !Abc_NodeIsTravIdCurrent(Abc_ObjFanin1(pNode)) ) + continue; + // save the node in the TFO and label it + Vec_PtrPush( p->vNodesTfo, pNode ); + Abc_NodeSetTravIdCurrent( pNode ); + } + // go through the fanouts and add them to the structure if they meet the conditions + Abc_ObjForEachFanout( pNode, pFanout, v ) + { + // skip if fanout is a CO or its level exceeds + if ( Abc_ObjIsCo(pFanout) || pFanout->Level > (unsigned)LevelMax ) + continue; + // skip if it is already added or if it is in MFFC + if ( Abc_NodeIsTravIdCurrent(pFanout) ) + continue; + // add it to the structure but do not mark it (until tested later) + Vec_VecPushUnique( p->vLevels, pFanout->Level, pFanout ); + } + } + + // clear the levelized structure + Vec_VecForEachLevelStart( p->vLevels, vVec, i, LevelMin ) + { + if ( i > LevelMax ) + break; + Vec_PtrClear( vVec ); + } + return p->vNodesTfo; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/base/abci/abcRefactor.c b/src/base/abci/abcRefactor.c new file mode 100644 index 00000000..791d2d53 --- /dev/null +++ b/src/base/abci/abcRefactor.c @@ -0,0 +1,354 @@ +/**CFile**************************************************************** + + FileName [abcResRef.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Network and node package.] + + Synopsis [Resynthesis based on refactoring.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: abcResRef.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abc.h" +#include "dec.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Abc_ManRef_t_ Abc_ManRef_t; +struct Abc_ManRef_t_ +{ + // user specified parameters + int nNodeSizeMax; // the limit on the size of the supernode + int nConeSizeMax; // the limit on the size of the containing cone + int fVerbose; // the verbosity flag + // internal data structures + DdManager * dd; // the BDD manager + Vec_Str_t * vCube; // temporary + Vec_Int_t * vForm; // temporary + Vec_Ptr_t * vVisited; // temporary + Vec_Ptr_t * vLeaves; // temporary + // node statistics + int nLastGain; + int nNodesConsidered; + int nNodesRefactored; + int nNodesGained; + // runtime statistics + int timeCut; + int timeBdd; + int timeDcs; + int timeSop; + int timeFact; + int timeEval; + int timeRes; + int timeNtk; + int timeTotal; +}; + +static void Abc_NtkManRefPrintStats( Abc_ManRef_t * p ); +static Abc_ManRef_t * Abc_NtkManRefStart( int nNodeSizeMax, int nConeSizeMax, bool fUseDcs, bool fVerbose ); +static void Abc_NtkManRefStop( Abc_ManRef_t * p ); +static Dec_Graph_t * Abc_NodeRefactor( Abc_ManRef_t * p, Abc_Obj_t * pNode, Vec_Ptr_t * vFanins, bool fUseZeros, bool fUseDcs, bool fVerbose ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Performs incremental resynthesis of the AIG.] + + Description [Starting from each node, computes a reconvergence-driven cut, + derives BDD of the cut function, constructs ISOP, factors the ISOP, + and replaces the current implementation of the MFFC of the node by the + new factored form, if the number of AIG nodes is reduced and the total + number of levels of the AIG network is not increated. Returns the + number of AIG nodes saved.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NtkRefactor( Abc_Ntk_t * pNtk, int nNodeSizeMax, int nConeSizeMax, bool fUseZeros, bool fUseDcs, bool fVerbose ) +{ + int fCheck = 1; + ProgressBar * pProgress; + Abc_ManRef_t * pManRef; + Abc_ManCut_t * pManCut; + Dec_Graph_t * pFForm; + Vec_Ptr_t * vFanins; + Abc_Obj_t * pNode; + int clk, clkStart = clock(); + int i, nNodes; + + assert( Abc_NtkIsStrash(pNtk) ); + // cleanup the AIG + Abc_AigCleanup(pNtk->pManFunc); + // start the managers + pManCut = Abc_NtkManCutStart( nNodeSizeMax, nConeSizeMax, 2, 1000 ); + pManRef = Abc_NtkManRefStart( nNodeSizeMax, nConeSizeMax, fUseDcs, fVerbose ); + pManRef->vLeaves = Abc_NtkManCutReadCutLarge( pManCut ); + Abc_NtkStartReverseLevels( pNtk ); + + // resynthesize each node once + nNodes = Abc_NtkObjNumMax(pNtk); + pProgress = Extra_ProgressBarStart( stdout, nNodes ); + Abc_NtkForEachNode( pNtk, pNode, i ) + { + Extra_ProgressBarUpdate( pProgress, i, NULL ); + // skip the constant node + if ( Abc_NodeIsConst(pNode) ) + continue; + // stop if all nodes have been tried once + if ( i >= nNodes ) + break; + // compute a reconvergence-driven cut +clk = clock(); + vFanins = Abc_NodeFindCut( pManCut, pNode, fUseDcs ); +pManRef->timeCut += clock() - clk; + // evaluate this cut +clk = clock(); + pFForm = Abc_NodeRefactor( pManRef, pNode, vFanins, fUseZeros, fUseDcs, fVerbose ); +pManRef->timeRes += clock() - clk; + if ( pFForm == NULL ) + continue; + // acceptable replacement found, update the graph +clk = clock(); + Dec_GraphUpdateNetwork( pNode, pFForm, pManRef->nLastGain ); +pManRef->timeNtk += clock() - clk; + Dec_GraphFree( pFForm ); + } + Extra_ProgressBarStop( pProgress ); +pManRef->timeTotal = clock() - clkStart; + + // print statistics of the manager + if ( fVerbose ) + Abc_NtkManRefPrintStats( pManRef ); + // delete the managers + Abc_NtkManCutStop( pManCut ); + Abc_NtkManRefStop( pManRef ); + Abc_NtkStopReverseLevels( pNtk ); + // check + if ( fCheck && !Abc_NtkCheck( pNtk ) ) + { + printf( "Abc_NtkRefactor: The network check has failed.\n" ); + return 0; + } + return 1; +} + +/**Function************************************************************* + + Synopsis [Resynthesizes the node using refactoring.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Dec_Graph_t * Abc_NodeRefactor( Abc_ManRef_t * p, Abc_Obj_t * pNode, Vec_Ptr_t * vFanins, bool fUseZeros, bool fUseDcs, bool fVerbose ) +{ + int fVeryVerbose = 0; + Abc_Obj_t * pFanin; + Dec_Graph_t * pFForm; + DdNode * bNodeFunc; + int nNodesSaved, nNodesAdded, i, clk; + char * pSop; + + p->nNodesConsidered++; + + // get the function of the cut +clk = clock(); + bNodeFunc = Abc_NodeConeBdd( p->dd, p->dd->vars, pNode, vFanins, p->vVisited ); Cudd_Ref( bNodeFunc ); +p->timeBdd += clock() - clk; + + // if don't-care are used, transform the function into ISOP + if ( fUseDcs ) + { + DdNode * bNodeDc, * bNodeOn, * bNodeOnDc; + int nMints, nMintsDc; +clk = clock(); + // get the don't-cares + bNodeDc = Abc_NodeConeDcs( p->dd, p->dd->vars + vFanins->nSize, p->dd->vars, p->vLeaves, vFanins, p->vVisited ); Cudd_Ref( bNodeDc ); + nMints = (1 << vFanins->nSize); + nMintsDc = (int)Cudd_CountMinterm( p->dd, bNodeDc, vFanins->nSize ); +// printf( "Percentage of minterms = %5.2f.\n", 100.0 * nMintsDc / nMints ); + // get the ISF + bNodeOn = Cudd_bddAnd( p->dd, bNodeFunc, Cudd_Not(bNodeDc) ); Cudd_Ref( bNodeOn ); + bNodeOnDc = Cudd_bddOr ( p->dd, bNodeFunc, bNodeDc ); Cudd_Ref( bNodeOnDc ); + Cudd_RecursiveDeref( p->dd, bNodeFunc ); + Cudd_RecursiveDeref( p->dd, bNodeDc ); + // get the ISOP + bNodeFunc = Cudd_bddIsop( p->dd, bNodeOn, bNodeOnDc ); Cudd_Ref( bNodeFunc ); + Cudd_RecursiveDeref( p->dd, bNodeOn ); + Cudd_RecursiveDeref( p->dd, bNodeOnDc ); +p->timeDcs += clock() - clk; + } + + // always accept the case of constant node + if ( Cudd_IsConstant(bNodeFunc) ) + { + p->nLastGain = Abc_NodeMffcSize( pNode ); + p->nNodesGained += p->nLastGain; + p->nNodesRefactored++; + Cudd_RecursiveDeref( p->dd, bNodeFunc ); + if ( Cudd_IsComplement(bNodeFunc) ) + return Dec_GraphCreateConst0(); + return Dec_GraphCreateConst1(); + } + + // get the SOP of the cut +clk = clock(); + pSop = Abc_ConvertBddToSop( NULL, p->dd, bNodeFunc, bNodeFunc, vFanins->nSize, p->vCube, -1 ); +p->timeSop += clock() - clk; + + // get the factored form +clk = clock(); + pFForm = Dec_Factor( pSop ); + free( pSop ); +p->timeFact += clock() - clk; + + // mark the fanin boundary + // (can mark only essential fanins, belonging to bNodeFunc!) + Vec_PtrForEachEntry( vFanins, pFanin, i ) + pFanin->vFanouts.nSize++; + // label MFFC with current traversal ID + Abc_NtkIncrementTravId( pNode->pNtk ); + nNodesSaved = Abc_NodeMffcLabel( pNode ); + // unmark the fanin boundary and set the fanins as leaves in the form + Vec_PtrForEachEntry( vFanins, pFanin, i ) + { + pFanin->vFanouts.nSize--; + Dec_GraphNode(pFForm, i)->pFunc = pFanin; + } + + // detect how many new nodes will be added (while taking into account reused nodes) +clk = clock(); + nNodesAdded = Dec_GraphToNetworkCount( pNode, pFForm, nNodesSaved, Abc_NodeReadRequiredLevel(pNode) ); +p->timeEval += clock() - clk; + // quit if there is no improvement + if ( nNodesAdded == -1 || nNodesAdded == nNodesSaved && !fUseZeros ) + { + Cudd_RecursiveDeref( p->dd, bNodeFunc ); + Dec_GraphFree( pFForm ); + return NULL; + } + + // compute the total gain in the number of nodes + p->nLastGain = nNodesSaved - nNodesAdded; + p->nNodesGained += p->nLastGain; + p->nNodesRefactored++; + + // report the progress + if ( fVeryVerbose ) + { + printf( "Node %6s : ", Abc_ObjName(pNode) ); + printf( "Cone = %2d. ", vFanins->nSize ); + printf( "BDD = %2d. ", Cudd_DagSize(bNodeFunc) ); + printf( "FF = %2d. ", 1 + Dec_GraphNodeNum(pFForm) ); + printf( "MFFC = %2d. ", nNodesSaved ); + printf( "Add = %2d. ", nNodesAdded ); + printf( "GAIN = %2d. ", p->nLastGain ); + printf( "\n" ); + } + Cudd_RecursiveDeref( p->dd, bNodeFunc ); + return pFForm; +} + + +/**Function************************************************************* + + Synopsis [Starts the resynthesis manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_ManRef_t * Abc_NtkManRefStart( int nNodeSizeMax, int nConeSizeMax, bool fUseDcs, bool fVerbose ) +{ + Abc_ManRef_t * p; + p = ALLOC( Abc_ManRef_t, 1 ); + memset( p, 0, sizeof(Abc_ManRef_t) ); + p->vCube = Vec_StrAlloc( 100 ); + p->vVisited = Vec_PtrAlloc( 100 ); + p->nNodeSizeMax = nNodeSizeMax; + p->nConeSizeMax = nConeSizeMax; + p->fVerbose = fVerbose; + // start the BDD manager + if ( fUseDcs ) + p->dd = Cudd_Init( p->nNodeSizeMax + p->nConeSizeMax, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 ); + else + p->dd = Cudd_Init( p->nNodeSizeMax, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 ); + Cudd_zddVarsFromBddVars( p->dd, 2 ); + return p; +} + +/**Function************************************************************* + + Synopsis [Stops the resynthesis manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkManRefStop( Abc_ManRef_t * p ) +{ + Extra_StopManager( p->dd ); + Vec_PtrFree( p->vVisited ); + Vec_StrFree( p->vCube ); + free( p ); +} + +/**Function************************************************************* + + Synopsis [Stops the resynthesis manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkManRefPrintStats( Abc_ManRef_t * p ) +{ + printf( "Refactoring statistics:\n" ); + printf( "Nodes considered = %8d.\n", p->nNodesConsidered ); + printf( "Nodes refactored = %8d.\n", p->nNodesRefactored ); + printf( "Calculated gain = %8d.\n", p->nNodesGained ); + PRT( "Cuts ", p->timeCut ); + PRT( "Resynthesis", p->timeRes ); + PRT( " BDD ", p->timeBdd ); + PRT( " DCs ", p->timeDcs ); + PRT( " SOP ", p->timeSop ); + PRT( " FF ", p->timeFact ); + PRT( " Eval ", p->timeEval ); + PRT( "AIG update ", p->timeNtk ); + PRT( "TOTAL ", p->timeTotal ); +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/base/abci/abcRenode.c b/src/base/abci/abcRenode.c new file mode 100644 index 00000000..c77c0d70 --- /dev/null +++ b/src/base/abci/abcRenode.c @@ -0,0 +1,609 @@ +/**CFile**************************************************************** + + FileName [abcRenode.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Network and node package.] + + Synopsis [Procedures which transform an AIG into the network of nodes.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: abcRenode.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abc.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static void Abc_NtkRenodeInt( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ); +static Abc_Obj_t * Abc_NtkRenode_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNodeOld ); + +static DdNode * Abc_NtkRenodeDeriveBdd_rec( DdManager * dd, Abc_Obj_t * pNodeOld, Vec_Ptr_t * vFanins ); + +static void Abc_NtkRenodeSetBounds( Abc_Ntk_t * pNtk, int nThresh, int nFaninMax ); +static void Abc_NtkRenodeSetBoundsCnf( Abc_Ntk_t * pNtk ); +static void Abc_NtkRenodeSetBoundsMulti( Abc_Ntk_t * pNtk, int nThresh ); +static void Abc_NtkRenodeSetBoundsSimple( Abc_Ntk_t * pNtk ); +static void Abc_NtkRenodeCone( Abc_Obj_t * pNode, Vec_Ptr_t * vCone ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Transforms the AIG into nodes.] + + Description [Threhold is the max number of nodes duplicated at a node.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkRenode( Abc_Ntk_t * pNtk, int nThresh, int nFaninMax, int fCnf, int fMulti, int fSimple ) +{ + int fCheck = 1; + Abc_Ntk_t * pNtkNew; + + assert( Abc_NtkIsStrash(pNtk) ); + assert( nThresh >= 0 ); + assert( nFaninMax > 1 ); + + // print a warning about choice nodes + if ( Abc_NtkGetChoiceNum( pNtk ) ) + printf( "Warning: The choice nodes in the AIG are removed by renoding.\n" ); + + // define the boundary + if ( fCnf ) + Abc_NtkRenodeSetBoundsCnf( pNtk ); + else if ( fMulti ) + Abc_NtkRenodeSetBoundsMulti( pNtk, nThresh ); + else if ( fSimple ) + Abc_NtkRenodeSetBoundsSimple( pNtk ); + else + Abc_NtkRenodeSetBounds( pNtk, nThresh, nFaninMax ); + + // perform renoding for this boundary + pNtkNew = Abc_NtkStartFrom( pNtk, ABC_TYPE_LOGIC, ABC_FUNC_BDD ); + Abc_NtkRenodeInt( pNtk, pNtkNew ); + Abc_NtkFinalize( pNtk, pNtkNew ); + + // make the network minimum base + Abc_NtkMinimumBase( pNtkNew ); + + // fix the problem with complemented and duplicated CO edges + Abc_NtkLogicMakeSimpleCos( pNtkNew, 0 ); + + // report the number of CNF objects + if ( fCnf ) + { +// int nClauses = Abc_NtkGetClauseNum(pNtkNew) + 2*Abc_NtkPoNum(pNtkNew) + 2*Abc_NtkLatchNum(pNtkNew); +// printf( "CNF variables = %d. CNF clauses = %d.\n", Abc_NtkNodeNum(pNtkNew), nClauses ); + } +//printf( "Maximum fanin = %d.\n", Abc_NtkGetFaninMax(pNtkNew) ); + + // make sure everything is okay + if ( fCheck && !Abc_NtkCheck( pNtkNew ) ) + { + printf( "Abc_NtkRenode: The network check has failed.\n" ); + Abc_NtkDelete( pNtkNew ); + return NULL; + } + return pNtkNew; +} + +/**Function************************************************************* + + Synopsis [Transforms the AIG into nodes.] + + Description [Threhold is the max number of nodes duplicated at a node.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkRenodeInt( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ) +{ + ProgressBar * pProgress; + Abc_Obj_t * pNode, * pConst1, * pNodeNew; + int i; + + // set the constant node + pConst1 = Abc_AigConst1(pNtk->pManFunc); + if ( Abc_ObjFanoutNum(pConst1) > 0 ) + { + pNodeNew = Abc_NtkCreateNode( pNtkNew ); + pNodeNew->pData = Cudd_ReadOne( pNtkNew->pManFunc ); Cudd_Ref( pNodeNew->pData ); + pConst1->pCopy = pNodeNew; + } + + // perform renoding for POs + pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCoNum(pNtk) ); + Abc_NtkForEachCo( pNtk, pNode, i ) + { + Extra_ProgressBarUpdate( pProgress, i, NULL ); + if ( Abc_ObjIsCi(Abc_ObjFanin0(pNode)) ) + continue; + Abc_NtkRenode_rec( pNtkNew, Abc_ObjFanin0(pNode) ); + } + Extra_ProgressBarStop( pProgress ); + + // clean the boundaries and data field in the old network + Abc_NtkForEachObj( pNtk, pNode, i ) + { + pNode->fMarkA = 0; + pNode->pData = NULL; + } +} + +/**Function************************************************************* + + Synopsis [Find the best multi-input node rooted at the given node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Abc_NtkRenode_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNodeOld ) +{ + Vec_Ptr_t * vCone; + Abc_Obj_t * pNodeNew; + int i; + + assert( !Abc_ObjIsComplement(pNodeOld) ); + // return if the result if known + if ( pNodeOld->pCopy ) + return pNodeOld->pCopy; + assert( Abc_ObjIsNode(pNodeOld) ); + assert( !Abc_NodeIsConst(pNodeOld) ); + assert( pNodeOld->fMarkA ); + + // collect the renoding cone + vCone = Vec_PtrAlloc( 10 ); + Abc_NtkRenodeCone( pNodeOld, vCone ); + + // create a new node + pNodeNew = Abc_NtkCreateNode( pNtkNew ); + for ( i = 0; i < vCone->nSize; i++ ) + Abc_ObjAddFanin( pNodeNew, Abc_NtkRenode_rec(pNtkNew, vCone->pArray[i]) ); + + // derive the function of this node + pNodeNew->pData = Abc_NtkRenodeDeriveBdd( pNtkNew->pManFunc, pNodeOld, vCone ); + Cudd_Ref( pNodeNew->pData ); + Vec_PtrFree( vCone ); + + // remember the node + pNodeOld->pCopy = pNodeNew; + return pNodeOld->pCopy; +} + + +/**Function************************************************************* + + Synopsis [Derives the local BDD of the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +DdNode * Abc_NtkRenodeDeriveBdd( DdManager * dd, Abc_Obj_t * pNodeOld, Vec_Ptr_t * vFaninsOld ) +{ + Abc_Obj_t * pFaninOld; + DdNode * bFunc; + int i; + assert( !Abc_NodeIsConst(pNodeOld) ); + assert( Abc_ObjIsNode(pNodeOld) ); + // set the elementary BDD variables for the input nodes + for ( i = 0; i < vFaninsOld->nSize; i++ ) + { + pFaninOld = vFaninsOld->pArray[i]; + pFaninOld->pData = Cudd_bddIthVar( dd, i ); Cudd_Ref( pFaninOld->pData ); + pFaninOld->fMarkC = 1; + } + // call the recursive BDD computation + bFunc = Abc_NtkRenodeDeriveBdd_rec( dd, pNodeOld, vFaninsOld ); Cudd_Ref( bFunc ); + // dereference the intermediate nodes + for ( i = 0; i < vFaninsOld->nSize; i++ ) + { + pFaninOld = vFaninsOld->pArray[i]; + Cudd_RecursiveDeref( dd, pFaninOld->pData ); + pFaninOld->fMarkC = 0; + } + Cudd_Deref( bFunc ); + return bFunc; +} + +/**Function************************************************************* + + Synopsis [Derives the local BDD of the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +DdNode * Abc_NtkRenodeDeriveBdd_rec( DdManager * dd, Abc_Obj_t * pNode, Vec_Ptr_t * vFanins ) +{ + DdNode * bFunc, * bFunc0, * bFunc1; + assert( !Abc_ObjIsComplement(pNode) ); + // if the result is available return + if ( pNode->fMarkC ) + { + assert( pNode->pData ); // network has a cycle + return pNode->pData; + } + // mark the node as visited + pNode->fMarkC = 1; + Vec_PtrPush( vFanins, pNode ); + // compute the result for both branches + bFunc0 = Abc_NtkRenodeDeriveBdd_rec( dd, Abc_ObjFanin(pNode,0), vFanins ); Cudd_Ref( bFunc0 ); + bFunc1 = Abc_NtkRenodeDeriveBdd_rec( dd, Abc_ObjFanin(pNode,1), vFanins ); Cudd_Ref( bFunc1 ); + bFunc0 = Cudd_NotCond( bFunc0, Abc_ObjFaninC0(pNode) ); + bFunc1 = Cudd_NotCond( bFunc1, Abc_ObjFaninC1(pNode) ); + // get the final result + bFunc = Cudd_bddAnd( dd, bFunc0, bFunc1 ); Cudd_Ref( bFunc ); + Cudd_RecursiveDeref( dd, bFunc0 ); + Cudd_RecursiveDeref( dd, bFunc1 ); + // set the result + pNode->pData = bFunc; + assert( pNode->pData ); + return bFunc; +} + + + +/**Function************************************************************* + + Synopsis [Limits the cones to be no more than the given size.] + + Description [Returns 1 if the last cone was limited. Returns 0 if no changes.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NtkRenodeLimit_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vCone, int nFaninMax, int fCanStop, int fFirst ) +{ + int nNodes0, nNodes1; + assert( !Abc_ObjIsComplement(pNode) ); + // check if the node should be added to the fanins + if ( !fFirst && (pNode->fMarkA || !Abc_ObjIsNode(pNode)) ) + { + Vec_PtrPushUnique( vCone, pNode ); + return 0; + } + // if we cannot stop in this branch, collect all nodes + if ( !fCanStop ) + { + Abc_NtkRenodeLimit_rec( Abc_ObjFanin(pNode,0), vCone, nFaninMax, 0, 0 ); + Abc_NtkRenodeLimit_rec( Abc_ObjFanin(pNode,1), vCone, nFaninMax, 0, 0 ); + return 0; + } + // if we can stop, try the left branch first, and return if we stopped + assert( vCone->nSize == 0 ); + if ( Abc_NtkRenodeLimit_rec( Abc_ObjFanin(pNode,0), vCone, nFaninMax, 1, 0 ) ) + return 1; + // save the number of nodes in the left branch and call for the right branch + nNodes0 = vCone->nSize; + assert( nNodes0 <= nFaninMax ); + Abc_NtkRenodeLimit_rec( Abc_ObjFanin(pNode,1), vCone, nFaninMax, 0, 0 ); + // check the number of nodes + if ( vCone->nSize <= nFaninMax ) + return 0; + // the number of nodes exceeds the limit + + // get the number of nodes in the right branch + vCone->nSize = 0; + Abc_NtkRenodeLimit_rec( Abc_ObjFanin(pNode,1), vCone, nFaninMax, 0, 0 ); + // if this number exceeds the limit, solve the problem for this branch + if ( vCone->nSize > nFaninMax ) + { + int RetValue; + vCone->nSize = 0; + RetValue = Abc_NtkRenodeLimit_rec( Abc_ObjFanin(pNode,1), vCone, nFaninMax, 1, 0 ); + assert( RetValue == 1 ); + return 1; + } + + nNodes1 = vCone->nSize; + assert( nNodes1 <= nFaninMax ); + if ( nNodes0 >= nNodes1 ) + { // the left branch is larger - cut it + assert( Abc_ObjFanin(pNode,0)->fMarkA == 0 ); + Abc_ObjFanin(pNode,0)->fMarkA = 1; + } + else + { // the right branch is larger - cut it + assert( Abc_ObjFanin(pNode,1)->fMarkA == 0 ); + Abc_ObjFanin(pNode,1)->fMarkA = 1; + } + return 1; +} + +/**Function************************************************************* + + Synopsis [Limits the cones to be no more than the given size.] + + Description [Returns 1 if the last cone was limited. Returns 0 if no changes.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NtkRenodeLimit( Abc_Obj_t * pNode, Vec_Ptr_t * vCone, int nFaninMax ) +{ + vCone->nSize = 0; + return Abc_NtkRenodeLimit_rec( pNode, vCone, nFaninMax, 1, 1 ); +} + +/**Function************************************************************* + + Synopsis [Sets the expansion boundary for multi-input nodes.] + + Description [The boundary includes the set of PIs and all nodes such that + when expanding over the node we duplicate no more than nThresh nodes.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkRenodeSetBounds( Abc_Ntk_t * pNtk, int nThresh, int nFaninMax ) +{ + Vec_Ptr_t * vCone = pNtk->vPtrTemp; + Abc_Obj_t * pNode; + int i, nFanouts, nConeSize; + + // make sure the mark is not set + Abc_NtkForEachObj( pNtk, pNode, i ) + assert( pNode->fMarkA == 0 ); + + // mark the nodes where expansion stops using pNode->fMarkA + Abc_NtkForEachNode( pNtk, pNode, i ) + { + // skip PI/PO nodes + if ( Abc_NodeIsConst(pNode) ) + continue; + // mark the nodes with multiple fanouts + nFanouts = Abc_ObjFanoutNum(pNode); + nConeSize = Abc_NodeMffcSize(pNode); + if ( (nFanouts - 1) * nConeSize > nThresh ) + pNode->fMarkA = 1; + } + + // mark the PO drivers + Abc_NtkForEachCo( pNtk, pNode, i ) + Abc_ObjFanin0(pNode)->fMarkA = 1; + + // make sure the fanin limit is met + Abc_NtkForEachNode( pNtk, pNode, i ) + { + // skip PI/PO nodes + if ( Abc_NodeIsConst(pNode) ) + continue; + if ( pNode->fMarkA == 0 ) + continue; + // continue cutting branches ntil it meets the fanin limit + while ( Abc_NtkRenodeLimit(pNode, vCone, nFaninMax) ); + assert( vCone->nSize <= nFaninMax ); + } +/* + // make sure the fanin limit is met + Abc_NtkForEachNode( pNtk, pNode, i ) + { + // skip PI/PO nodes + if ( Abc_NodeIsConst(pNode) ) + continue; + if ( pNode->fMarkA == 0 ) + continue; + Abc_NtkRenodeCone( pNode, vCone ); + assert( vCone->nSize <= nFaninMax ); + } +*/ +} + +/**Function************************************************************* + + Synopsis [Sets the expansion boundary for conversion into CNF.] + + Description [The boundary includes the set of PIs, the roots of MUXes, + the nodes with multiple fanouts and the nodes with complemented outputs.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkRenodeSetBoundsCnf( Abc_Ntk_t * pNtk ) +{ + Abc_Obj_t * pNode; + int i, nMuxes; + + // make sure the mark is not set + Abc_NtkForEachObj( pNtk, pNode, i ) + assert( pNode->fMarkA == 0 ); + + // mark the nodes where expansion stops using pNode->fMarkA + Abc_NtkForEachNode( pNtk, pNode, i ) + { + // skip PI/PO nodes + if ( Abc_NodeIsConst(pNode) ) + continue; + // mark the nodes with multiple fanouts + if ( Abc_ObjFanoutNum(pNode) > 1 ) + pNode->fMarkA = 1; + // mark the nodes that are roots of MUXes + if ( Abc_NodeIsMuxType( pNode ) ) + { + pNode->fMarkA = 1; + Abc_ObjFanin0( Abc_ObjFanin0(pNode) )->fMarkA = 1; + Abc_ObjFanin0( Abc_ObjFanin1(pNode) )->fMarkA = 1; + Abc_ObjFanin1( Abc_ObjFanin0(pNode) )->fMarkA = 1; + Abc_ObjFanin1( Abc_ObjFanin1(pNode) )->fMarkA = 1; + } + else // mark the complemented edges + { + if ( Abc_ObjFaninC0(pNode) ) + Abc_ObjFanin0(pNode)->fMarkA = 1; + if ( Abc_ObjFaninC1(pNode) ) + Abc_ObjFanin1(pNode)->fMarkA = 1; + } + } + + // mark the PO drivers + Abc_NtkForEachCo( pNtk, pNode, i ) + Abc_ObjFanin0(pNode)->fMarkA = 1; + + // count the number of MUXes + nMuxes = 0; + Abc_NtkForEachNode( pNtk, pNode, i ) + { + // skip PI/PO nodes + if ( Abc_NodeIsConst(pNode) ) + continue; + if ( Abc_NodeIsMuxType(pNode) && + Abc_ObjFanin0(pNode)->fMarkA == 0 && + Abc_ObjFanin1(pNode)->fMarkA == 0 ) + nMuxes++; + } + printf( "The number of MUXes detected = %d (%5.2f %% of logic).\n", nMuxes, 300.0*nMuxes/Abc_NtkNodeNum(pNtk) ); +} + +/**Function************************************************************* + + Synopsis [Sets the expansion boundary for conversion into multi-input AND graph.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkRenodeSetBoundsMulti( Abc_Ntk_t * pNtk, int nThresh ) +{ + Abc_Obj_t * pNode; + int i, nFanouts, nConeSize; + + // make sure the mark is not set + Abc_NtkForEachObj( pNtk, pNode, i ) + assert( pNode->fMarkA == 0 ); + + // mark the nodes where expansion stops using pNode->fMarkA + Abc_NtkForEachNode( pNtk, pNode, i ) + { + // skip PI/PO nodes + if ( Abc_NodeIsConst(pNode) ) + continue; + // mark the nodes with multiple fanouts +// if ( Abc_ObjFanoutNum(pNode) > 1 ) +// pNode->fMarkA = 1; + // mark the nodes with multiple fanouts + nFanouts = Abc_ObjFanoutNum(pNode); + nConeSize = Abc_NodeMffcSizeStop(pNode); + if ( (nFanouts - 1) * nConeSize > nThresh ) + pNode->fMarkA = 1; + // mark the children if they are pointed by the complemented edges + if ( Abc_ObjFaninC0(pNode) ) + Abc_ObjFanin0(pNode)->fMarkA = 1; + if ( Abc_ObjFaninC1(pNode) ) + Abc_ObjFanin1(pNode)->fMarkA = 1; + } + + // mark the PO drivers + Abc_NtkForEachCo( pNtk, pNode, i ) + Abc_ObjFanin0(pNode)->fMarkA = 1; +} + +/**Function************************************************************* + + Synopsis [Sets a simple boundary.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkRenodeSetBoundsSimple( Abc_Ntk_t * pNtk ) +{ + Abc_Obj_t * pNode; + int i; + // make sure the mark is not set + Abc_NtkForEachObj( pNtk, pNode, i ) + assert( pNode->fMarkA == 0 ); + // mark the nodes where expansion stops using pNode->fMarkA + Abc_NtkForEachNode( pNtk, pNode, i ) + pNode->fMarkA = 1; +} + +/**Function************************************************************* + + Synopsis [Collects the fanins of a large node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkRenodeCone_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vCone ) +{ + assert( !Abc_ObjIsComplement(pNode) ); + if ( pNode->fMarkA || !Abc_ObjIsNode(pNode) ) + { + Vec_PtrPushUnique( vCone, pNode ); + return; + } + Abc_NtkRenodeCone_rec( Abc_ObjFanin(pNode,0), vCone ); + Abc_NtkRenodeCone_rec( Abc_ObjFanin(pNode,1), vCone ); +} + +/**Function************************************************************* + + Synopsis [Collects the fanins of a large node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkRenodeCone( Abc_Obj_t * pNode, Vec_Ptr_t * vCone ) +{ + assert( !Abc_ObjIsComplement(pNode) ); + assert( Abc_ObjIsNode(pNode) ); + vCone->nSize = 0; + Abc_NtkRenodeCone_rec( Abc_ObjFanin(pNode,0), vCone ); + Abc_NtkRenodeCone_rec( Abc_ObjFanin(pNode,1), vCone ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/base/abci/abcRewrite.c b/src/base/abci/abcRewrite.c new file mode 100644 index 00000000..75fe1627 --- /dev/null +++ b/src/base/abci/abcRewrite.c @@ -0,0 +1,184 @@ +/**CFile**************************************************************** + + FileName [abcRes.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Network and node package.] + + Synopsis [Technology-independent resynthesis of the AIG.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: abcRes.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abc.h" +#include "rwr.h" +#include "dec.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static Cut_Man_t * Abc_NtkStartCutManForRewrite( Abc_Ntk_t * pNtk, int fDrop ); +static void Abc_NodePrintCuts( Abc_Obj_t * pNode ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Performs incremental rewriting of the AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NtkRewrite( Abc_Ntk_t * pNtk, int fUseZeros, int fVerbose ) +{ + int fCheck = 1; + int fDrop = 0; + ProgressBar * pProgress; + Cut_Man_t * pManCut; + Rwr_Man_t * pManRwr; + Abc_Obj_t * pNode; + int i, nNodes, nGain; + int clk, clkStart = clock(); + + assert( Abc_NtkIsStrash(pNtk) ); + // cleanup the AIG + Abc_AigCleanup(pNtk->pManFunc); + // start the rewriting manager + pManRwr = Rwr_ManStart( 0 ); + if ( pManRwr == NULL ) + return 0; + Abc_NtkStartReverseLevels( pNtk ); + // start the cut manager +clk = clock(); + pManCut = Abc_NtkStartCutManForRewrite( pNtk, fDrop ); +Rwr_ManAddTimeCuts( pManRwr, clock() - clk ); + pNtk->pManCut = pManCut; + + // resynthesize each node once + nNodes = Abc_NtkObjNumMax(pNtk); + pProgress = Extra_ProgressBarStart( stdout, nNodes ); + Abc_NtkForEachNode( pNtk, pNode, i ) + { + Extra_ProgressBarUpdate( pProgress, i, NULL ); + // stop if all nodes have been tried once + if ( i >= nNodes ) + break; + // skip the constant node + if ( Abc_NodeIsConst(pNode) ) + continue; + // for each cut, try to resynthesize it + nGain = Rwr_NodeRewrite( pManRwr, pManCut, pNode, fUseZeros ); + if ( nGain > 0 || nGain == 0 && fUseZeros ) + { + Dec_Graph_t * pGraph = Rwr_ManReadDecs(pManRwr); + int fCompl = Rwr_ManReadCompl(pManRwr); + // complement the FF if needed + if ( fCompl ) Dec_GraphComplement( pGraph ); + Dec_GraphUpdateNetwork( pNode, pGraph, nGain ); + if ( fCompl ) Dec_GraphComplement( pGraph ); + } + } + Extra_ProgressBarStop( pProgress ); +Rwr_ManAddTimeTotal( pManRwr, clock() - clkStart ); + // print stats + if ( fVerbose ) + Rwr_ManPrintStats( pManRwr ); + // delete the managers + Rwr_ManStop( pManRwr ); + Cut_ManStop( pManCut ); + pNtk->pManCut = NULL; + Abc_NtkStopReverseLevels( pNtk ); + // check + if ( fCheck && !Abc_NtkCheck( pNtk ) ) + { + printf( "Abc_NtkRewrite: The network check has failed.\n" ); + return 0; + } + return 1; +} + + +/**Function************************************************************* + + Synopsis [Starts the cut manager for rewriting.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Cut_Man_t * Abc_NtkStartCutManForRewrite( Abc_Ntk_t * pNtk, int fDrop ) +{ + static Cut_Params_t Params, * pParams = &Params; + Cut_Man_t * pManCut; + Abc_Obj_t * pObj; + int i; + // start the cut manager + memset( pParams, 0, sizeof(Cut_Params_t) ); + pParams->nVarsMax = 4; // the max cut size ("k" of the k-feasible cuts) + pParams->nKeepMax = 250; // the max number of cuts kept at a node + pParams->fTruth = 1; // compute truth tables + pParams->fHash = 1; // hash cuts to detect unique + pParams->fFilter = 0; // filter dominated cuts + pParams->fSeq = 0; // compute sequential cuts + pParams->fDrop = fDrop; // drop cuts on the fly + pParams->fVerbose = 0; // the verbosiness flag + pParams->nIdsMax = Abc_NtkObjNumMax( pNtk ); + pManCut = Cut_ManStart( pParams ); + if ( pParams->fDrop ) + Cut_ManSetFanoutCounts( pManCut, Abc_NtkFanoutCounts(pNtk) ); + // set cuts for PIs + Abc_NtkForEachCi( pNtk, pObj, i ) + if ( Abc_ObjFanoutNum(pObj) > 0 ) + Cut_NodeSetTriv( pManCut, pObj->Id ); + return pManCut; +} + +/**Function************************************************************* + + Synopsis [Prints the cuts at the nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NodePrintCuts( Abc_Obj_t * pNode ) +{ + Cut_Cut_t * pCut; + unsigned uTruth; + printf( "\nNode %s\n", Abc_ObjName(pNode) ); + for ( pCut = (Cut_Cut_t *)pNode->pCopy; pCut; pCut = pCut->pNext ) + { + uTruth = pCut->uTruth; + Extra_PrintBinary( stdout, &uTruth, 16 ); + printf( " " ); + Cut_CutPrint( pCut ); + printf( "\n" ); + } +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/base/abci/abcSat.c b/src/base/abci/abcSat.c new file mode 100644 index 00000000..4fb059e5 --- /dev/null +++ b/src/base/abci/abcSat.c @@ -0,0 +1,252 @@ +/**CFile**************************************************************** + + FileName [abcSat.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Network and node package.] + + Synopsis [Procedures to solve the miter using the internal SAT solver.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: abcSat.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abc.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static void Abc_NodeAddClauses( solver * pSat, char * pSop0, char * pSop1, Abc_Obj_t * pNode, Vec_Int_t * vVars ); +static void Abc_NodeAddClausesTop( solver * pSat, Abc_Obj_t * pNode, Vec_Int_t * vVars ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Attempts to solve the miter using an internal SAT solver.] + + Description [Returns 1 if the miter is SAT.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +bool Abc_NtkMiterSat( Abc_Ntk_t * pNtk, int fVerbose ) +{ + solver * pSat; + lbool status; + int clk; + + assert( Abc_NtkIsBddLogic(pNtk) ); + assert( Abc_NtkLatchNum(pNtk) == 0 ); + + if ( Abc_NtkPoNum(pNtk) > 1 ) + fprintf( stdout, "Warning: The miter has more than 1 output. SAT will try to prove all of them.\n" ); + + // load clauses into the solver + clk = clock(); + pSat = Abc_NtkMiterSatCreate( pNtk ); +// printf( "Created SAT problem with %d variable and %d clauses. ", +// solver_nvars(pSat), solver_nclauses(pSat) ); +// PRT( "Time", clock() - clk ); + + // simplify the problem + clk = clock(); + status = solver_simplify(pSat); +// printf( "Simplified the problem to %d variables and %d clauses. ", +// solver_nvars(pSat), solver_nclauses(pSat) ); +// PRT( "Time", clock() - clk ); + if ( status == l_False ) + { + solver_delete( pSat ); + printf( "The problem is UNSAT after simplification.\n" ); + return 0; + } + + // solve the miter + clk = clock(); + if ( fVerbose ) + pSat->verbosity = 1; + status = solver_solve( pSat, NULL, NULL ); +// if ( fVerbose ) +// { + printf( "The problem is %5s. ", (status == l_True)? "SAT" : "UNSAT" ); + PRT( "SAT solver time", clock() - clk ); +// } + // free the solver + solver_delete( pSat ); + return status == l_True; +} + +/**Function************************************************************* + + Synopsis [Sets up the SAT solver.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +solver * Abc_NtkMiterSatCreate( Abc_Ntk_t * pNtk ) +{ + solver * pSat; + Extra_MmFlex_t * pMmFlex; + Abc_Obj_t * pNode; + Vec_Str_t * vCube; + Vec_Int_t * vVars; + char * pSop0, * pSop1; + int i; + + assert( Abc_NtkIsBddLogic(pNtk) ); + + // start the data structures + pSat = solver_new(); + pMmFlex = Extra_MmFlexStart(); + vCube = Vec_StrAlloc( 100 ); + vVars = Vec_IntAlloc( 100 ); + + // add clauses for each internal nodes + Abc_NtkForEachNode( pNtk, pNode, i ) + { + // derive SOPs for both phases of the node + Abc_NodeBddToCnf( pNode, pMmFlex, vCube, &pSop0, &pSop1 ); + // add the clauses to the solver + Abc_NodeAddClauses( pSat, pSop0, pSop1, pNode, vVars ); + } + // add clauses for each PO + Abc_NtkForEachPo( pNtk, pNode, i ) + Abc_NodeAddClausesTop( pSat, pNode, vVars ); + + // delete + Vec_StrFree( vCube ); + Vec_IntFree( vVars ); + Extra_MmFlexStop( pMmFlex, 0 ); + return pSat; +} + +/**Function************************************************************* + + Synopsis [Adds clauses for the internal node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NodeAddClauses( solver * pSat, char * pSop0, char * pSop1, Abc_Obj_t * pNode, Vec_Int_t * vVars ) +{ + Abc_Obj_t * pFanin; + int i, c, nFanins; + char * pCube; + + nFanins = Abc_ObjFaninNum( pNode ); + assert( nFanins == Abc_SopGetVarNum( pSop0 ) ); + + // add clauses for the negative phase + for ( c = 0; ; c++ ) + { + // get the cube + pCube = pSop0 + c * (nFanins + 3); + if ( *pCube == 0 ) + break; + // add the clause + vVars->nSize = 0; + Abc_ObjForEachFanin( pNode, pFanin, i ) + { + if ( pCube[i] == '0' ) + Vec_IntPush( vVars, toLit(pFanin->Id) ); + else if ( pCube[i] == '1' ) + Vec_IntPush( vVars, neg(toLit(pFanin->Id)) ); + } + Vec_IntPush( vVars, neg(toLit(pNode->Id)) ); + solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize ); + } + + // add clauses for the positive phase + for ( c = 0; ; c++ ) + { + // get the cube + pCube = pSop1 + c * (nFanins + 3); + if ( *pCube == 0 ) + break; + // add the clause + vVars->nSize = 0; + Abc_ObjForEachFanin( pNode, pFanin, i ) + { + if ( pCube[i] == '0' ) + Vec_IntPush( vVars, toLit(pFanin->Id) ); + else if ( pCube[i] == '1' ) + Vec_IntPush( vVars, neg(toLit(pFanin->Id)) ); + } + Vec_IntPush( vVars, toLit(pNode->Id) ); + solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize ); + } +} + +/**Function************************************************************* + + Synopsis [Adds clauses for the PO node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NodeAddClausesTop( solver * pSat, Abc_Obj_t * pNode, Vec_Int_t * vVars ) +{ + Abc_Obj_t * pFanin; + + pFanin = Abc_ObjFanin0(pNode); + if ( Abc_ObjFaninC0(pNode) ) + { + vVars->nSize = 0; + Vec_IntPush( vVars, toLit(pFanin->Id) ); + Vec_IntPush( vVars, toLit(pNode->Id) ); + solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize ); + + vVars->nSize = 0; + Vec_IntPush( vVars, neg(toLit(pFanin->Id)) ); + Vec_IntPush( vVars, neg(toLit(pNode->Id)) ); + solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize ); + } + else + { + vVars->nSize = 0; + Vec_IntPush( vVars, neg(toLit(pFanin->Id)) ); + Vec_IntPush( vVars, toLit(pNode->Id) ); + solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize ); + + vVars->nSize = 0; + Vec_IntPush( vVars, toLit(pFanin->Id) ); + Vec_IntPush( vVars, neg(toLit(pNode->Id)) ); + solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize ); + } + + vVars->nSize = 0; + Vec_IntPush( vVars, toLit(pNode->Id) ); + solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize ); +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/base/abci/abcStrash.c b/src/base/abci/abcStrash.c new file mode 100644 index 00000000..935f1300 --- /dev/null +++ b/src/base/abci/abcStrash.c @@ -0,0 +1,287 @@ +/**CFile**************************************************************** + + FileName [aigStrash.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Network and node package.] + + Synopsis [Strashing of the current network.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: aigStrash.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abc.h" +#include "extra.h" +#include "dec.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +// static functions +static void Abc_NtkStrashPerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkAig, bool fAllNodes ); +static Abc_Obj_t * Abc_NodeStrashSop( Abc_Aig_t * pMan, Abc_Obj_t * pNode, char * pSop ); +static Abc_Obj_t * Abc_NodeStrashFactor( Abc_Aig_t * pMan, Abc_Obj_t * pNode, char * pSop ); + +extern char * Mio_GateReadSop( void * pGate ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Creates the strashed AIG network.] + + Description [Converts the logic network or the AIG into a + structurally hashed AIG.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkStrash( Abc_Ntk_t * pNtk, bool fAllNodes, bool fCleanup ) +{ + int fCheck = 1; + Abc_Ntk_t * pNtkAig; + int nNodes; + + assert( !Abc_NtkIsNetlist(pNtk) ); + if ( Abc_NtkIsBddLogic(pNtk) ) + Abc_NtkBddToSop(pNtk); + // print warning about choice nodes + if ( Abc_NtkGetChoiceNum( pNtk ) ) + printf( "Warning: The choice nodes in the initial AIG are removed by strashing.\n" ); + // perform strashing + pNtkAig = Abc_NtkStartFrom( pNtk, ABC_TYPE_STRASH, ABC_FUNC_AIG ); + Abc_NtkStrashPerform( pNtk, pNtkAig, fAllNodes ); + Abc_NtkFinalize( pNtk, pNtkAig ); + // print warning about self-feed latches + if ( Abc_NtkCountSelfFeedLatches(pNtkAig) ) + printf( "The network has %d self-feeding latches.\n", Abc_NtkCountSelfFeedLatches(pNtkAig) ); + if ( fCleanup && (nNodes = Abc_AigCleanup(pNtkAig->pManFunc)) ) + printf( "Cleanup has removed %d nodes.\n", nNodes ); + // duplicate EXDC + if ( pNtk->pExdc ) + pNtkAig->pExdc = Abc_NtkStrash( pNtk->pExdc, 0, 1 ); + // make sure everything is okay + if ( fCheck && !Abc_NtkCheck( pNtkAig ) ) + { + printf( "Abc_NtkStrash: The network check has failed.\n" ); + Abc_NtkDelete( pNtkAig ); + return NULL; + } + return pNtkAig; +} + +/**Function************************************************************* + + Synopsis [Appends the second network to the first.] + + Description [Modifies the first network by adding the logic of the second. + Performs structural hashing while appending the networks. Does not add + the COs of the second. Does not change the second network. Returns 0 + if the appending failed, 1 otherise.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NtkAppend( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2 ) +{ + int fCheck = 1; + Abc_Obj_t * pObj; + int i; + // the first network should be an AIG + assert( Abc_NtkIsStrash(pNtk1) ); + assert( Abc_NtkIsLogic(pNtk2) || Abc_NtkIsStrash(pNtk2) ); + if ( Abc_NtkIsBddLogic(pNtk2) ) + Abc_NtkBddToSop(pNtk2); + // check that the networks have the same PIs + // reorder PIs of pNtk2 according to pNtk1 + if ( !Abc_NtkCompareSignals( pNtk1, pNtk2, 1 ) ) + return 0; + // perform strashing + Abc_NtkCleanCopy( pNtk2 ); + Abc_NtkForEachCi( pNtk2, pObj, i ) + pObj->pCopy = Abc_NtkCi(pNtk1, i); + // add pNtk2 to pNtk1 while strashing + Abc_NtkStrashPerform( pNtk2, pNtk1, 1 ); + // make sure that everything is okay + if ( fCheck && !Abc_NtkCheck( pNtk1 ) ) + { + printf( "Abc_NtkAppend: The network check has failed.\n" ); + return 0; + } + return 1; +} + + +/**Function************************************************************* + + Synopsis [Prepares the network for strashing.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkStrashPerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew, bool fAllNodes ) +{ + ProgressBar * pProgress; + Abc_Aig_t * pMan = pNtkNew->pManFunc; + Vec_Ptr_t * vNodes; + Abc_Obj_t * pNode, * pNodeNew, * pObj; + int i; + + // perform strashing + vNodes = Abc_NtkDfs( pNtk, fAllNodes ); + pProgress = Extra_ProgressBarStart( stdout, vNodes->nSize ); + Vec_PtrForEachEntry( vNodes, pNode, i ) + { + Extra_ProgressBarUpdate( pProgress, i, NULL ); + // get the node + assert( Abc_ObjIsNode(pNode) ); + // strash the node + pNodeNew = Abc_NodeStrash( pMan, pNode ); + // get the old object + pObj = Abc_ObjFanout0Ntk( pNode ); + // make sure the node is not yet strashed + assert( pObj->pCopy == NULL ); + // mark the old object with the new AIG node + pObj->pCopy = pNodeNew; + } + Vec_PtrFree( vNodes ); + Extra_ProgressBarStop( pProgress ); +} + +/**Function************************************************************* + + Synopsis [Strashes one logic node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Abc_NodeStrash( Abc_Aig_t * pMan, Abc_Obj_t * pNode ) +{ + int fUseFactor = 1; + char * pSop; + + assert( Abc_ObjIsNode(pNode) ); + + // consider the case when the graph is an AIG + if ( Abc_NtkIsStrash(pNode->pNtk) ) + { + if ( Abc_NodeIsConst(pNode) ) + return Abc_AigConst1(pMan); + return Abc_AigAnd( pMan, Abc_ObjChild0Copy(pNode), Abc_ObjChild1Copy(pNode) ); + } + + // get the SOP of the node + if ( Abc_NtkHasMapping(pNode->pNtk) ) + pSop = Mio_GateReadSop(pNode->pData); + else + pSop = pNode->pData; + + // consider the constant node + if ( Abc_NodeIsConst(pNode) ) + return Abc_ObjNotCond( Abc_AigConst1(pMan), Abc_SopIsConst0(pSop) ); + + // decide when to use factoring + if ( fUseFactor && Abc_ObjFaninNum(pNode) > 2 && Abc_SopGetCubeNum(pSop) > 1 ) + return Abc_NodeStrashFactor( pMan, pNode, pSop ); + return Abc_NodeStrashSop( pMan, pNode, pSop ); +} + +/**Function************************************************************* + + Synopsis [Strashes one logic node using its SOP.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Abc_NodeStrashSop( Abc_Aig_t * pMan, Abc_Obj_t * pNode, char * pSop ) +{ + Abc_Obj_t * pFanin, * pAnd, * pSum; + Abc_Obj_t * pConst1 = Abc_AigConst1(pMan); + char * pCube; + int i, nFanins; + + // get the number of node's fanins + nFanins = Abc_ObjFaninNum( pNode ); + assert( nFanins == Abc_SopGetVarNum(pSop) ); + // go through the cubes of the node's SOP + pSum = Abc_ObjNot(pConst1); + Abc_SopForEachCube( pSop, nFanins, pCube ) + { + // create the AND of literals + pAnd = pConst1; + Abc_ObjForEachFanin( pNode, pFanin, i ) // pFanin can be a net + { + if ( pCube[i] == '1' ) + pAnd = Abc_AigAnd( pMan, pAnd, pFanin->pCopy ); + else if ( pCube[i] == '0' ) + pAnd = Abc_AigAnd( pMan, pAnd, Abc_ObjNot(pFanin->pCopy) ); + } + // add to the sum of cubes + pSum = Abc_AigOr( pMan, pSum, pAnd ); + } + // decide whether to complement the result + if ( Abc_SopIsComplement(pSop) ) + pSum = Abc_ObjNot(pSum); + return pSum; +} + +/**Function************************************************************* + + Synopsis [Strashes one logic node using its SOP.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Abc_NodeStrashFactor( Abc_Aig_t * pMan, Abc_Obj_t * pRoot, char * pSop ) +{ + Dec_Graph_t * pFForm; + Dec_Node_t * pNode; + Abc_Obj_t * pAnd; + int i; + // perform factoring + pFForm = Dec_Factor( pSop ); + // collect the fanins + Dec_GraphForEachLeaf( pFForm, pNode, i ) + pNode->pFunc = Abc_ObjFanin(pRoot,i)->pCopy; + // perform strashing + pAnd = Dec_GraphToNetwork( pMan, pFForm ); + Dec_GraphFree( pFForm ); + return pAnd; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/base/abci/abcSweep.c b/src/base/abci/abcSweep.c new file mode 100644 index 00000000..ca9bd34e --- /dev/null +++ b/src/base/abci/abcSweep.c @@ -0,0 +1,607 @@ +/**CFile**************************************************************** + + FileName [abcDsd.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Network and node package.] + + Synopsis [Technology dependent sweep.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: abcDsd.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abc.h" +#include "fraig.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +extern Fraig_Man_t * Abc_NtkToFraig( Abc_Ntk_t * pNtk, Fraig_Params_t * pParams, int fAllNodes ); + +static stmm_table * Abc_NtkFraigEquiv( Fraig_Man_t * p, Abc_Ntk_t * pNtk, int fUseInv, bool fVerbose ); +static void Abc_NtkFraigTransform( Abc_Ntk_t * pNtk, stmm_table * tEquiv, int fUseInv, bool fVerbose ); +static void Abc_NtkFraigMergeClassMapped( Abc_Ntk_t * pNtk, Abc_Obj_t * pChain, int fVerbose, int fUseInv ); +static void Abc_NtkFraigMergeClass( Abc_Ntk_t * pNtk, Abc_Obj_t * pChain, int fVerbose, int fUseInv ); +static int Abc_NodeDroppingCost( Abc_Obj_t * pNode ); + +static void Abc_NodeSweep( Abc_Obj_t * pNode, int fVerbose ); +static void Abc_NodeConstantInput( Abc_Obj_t * pNode, Abc_Obj_t * pFanin, bool fConst0 ); +static void Abc_NodeComplementInput( Abc_Obj_t * pNode, Abc_Obj_t * pFanin ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Sweping functionally equivalence nodes.] + + Description [Removes gates with equivalent functionality. Works for + both technology-independent and mapped networks. If the flag is set, + allows adding inverters at the gate outputs.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +bool Abc_NtkFraigSweep( Abc_Ntk_t * pNtk, int fUseInv, int fVerbose ) +{ + int fCheck = 1; + Fraig_Params_t Params; + Abc_Ntk_t * pNtkAig; + Fraig_Man_t * pMan; + stmm_table * tEquiv; + + assert( !Abc_NtkIsStrash(pNtk) ); + + // derive the AIG + pNtkAig = Abc_NtkStrash( pNtk, 0, 1 ); + // perform fraiging of the AIG + Fraig_ParamsSetDefault( &Params ); + pMan = Abc_NtkToFraig( pNtkAig, &Params, 0 ); + // collect the classes of equivalent nets + tEquiv = Abc_NtkFraigEquiv( pMan, pNtk, fUseInv, fVerbose ); + + // transform the network into the equivalent one + Abc_NtkFraigTransform( pNtk, tEquiv, fUseInv, fVerbose ); + stmm_free_table( tEquiv ); + + // free the manager + Fraig_ManFree( pMan ); + Abc_NtkDelete( pNtkAig ); + + // cleanup the dangling nodes + Abc_NtkCleanup( pNtk, fVerbose ); + // check + if ( fCheck && !Abc_NtkCheck( pNtk ) ) + { + printf( "Abc_NtkFraigSweep: The network check has failed.\n" ); + return 0; + } + return 1; +} + +/**Function************************************************************* + + Synopsis [Collects equivalence classses of node in the network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +stmm_table * Abc_NtkFraigEquiv( Fraig_Man_t * p, Abc_Ntk_t * pNtk, int fUseInv, bool fVerbose ) +{ + Abc_Obj_t * pList, * pNode, * pNodeAig; + Fraig_Node_t * gNode; + Abc_Obj_t ** ppSlot; + stmm_table * tStrash2Net; + stmm_table * tResult; + stmm_generator * gen; + int c, Counter; + + // create mapping of strashed nodes into the corresponding network nodes + tStrash2Net = stmm_init_table(stmm_ptrcmp,stmm_ptrhash); + Abc_NtkForEachNode( pNtk, pNode, c ) + { + // get the strashed node + pNodeAig = pNode->pCopy; + // skip the dangling nodes + if ( pNodeAig == NULL ) + continue; + // skip the constant input nodes + if ( Abc_ObjFaninNum(pNode) == 0 ) + continue; + // skip the nodes that fanout into POs + if ( Abc_NodeHasUniqueCoFanout(pNode) ) + continue; + // get the FRAIG node + gNode = Fraig_NotCond( Abc_ObjRegular(pNodeAig)->pCopy, Abc_ObjIsComplement(pNodeAig) ); + if ( !stmm_find_or_add( tStrash2Net, (char *)Fraig_Regular(gNode), (char ***)&ppSlot ) ) + *ppSlot = NULL; + // add the node to the list + pNode->pNext = *ppSlot; + *ppSlot = pNode; + // mark the node if it is complemented + pNode->fPhase = Fraig_IsComplement(gNode); + } + + // print the classes + c = 0; + Counter = 0; + tResult = stmm_init_table(stmm_ptrcmp,stmm_ptrhash); + stmm_foreach_item( tStrash2Net, gen, (char **)&gNode, (char **)&pList ) + { + // skip the trival classes + if ( pList == NULL || pList->pNext == NULL ) + continue; + // add the non-trival class + stmm_insert( tResult, (char *)pList, NULL ); + // count nodes in the non-trival classes + for ( pNode = pList; pNode; pNode = pNode->pNext ) + Counter++; +/* + if ( fVerbose ) + { + printf( "Class %2d : {", c ); + for ( pNode = pList; pNode; pNode = pNode->pNext ) + { + pNode->pCopy = NULL; + printf( " %s", Abc_ObjName(pNode) ); + if ( pNode->fPhase ) printf( "(*)" ); + } + printf( " }\n" ); + c++; + } +*/ + } + if ( fVerbose ) + { + printf( "Sweeping stats for network \"%s\":\n", pNtk->pName ); + printf( "Internal nodes = %d. Different functions (up to compl) = %d.\n", Abc_NtkNodeNum(pNtk), stmm_count(tStrash2Net) ); + printf( "Non-trivial classes = %d. Nodes in non-trivial classes = %d.\n", stmm_count(tResult), Counter ); + } + stmm_free_table( tStrash2Net ); + return tResult; +} + + +/**Function************************************************************* + + Synopsis [Transforms the network using the equivalence relation on nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkFraigTransform( Abc_Ntk_t * pNtk, stmm_table * tEquiv, int fUseInv, bool fVerbose ) +{ + stmm_generator * gen; + Abc_Obj_t * pList; + if ( stmm_count(tEquiv) == 0 ) + return; + // assign levels to the nodes of the network + Abc_NtkGetLevelNum( pNtk ); + // merge nodes in the classes + if ( Abc_NtkHasMapping( pNtk ) ) + { + Abc_NtkDelayTrace( pNtk ); + stmm_foreach_item( tEquiv, gen, (char **)&pList, NULL ) + Abc_NtkFraigMergeClassMapped( pNtk, pList, fUseInv, fVerbose ); + } + else + { + stmm_foreach_item( tEquiv, gen, (char **)&pList, NULL ) + Abc_NtkFraigMergeClass( pNtk, pList, fUseInv, fVerbose ); + } +} + + +/**Function************************************************************* + + Synopsis [Transforms the list of one-phase equivalent nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkFraigMergeClassMapped( Abc_Ntk_t * pNtk, Abc_Obj_t * pChain, int fUseInv, int fVerbose ) +{ + Abc_Obj_t * pListDir, * pListInv; + Abc_Obj_t * pNodeMin, * pNode, * pNext; + float Arrival1, Arrival2; + + assert( pChain ); + assert( pChain->pNext ); + + // divide the nodes into two parts: + // those that need the invertor and those that don't need + pListDir = pListInv = NULL; + for ( pNode = pChain, pNext = pChain->pNext; + pNode; + pNode = pNext, pNext = pNode? pNode->pNext : NULL ) + { + // check to which class the node belongs + if ( pNode->fPhase == 1 ) + { + pNode->pNext = pListDir; + pListDir = pNode; + } + else + { + pNode->pNext = pListInv; + pListInv = pNode; + } + } + + // find the node with the smallest number of logic levels + pNodeMin = pListDir; + for ( pNode = pListDir; pNode; pNode = pNode->pNext ) + { + Arrival1 = Abc_NodeReadArrival(pNodeMin)->Worst; + Arrival2 = Abc_NodeReadArrival(pNode )->Worst; + assert( Abc_ObjIsCi(pNodeMin) || Arrival1 > 0 ); + assert( Abc_ObjIsCi(pNode) || Arrival2 > 0 ); + if ( Arrival1 > Arrival2 || + Arrival1 == Arrival2 && pNodeMin->Level > pNode->Level || + Arrival1 == Arrival2 && pNodeMin->Level == pNode->Level && + Abc_NodeDroppingCost(pNodeMin) < Abc_NodeDroppingCost(pNode) ) + pNodeMin = pNode; + } + + // move the fanouts of the direct nodes + for ( pNode = pListDir; pNode; pNode = pNode->pNext ) + if ( pNode != pNodeMin ) + Abc_ObjTransferFanout( pNode, pNodeMin ); + + // find the node with the smallest number of logic levels + pNodeMin = pListInv; + for ( pNode = pListInv; pNode; pNode = pNode->pNext ) + { + Arrival1 = Abc_NodeReadArrival(pNodeMin)->Worst; + Arrival2 = Abc_NodeReadArrival(pNode )->Worst; + assert( Abc_ObjIsCi(pNodeMin) || Arrival1 > 0 ); + assert( Abc_ObjIsCi(pNode) || Arrival2 > 0 ); + if ( Arrival1 > Arrival2 || + Arrival1 == Arrival2 && pNodeMin->Level > pNode->Level || + Arrival1 == Arrival2 && pNodeMin->Level == pNode->Level && + Abc_NodeDroppingCost(pNodeMin) < Abc_NodeDroppingCost(pNode) ) + pNodeMin = pNode; + } + + // move the fanouts of the direct nodes + for ( pNode = pListInv; pNode; pNode = pNode->pNext ) + if ( pNode != pNodeMin ) + Abc_ObjTransferFanout( pNode, pNodeMin ); +} + +/**Function************************************************************* + + Synopsis [Process one equivalence class of nodes.] + + Description [This function does not remove the nodes. It only switches + around the connections.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkFraigMergeClass( Abc_Ntk_t * pNtk, Abc_Obj_t * pChain, int fUseInv, int fVerbose ) +{ + Abc_Obj_t * pListDir, * pListInv; + Abc_Obj_t * pNodeMin, * pNodeMinInv; + Abc_Obj_t * pNode, * pNext; + + assert( pChain ); + assert( pChain->pNext ); + + // find the node with the smallest number of logic levels + pNodeMin = pChain; + for ( pNode = pChain->pNext; pNode; pNode = pNode->pNext ) + if ( pNodeMin->Level > pNode->Level || + ( pNodeMin->Level == pNode->Level && + Abc_NodeDroppingCost(pNodeMin) < Abc_NodeDroppingCost(pNode) ) ) + pNodeMin = pNode; + + // divide the nodes into two parts: + // those that need the invertor and those that don't need + pListDir = pListInv = NULL; + for ( pNode = pChain, pNext = pChain->pNext; + pNode; + pNode = pNext, pNext = pNode? pNode->pNext : NULL ) + { + if ( pNode == pNodeMin ) + continue; + // check to which class the node belongs + if ( pNodeMin->fPhase == pNode->fPhase ) + { + pNode->pNext = pListDir; + pListDir = pNode; + } + else + { + pNode->pNext = pListInv; + pListInv = pNode; + } + } + + // move the fanouts of the direct nodes + for ( pNode = pListDir; pNode; pNode = pNode->pNext ) + Abc_ObjTransferFanout( pNode, pNodeMin ); + + // skip if there are no inverted nodes + if ( pListInv == NULL ) + return; + + // add the invertor + pNodeMinInv = Abc_NodeCreateInv( pNtk, pNodeMin ); + + // move the fanouts of the inverted nodes + for ( pNode = pListInv; pNode; pNode = pNode->pNext ) + Abc_ObjTransferFanout( pNode, pNodeMinInv ); +} + + +/**Function************************************************************* + + Synopsis [Returns the number of literals saved if this node becomes useless.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NodeDroppingCost( Abc_Obj_t * pNode ) +{ + return 1; +} + + + + + +/**Function************************************************************* + + Synopsis [Removes dangling nodes.] + + Description [Returns the number of nodes removed.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NtkCleanup( Abc_Ntk_t * pNtk, int fVerbose ) +{ + int fCheck = 1; + Vec_Ptr_t * vNodes; + Abc_Obj_t * pNode; + int i, Counter; + // mark the nodes reachable from the POs + vNodes = Abc_NtkDfs( pNtk, 0 ); + for ( i = 0; i < vNodes->nSize; i++ ) + { + pNode = vNodes->pArray[i]; + pNode->fMarkA = 1; + } + Vec_PtrFree( vNodes ); + // if it is an AIG, also mark the constant 1 node + if ( Abc_NtkIsStrash(pNtk) ) + Abc_AigConst1(pNtk->pManFunc)->fMarkA = 1; + // remove the non-marked nodes + Counter = 0; + Abc_NtkForEachNode( pNtk, pNode, i ) + if ( pNode->fMarkA == 0 ) + { + Abc_NtkDeleteObj( pNode ); + Counter++; + } + // unmark the remaining nodes + Abc_NtkForEachNode( pNtk, pNode, i ) + pNode->fMarkA = 0; + if ( fVerbose ) + printf( "Cleanup removed %d dangling nodes.\n", Counter ); + // check + if ( fCheck && !Abc_NtkCheck( pNtk ) ) + { + printf( "Abc_NtkCleanup: The network check has failed.\n" ); + return -1; + } + return Counter; +} + + + + +/**Function************************************************************* + + Synopsis [Tranditional sweep of the network.] + + Description [Propagates constant and single-input node, removes dangling nodes.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NtkSweep( Abc_Ntk_t * pNtk, int fVerbose ) +{ + int fCheck = 1; + Abc_Obj_t * pNode; + int i, fConvert, nSwept, nSweptNew; + assert( Abc_NtkIsSopLogic(pNtk) || Abc_NtkIsBddLogic(pNtk) ); + // convert to the BDD representation + fConvert = 0; + if ( Abc_NtkIsSopLogic(pNtk) ) + Abc_NtkSopToBdd(pNtk), fConvert = 1; + // perform cleanup to get rid of dangling nodes + nSwept = Abc_NtkCleanup( pNtk, 0 ); + // make the network minimum base + Abc_NtkRemoveDupFanins(pNtk); + Abc_NtkMinimumBase(pNtk); + do + { + // sweep constants and single-input nodes + Abc_NtkForEachNode( pNtk, pNode, i ) + if ( Abc_ObjFaninNum(pNode) < 2 ) + Abc_NodeSweep( pNode, fVerbose ); + // make the network minimum base + Abc_NtkRemoveDupFanins(pNtk); + Abc_NtkMinimumBase(pNtk); + // perform final clean up (in case new danglies are created) + nSweptNew = Abc_NtkCleanup( pNtk, 0 ); + nSwept += nSweptNew; + } + while ( nSweptNew ); + // conver back to BDD + if ( fConvert ) + Abc_NtkBddToSop(pNtk); + // report + if ( fVerbose ) + printf( "Sweep removed %d nodes.\n", nSwept ); + // check + if ( fCheck && !Abc_NtkCheck( pNtk ) ) + { + printf( "Abc_NtkSweep: The network check has failed.\n" ); + return -1; + } + return nSwept; +} + +/**Function************************************************************* + + Synopsis [Tranditional sweep of the network.] + + Description [Propagates constant and single-input node, removes dangling nodes.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NodeSweep( Abc_Obj_t * pNode, int fVerbose ) +{ + Vec_Ptr_t * vFanout = pNode->pNtk->vPtrTemp; + Abc_Obj_t * pFanout, * pDriver; + int i; + assert( Abc_ObjFaninNum(pNode) < 2 ); + assert( Abc_ObjFanoutNum(pNode) > 0 ); + // iterate through the fanouts + Abc_NodeCollectFanouts( pNode, vFanout ); + Vec_PtrForEachEntry( vFanout, pFanout, i ) + { + if ( Abc_ObjIsCo(pFanout) ) + { + if ( Abc_ObjFaninNum(pNode) == 1 ) + { + pDriver = Abc_ObjFanin0(pNode); + if ( Abc_ObjIsCi(pDriver) || Abc_ObjFanoutNum(pDriver) > 1 || Abc_ObjFanoutNum(pNode) > 1 ) + continue; + // the driver is a node and its only fanout is this node + if ( Abc_NodeIsInv(pNode) ) + pDriver->pData = Cudd_Not(pDriver->pData); + // replace the fanin of the fanout + Abc_ObjPatchFanin( pFanout, pNode, pDriver ); + } + continue; + } + // the fanout is a regular node + if ( Abc_ObjFaninNum(pNode) == 0 ) + Abc_NodeConstantInput( pFanout, pNode, Abc_NodeIsConst0(pNode) ); + else + { + assert( Abc_ObjFaninNum(pNode) == 1 ); + pDriver = Abc_ObjFanin0(pNode); + if ( Abc_NodeIsInv(pNode) ) + Abc_NodeComplementInput( pFanout, pNode ); + Abc_ObjPatchFanin( pFanout, pNode, pDriver ); + } + } +} + +/**Function************************************************************* + + Synopsis [Replaces the local function by its cofactor.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NodeConstantInput( Abc_Obj_t * pNode, Abc_Obj_t * pFanin, bool fConst0 ) +{ + DdManager * dd = pNode->pNtk->pManFunc; + DdNode * bVar, * bTemp; + int iFanin; + assert( Abc_NtkIsBddLogic(pNode->pNtk) ); + if ( (iFanin = Vec_FanFindEntry( &pNode->vFanins, pFanin->Id )) == -1 ) + { + printf( "Node %s should be among", Abc_ObjName(pFanin) ); + printf( " the fanins of node %s...\n", Abc_ObjName(pNode) ); + return; + } + bVar = Cudd_NotCond( Cudd_bddIthVar(dd, iFanin), fConst0 ); + pNode->pData = Cudd_Cofactor( dd, bTemp = pNode->pData, bVar ); Cudd_Ref( pNode->pData ); + Cudd_RecursiveDeref( dd, bTemp ); +} + +/**Function************************************************************* + + Synopsis [Changes the polarity of one fanin.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NodeComplementInput( Abc_Obj_t * pNode, Abc_Obj_t * pFanin ) +{ + DdManager * dd = pNode->pNtk->pManFunc; + DdNode * bVar, * bCof0, * bCof1; + int iFanin; + assert( Abc_NtkIsBddLogic(pNode->pNtk) ); + if ( (iFanin = Vec_FanFindEntry( &pNode->vFanins, pFanin->Id )) == -1 ) + { + printf( "Node %s should be among", Abc_ObjName(pFanin) ); + printf( " the fanins of node %s...\n", Abc_ObjName(pNode) ); + return; + } + bVar = Cudd_bddIthVar( dd, iFanin ); + bCof0 = Cudd_Cofactor( dd, pNode->pData, Cudd_Not(bVar) ); Cudd_Ref( bCof0 ); + bCof1 = Cudd_Cofactor( dd, pNode->pData, bVar ); Cudd_Ref( bCof1 ); + Cudd_RecursiveDeref( dd, pNode->pData ); + pNode->pData = Cudd_bddIte( dd, bVar, bCof0, bCof1 ); Cudd_Ref( pNode->pData ); + Cudd_RecursiveDeref( dd, bCof0 ); + Cudd_RecursiveDeref( dd, bCof1 ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/base/abci/abcSymm.c b/src/base/abci/abcSymm.c new file mode 100644 index 00000000..f9229639 --- /dev/null +++ b/src/base/abci/abcSymm.c @@ -0,0 +1,221 @@ +/**CFile**************************************************************** + + FileName [abcSymm.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Network and node package.] + + Synopsis [Computation of two-variable symmetries.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: abcSymm.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abc.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static void Abc_NtkSymmetriesUsingBdds( Abc_Ntk_t * pNtk, int fNaive, int fVerbose ); +static void Abc_NtkSymmetriesUsingSandS( Abc_Ntk_t * pNtk, int fVerbose ); +static void Ntk_NetworkSymmsBdd( DdManager * dd, Abc_Ntk_t * pNtk, int fNaive, int fVerbose ); +static void Ntk_NetworkSymmsPrint( Abc_Ntk_t * pNtk, Extra_SymmInfo_t * pSymms ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [The top level procedure to compute symmetries.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkSymmetries( Abc_Ntk_t * pNtk, int fUseBdds, int fNaive, int fVerbose ) +{ + if ( fUseBdds || fNaive ) + Abc_NtkSymmetriesUsingBdds( pNtk, fNaive, fVerbose ); + else + Abc_NtkSymmetriesUsingSandS( pNtk, fVerbose ); +} + +/**Function************************************************************* + + Synopsis [Symmetry computation using simulation and SAT.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkSymmetriesUsingSandS( Abc_Ntk_t * pNtk, int fVerbose ) +{ + extern int Sim_ComputeTwoVarSymms( Abc_Ntk_t * pNtk ); + int nSymms = Sim_ComputeTwoVarSymms( pNtk ); + printf( "The total number of symmetries is %d.\n", nSymms ); +} + +/**Function************************************************************* + + Synopsis [Symmetry computation using BDDs (both naive and smart).] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkSymmetriesUsingBdds( Abc_Ntk_t * pNtk, int fNaive, int fVerbose ) +{ + DdManager * dd; + int clk, clkBdd, clkSym; + + // compute the global functions +clk = clock(); + dd = Abc_NtkGlobalBdds( pNtk, 0 ); + Cudd_AutodynDisable( dd ); + Cudd_zddVarsFromBddVars( dd, 2 ); +clkBdd = clock() - clk; + // create the collapsed network +clk = clock(); + Ntk_NetworkSymmsBdd( dd, pNtk, fNaive, fVerbose ); +clkSym = clock() - clk; + // undo the global functions + Abc_NtkFreeGlobalBdds( pNtk ); + Extra_StopManager( dd ); + pNtk->pManGlob = NULL; + +PRT( "Constructing BDDs", clkBdd ); +PRT( "Computing symms ", clkSym ); +PRT( "TOTAL ", clkBdd + clkSym ); +} + +/**Function************************************************************* + + Synopsis [Symmetry computation using BDDs (both naive and smart).] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ntk_NetworkSymmsBdd( DdManager * dd, Abc_Ntk_t * pNtk, int fNaive, int fVerbose ) +{ + Extra_SymmInfo_t * pSymms; + Abc_Obj_t * pNode; + DdNode * bFunc; + int nSymms = 0; + int i; + + // compute symmetry info for each PO + Abc_NtkForEachCo( pNtk, pNode, i ) + { + bFunc = pNtk->vFuncsGlob->pArray[i]; + if ( Cudd_IsConstant(bFunc) ) + continue; + if ( fNaive ) + pSymms = Extra_SymmPairsComputeNaive( dd, bFunc ); + else + pSymms = Extra_SymmPairsCompute( dd, bFunc ); + nSymms += pSymms->nSymms; + if ( fVerbose ) + { + printf( "Output %6s (%d): ", Abc_ObjName(pNode), pSymms->nSymms ); + Ntk_NetworkSymmsPrint( pNtk, pSymms ); + } +//Extra_SymmPairsPrint( pSymms ); + Extra_SymmPairsDissolve( pSymms ); + } + printf( "The total number of symmetries is %d.\n", nSymms ); +} + +/**Function************************************************************* + + Synopsis [Printing symmetry groups from the symmetry data structure.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ntk_NetworkSymmsPrint( Abc_Ntk_t * pNtk, Extra_SymmInfo_t * pSymms ) +{ + char ** pInputNames; + int * pVarTaken; + int i, k, nVars, nSize, fStart; + + // get variable names + nVars = Abc_NtkCiNum(pNtk); + pInputNames = Abc_NtkCollectCioNames( pNtk, 0 ); + + // alloc the array of marks + pVarTaken = ALLOC( int, nVars ); + memset( pVarTaken, 0, sizeof(int) * nVars ); + + // print the groups + fStart = 1; + nSize = pSymms->nVars; + for ( i = 0; i < nSize; i++ ) + { + // skip the variable already considered + if ( pVarTaken[i] ) + continue; + // find all the vars symmetric with this one + for ( k = 0; k < nSize; k++ ) + { + if ( k == i ) + continue; + if ( pSymms->pSymms[i][k] == 0 ) + continue; + // vars i and k are symmetric + assert( pVarTaken[k] == 0 ); + // there is a new symmetry pair + if ( fStart == 1 ) + { // start a new symmetry class + fStart = 0; + printf( " { %s", pInputNames[ pSymms->pVars[i] ] ); + // mark the var as taken + pVarTaken[i] = 1; + } + printf( " %s", pInputNames[ pSymms->pVars[k] ] ); + // mark the var as taken + pVarTaken[k] = 1; + } + if ( fStart == 0 ) + { + printf( " }" ); + fStart = 1; + } + } + printf( "\n" ); + + free( pInputNames ); + free( pVarTaken ); +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/base/abci/abcTiming.c b/src/base/abci/abcTiming.c new file mode 100644 index 00000000..b8524bd5 --- /dev/null +++ b/src/base/abci/abcTiming.c @@ -0,0 +1,755 @@ +/**CFile**************************************************************** + + FileName [abcTiming.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Network and node package.] + + Synopsis [Computation of timing info for mapped circuits.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: abcTiming.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abc.h" +#include "main.h" +#include "mio.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +struct Abc_ManTime_t_ +{ + Abc_Time_t tArrDef; + Abc_Time_t tReqDef; + Vec_Ptr_t * vArrs; + Vec_Ptr_t * vReqs; +}; + +// static functions +static Abc_ManTime_t * Abc_ManTimeStart(); +static void Abc_ManTimeExpand( Abc_ManTime_t * p, int nSize, int fProgressive ); +static void Abc_NtkTimePrepare( Abc_Ntk_t * pNtk ); + +static void Abc_NodeDelayTraceArrival( Abc_Obj_t * pNode ); + +// accessing the arrival and required times of a node +static inline Abc_Time_t * Abc_NodeArrival( Abc_Obj_t * pNode ) { return pNode->pNtk->pManTime->vArrs->pArray[pNode->Id]; } +static inline Abc_Time_t * Abc_NodeRequired( Abc_Obj_t * pNode ) { return pNode->pNtk->pManTime->vReqs->pArray[pNode->Id]; } + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Reads the arrival time of the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Time_t * Abc_NodeReadArrival( Abc_Obj_t * pNode ) +{ + assert( pNode->pNtk->pManTime ); + return Abc_NodeArrival(pNode); +} + +/**Function************************************************************* + + Synopsis [Reads the arrival time of the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Time_t * Abc_NodeReadRequired( Abc_Obj_t * pNode ) +{ + assert( pNode->pNtk->pManTime ); + return Abc_NodeRequired(pNode); +} + +/**Function************************************************************* + + Synopsis [Reads the arrival time of the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Time_t * Abc_NtkReadDefaultArrival( Abc_Ntk_t * pNtk ) +{ + assert( pNtk->pManTime ); + return &pNtk->pManTime->tArrDef; +} + +/**Function************************************************************* + + Synopsis [Reads the arrival time of the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Time_t * Abc_NtkReadDefaultRequired( Abc_Ntk_t * pNtk ) +{ + assert( pNtk->pManTime ); + return &pNtk->pManTime->tReqDef; +} + +/**Function************************************************************* + + Synopsis [Sets the default arrival time for the network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkTimeSetDefaultArrival( Abc_Ntk_t * pNtk, float Rise, float Fall ) +{ + if ( Rise == 0.0 && Fall == 0.0 ) + return; + if ( pNtk->pManTime == NULL ) + pNtk->pManTime = Abc_ManTimeStart(); + pNtk->pManTime->tArrDef.Rise = Rise; + pNtk->pManTime->tArrDef.Fall = Fall; + pNtk->pManTime->tArrDef.Worst = ABC_MAX( Rise, Fall ); +} + +/**Function************************************************************* + + Synopsis [Sets the default arrival time for the network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkTimeSetDefaultRequired( Abc_Ntk_t * pNtk, float Rise, float Fall ) +{ + if ( Rise == 0.0 && Fall == 0.0 ) + return; + if ( pNtk->pManTime == NULL ) + pNtk->pManTime = Abc_ManTimeStart(); + pNtk->pManTime->tReqDef.Rise = Rise; + pNtk->pManTime->tReqDef.Rise = Fall; + pNtk->pManTime->tReqDef.Worst = ABC_MAX( Rise, Fall ); +} + +/**Function************************************************************* + + Synopsis [Sets the arrival time for an object.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkTimeSetArrival( Abc_Ntk_t * pNtk, int ObjId, float Rise, float Fall ) +{ + Vec_Ptr_t * vTimes; + Abc_Time_t * pTime; + if ( pNtk->pManTime == NULL ) + pNtk->pManTime = Abc_ManTimeStart(); + if ( pNtk->pManTime->tArrDef.Rise == Rise && pNtk->pManTime->tArrDef.Fall == Fall ) + return; + Abc_ManTimeExpand( pNtk->pManTime, ObjId + 1, 1 ); + // set the arrival time + vTimes = pNtk->pManTime->vArrs; + pTime = vTimes->pArray[ObjId]; + pTime->Rise = Rise; + pTime->Fall = Rise; + pTime->Worst = ABC_MAX( Rise, Fall ); +} + +/**Function************************************************************* + + Synopsis [Sets the arrival time for an object.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkTimeSetRequired( Abc_Ntk_t * pNtk, int ObjId, float Rise, float Fall ) +{ + Vec_Ptr_t * vTimes; + Abc_Time_t * pTime; + if ( pNtk->pManTime == NULL ) + pNtk->pManTime = Abc_ManTimeStart(); + if ( pNtk->pManTime->tReqDef.Rise == Rise && pNtk->pManTime->tReqDef.Fall == Fall ) + return; + Abc_ManTimeExpand( pNtk->pManTime, ObjId + 1, 1 ); + // set the required time + vTimes = pNtk->pManTime->vReqs; + pTime = vTimes->pArray[ObjId]; + pTime->Rise = Rise; + pTime->Fall = Rise; + pTime->Worst = ABC_MAX( Rise, Fall ); +} + +/**Function************************************************************* + + Synopsis [Finalizes the timing manager after setting arr/req times.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkTimeInitialize( Abc_Ntk_t * pNtk ) +{ + Abc_Obj_t * pObj; + Abc_Time_t ** ppTimes, * pTime; + int i; + if ( pNtk->pManTime == NULL ) + return; + Abc_ManTimeExpand( pNtk->pManTime, Abc_NtkObjNumMax(pNtk), 0 ); + // set the default timing + ppTimes = (Abc_Time_t **)pNtk->pManTime->vArrs->pArray; + Abc_NtkForEachPi( pNtk, pObj, i ) + { + pTime = ppTimes[pObj->Id]; + if ( pTime->Worst != -ABC_INFINITY ) + continue; + *pTime = pNtk->pManTime->tArrDef; + } + // set the default timing + ppTimes = (Abc_Time_t **)pNtk->pManTime->vReqs->pArray; + Abc_NtkForEachPo( pNtk, pObj, i ) + { + pTime = ppTimes[pObj->Id]; + if ( pTime->Worst != -ABC_INFINITY ) + continue; + *pTime = pNtk->pManTime->tReqDef; + } + // set the 0 arrival times for latches and constant nodes + ppTimes = (Abc_Time_t **)pNtk->pManTime->vArrs->pArray; + Abc_NtkForEachLatch( pNtk, pObj, i ) + { + pTime = ppTimes[pObj->Id]; + pTime->Fall = pTime->Rise = pTime->Worst = 0.0; + } +} + +/**Function************************************************************* + + Synopsis [Prepares the timing manager for delay trace.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkTimePrepare( Abc_Ntk_t * pNtk ) +{ + Abc_Obj_t * pObj; + Abc_Time_t ** ppTimes, * pTime; + int i; + // if there is no timing manager, allocate and initialize + if ( pNtk->pManTime == NULL ) + { + pNtk->pManTime = Abc_ManTimeStart(); + Abc_NtkTimeInitialize( pNtk ); + return; + } + // if timing manager is given, expand it if necessary + Abc_ManTimeExpand( pNtk->pManTime, Abc_NtkObjNumMax(pNtk), 0 ); + // clean arrivals except for PIs + ppTimes = (Abc_Time_t **)pNtk->pManTime->vArrs->pArray; + Abc_NtkForEachNode( pNtk, pObj, i ) + { + pTime = ppTimes[pObj->Id]; + pTime->Fall = pTime->Rise = pTime->Worst = -ABC_INFINITY; + } + Abc_NtkForEachPo( pNtk, pObj, i ) + { + pTime = ppTimes[pObj->Id]; + pTime->Fall = pTime->Rise = pTime->Worst = -ABC_INFINITY; + } + // clean required except for POs +} + + + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_ManTime_t * Abc_ManTimeStart() +{ + Abc_ManTime_t * p; + p = ALLOC( Abc_ManTime_t, 1 ); + memset( p, 0, sizeof(Abc_ManTime_t) ); + p->vArrs = Vec_PtrAlloc( 0 ); + p->vReqs = Vec_PtrAlloc( 0 ); + return p; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_ManTimeStop( Abc_ManTime_t * p ) +{ + if ( p->vArrs->nSize > 0 ) + { + free( p->vArrs->pArray[0] ); + Vec_PtrFree( p->vArrs ); + } + if ( p->vReqs->nSize > 0 ) + { + free( p->vReqs->pArray[0] ); + Vec_PtrFree( p->vReqs ); + } + free( p ); +} + +/**Function************************************************************* + + Synopsis [Duplicates the timing manager with the PI/PO timing info.] + + Description [The PIs/POs of the new network should be allocated.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_ManTimeDup( Abc_Ntk_t * pNtkOld, Abc_Ntk_t * pNtkNew ) +{ + Abc_Obj_t * pObj; + Abc_Time_t ** ppTimesOld, ** ppTimesNew; + int i; + if ( pNtkOld->pManTime == NULL ) + return; + assert( Abc_NtkPiNum(pNtkOld) == Abc_NtkPiNum(pNtkNew) ); + assert( Abc_NtkPoNum(pNtkOld) == Abc_NtkPoNum(pNtkNew) ); + assert( Abc_NtkLatchNum(pNtkOld) == Abc_NtkLatchNum(pNtkNew) ); + // create the new timing manager + pNtkNew->pManTime = Abc_ManTimeStart(); + Abc_ManTimeExpand( pNtkNew->pManTime, Abc_NtkObjNumMax(pNtkNew), 0 ); + // set the default timing + pNtkNew->pManTime->tArrDef = pNtkOld->pManTime->tArrDef; + pNtkNew->pManTime->tReqDef = pNtkOld->pManTime->tReqDef; + // set the CI timing + ppTimesOld = (Abc_Time_t **)pNtkOld->pManTime->vArrs->pArray; + ppTimesNew = (Abc_Time_t **)pNtkNew->pManTime->vArrs->pArray; + Abc_NtkForEachCi( pNtkOld, pObj, i ) + *ppTimesNew[ Abc_NtkCi(pNtkNew,i)->Id ] = *ppTimesOld[ pObj->Id ]; + // set the CO timing + ppTimesOld = (Abc_Time_t **)pNtkOld->pManTime->vReqs->pArray; + ppTimesNew = (Abc_Time_t **)pNtkNew->pManTime->vReqs->pArray; + Abc_NtkForEachCo( pNtkOld, pObj, i ) + *ppTimesNew[ Abc_NtkCo(pNtkNew,i)->Id ] = *ppTimesOld[ pObj->Id ]; +} + +/**Function************************************************************* + + Synopsis [Expends the storage for timing information.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_ManTimeExpand( Abc_ManTime_t * p, int nSize, int fProgressive ) +{ + Vec_Ptr_t * vTimes; + Abc_Time_t * ppTimes, * ppTimesOld, * pTime; + int nSizeOld, nSizeNew, i; + + nSizeOld = p->vArrs->nSize; + if ( nSizeOld >= nSize ) + return; + nSizeNew = fProgressive? 2 * nSize : nSize; + if ( nSizeNew < 100 ) + nSizeNew = 100; + + vTimes = p->vArrs; + Vec_PtrGrow( vTimes, nSizeNew ); + vTimes->nSize = nSizeNew; + ppTimesOld = ( nSizeOld == 0 )? NULL : vTimes->pArray[0]; + ppTimes = REALLOC( Abc_Time_t, ppTimesOld, nSizeNew ); + for ( i = 0; i < nSizeNew; i++ ) + vTimes->pArray[i] = ppTimes + i; + for ( i = nSizeOld; i < nSizeNew; i++ ) + { + pTime = vTimes->pArray[i]; + pTime->Rise = -ABC_INFINITY; + pTime->Fall = -ABC_INFINITY; + pTime->Worst = -ABC_INFINITY; + } + + vTimes = p->vReqs; + Vec_PtrGrow( vTimes, nSizeNew ); + vTimes->nSize = nSizeNew; + ppTimesOld = ( nSizeOld == 0 )? NULL : vTimes->pArray[0]; + ppTimes = REALLOC( Abc_Time_t, ppTimesOld, nSizeNew ); + for ( i = 0; i < nSizeNew; i++ ) + vTimes->pArray[i] = ppTimes + i; + for ( i = nSizeOld; i < nSizeNew; i++ ) + { + pTime = vTimes->pArray[i]; + pTime->Rise = -ABC_INFINITY; + pTime->Fall = -ABC_INFINITY; + pTime->Worst = -ABC_INFINITY; + } +} + + + + + + +/**Function************************************************************* + + Synopsis [Sets the CI node levels according to the arrival info.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkSetNodeLevelsArrival( Abc_Ntk_t * pNtkOld ) +{ + Abc_Obj_t * pNodeOld, * pNodeNew; + float tAndDelay; + int i; + if ( pNtkOld->pManTime == NULL ) + return; + if ( Mio_LibraryReadNand2(Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame())) == NULL ) + return; + tAndDelay = Mio_LibraryReadDelayNand2Max(Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame())); + Abc_NtkForEachPi( pNtkOld, pNodeOld, i ) + { + pNodeNew = pNodeOld->pCopy; + pNodeNew->Level = (int)(Abc_NodeArrival(pNodeOld)->Worst / tAndDelay); + } +} + +/**Function************************************************************* + + Synopsis [Sets the CI node levels according to the arrival info.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Time_t * Abc_NtkGetCiArrivalTimes( Abc_Ntk_t * pNtk ) +{ + Abc_Time_t * p; + Abc_Obj_t * pNode; + int i; + p = ALLOC( Abc_Time_t, Abc_NtkCiNum(pNtk) ); + memset( p, 0, sizeof(Abc_Time_t) * Abc_NtkCiNum(pNtk) ); + if ( pNtk->pManTime == NULL ) + return p; + // set the PI arrival times + Abc_NtkForEachPi( pNtk, pNode, i ) + p[i] = *Abc_NodeArrival(pNode); + return p; +} + + +/**Function************************************************************* + + Synopsis [Sets the CI node levels according to the arrival info.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +float * Abc_NtkGetCiArrivalFloats( Abc_Ntk_t * pNtk ) +{ + float * p; + Abc_Obj_t * pNode; + int i; + p = ALLOC( float, Abc_NtkCiNum(pNtk) ); + memset( p, 0, sizeof(float) * Abc_NtkCiNum(pNtk) ); + if ( pNtk->pManTime == NULL ) + return p; + // set the PI arrival times + Abc_NtkForEachPi( pNtk, pNode, i ) + p[i] = Abc_NodeArrival(pNode)->Worst; + return p; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +float Abc_NtkDelayTrace( Abc_Ntk_t * pNtk ) +{ + Abc_Obj_t * pNode, * pDriver; + Vec_Ptr_t * vNodes; + Abc_Time_t * pTime; + float tArrivalMax; + int i; + + assert( Abc_NtkIsMappedLogic(pNtk) ); + + Abc_NtkTimePrepare( pNtk ); + vNodes = Abc_NtkDfs( pNtk, 1 ); + for ( i = 0; i < vNodes->nSize; i++ ) + Abc_NodeDelayTraceArrival( vNodes->pArray[i] ); + Vec_PtrFree( vNodes ); + + // get the latest arrival times + tArrivalMax = -ABC_INFINITY; + Abc_NtkForEachCo( pNtk, pNode, i ) + { + pDriver = Abc_ObjFanin0(pNode); + pTime = Abc_NodeArrival(pDriver); + if ( tArrivalMax < pTime->Worst ) + tArrivalMax = pTime->Worst; + } + return tArrivalMax; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NodeDelayTraceArrival( Abc_Obj_t * pNode ) +{ + Abc_Obj_t * pFanin; + Abc_Time_t * pTimeIn, * pTimeOut; + float tDelayBlockRise, tDelayBlockFall; + Mio_PinPhase_t PinPhase; + Mio_Pin_t * pPin; + int i; + + // start the arrival time of the node + pTimeOut = Abc_NodeArrival(pNode); + pTimeOut->Rise = pTimeOut->Fall = 0; + // go through the pins of the gate + pPin = Mio_GateReadPins(pNode->pData); + Abc_ObjForEachFanin( pNode, pFanin, i ) + { + pTimeIn = Abc_NodeArrival(pFanin); + assert( pTimeIn->Worst != -ABC_INFINITY ); + // get the interesting parameters of this pin + PinPhase = Mio_PinReadPhase(pPin); + tDelayBlockRise = (float)Mio_PinReadDelayBlockRise( pPin ); + tDelayBlockFall = (float)Mio_PinReadDelayBlockFall( pPin ); + // compute the arrival times of the positive phase + if ( PinPhase != MIO_PHASE_INV ) // NONINV phase is present + { + if ( pTimeOut->Rise < pTimeIn->Rise + tDelayBlockRise ) + pTimeOut->Rise = pTimeIn->Rise + tDelayBlockRise; + if ( pTimeOut->Fall < pTimeIn->Fall + tDelayBlockFall ) + pTimeOut->Fall = pTimeIn->Fall + tDelayBlockFall; + } + if ( PinPhase != MIO_PHASE_NONINV ) // INV phase is present + { + if ( pTimeOut->Rise < pTimeIn->Fall + tDelayBlockRise ) + pTimeOut->Rise = pTimeIn->Fall + tDelayBlockRise; + if ( pTimeOut->Fall < pTimeIn->Rise + tDelayBlockFall ) + pTimeOut->Fall = pTimeIn->Rise + tDelayBlockFall; + } + pPin = Mio_PinReadNext(pPin); + } + pTimeOut->Worst = ABC_MAX( pTimeOut->Rise, pTimeOut->Fall ); +} + + + + +/**Function************************************************************* + + Synopsis [Prepares the AIG for the comptuation of required levels.] + + Description [This procedure should be called before the required times + are used. It starts internal data structures, which records the level + from the COs of the AIG nodes in reverse topologogical order.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkStartReverseLevels( Abc_Ntk_t * pNtk ) +{ + Vec_Ptr_t * vNodes; + Abc_Obj_t * pObj, * pFanout; + int i, k, nLevelsCur; + assert( Abc_NtkIsStrash(pNtk) ); + // remember the maximum number of direct levels + pNtk->LevelMax = Abc_AigGetLevelNum(pNtk); + // start the reverse levels + pNtk->vLevelsR = Vec_IntAlloc( 0 ); + Vec_IntFill( pNtk->vLevelsR, Abc_NtkObjNumMax(pNtk), 0 ); + // compute levels in reverse topological order + vNodes = Abc_NtkDfsReverse( pNtk ); + Vec_PtrForEachEntry( vNodes, pObj, i ) + { + nLevelsCur = 0; + Abc_ObjForEachFanout( pObj, pFanout, k ) + if ( nLevelsCur < Vec_IntEntry(pNtk->vLevelsR, pFanout->Id) ) + nLevelsCur = Vec_IntEntry(pNtk->vLevelsR, pFanout->Id); + Vec_IntWriteEntry( pNtk->vLevelsR, pObj->Id, nLevelsCur + 1 ); + } + Vec_PtrFree( vNodes ); +} + +/**Function************************************************************* + + Synopsis [Cleans the data structures used to compute required levels.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkStopReverseLevels( Abc_Ntk_t * pNtk ) +{ + assert( pNtk->vLevelsR ); + Vec_IntFree( pNtk->vLevelsR ); + pNtk->vLevelsR = NULL; + pNtk->LevelMax = 0; + +} + +/**Function************************************************************* + + Synopsis [Sets the reverse level of the node.] + + Description [The reverse level is the level of the node in reverse + topological order, starting from the COs.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NodeSetReverseLevel( Abc_Obj_t * pObj, int LevelR ) +{ + Abc_Ntk_t * pNtk = pObj->pNtk; + assert( Abc_NtkIsStrash(pNtk) ); + assert( pNtk->vLevelsR ); + Vec_IntFillExtra( pNtk->vLevelsR, pObj->Id + 1, 0 ); + Vec_IntWriteEntry( pNtk->vLevelsR, pObj->Id, LevelR ); +} + +/**Function************************************************************* + + Synopsis [Returns the reverse level of the node.] + + Description [The reverse level is the level of the node in reverse + topological order, starting from the COs.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NodeReadReverseLevel( Abc_Obj_t * pObj ) +{ + Abc_Ntk_t * pNtk = pObj->pNtk; + assert( Abc_NtkIsStrash(pNtk) ); + assert( pNtk->vLevelsR ); + Vec_IntFillExtra( pNtk->vLevelsR, pObj->Id + 1, 0 ); + return Vec_IntEntry(pNtk->vLevelsR, pObj->Id); +} + +/**Function************************************************************* + + Synopsis [Returns required level of the node.] + + Description [Converts the reverse levels of the node into its required + level as follows: ReqLevel(Node) = MaxLevels(Ntk) + 1 - LevelR(Node).] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NodeReadRequiredLevel( Abc_Obj_t * pObj ) +{ + Abc_Ntk_t * pNtk = pObj->pNtk; + assert( Abc_NtkIsStrash(pNtk) ); + assert( pNtk->vLevelsR ); + return pNtk->LevelMax + 1 - Vec_IntEntry(pNtk->vLevelsR, pObj->Id); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/base/abci/abcUnreach.c b/src/base/abci/abcUnreach.c new file mode 100644 index 00000000..0fe3ec63 --- /dev/null +++ b/src/base/abci/abcUnreach.c @@ -0,0 +1,336 @@ +/**CFile**************************************************************** + + FileName [abcUnreach.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Network and node package.] + + Synopsis [Computes unreachable states for small benchmarks.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: abcUnreach.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abc.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static DdNode * Abc_NtkTransitionRelation( DdManager * dd, Abc_Ntk_t * pNtk, int fVerbose ); +static DdNode * Abc_NtkInitStateAndVarMap( DdManager * dd, Abc_Ntk_t * pNtk, int fVerbose ); +static DdNode * Abc_NtkComputeUnreachable( DdManager * dd, Abc_Ntk_t * pNtk, DdNode * bRelation, DdNode * bInitial, bool fVerbose ); +static Abc_Ntk_t * Abc_NtkConstructExdc ( DdManager * dd, Abc_Ntk_t * pNtk, DdNode * bUnreach ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Extracts sequential DCs of the network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NtkExtractSequentialDcs( Abc_Ntk_t * pNtk, bool fVerbose ) +{ + int fCheck = 1; + int fReorder = 1; + DdManager * dd; + DdNode * bRelation, * bInitial, * bUnreach; + + // remove EXDC network if present + if ( pNtk->pExdc ) + { + Abc_NtkDelete( pNtk->pExdc ); + pNtk->pExdc = NULL; + } + + // compute the global BDDs of the latches + dd = Abc_NtkGlobalBdds( pNtk, 1 ); + if ( dd == NULL ) + return 0; + if ( fVerbose ) + printf( "The shared BDD size is %d nodes.\n", Cudd_ReadKeys(dd) - Cudd_ReadDead(dd) ); + + // create the transition relation (dereferenced global BDDs) + bRelation = Abc_NtkTransitionRelation( dd, pNtk, fVerbose ); Cudd_Ref( bRelation ); + // create the initial state and the variable map + bInitial = Abc_NtkInitStateAndVarMap( dd, pNtk, fVerbose ); Cudd_Ref( bInitial ); + // compute the unreachable states + bUnreach = Abc_NtkComputeUnreachable( dd, pNtk, bRelation, bInitial, fVerbose ); Cudd_Ref( bUnreach ); + Cudd_RecursiveDeref( dd, bRelation ); + Cudd_RecursiveDeref( dd, bInitial ); + + // reorder and disable reordering + if ( fReorder ) + { + if ( fVerbose ) + fprintf( stdout, "BDD nodes in the unreachable states before reordering %d.\n", Cudd_DagSize(bUnreach) ); + Cudd_ReduceHeap( dd, CUDD_REORDER_SYMM_SIFT, 1 ); + Cudd_AutodynDisable( dd ); + if ( fVerbose ) + fprintf( stdout, "BDD nodes in the unreachable states after reordering %d.\n", Cudd_DagSize(bUnreach) ); + } + + // allocate ZDD variables + Cudd_zddVarsFromBddVars( dd, 2 ); + // create the EXDC network representing the unreachable states + pNtk->pExdc = Abc_NtkConstructExdc( dd, pNtk, bUnreach ); + Cudd_RecursiveDeref( dd, bUnreach ); + Extra_StopManager( dd ); + pNtk->pManGlob = NULL; + + // make sure that everything is okay + if ( fCheck && !Abc_NtkCheck( pNtk->pExdc ) ) + { + printf( "Abc_NtkExtractSequentialDcs: The network check has failed.\n" ); + Abc_NtkDelete( pNtk->pExdc ); + return 0; + } + return 1; +} + +/**Function************************************************************* + + Synopsis [Computes the transition relation of the network.] + + Description [Assumes that the global BDDs are computed.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +DdNode * Abc_NtkTransitionRelation( DdManager * dd, Abc_Ntk_t * pNtk, int fVerbose ) +{ + DdNode * bRel, * bTemp, * bProd, * bVar, * bInputs; + Abc_Obj_t * pNode; + int fReorder = 1; + int i; + + // extand the BDD manager to represent NS variables + assert( dd->size == Abc_NtkCiNum(pNtk) ); + Cudd_bddIthVar( dd, Abc_NtkCiNum(pNtk) + Abc_NtkLatchNum(pNtk) - 1 ); + + // enable reordering + if ( fReorder ) + Cudd_AutodynEnable( dd, CUDD_REORDER_SYMM_SIFT ); + else + Cudd_AutodynDisable( dd ); + + // compute the transition relation + bRel = b1; Cudd_Ref( bRel ); + Abc_NtkForEachLatch( pNtk, pNode, i ) + { + bVar = Cudd_bddIthVar( dd, Abc_NtkCiNum(pNtk) + i ); + bProd = Cudd_bddXnor( dd, bVar, pNtk->vFuncsGlob->pArray[i] ); Cudd_Ref( bProd ); + bRel = Cudd_bddAnd( dd, bTemp = bRel, bProd ); Cudd_Ref( bRel ); + Cudd_RecursiveDeref( dd, bTemp ); + Cudd_RecursiveDeref( dd, bProd ); + } + // free the global BDDs + Abc_NtkFreeGlobalBdds( pNtk ); + + // quantify the PI variables + bInputs = Extra_bddComputeRangeCube( dd, 0, Abc_NtkPiNum(pNtk) ); Cudd_Ref( bInputs ); + bRel = Cudd_bddExistAbstract( dd, bTemp = bRel, bInputs ); Cudd_Ref( bRel ); + Cudd_RecursiveDeref( dd, bTemp ); + Cudd_RecursiveDeref( dd, bInputs ); + + // reorder and disable reordering + if ( fReorder ) + { + if ( fVerbose ) + fprintf( stdout, "BDD nodes in the transition relation before reordering %d.\n", Cudd_DagSize(bRel) ); + Cudd_ReduceHeap( dd, CUDD_REORDER_SYMM_SIFT, 100 ); + Cudd_AutodynDisable( dd ); + if ( fVerbose ) + fprintf( stdout, "BDD nodes in the transition relation after reordering %d.\n", Cudd_DagSize(bRel) ); + } + Cudd_Deref( bRel ); + return bRel; +} + +/**Function************************************************************* + + Synopsis [Computes the initial state and sets up the variable map.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +DdNode * Abc_NtkInitStateAndVarMap( DdManager * dd, Abc_Ntk_t * pNtk, int fVerbose ) +{ + DdNode ** pbVarsX, ** pbVarsY; + DdNode * bTemp, * bProd, * bVar; + Abc_Obj_t * pLatch; + int i; + + // set the variable mapping for Cudd_bddVarMap() + pbVarsX = ALLOC( DdNode *, dd->size ); + pbVarsY = ALLOC( DdNode *, dd->size ); + bProd = b1; Cudd_Ref( bProd ); + Abc_NtkForEachLatch( pNtk, pLatch, i ) + { + pbVarsX[i] = dd->vars[ Abc_NtkPiNum(pNtk) + i ]; + pbVarsY[i] = dd->vars[ Abc_NtkCiNum(pNtk) + i ]; + // get the initial value of the latch + bVar = Cudd_NotCond( pbVarsX[i], !Abc_LatchIsInit1(pLatch) ); + bProd = Cudd_bddAnd( dd, bTemp = bProd, bVar ); Cudd_Ref( bProd ); + Cudd_RecursiveDeref( dd, bTemp ); + } + Cudd_SetVarMap( dd, pbVarsX, pbVarsY, Abc_NtkLatchNum(pNtk) ); + FREE( pbVarsX ); + FREE( pbVarsY ); + + Cudd_Deref( bProd ); + return bProd; +} + +/**Function************************************************************* + + Synopsis [Computes the set of unreachable states.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +DdNode * Abc_NtkComputeUnreachable( DdManager * dd, Abc_Ntk_t * pNtk, DdNode * bTrans, DdNode * bInitial, bool fVerbose ) +{ + DdNode * bRelation, * bReached, * bCubeCs; + DdNode * bCurrent, * bNext, * bTemp; + int nIters; + + // perform reachability analisys + bCurrent = bInitial; Cudd_Ref( bCurrent ); + bReached = bInitial; Cudd_Ref( bReached ); + bRelation = bTrans; Cudd_Ref( bRelation ); + bCubeCs = Extra_bddComputeRangeCube( dd, Abc_NtkPiNum(pNtk), Abc_NtkCiNum(pNtk) ); Cudd_Ref( bCubeCs ); + for ( nIters = 1; ; nIters++ ) + { + // compute the next states + bNext = Cudd_bddAndAbstract( dd, bRelation, bCurrent, bCubeCs ); Cudd_Ref( bNext ); + Cudd_RecursiveDeref( dd, bCurrent ); + // remap these states into the current state vars + bNext = Cudd_bddVarMap( dd, bTemp = bNext ); Cudd_Ref( bNext ); + Cudd_RecursiveDeref( dd, bTemp ); + // check if there are any new states + if ( Cudd_bddLeq( dd, bNext, bReached ) ) + break; + // get the new states + bCurrent = Cudd_bddAnd( dd, bNext, Cudd_Not(bReached) ); Cudd_Ref( bCurrent ); + // minimize the new states with the reached states +// bCurrent = Cudd_bddConstrain( dd, bTemp = bCurrent, Cudd_Not(bReached) ); Cudd_Ref( bCurrent ); +// Cudd_RecursiveDeref( dd, bTemp ); + // add to the reached states + bReached = Cudd_bddOr( dd, bTemp = bReached, bNext ); Cudd_Ref( bReached ); + Cudd_RecursiveDeref( dd, bTemp ); + Cudd_RecursiveDeref( dd, bNext ); + // minimize the transition relation +// bRelation = Cudd_bddConstrain( dd, bTemp = bRelation, Cudd_Not(bReached) ); Cudd_Ref( bRelation ); +// Cudd_RecursiveDeref( dd, bTemp ); + } + Cudd_RecursiveDeref( dd, bRelation ); + Cudd_RecursiveDeref( dd, bCubeCs ); + Cudd_RecursiveDeref( dd, bNext ); + // report the stats + if ( fVerbose ) + { + fprintf( stdout, "Reachability analysis completed in %d iterations.\n", nIters ); + fprintf( stdout, "The number of minterms in the reachable state set = %d.\n", + (int)Cudd_CountMinterm(dd, bReached, Abc_NtkLatchNum(pNtk) ) ); + } +//PRB( dd, bReached ); + Cudd_Deref( bReached ); + return Cudd_Not( bReached ); +} + +/**Function************************************************************* + + Synopsis [Creates the EXDC network.] + + Description [The set of unreachable states depends on CS variables.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkConstructExdc( DdManager * dd, Abc_Ntk_t * pNtk, DdNode * bUnreach ) +{ + Abc_Ntk_t * pNtkNew; + Abc_Obj_t * pNode, * pNodeNew; + int * pPermute; + int i; + + // start the new network + pNtkNew = Abc_NtkAlloc( ABC_TYPE_LOGIC, ABC_FUNC_BDD ); + // create PIs corresponding to LOs + Abc_NtkForEachLatch( pNtk, pNode, i ) + pNode->pCopy = Abc_NtkCreatePi(pNtkNew); + + // create a new node + pNodeNew = Abc_NtkCreateNode(pNtkNew); + // add the fanins corresponding to latch outputs + Abc_NtkForEachLatch( pNtk, pNode, i ) + Abc_ObjAddFanin( pNodeNew, pNode->pCopy ); + + // create the logic function + pPermute = ALLOC( int, dd->size ); + for ( i = 0; i < dd->size; i++ ) + pPermute[i] = -1; + Abc_NtkForEachLatch( pNtk, pNode, i ) + pPermute[Abc_NtkPiNum(pNtk) + i] = i; + // remap the functions + pNodeNew->pData = Extra_TransferPermute( dd, pNtkNew->pManFunc, bUnreach, pPermute ); Cudd_Ref( pNodeNew->pData ); + free( pPermute ); + Abc_NodeMinimumBase( pNodeNew ); + + // make the new node drive all the COs + Abc_NtkForEachCo( pNtk, pNode, i ) + Abc_ObjAddFanin( Abc_NtkCreatePo(pNtkNew), pNodeNew ); + + // store the PI names of the EXDC network + Abc_NtkForEachLatch( pNtk, pNode, i ) + Abc_NtkLogicStoreName( Abc_NtkPi(pNtkNew,i), Abc_ObjName(pNode) ); + // store the PO names of the EXDC network + Abc_NtkForEachPo( pNtk, pNode, i ) + Abc_NtkLogicStoreName( Abc_NtkPo(pNtkNew,i), Abc_ObjName(pNode) ); + Abc_NtkForEachLatch( pNtk, pNode, i ) + Abc_NtkLogicStoreName( Abc_NtkCo(pNtkNew,Abc_NtkPoNum(pNtk) + i), Abc_ObjNameSuffix(pNode, "_in") ); + + // make the network minimum base + Abc_NtkMinimumBase( pNtkNew ); + + // fix the problem with complemented and duplicated CO edges + Abc_NtkLogicMakeSimpleCos( pNtkNew, 0 ); + + // transform the network to the SOP representation + Abc_NtkBddToSop( pNtkNew ); + return pNtkNew; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/base/abci/abcVerify.c b/src/base/abci/abcVerify.c new file mode 100644 index 00000000..55d6cf7d --- /dev/null +++ b/src/base/abci/abcVerify.c @@ -0,0 +1,311 @@ +/**CFile**************************************************************** + + FileName [abcVerify.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Network and node package.] + + Synopsis [Combinational and sequential verification for two networks.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: abcVerify.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abc.h" +#include "fraig.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Verifies combinational equivalence by brute-force SAT.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkCecSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2 ) +{ + Abc_Ntk_t * pMiter; + Abc_Ntk_t * pCnf; + int RetValue; + + // get the miter of the two networks + pMiter = Abc_NtkMiter( pNtk1, pNtk2, 1 ); + if ( pMiter == NULL ) + { + printf( "Miter computation has failed.\n" ); + return; + } + RetValue = Abc_NtkMiterIsConstant( pMiter ); + if ( RetValue == 1 ) + { + Abc_NtkDelete( pMiter ); + printf( "Networks are NOT EQUIVALENT after structural hashing.\n" ); + return; + } + if ( RetValue == 0 ) + { + Abc_NtkDelete( pMiter ); + printf( "Networks are equivalent after structural hashing.\n" ); + return; + } + + // convert the miter into a CNF + pCnf = Abc_NtkRenode( pMiter, 0, 100, 1, 0, 0 ); + Abc_NtkDelete( pMiter ); + if ( pCnf == NULL ) + { + printf( "Renoding for CNF has failed.\n" ); + return; + } + + // solve the CNF using the SAT solver + if ( Abc_NtkMiterSat( pCnf, 0 ) ) + printf( "Networks are NOT EQUIVALENT after SAT.\n" ); + else + printf( "Networks are equivalent after SAT.\n" ); + Abc_NtkDelete( pCnf ); +} + + +/**Function************************************************************* + + Synopsis [Verifies sequential equivalence by fraiging followed by SAT.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkCecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fVerbose ) +{ + Fraig_Params_t Params; + Abc_Ntk_t * pMiter; + Abc_Ntk_t * pFraig; + int RetValue; + + // get the miter of the two networks + pMiter = Abc_NtkMiter( pNtk1, pNtk2, 1 ); + if ( pMiter == NULL ) + { + printf( "Miter computation has failed.\n" ); + return; + } + RetValue = Abc_NtkMiterIsConstant( pMiter ); + if ( RetValue == 1 ) + { + Abc_NtkDelete( pMiter ); + printf( "Networks are NOT EQUIVALENT after structural hashing.\n" ); + return; + } + if ( RetValue == 0 ) + { + Abc_NtkDelete( pMiter ); + printf( "Networks are equivalent after structural hashing.\n" ); + return; + } + + // convert the miter into a FRAIG + Fraig_ParamsSetDefault( &Params ); + Params.fVerbose = fVerbose; + pFraig = Abc_NtkFraig( pMiter, &Params, 0 ); + Abc_NtkDelete( pMiter ); + if ( pFraig == NULL ) + { + printf( "Fraiging has failed.\n" ); + return; + } + RetValue = Abc_NtkMiterIsConstant( pFraig ); + Abc_NtkDelete( pFraig ); + if ( RetValue == 0 ) + { + printf( "Networks are equivalent after fraiging.\n" ); + return; + } + printf( "Networks are NOT EQUIVALENT after fraiging.\n" ); +} + +/**Function************************************************************* + + Synopsis [Verifies sequential equivalence by brute-force SAT.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkSecSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nFrames ) +{ + Abc_Ntk_t * pMiter; + Abc_Ntk_t * pFrames; + Abc_Ntk_t * pCnf; + int RetValue; + + // get the miter of the two networks + pMiter = Abc_NtkMiter( pNtk1, pNtk2, 0 ); + if ( pMiter == NULL ) + { + printf( "Miter computation has failed.\n" ); + return; + } + RetValue = Abc_NtkMiterIsConstant( pMiter ); + if ( RetValue == 1 ) + { + Abc_NtkDelete( pMiter ); + printf( "Networks are NOT EQUIVALENT after structural hashing.\n" ); + return; + } + if ( RetValue == 0 ) + { + Abc_NtkDelete( pMiter ); + printf( "Networks are equivalent after structural hashing.\n" ); + return; + } + + // create the timeframes + pFrames = Abc_NtkFrames( pMiter, nFrames, 1 ); + Abc_NtkDelete( pMiter ); + if ( pFrames == NULL ) + { + printf( "Frames computation has failed.\n" ); + return; + } + RetValue = Abc_NtkMiterIsConstant( pFrames ); + if ( RetValue == 1 ) + { + Abc_NtkDelete( pFrames ); + printf( "Networks are NOT EQUIVALENT after framing.\n" ); + return; + } + if ( RetValue == 0 ) + { + Abc_NtkDelete( pFrames ); + printf( "Networks are equivalent after framing.\n" ); + return; + } + + // convert the miter into a CNF + pCnf = Abc_NtkRenode( pFrames, 0, 100, 1, 0, 0 ); + Abc_NtkDelete( pFrames ); + if ( pCnf == NULL ) + { + printf( "Renoding for CNF has failed.\n" ); + return; + } + + // solve the CNF using the SAT solver + if ( Abc_NtkMiterSat( pCnf, 0 ) ) + printf( "Networks are NOT EQUIVALENT after SAT.\n" ); + else + printf( "Networks are equivalent after SAT.\n" ); + Abc_NtkDelete( pCnf ); +} + +/**Function************************************************************* + + Synopsis [Verifies combinational equivalence by fraiging followed by SAT] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkSecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nFrames ) +{ + Fraig_Params_t Params; + Abc_Ntk_t * pMiter; + Abc_Ntk_t * pFraig; + Abc_Ntk_t * pFrames; + int RetValue; + + // get the miter of the two networks + pMiter = Abc_NtkMiter( pNtk1, pNtk2, 0 ); + if ( pMiter == NULL ) + { + printf( "Miter computation has failed.\n" ); + return; + } + RetValue = Abc_NtkMiterIsConstant( pMiter ); + if ( RetValue == 1 ) + { + Abc_NtkDelete( pMiter ); + printf( "Networks are NOT EQUIVALENT after structural hashing.\n" ); + return; + } + if ( RetValue == 0 ) + { + Abc_NtkDelete( pMiter ); + printf( "Networks are equivalent after structural hashing.\n" ); + return; + } + + // create the timeframes + pFrames = Abc_NtkFrames( pMiter, nFrames, 1 ); + Abc_NtkDelete( pMiter ); + if ( pFrames == NULL ) + { + printf( "Frames computation has failed.\n" ); + return; + } + RetValue = Abc_NtkMiterIsConstant( pFrames ); + if ( RetValue == 1 ) + { + Abc_NtkDelete( pFrames ); + printf( "Networks are NOT EQUIVALENT after framing.\n" ); + return; + } + if ( RetValue == 0 ) + { + Abc_NtkDelete( pFrames ); + printf( "Networks are equivalent after framing.\n" ); + return; + } + + // convert the miter into a FRAIG + Fraig_ParamsSetDefault( &Params ); + pFraig = Abc_NtkFraig( pFrames, &Params, 0 ); + Abc_NtkDelete( pFrames ); + if ( pFraig == NULL ) + { + printf( "Fraiging has failed.\n" ); + return; + } + RetValue = Abc_NtkMiterIsConstant( pFraig ); + Abc_NtkDelete( pFraig ); + if ( RetValue == 0 ) + { + printf( "Networks are equivalent after fraiging.\n" ); + return; + } + printf( "Networks are NOT EQUIVALENT after fraiging.\n" ); +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/base/abci/abc_.c b/src/base/abci/abc_.c new file mode 100644 index 00000000..bef3836f --- /dev/null +++ b/src/base/abci/abc_.c @@ -0,0 +1,47 @@ +/**CFile**************************************************************** + + FileName [abc_.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Network and node package.] + + Synopsis [] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: abc_.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abc.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/base/abci/module.make b/src/base/abci/module.make new file mode 100644 index 00000000..d7c0add2 --- /dev/null +++ b/src/base/abci/module.make @@ -0,0 +1,24 @@ +SRC += src/base/abci/abc.c \ + src/base/abci/abcAttach.c \ + src/base/abci/abcBalance.c \ + src/base/abci/abcCollapse.c \ + src/base/abci/abcCut.c \ + src/base/abci/abcDsd.c \ + src/base/abci/abcFpga.c \ + src/base/abci/abcFraig.c \ + src/base/abci/abcFxu.c \ + src/base/abci/abcMap.c \ + src/base/abci/abcMiter.c \ + src/base/abci/abcNtbdd.c \ + src/base/abci/abcPrint.c \ + src/base/abci/abcReconv.c \ + src/base/abci/abcRefactor.c \ + src/base/abci/abcRenode.c \ + src/base/abci/abcRewrite.c \ + src/base/abci/abcSat.c \ + src/base/abci/abcStrash.c \ + src/base/abci/abcSweep.c \ + src/base/abci/abcSymm.c \ + src/base/abci/abcTiming.c \ + src/base/abci/abcUnreach.c \ + src/base/abci/abcVerify.c diff --git a/src/base/abcs/abcRetime.c b/src/base/abcs/abcRetime.c new file mode 100644 index 00000000..13b8a926 --- /dev/null +++ b/src/base/abcs/abcRetime.c @@ -0,0 +1,203 @@ +/**CFile**************************************************************** + + FileName [abcSeqRetime.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Network and node package.] + + Synopsis [Peforms retiming for optimal clock cycle.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: abcSeqRetime.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abc.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +// storing arrival times in the nodes +static inline int Abc_NodeReadLValue( Abc_Obj_t * pNode ) { return Vec_IntEntry( (pNode)->pNtk->pData, (pNode)->Id ); } +static inline void Abc_NodeSetLValue( Abc_Obj_t * pNode, int Value ) { Vec_IntWriteEntry( (pNode)->pNtk->pData, (pNode)->Id, (Value) ); } + +// the internal procedures +static int Abc_NtkRetimeSearch_rec( Abc_Ntk_t * pNtk, int FiMin, int FiMax ); +static int Abc_NtkRetimeForPeriod( Abc_Ntk_t * pNtk, int Fi ); +static int Abc_NodeUpdateLValue( Abc_Obj_t * pObj, int Fi ); + +// node status after updating its arrival time +enum { ABC_UPDATE_FAIL, ABC_UPDATE_NO, ABC_UPDATE_YES }; + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Retimes AIG for optimal delay.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkSeqRetimeDelay( Abc_Ntk_t * pNtk ) +{ + int FiMax, FiBest; + assert( Abc_NtkIsSeq( pNtk ) ); + + // start storage for sequential arrival times + assert( pNtk->pData == NULL ); + pNtk->pData = Vec_IntAlloc( 0 ); + + // get the maximum possible clock + FiMax = Abc_NtkNodeNum(pNtk); + + // make sure this clock period is feasible + assert( Abc_NtkRetimeForPeriod( pNtk, FiMax ) ); + + // search for the optimal clock period between 0 and nLevelMax + FiBest = Abc_NtkRetimeSearch_rec( pNtk, 0, FiMax ); + // print the result + printf( "The best clock period is %3d.\n", FiBest ); + + // free storage + Vec_IntFree( pNtk->pData ); + pNtk->pData = NULL; +} + +/**Function************************************************************* + + Synopsis [Performs binary search for the optimal clock period.] + + Description [Assumes that FiMin is infeasible while FiMax is feasible.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NtkRetimeSearch_rec( Abc_Ntk_t * pNtk, int FiMin, int FiMax ) +{ + int Median; + + assert( FiMin < FiMax ); + if ( FiMin + 1 == FiMax ) + return FiMax; + + Median = FiMin + (FiMax - FiMin)/2; + + if ( Abc_NtkRetimeForPeriod( pNtk, Median ) ) + return Abc_NtkRetimeSearch_rec( pNtk, FiMin, Median ); // Median is feasible + else + return Abc_NtkRetimeSearch_rec( pNtk, Median, FiMax ); // Median is infeasible +} + +/**Function************************************************************* + + Synopsis [Returns 1 if retiming with this clock period is feasible.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NtkRetimeForPeriod( Abc_Ntk_t * pNtk, int Fi ) +{ + Vec_Ptr_t * vFrontier; + Abc_Obj_t * pObj, * pFanout; + int RetValue, i, k; + + // set l-values of all nodes to be minus infinity + Vec_IntFill( pNtk->pData, Abc_NtkObjNumMax(pNtk), -ABC_INFINITY ); + + // start the frontier by including PI fanouts + vFrontier = Vec_PtrAlloc( 100 ); + Abc_NtkForEachPi( pNtk, pObj, i ) + { + Abc_NodeSetLValue( pObj, 0 ); + Abc_ObjForEachFanout( pObj, pFanout, k ) + if ( pFanout->fMarkA == 0 ) + { + Vec_PtrPush( vFrontier, pFanout ); + pFanout->fMarkA = 1; + } + } + + // iterate until convergence + Vec_PtrForEachEntry( vFrontier, pObj, i ) + { + RetValue = Abc_NodeUpdateLValue( pObj, Fi ); + if ( RetValue == ABC_UPDATE_FAIL ) + break; + // unmark the node as processed + pObj->fMarkA = 0; + if ( RetValue == ABC_UPDATE_NO ) + continue; + assert( RetValue == ABC_UPDATE_YES ); + // arrival times have changed - add fanouts to the frontier + Abc_ObjForEachFanout( pObj, pFanout, k ) + if ( pFanout->fMarkA == 0 ) + { + Vec_PtrPush( vFrontier, pFanout ); + pFanout->fMarkA = 1; + } + } + // clean the nodes + Vec_PtrForEachEntryStart( vFrontier, pObj, k, i ) + pObj->fMarkA = 0; + + // report the results + if ( RetValue == ABC_UPDATE_FAIL ) + printf( "Period = %3d. Updated nodes = %6d. Infeasible\n", Fi, vFrontier->nSize ); + else + printf( "Period = %3d. Updated nodes = %6d. Feasible\n", Fi, vFrontier->nSize ); + Vec_PtrFree( vFrontier ); + return RetValue != ABC_UPDATE_FAIL; +} + +/**Function************************************************************* + + Synopsis [Computes the l-value of the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NodeUpdateLValue( Abc_Obj_t * pObj, int Fi ) +{ + int lValueNew, lValue0, lValue1; + assert( !Abc_ObjIsPi(pObj) ); + lValue0 = Abc_NodeReadLValue(Abc_ObjFanin0(pObj)) - Fi * Abc_ObjFaninL0(pObj); + if ( Abc_ObjFaninNum(pObj) == 2 ) + lValue1 = Abc_NodeReadLValue(Abc_ObjFanin1(pObj)) - Fi * Abc_ObjFaninL1(pObj); + else + lValue1 = -ABC_INFINITY; + lValueNew = 1 + ABC_MAX( lValue0, lValue1 ); + if ( Abc_ObjIsPo(pObj) && lValueNew > Fi ) + return ABC_UPDATE_FAIL; + if ( lValueNew == Abc_NodeReadLValue(pObj) ) + return ABC_UPDATE_NO; + Abc_NodeSetLValue( pObj, lValueNew ); + return ABC_UPDATE_YES; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + diff --git a/src/base/abcs/abcSeq.c b/src/base/abcs/abcSeq.c new file mode 100644 index 00000000..d6b1b8e5 --- /dev/null +++ b/src/base/abcs/abcSeq.c @@ -0,0 +1,644 @@ +/**CFile**************************************************************** + + FileName [abcSeq.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: abcSeq.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abc.h" + +/* + A sequential network is an AIG whose edges have number-of-latches attributes, + in addition to the complemented attibutes. + + The sets of PIs/POs remain the same as in logic network. + Constant 1 node can only be used as a fanin of a PO node and the reset node. + The reset node produces sequence (01111...). It is used to create the + initialization logic of all latches. + The latches do not have explicit initial state but they are implicitly + reset by the reset node. + +*/ + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static Vec_Int_t * Abc_NtkSeqCountLatches( Abc_Ntk_t * pNtk ); +static void Abc_NodeSeqCountLatches( Abc_Obj_t * pObj, Vec_Int_t * vNumbers ); + +static void Abc_NtkSeqCreateLatches( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ); +static void Abc_NodeSeqCreateLatches( Abc_Obj_t * pObj, int nLatches ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Converts a normal AIG into a sequential AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkAigToSeq( Abc_Ntk_t * pNtk ) +{ + int fCheck = 1; + Abc_Ntk_t * pNtkNew; + Abc_Aig_t * pManNew; + Vec_Ptr_t * vNodes; + Abc_Obj_t * pObj, * pConst, * pFanout, * pFaninNew, * pLatch; + int i, k, fChange, Counter; + + assert( Abc_NtkIsStrash(pNtk) ); + // start the network + pNtkNew = Abc_NtkStartFrom( pNtk, ABC_TYPE_SEQ, ABC_FUNC_AIG ); + pManNew = pNtkNew->pManFunc; + + // set mapping of the constant nodes + Abc_AigConst1(pNtk->pManFunc)->pCopy = Abc_AigConst1( pManNew ); + Abc_AigReset(pNtk->pManFunc)->pCopy = Abc_AigReset( pManNew ); + + // get rid of initial states + Abc_NtkForEachLatch( pNtk, pObj, i ) + { + pObj->pNext = pObj->pCopy; + if ( Abc_LatchIsInit0(pObj) ) + pObj->pCopy = Abc_AigAnd( pManNew, pObj->pCopy, Abc_AigReset(pManNew) ); + else if ( Abc_LatchIsInit1(pObj) ) + pObj->pCopy = Abc_AigOr( pManNew, pObj->pCopy, Abc_ObjNot( Abc_AigReset(pManNew) ) ); + } + + // copy internal nodes + vNodes = Abc_AigDfs( pNtk, 1, 0 ); + Vec_PtrForEachEntry( vNodes, pObj, i ) + if ( Abc_ObjFaninNum(pObj) == 2 ) + pObj->pCopy = Abc_AigAnd( pManNew, Abc_ObjChild0Copy(pObj), Abc_ObjChild1Copy(pObj) ); + Vec_PtrFree( vNodes ); + + // relink the CO nodes + Abc_NtkForEachPo( pNtk, pObj, i ) + Abc_ObjAddFanin( pObj->pCopy, Abc_ObjChild0Copy(pObj) ); + Abc_NtkForEachLatch( pNtk, pObj, i ) + Abc_ObjAddFanin( pObj->pNext, Abc_ObjChild0Copy(pObj) ); + + // propagate constant input latches in the new network + Counter = 0; + fChange = 1; + while ( fChange ) + { + fChange = 0; + Abc_NtkForEachLatch( pNtkNew, pLatch, i ) + { + if ( Abc_ObjFanoutNum(pLatch) == 0 ) + continue; + pFaninNew = Abc_ObjFanin0(pLatch); + if ( Abc_ObjIsCi(pFaninNew) || !Abc_NodeIsConst(pFaninNew) ) + continue; + pConst = Abc_ObjNotCond( Abc_AigConst1(pManNew), Abc_ObjFaninC0(pLatch) ); + Abc_AigReplace( pManNew, pLatch, pConst ); + fChange = 1; + Counter++; + } + } + if ( Counter ) + fprintf( stdout, "Latch sweeping removed %d latches (out of %d).\n", Counter, Abc_NtkLatchNum(pNtk) ); + + // redirect fanouts of each latch to the latch fanins + vNodes = Vec_PtrAlloc( 100 ); + Abc_NtkForEachLatch( pNtkNew, pLatch, i ) + { +//printf( "Latch %s. Fanouts = %d.\n", Abc_ObjName(pLatch), Abc_ObjFanoutNum(pLatch) ); + + Abc_NodeCollectFanouts( pLatch, vNodes ); + Vec_PtrForEachEntry( vNodes, pFanout, k ) + { + if ( Abc_ObjFaninId0(pFanout) == Abc_ObjFaninId1(pFanout)) + printf( " ******* Identical fanins!!! ******* \n" ); + + if ( Abc_ObjFaninId0(pFanout) == (int)pLatch->Id ) + { +// pFaninNew = Abc_ObjNotCond( Abc_ObjChild0(pLatch), Abc_ObjFaninC0(pFanout) ); + pFaninNew = Abc_ObjChild0(pLatch); + Abc_ObjPatchFanin( pFanout, pLatch, pFaninNew ); + Abc_ObjAddFaninL0( pFanout, 1 ); + } + else if ( Abc_ObjFaninId1(pFanout) == (int)pLatch->Id ) + { +// pFaninNew = Abc_ObjNotCond( Abc_ObjChild0(pLatch), Abc_ObjFaninC1(pFanout) ); + pFaninNew = Abc_ObjChild0(pLatch); + Abc_ObjPatchFanin( pFanout, pLatch, pFaninNew ); + Abc_ObjAddFaninL1( pFanout, 1 ); + } + else + assert( 0 ); + } + assert( Abc_ObjFanoutNum(pLatch) == 0 ); + Abc_NtkDeleteObj( pLatch ); + } + Vec_PtrFree( vNodes ); + // get rid of latches altogether +// Abc_NtkForEachLatch( pNtkNew, pObj, i ) +// Abc_NtkDeleteObj( pObj ); + assert( pNtkNew->nLatches == 0 ); + Vec_PtrClear( pNtkNew->vLats ); + Vec_PtrShrink( pNtkNew->vCis, pNtk->nPis ); + Vec_PtrShrink( pNtkNew->vCos, pNtk->nPos ); + +/* +///////////////////////////////////////////// +Abc_NtkForEachNode( pNtkNew, pObj, i ) + if ( !Abc_NodeIsConst(pObj) ) + if ( Abc_ObjFaninL0(pObj) + Abc_ObjFaninL1(pObj) > 20 ) + printf( "(%d,%d) ", Abc_ObjFaninL0(pObj), Abc_ObjFaninL1(pObj) ); +Abc_NtkForEachCo( pNtkNew, pObj, i ) + printf( "(%d) ", Abc_ObjFaninL0(pObj) ); +///////////////////////////////////////////// +printf( "\n" ); +*/ + + if ( pNtk->pExdc ) + fprintf( stdout, "Warning: EXDC is dropped when converting to sequential AIG.\n" ); + if ( fCheck && !Abc_NtkCheck( pNtkNew ) ) + fprintf( stdout, "Abc_NtkAigToSeq(): Network check has failed.\n" ); + return pNtkNew; +} + +/**Function************************************************************* + + Synopsis [Converts a sequential AIG into a logic SOP network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkSeqToLogicSop( Abc_Ntk_t * pNtk ) +{ + int fCheck = 1; + Abc_Ntk_t * pNtkNew; + Abc_Obj_t * pObj, * pFanin, * pFaninNew; + int i, k, c; + assert( Abc_NtkIsSeq(pNtk) ); + // start the network + pNtkNew = Abc_NtkStartFrom( pNtk, ABC_TYPE_LOGIC, ABC_FUNC_SOP ); + // create the constant and reset nodes + Abc_NtkDupConst1( pNtk, pNtkNew ); + Abc_NtkDupReset( pNtk, pNtkNew ); + // duplicate the nodes, create node functions and latches + Abc_NtkForEachNode( pNtk, pObj, i ) + { + if ( Abc_NodeIsConst(pObj) ) + continue; + Abc_NtkDupObj(pNtkNew, pObj); + pObj->pCopy->pData = Abc_SopCreateAnd2( pNtkNew->pManFunc, Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj) ); + } + // create latches for the new nodes + Abc_NtkSeqCreateLatches( pNtk, pNtkNew ); + // connect the objects + Abc_NtkForEachObj( pNtk, pObj, i ) + Abc_ObjForEachFanin( pObj, pFanin, k ) + { + // find the fanin + pFaninNew = pFanin->pCopy; + for ( c = 0; c < Abc_ObjFaninL(pObj, k); c++ ) + pFaninNew = pFaninNew->pCopy; + Abc_ObjAddFanin( pObj->pCopy, pFaninNew ); + } + // set the complemented attributed of CO edges (to be fixed by making simple COs) + Abc_NtkForEachPo( pNtk, pObj, i ) + if ( Abc_ObjFaninC0(pObj) ) + Abc_ObjSetFaninC( pObj->pCopy, 0 ); + // fix the problem with complemented and duplicated CO edges + Abc_NtkLogicMakeSimpleCos( pNtkNew, 0 ); + // duplicate the EXDC network + if ( pNtk->pExdc ) + fprintf( stdout, "Warning: EXDC network is not copied.\n" ); + if ( fCheck && !Abc_NtkCheck( pNtkNew ) ) + fprintf( stdout, "Abc_NtkSeqToLogic(): Network check has failed.\n" ); + return pNtkNew; +} + + + + +/**Function************************************************************* + + Synopsis [Finds max number of latches on the fanout edges of each node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Abc_NtkSeqCountLatches( Abc_Ntk_t * pNtk ) +{ + Vec_Int_t * vNumbers; + Abc_Obj_t * pObj; + int i; + assert( Abc_NtkIsSeq( pNtk ) ); + // start the array of counters + vNumbers = Vec_IntAlloc( 0 ); + Vec_IntFill( vNumbers, Abc_NtkObjNumMax(pNtk), 0 ); + // count for each edge + Abc_NtkForEachObj( pNtk, pObj, i ) + Abc_NodeSeqCountLatches( pObj, vNumbers ); + return vNumbers; +} + +/**Function************************************************************* + + Synopsis [Countes the latch numbers due to the fanins edges of the given node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NodeSeqCountLatches( Abc_Obj_t * pObj, Vec_Int_t * vNumbers ) +{ + Abc_Obj_t * pFanin; + int k, nLatches; + // go through each fanin edge + Abc_ObjForEachFanin( pObj, pFanin, k ) + { + nLatches = Abc_ObjFaninL( pObj, k ); + if ( nLatches == 0 ) + continue; + if ( Vec_IntEntry( vNumbers, pFanin->Id ) < nLatches ) + Vec_IntWriteEntry( vNumbers, pFanin->Id, nLatches ); + } +} + + + +/**Function************************************************************* + + Synopsis [Creates latches.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkSeqCreateLatches( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ) +{ + Vec_Int_t * vNumbers; + Abc_Obj_t * pObj; + int i; + assert( Abc_NtkIsSeq( pNtk ) ); + // create latches for each new object according to the counters + vNumbers = Abc_NtkSeqCountLatches( pNtk ); + Abc_NtkForEachObj( pNtk, pObj, i ) + { + if ( pObj->pCopy == NULL ) + continue; + Abc_NodeSeqCreateLatches( pObj->pCopy, Vec_IntEntry(vNumbers, (int)pObj->Id) ); + } + Vec_IntFree( vNumbers ); + // add latch to the PI/PO lists, create latch names + Abc_NtkFinalizeLatches( pNtkNew ); +} + +/**Function************************************************************* + + Synopsis [Creates the given number of latches for this object.] + + Description [The latches are attached to the node and to each other + through the pCopy field.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NodeSeqCreateLatches( Abc_Obj_t * pObj, int nLatches ) +{ + Abc_Ntk_t * pNtk = pObj->pNtk; + Abc_Obj_t * pLatch, * pFanin; + int i; + pFanin = pObj; + for ( i = 0, pFanin = pObj; i < nLatches; pFanin = pLatch, i++ ) + { + pLatch = Abc_NtkCreateLatch( pNtk ); + Abc_LatchSetInitDc(pLatch); + Abc_ObjAddFanin( pLatch, pFanin ); + pFanin->pCopy = pLatch; + } +} + +/**Function************************************************************* + + Synopsis [Counters the number of latches in the sequential AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NtkSeqLatchNum( Abc_Ntk_t * pNtk ) +{ + Vec_Int_t * vNumbers; + Abc_Obj_t * pObj; + int i, Counter; + assert( Abc_NtkIsSeq( pNtk ) ); + // create latches for each new object according to the counters + Counter = 0; + vNumbers = Abc_NtkSeqCountLatches( pNtk ); + Abc_NtkForEachPi( pNtk, pObj, i ) + { + assert( Abc_ObjFanoutLMax(pObj) == Vec_IntEntry(vNumbers, (int)pObj->Id) ); + Counter += Vec_IntEntry(vNumbers, (int)pObj->Id); + } + Abc_NtkForEachNode( pNtk, pObj, i ) + { + if ( Abc_NodeIsConst(pObj) ) + continue; + assert( Abc_ObjFanoutLMax(pObj) == Vec_IntEntry(vNumbers, (int)pObj->Id) ); + Counter += Vec_IntEntry(vNumbers, (int)pObj->Id); + } + Vec_IntFree( vNumbers ); + if ( Abc_ObjFanoutNum( Abc_AigReset(pNtk->pManFunc) ) > 0 ) + Counter++; + return Counter; +} + + + + + + +/**Function************************************************************* + + Synopsis [Performs forward retiming of the sequential AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkSeqRetimeForward( Abc_Ntk_t * pNtk ) +{ + Vec_Ptr_t * vNodes; + Abc_Obj_t * pNode, * pFanout; + int i, k, nLatches; + assert( Abc_NtkIsSeq( pNtk ) ); + // assume that all nodes can be retimed + vNodes = Vec_PtrAlloc( 100 ); + Abc_NtkForEachNode( pNtk, pNode, i ) + { + if ( Abc_NodeIsConst(pNode) ) + continue; + Vec_PtrPush( vNodes, pNode ); + pNode->fMarkA = 1; + } + // process the nodes + Vec_PtrForEachEntry( vNodes, pNode, i ) + { +// printf( "(%d,%d) ", Abc_ObjFaninL0(pNode), Abc_ObjFaninL0(pNode) ); + // get the number of latches to retime + nLatches = Abc_ObjFaninLMin(pNode); + if ( nLatches == 0 ) + continue; + assert( nLatches > 0 ); + // subtract these latches on the fanin side + Abc_ObjAddFaninL0( pNode, -nLatches ); + Abc_ObjAddFaninL1( pNode, -nLatches ); + // add these latches on the fanout size + Abc_ObjForEachFanout( pNode, pFanout, k ) + { + Abc_ObjAddFanoutL( pNode, pFanout, nLatches ); + if ( pFanout->fMarkA == 0 ) + { // schedule the node for updating + Vec_PtrPush( vNodes, pFanout ); + pFanout->fMarkA = 1; + } + } + // unmark the node as processed + pNode->fMarkA = 0; + } + Vec_PtrFree( vNodes ); + // clean the marks + Abc_NtkForEachNode( pNtk, pNode, i ) + { + pNode->fMarkA = 0; + if ( Abc_NodeIsConst(pNode) ) + continue; + assert( Abc_ObjFaninLMin(pNode) == 0 ); + } +} + +/**Function************************************************************* + + Synopsis [Performs forward retiming of the sequential AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkSeqRetimeBackward( Abc_Ntk_t * pNtk ) +{ + Vec_Ptr_t * vNodes; + Abc_Obj_t * pNode, * pFanin, * pFanout; + int i, k, nLatches; + assert( Abc_NtkIsSeq( pNtk ) ); + // assume that all nodes can be retimed + vNodes = Vec_PtrAlloc( 100 ); + Abc_NtkForEachNode( pNtk, pNode, i ) + { + if ( Abc_NodeIsConst(pNode) ) + continue; + Vec_PtrPush( vNodes, pNode ); + pNode->fMarkA = 1; + } + // process the nodes + Vec_PtrForEachEntry( vNodes, pNode, i ) + { + // get the number of latches to retime + nLatches = Abc_ObjFanoutLMin(pNode); + if ( nLatches == 0 ) + continue; + assert( nLatches > 0 ); + // subtract these latches on the fanout side + Abc_ObjForEachFanout( pNode, pFanout, k ) + Abc_ObjAddFanoutL( pNode, pFanout, -nLatches ); + // add these latches on the fanin size + Abc_ObjForEachFanin( pNode, pFanin, k ) + { + Abc_ObjAddFaninL( pNode, k, nLatches ); + if ( Abc_ObjIsPi(pFanin) || Abc_NodeIsConst(pFanin) ) + continue; + if ( pFanin->fMarkA == 0 ) + { // schedule the node for updating + Vec_PtrPush( vNodes, pFanin ); + pFanin->fMarkA = 1; + } + } + // unmark the node as processed + pNode->fMarkA = 0; + } + Vec_PtrFree( vNodes ); + // clean the marks + Abc_NtkForEachNode( pNtk, pNode, i ) + { + pNode->fMarkA = 0; + if ( Abc_NodeIsConst(pNode) ) + continue; +// assert( Abc_ObjFanoutLMin(pNode) == 0 ); + } +} + + + + +/**Function************************************************************* + + Synopsis [Returns the latch number of the fanout.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_ObjFanoutL( Abc_Obj_t * pObj, Abc_Obj_t * pFanout ) +{ + assert( Abc_NtkIsSeq(pObj->pNtk) ); + if ( Abc_ObjFaninId0(pFanout) == (int)pObj->Id ) + return Abc_ObjFaninL0(pFanout); + else if ( Abc_ObjFaninId1(pFanout) == (int)pObj->Id ) + return Abc_ObjFaninL1(pFanout); + else + assert( 0 ); + return 0; +} + +/**Function************************************************************* + + Synopsis [Sets the latch number of the fanout.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_ObjSetFanoutL( Abc_Obj_t * pObj, Abc_Obj_t * pFanout, int nLats ) +{ + assert( Abc_NtkIsSeq(pObj->pNtk) ); + if ( Abc_ObjFaninId0(pFanout) == (int)pObj->Id ) + Abc_ObjSetFaninL0(pFanout, nLats); + else if ( Abc_ObjFaninId1(pFanout) == (int)pObj->Id ) + Abc_ObjSetFaninL1(pFanout, nLats); + else + assert( 0 ); +} + +/**Function************************************************************* + + Synopsis [Adds to the latch number of the fanout.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_ObjAddFanoutL( Abc_Obj_t * pObj, Abc_Obj_t * pFanout, int nLats ) +{ + assert( Abc_NtkIsSeq(pObj->pNtk) ); + if ( Abc_ObjFaninId0(pFanout) == (int)pObj->Id ) + Abc_ObjAddFaninL0(pFanout, nLats); + else if ( Abc_ObjFaninId1(pFanout) == (int)pObj->Id ) + Abc_ObjAddFaninL1(pFanout, nLats); + else + assert( 0 ); +} + +/**Function************************************************************* + + Synopsis [Returns the latch number of the fanout.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_ObjFanoutLMax( Abc_Obj_t * pObj ) +{ + Abc_Obj_t * pFanout; + int i, nLatch, nLatchRes; + nLatchRes = 0; + Abc_ObjForEachFanout( pObj, pFanout, i ) + if ( nLatchRes < (nLatch = Abc_ObjFanoutL(pObj, pFanout)) ) + nLatchRes = nLatch; + assert( nLatchRes >= 0 ); + return nLatchRes; +} + +/**Function************************************************************* + + Synopsis [Returns the latch number of the fanout.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_ObjFanoutLMin( Abc_Obj_t * pObj ) +{ + Abc_Obj_t * pFanout; + int i, nLatch, nLatchRes; + nLatchRes = ABC_INFINITY; + Abc_ObjForEachFanout( pObj, pFanout, i ) + if ( nLatchRes > (nLatch = Abc_ObjFanoutL(pObj, pFanout)) ) + nLatchRes = nLatch; + assert( nLatchRes < ABC_INFINITY ); + return nLatchRes; +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/base/abcs/abc_.c b/src/base/abcs/abc_.c new file mode 100644 index 00000000..bef3836f --- /dev/null +++ b/src/base/abcs/abc_.c @@ -0,0 +1,47 @@ +/**CFile**************************************************************** + + FileName [abc_.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Network and node package.] + + Synopsis [] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: abc_.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abc.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/base/abcs/module.make b/src/base/abcs/module.make new file mode 100644 index 00000000..ad084bb8 --- /dev/null +++ b/src/base/abcs/module.make @@ -0,0 +1,2 @@ +SRC += src/base/abcs/abcRetime.c \ + src/base/abcs/abcSeq.c diff --git a/src/base/io/ioWriteDot_old.c b/src/base/io/ioWriteDot_old.c deleted file mode 100644 index 59bbbde3..00000000 --- a/src/base/io/ioWriteDot_old.c +++ /dev/null @@ -1,325 +0,0 @@ -/**CFile**************************************************************** - - FileName [ioWriteDot.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Command processing package.] - - Synopsis [Procedures to write the graph structure of AIG in DOT.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: ioWriteDot.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "io.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Writes the graph structure of AIG in DOT.] - - Description [Useful for graph visualization using tools such as GraphViz: - http://www.graphviz.org/] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Io_WriteDot( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesShow, char * pFileName ) -{ - FILE * pFile; - Abc_Obj_t * pNode, * pFanin, * pPrev, * pTemp; - int LevelMin, LevelMax, fHasCos, Level, i; - int Limit = 200; - - if ( vNodes->nSize < 1 ) - { - printf( "The set has no nodes. DOT file is not written.\n" ); - return; - } - - if ( vNodes->nSize > Limit ) - { - printf( "The set has more than %d nodes. DOT file is not written.\n", Limit ); - return; - } - - // start the output file - if ( (pFile = fopen( pFileName, "w" )) == NULL ) - { - fprintf( stdout, "Cannot open the intermediate file \"%s\".\n", pFileName ); - return; - } - - // mark the nodes from the set - Vec_PtrForEachEntry( vNodes, pNode, i ) - pNode->fMarkC = 1; - if ( vNodesShow ) - Vec_PtrForEachEntry( vNodesShow, pNode, i ) - pNode->fMarkB = 1; - - // find the largest and the smallest levels - LevelMin = 10000; - LevelMax = -1; - fHasCos = 0; - Vec_PtrForEachEntry( vNodes, pNode, i ) - { - if ( Abc_ObjIsCo(pNode) ) - { - fHasCos = 1; - continue; - } - if ( LevelMin > (int)pNode->Level ) - LevelMin = pNode->Level; - if ( LevelMax < (int)pNode->Level ) - LevelMax = pNode->Level; - } - - // set the level of the CO nodes - if ( fHasCos ) - { - LevelMax++; - Vec_PtrForEachEntry( vNodes, pNode, i ) - { - if ( Abc_ObjIsCo(pNode) ) - pNode->Level = LevelMax; - } - } - - // write the DOT header - fprintf( pFile, "# %s\n", "AIG generated by ABC" ); - fprintf( pFile, "\n" ); - fprintf( pFile, "digraph AIG {\n" ); - fprintf( pFile, "size = \"7.5,10\";\n" ); -// fprintf( pFile, "ranksep = 0.5;\n" ); -// fprintf( pFile, "nodesep = 0.5;\n" ); - fprintf( pFile, "center = true;\n" ); -// fprintf( pFile, "edge [fontsize = 10];\n" ); -// fprintf( pFile, "edge [dir = back];\n" ); -// fprintf( pFile, "edge [dir = none];\n" ); - fprintf( pFile, "\n" ); - - // labels on the left of the picture - fprintf( pFile, "{\n" ); - fprintf( pFile, " node [shape = plaintext];\n" ); - fprintf( pFile, " edge [style = invis];\n" ); - fprintf( pFile, " LevelTitle1 [label=\"\"];\n" ); - fprintf( pFile, " LevelTitle2 [label=\"\"];\n" ); - // generate node names with labels - for ( Level = LevelMax; Level >= LevelMin; Level-- ) - { - // the visible node name - fprintf( pFile, " Level%d", Level ); - fprintf( pFile, " [label = " ); - // label name - fprintf( pFile, "\"" ); - fprintf( pFile, "\"" ); - fprintf( pFile, "];\n" ); - } - - // genetate the sequence of visible/invisible nodes to mark levels - fprintf( pFile, " LevelTitle1 -> LevelTitle2 ->" ); - for ( Level = LevelMax; Level >= LevelMin; Level-- ) - { - // the visible node name - fprintf( pFile, " Level%d", Level ); - // the connector - if ( Level != LevelMin ) - fprintf( pFile, " ->" ); - else - fprintf( pFile, ";" ); - } - fprintf( pFile, "\n" ); - fprintf( pFile, "}" ); - fprintf( pFile, "\n" ); - fprintf( pFile, "\n" ); - - // generate title box on top - fprintf( pFile, "{\n" ); - fprintf( pFile, " rank = same;\n" ); - fprintf( pFile, " LevelTitle1;\n" ); - fprintf( pFile, " title1 [shape=plaintext,\n" ); - fprintf( pFile, " fontsize=20,\n" ); - fprintf( pFile, " fontname = \"Times-Roman\",\n" ); - fprintf( pFile, " label=\"" ); - fprintf( pFile, "%s", "AIG generated by ABC" ); - fprintf( pFile, "\\n" ); - fprintf( pFile, "Benchmark \\\"%s\\\". ", pNtk->pName ); - fprintf( pFile, "Time was %s. ", Extra_TimeStamp() ); - fprintf( pFile, "\"\n" ); - fprintf( pFile, " ];\n" ); - fprintf( pFile, "}" ); - fprintf( pFile, "\n" ); - fprintf( pFile, "\n" ); - - // generate statistics box - fprintf( pFile, "{\n" ); - fprintf( pFile, " rank = same;\n" ); - fprintf( pFile, " LevelTitle2;\n" ); - fprintf( pFile, " title2 [shape=plaintext,\n" ); - fprintf( pFile, " fontsize=18,\n" ); - fprintf( pFile, " fontname = \"Times-Roman\",\n" ); - fprintf( pFile, " label=\"" ); - fprintf( pFile, "The set contains %d nodes and spans %d levels.", vNodes->nSize, LevelMax - LevelMin ); - fprintf( pFile, "\\n" ); - fprintf( pFile, "\"\n" ); - fprintf( pFile, " ];\n" ); - fprintf( pFile, "}" ); - fprintf( pFile, "\n" ); - fprintf( pFile, "\n" ); - - // generate the POs - if ( fHasCos ) - { - fprintf( pFile, "{\n" ); - fprintf( pFile, " rank = same;\n" ); - // the labeling node of this level - fprintf( pFile, " Level%d;\n", LevelMax ); - // generat the PO nodes - Vec_PtrForEachEntry( vNodes, pNode, i ) - { - if ( !Abc_ObjIsCo(pNode) ) - continue; - fprintf( pFile, " Node%d%s [label = \"%s\"", pNode->Id, (Abc_ObjIsLatch(pNode)? "Top":""), Abc_ObjName(pNode) ); - fprintf( pFile, ", shape = invtriangle" ); - if ( pNode->fMarkB ) - fprintf( pFile, ", style = filled" ); - fprintf( pFile, ", color = coral, fillcolor = coral" ); - fprintf( pFile, "];\n" ); - } - fprintf( pFile, "}" ); - fprintf( pFile, "\n" ); - fprintf( pFile, "\n" ); - } - - // generate nodes of each rank - for ( Level = LevelMax - fHasCos; Level >= LevelMin && Level > 0; Level-- ) - { - fprintf( pFile, "{\n" ); - fprintf( pFile, " rank = same;\n" ); - // the labeling node of this level - fprintf( pFile, " Level%d;\n", Level ); - Vec_PtrForEachEntry( vNodes, pNode, i ) - { - if ( (int)pNode->Level != Level ) - continue; - fprintf( pFile, " Node%d [label = \"%d\"", pNode->Id, pNode->Id ); - fprintf( pFile, ", shape = ellipse" ); - if ( pNode->fMarkB ) - fprintf( pFile, ", style = filled" ); - fprintf( pFile, "];\n" ); - } - fprintf( pFile, "}" ); - fprintf( pFile, "\n" ); - fprintf( pFile, "\n" ); - } - - // generate the PI nodes if any - if ( LevelMin == 0 ) - { - fprintf( pFile, "{\n" ); - fprintf( pFile, " rank = same;\n" ); - // the labeling node of this level - fprintf( pFile, " Level%d;\n", LevelMin ); - // generat the PO nodes - Vec_PtrForEachEntry( vNodes, pNode, i ) - { - if ( !Abc_ObjIsCi(pNode) ) - continue; - fprintf( pFile, " Node%d%s [label = \"%s\"", pNode->Id, (Abc_ObjIsLatch(pNode)? "Bot":""), Abc_ObjName(pNode) ); - fprintf( pFile, ", shape = triangle" ); - if ( pNode->fMarkB ) - fprintf( pFile, ", style = filled" ); - fprintf( pFile, ", color = coral, fillcolor = coral" ); - fprintf( pFile, "];\n" ); - } - fprintf( pFile, "}" ); - fprintf( pFile, "\n" ); - fprintf( pFile, "\n" ); - } - - // generate invisible edges from the square down - fprintf( pFile, "title1 -> title2 [style = invis];\n" ); - Vec_PtrForEachEntry( vNodes, pNode, i ) - { - if ( (int)pNode->Level != LevelMax ) - continue; - fprintf( pFile, "title2 -> Node%d%s [style = invis];\n", pNode->Id ); - } - - // generate edges - Vec_PtrForEachEntry( vNodes, pNode, i ) - { - if ( Abc_ObjFaninNum(pNode) == 0 ) - continue; - // generate the edge from this node to the next - pFanin = Abc_ObjFanin0(pNode); - if ( pFanin->fMarkC ) - { - fprintf( pFile, "Node%d%s", pNode->Id, (Abc_ObjIsLatch(pNode)? "Top":"") ); - fprintf( pFile, " -> " ); - fprintf( pFile, "Node%d%s", pFanin->Id, (Abc_ObjIsLatch(pFanin)? "Bot":"") ); - fprintf( pFile, " [style = %s]", Abc_ObjFaninC0(pNode)? "dashed" : "bold" ); - fprintf( pFile, ";\n" ); - } - if ( Abc_ObjFaninNum(pNode) == 1 ) - continue; - // generate the edge from this node to the next - pFanin = Abc_ObjFanin1(pNode); - if ( pFanin->fMarkC ) - { - fprintf( pFile, "Node%d", pNode->Id ); - fprintf( pFile, " -> " ); - fprintf( pFile, "Node%d%s", pFanin->Id, (Abc_ObjIsLatch(pFanin)? "Bot":"") ); - fprintf( pFile, " [style = %s]", Abc_ObjFaninC1(pNode)? "dashed" : "bold" ); - fprintf( pFile, ";\n" ); - } - // generate the edges between the equivalent nodes - pPrev = pNode; - for ( pTemp = pNode->pData; pTemp; pTemp = pTemp->pData ) - { - if ( pTemp->fMarkC ) - { - fprintf( pFile, "Node%d", pPrev->Id ); - fprintf( pFile, " -> " ); - fprintf( pFile, "Node%d", pTemp->Id ); - fprintf( pFile, " [style = %s]", (pPrev->fPhase ^ pTemp->fPhase)? "dashed" : "bold" ); - fprintf( pFile, ";\n" ); - pPrev = pTemp; - } - } - } - - fprintf( pFile, "}" ); - fprintf( pFile, "\n" ); - fprintf( pFile, "\n" ); - fclose( pFile ); - - // unmark the nodes from the set - Vec_PtrForEachEntry( vNodes, pNode, i ) - pNode->fMarkC = 0; - if ( vNodesShow ) - Vec_PtrForEachEntry( vNodesShow, pNode, i ) - pNode->fMarkB = 0; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/map/fpga/fpga.h b/src/map/fpga/fpga.h index 9dad1670..19241a74 100644 --- a/src/map/fpga/fpga.h +++ b/src/map/fpga/fpga.h @@ -91,6 +91,7 @@ extern void Fpga_ManSetFanoutViolations( Fpga_Man_t * p, int nVio ); extern void Fpga_ManSetChoiceNodeNum( Fpga_Man_t * p, int nChoiceNodes ); extern void Fpga_ManSetChoiceNum( Fpga_Man_t * p, int nChoices ); extern void Fpga_ManSetVerbose( Fpga_Man_t * p, int fVerbose ); +extern void Fpga_ManSetSwitching( Fpga_Man_t * p, int fSwitching ); extern void Fpga_ManSetLatchNum( Fpga_Man_t * p, int nLatches ); extern void Fpga_ManSetName( Fpga_Man_t * p, char * pFileName ); @@ -110,6 +111,7 @@ extern void Fpga_NodeSetData1( Fpga_Node_t * p, Fpga_Node_t * pNode ) extern void Fpga_NodeSetArrival( Fpga_Node_t * p, float Time ); extern void Fpga_NodeSetNextE( Fpga_Node_t * p, Fpga_Node_t * pNextE ); extern void Fpga_NodeSetRepr( Fpga_Node_t * p, Fpga_Node_t * pRepr ); +extern void Fpga_NodeSetSwitching( Fpga_Node_t * p, float Switching ); extern int Fpga_NodeIsConst( Fpga_Node_t * p ); extern int Fpga_NodeIsVar( Fpga_Node_t * p ); diff --git a/src/map/fpga/fpgaCore.c b/src/map/fpga/fpgaCore.c index 0fc90228..95b9ca49 100644 --- a/src/map/fpga/fpgaCore.c +++ b/src/map/fpga/fpgaCore.c @@ -97,22 +97,26 @@ int Fpga_Mapping( Fpga_Man_t * p ) ***********************************************************************/ int Fpga_MappingPostProcess( Fpga_Man_t * p ) { - float aAreaTotalPrev, aAreaTotalCur, aAreaTotalCur2; + int fShowSwitching = 0; + int fRecoverAreaFlow = 1; + int fRecoverArea = 1; + float aAreaTotalCur, aAreaTotalCur2; int Iter, clk; // compute area, set references, and collect nodes used in the mapping + Iter = 1; aAreaTotalCur = Fpga_MappingSetRefsAndArea( p ); if ( p->fVerbose ) { -printf( "Iteration %dD : Area = %11.1f ", 0, aAreaTotalCur ); +printf( "Iteration %dD : Area = %8.1f ", Iter++, aAreaTotalCur ); +if ( fShowSwitching ) +printf( "Switch = %8.1f ", Fpga_MappingGetSwitching(p,p->vMapping) ); PRT( "Time", p->timeMatch ); } - Iter = 1; - do { + if ( fRecoverAreaFlow ) + { clk = clock(); - // save the previous area flow - aAreaTotalPrev = aAreaTotalCur; // compute the required times and the fanouts Fpga_TimeComputeRequiredGlobal( p ); // remap topologically @@ -124,33 +128,38 @@ clk = clock(); // for some reason, this works better on benchmarks if ( p->fVerbose ) { -printf( "Iteration %dF : Area = %11.1f ", Iter++, aAreaTotalCur ); +printf( "Iteration %dF : Area = %8.1f ", Iter++, aAreaTotalCur ); +if ( fShowSwitching ) +printf( "Switch = %8.1f ", Fpga_MappingGetSwitching(p,p->vMapping) ); PRT( "Time", clock() - clk ); } - // quit if this iteration reduced area flow by less than 1% - } while ( aAreaTotalPrev > 1.02 * aAreaTotalCur ); + } // update reference counters aAreaTotalCur2 = Fpga_MappingSetRefsAndArea( p ); assert( aAreaTotalCur == aAreaTotalCur2 ); - do { + if ( fRecoverArea ) + { clk = clock(); - // save the previous area flow - aAreaTotalPrev = aAreaTotalCur; // compute the required times and the fanouts Fpga_TimeComputeRequiredGlobal( p ); // remap topologically - Fpga_MappingMatchesArea( p ); + if ( p->fSwitching ) + Fpga_MappingMatchesSwitch( p ); + else + Fpga_MappingMatchesArea( p ); // get the resulting area aAreaTotalCur = Fpga_MappingSetRefsAndArea( p ); if ( p->fVerbose ) { -printf( "Iteration %dA : Area = %11.1f ", Iter++, aAreaTotalCur ); +printf( "Iteration %d%s : Area = %8.1f ", Iter++, (p->fSwitching?"S":"A"), aAreaTotalCur ); +if ( fShowSwitching ) +printf( "Switch = %8.1f ", Fpga_MappingGetSwitching(p,p->vMapping) ); PRT( "Time", clock() - clk ); } - // quit if this iteration reduced area flow by less than 1% - } while ( aAreaTotalPrev > 1.02 * aAreaTotalCur ); + } + p->fAreaGlo = aAreaTotalCur; return 1; } diff --git a/src/map/fpga/fpgaCreate.c b/src/map/fpga/fpgaCreate.c index f3abbedb..b7bfa3c5 100644 --- a/src/map/fpga/fpgaCreate.c +++ b/src/map/fpga/fpgaCreate.c @@ -65,6 +65,7 @@ void Fpga_ManSetTimeLimit( Fpga_Man_t * p, float TimeLimit ) { p void Fpga_ManSetChoiceNodeNum( Fpga_Man_t * p, int nChoiceNodes ) { p->nChoiceNodes = nChoiceNodes; } void Fpga_ManSetChoiceNum( Fpga_Man_t * p, int nChoices ) { p->nChoices = nChoices; } void Fpga_ManSetVerbose( Fpga_Man_t * p, int fVerbose ) { p->fVerbose = fVerbose; } +void Fpga_ManSetSwitching( Fpga_Man_t * p, int fSwitching ) { p->fSwitching = fSwitching; } void Fpga_ManSetLatchNum( Fpga_Man_t * p, int nLatches ) { p->nLatches = nLatches; } void Fpga_ManSetName( Fpga_Man_t * p, char * pFileName ) { p->pFileName = pFileName; } @@ -104,6 +105,7 @@ void Fpga_NodeSetData0( Fpga_Node_t * p, char * pData ) { p-> void Fpga_NodeSetData1( Fpga_Node_t * p, Fpga_Node_t * pNode ) { p->pLevel = pNode; } void Fpga_NodeSetNextE( Fpga_Node_t * p, Fpga_Node_t * pNextE ) { p->pNextE = pNextE; } void Fpga_NodeSetRepr( Fpga_Node_t * p, Fpga_Node_t * pRepr ) { p->pRepr = pRepr; } +void Fpga_NodeSetSwitching( Fpga_Node_t * p, float Switching ) { p->Switching = Switching; } /**Function************************************************************* diff --git a/src/map/fpga/fpgaCutUtils.c b/src/map/fpga/fpgaCutUtils.c index abe703a2..2419cac4 100644 --- a/src/map/fpga/fpgaCutUtils.c +++ b/src/map/fpga/fpgaCutUtils.c @@ -439,109 +439,6 @@ float Fpga_CutDeref( Fpga_Man_t * pMan, Fpga_Node_t * pNode, Fpga_Cut_t * pCut, } - -/**function************************************************************* - - synopsis [Computes the exact area associated with the cut.] - - description [] - - sideeffects [] - - seealso [] - -***********************************************************************/ -float Fpga_CutGetSwitchDerefed( Fpga_Man_t * pMan, Fpga_Node_t * pNode, Fpga_Cut_t * pCut ) -{ - float aResult, aResult2; - if ( pCut->nLeaves == 1 ) - return 0; - aResult2 = Fpga_CutRefSwitch( pMan, pNode, pCut, 0 ); - aResult = Fpga_CutDerefSwitch( pMan, pNode, pCut, 0 ); -// assert( aResult == aResult2 ); - return aResult; -} - -/**function************************************************************* - - synopsis [References the cut.] - - description [This procedure is similar to the procedure NodeReclaim.] - - sideeffects [] - - seealso [] - -***********************************************************************/ -float Fpga_CutRefSwitch( Fpga_Man_t * pMan, Fpga_Node_t * pNode, Fpga_Cut_t * pCut, int fFanouts ) -{ - Fpga_Node_t * pNodeChild; - float aArea; - int i; - - // deref the fanouts -// if ( fFanouts ) -// Fpga_CutInsertFanouts( pMan, pNode, pCut ); - - // start the area of this cut - aArea = pNode->SwitchProb; - // go through the children - for ( i = 0; i < pCut->nLeaves; i++ ) - { - pNodeChild = pCut->ppLeaves[i]; - assert( pNodeChild->nRefs >= 0 ); - if ( pNodeChild->nRefs++ > 0 ) - continue; - if ( !Fpga_NodeIsAnd(pNodeChild) ) - { - aArea += pNodeChild->SwitchProb; - continue; - } - aArea += Fpga_CutRefSwitch( pMan, pNodeChild, pNodeChild->pCutBest, fFanouts ); - } - return aArea; -} - -/**function************************************************************* - - synopsis [Dereferences the cut.] - - description [This procedure is similar to the procedure NodeRecusiveDeref.] - - sideeffects [] - - seealso [] - -***********************************************************************/ -float Fpga_CutDerefSwitch( Fpga_Man_t * pMan, Fpga_Node_t * pNode, Fpga_Cut_t * pCut, int fFanouts ) -{ - Fpga_Node_t * pNodeChild; - float aArea; - int i; - - // deref the fanouts -// if ( fFanouts ) -// Fpga_CutRemoveFanouts( pMan, pNode, pCut ); - - // start the area of this cut - aArea = pNode->SwitchProb; - // go through the children - for ( i = 0; i < pCut->nLeaves; i++ ) - { - pNodeChild = pCut->ppLeaves[i]; - assert( pNodeChild->nRefs > 0 ); - if ( --pNodeChild->nRefs > 0 ) - continue; - if ( !Fpga_NodeIsAnd(pNodeChild) ) - { - aArea += pNodeChild->SwitchProb; - continue; - } - aArea += Fpga_CutDerefSwitch( pMan, pNodeChild, pNodeChild->pCutBest, fFanouts ); - } - return aArea; -} - /**Function************************************************************* Synopsis [Sets the used cuts to be the currently selected ones.] diff --git a/src/map/fpga/fpgaInt.h b/src/map/fpga/fpgaInt.h index 95203378..ec6057a7 100644 --- a/src/map/fpga/fpgaInt.h +++ b/src/map/fpga/fpgaInt.h @@ -120,12 +120,9 @@ struct Fpga_ManStruct_t_ // mapping parameters int nVarsMax; // the max number of variables -// int fTree; // the flag to enable tree mapping -// int fPower; // the flag to enable power optimization int fAreaRecovery; // the flag to use area flow as the first parameter int fVerbose; // the verbosiness flag -// int fRefCount; // enables reference counting -// int fSequential; // use sequential mapping + int fSwitching; // minimize the switching activity (instead of area) int nTravIds; // support of choice nodes @@ -137,7 +134,6 @@ struct Fpga_ManStruct_t_ // the supergate library Fpga_LutLib_t * pLutLib; // the current LUT library -// unsigned uTruths[6][2]; // the elementary truth tables // the memory managers Extra_MmFixed_t * mmNodes; // the memory manager for nodes @@ -215,7 +211,7 @@ struct Fpga_NodeStruct_t_ // the delay information float tRequired; // the best area flow float aEstFanouts; // the fanout estimation - float SwitchProb; // the probability of switching + float Switching; // the probability of switching int LValue; // the l-value of the node short nLatches1; // the number of latches on the first edge short nLatches2; // the number of latches on the second edge @@ -308,9 +304,6 @@ extern float Fpga_CutGetAreaRefed( Fpga_Man_t * pMan, Fpga_Cut_t * p extern float Fpga_CutGetAreaDerefed( Fpga_Man_t * pMan, Fpga_Cut_t * pCut ); extern float Fpga_CutRef( Fpga_Man_t * pMan, Fpga_Node_t * pNode, Fpga_Cut_t * pCut, int fFanouts ); extern float Fpga_CutDeref( Fpga_Man_t * pMan, Fpga_Node_t * pNode, Fpga_Cut_t * pCut, int fFanouts ); -extern float Fpga_CutGetSwitchDerefed( Fpga_Man_t * pMan, Fpga_Node_t * pNode, Fpga_Cut_t * pCut ); -extern float Fpga_CutRefSwitch( Fpga_Man_t * pMan, Fpga_Node_t * pNode, Fpga_Cut_t * pCut, int fFanouts ); -extern float Fpga_CutDerefSwitch( Fpga_Man_t * pMan, Fpga_Node_t * pNode, Fpga_Cut_t * pCut, int fFanouts ); extern float Fpga_CutGetAreaFlow( Fpga_Man_t * pMan, Fpga_Cut_t * pCut ); extern void Fpga_CutGetParameters( Fpga_Man_t * pMan, Fpga_Cut_t * pCut ); /*=== fraigFanout.c =============================================================*/ @@ -329,6 +322,11 @@ extern int Fpga_MappingMatchesSwitch( Fpga_Man_t * p ); /*=== fpgaShow.c =============================================================*/ extern void Fpga_MappingShow( Fpga_Man_t * pMan, char * pFileName ); extern void Fpga_MappingShowNodes( Fpga_Man_t * pMan, Fpga_Node_t ** ppRoots, int nRoots, char * pFileName ); +/*=== fpgaSwitch.c =============================================================*/ +extern float Fpga_CutGetSwitchDerefed( Fpga_Man_t * pMan, Fpga_Node_t * pNode, Fpga_Cut_t * pCut ); +extern float Fpga_CutRefSwitch( Fpga_Man_t * pMan, Fpga_Node_t * pNode, Fpga_Cut_t * pCut, int fFanouts ); +extern float Fpga_CutDerefSwitch( Fpga_Man_t * pMan, Fpga_Node_t * pNode, Fpga_Cut_t * pCut, int fFanouts ); +extern float Fpga_MappingGetSwitching( Fpga_Man_t * pMan, Fpga_NodeVec_t * vMapping ); /*=== fpgaTime.c ===============================================================*/ extern float Fpga_TimeCutComputeArrival( Fpga_Man_t * pMan, Fpga_Cut_t * pCut ); extern float Fpga_TimeCutComputeArrival_rec( Fpga_Man_t * pMan, Fpga_Cut_t * pCut ); @@ -370,7 +368,6 @@ extern void Fpga_MappingSetupMask( unsigned uMask[], int nVarsMax ) extern void Fpga_MappingSortByLevel( Fpga_Man_t * pMan, Fpga_NodeVec_t * vNodes, int fIncreasing ); extern Fpga_NodeVec_t * Fpga_DfsLim( Fpga_Man_t * pMan, Fpga_Node_t * pNode, int nLevels ); extern Fpga_NodeVec_t * Fpga_MappingLevelize( Fpga_Man_t * pMan, Fpga_NodeVec_t * vNodes ); -extern float Fpga_MappingPrintSwitching( Fpga_Man_t * pMan ); extern int Fpga_MappingMaxLevel( Fpga_Man_t * pMan ); extern void Fpga_ManReportChoices( Fpga_Man_t * pMan ); extern void Fpga_MappingSetChoiceLevels( Fpga_Man_t * pMan ); diff --git a/src/map/fpga/fpgaMatch.c b/src/map/fpga/fpgaMatch.c index 63ee682d..20444209 100644 --- a/src/map/fpga/fpgaMatch.c +++ b/src/map/fpga/fpgaMatch.c @@ -432,7 +432,7 @@ clk = clock(); if ( pNode->nRefs ) { pNode->pCutBest->aFlow = Fpga_CutRefSwitch( p, pNode, pNode->pCutBest, 0 ); - assert( pNode->pCutBest->aFlow <= aAreaCutBest ); + assert( pNode->pCutBest->aFlow <= aAreaCutBest + 0.001 ); // assert( pNode->tRequired < FPGA_FLOAT_LARGE ); } return 1; diff --git a/src/map/fpga/fpgaSwitch.c b/src/map/fpga/fpgaSwitch.c new file mode 100644 index 00000000..0d2ec3fc --- /dev/null +++ b/src/map/fpga/fpgaSwitch.c @@ -0,0 +1,176 @@ +/**CFile**************************************************************** + + FileName [fpgaSwitch.c] + + PackageName [MVSIS 1.3: Multi-valued logic synthesis system.] + + Synopsis [Generic technology mapping engine.] + + Author [MVSIS Group] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - September 8, 2003.] + + Revision [$Id: fpgaSwitch.h,v 1.0 2003/09/08 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "fpgaInt.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static float Fpga_CutGetSwitching( Fpga_Cut_t * pCut ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**function************************************************************* + + synopsis [Computes the exact area associated with the cut.] + + description [] + + sideeffects [] + + seealso [] + +***********************************************************************/ +float Fpga_CutGetSwitchDerefed( Fpga_Man_t * pMan, Fpga_Node_t * pNode, Fpga_Cut_t * pCut ) +{ + float aResult, aResult2; + aResult2 = Fpga_CutRefSwitch( pMan, pNode, pCut, 0 ); + aResult = Fpga_CutDerefSwitch( pMan, pNode, pCut, 0 ); +// assert( aResult == aResult2 ); + return aResult; +} + +/**function************************************************************* + + synopsis [References the cut.] + + description [This procedure is similar to the procedure NodeReclaim.] + + sideeffects [] + + seealso [] + +***********************************************************************/ +float Fpga_CutRefSwitch( Fpga_Man_t * pMan, Fpga_Node_t * pNode, Fpga_Cut_t * pCut, int fFanouts ) +{ + Fpga_Node_t * pNodeChild; + float aArea; + int i; + if ( pCut->nLeaves == 1 ) + return 0; + // start the area of this cut + aArea = Fpga_CutGetSwitching( pCut ); + // go through the children + for ( i = 0; i < pCut->nLeaves; i++ ) + { + pNodeChild = pCut->ppLeaves[i]; + assert( pNodeChild->nRefs >= 0 ); + if ( pNodeChild->nRefs++ > 0 ) + continue; + aArea += Fpga_CutRefSwitch( pMan, pNodeChild, pNodeChild->pCutBest, fFanouts ); + } + return aArea; +} + +/**function************************************************************* + + synopsis [Dereferences the cut.] + + description [This procedure is similar to the procedure NodeRecusiveDeref.] + + sideeffects [] + + seealso [] + +***********************************************************************/ +float Fpga_CutDerefSwitch( Fpga_Man_t * pMan, Fpga_Node_t * pNode, Fpga_Cut_t * pCut, int fFanouts ) +{ + Fpga_Node_t * pNodeChild; + float aArea; + int i; + if ( pCut->nLeaves == 1 ) + return 0; + // start the area of this cut + aArea = Fpga_CutGetSwitching( pCut ); + // go through the children + for ( i = 0; i < pCut->nLeaves; i++ ) + { + pNodeChild = pCut->ppLeaves[i]; + assert( pNodeChild->nRefs > 0 ); + if ( --pNodeChild->nRefs > 0 ) + continue; + aArea += Fpga_CutDerefSwitch( pMan, pNodeChild, pNodeChild->pCutBest, fFanouts ); + } + return aArea; +} + +/**function************************************************************* + + synopsis [Computes the exact area associated with the cut.] + + description [] + + sideeffects [] + + seealso [] + +***********************************************************************/ +float Fpga_CutGetSwitching( Fpga_Cut_t * pCut ) +{ + float Result; + int i; + Result = 0.0; + for ( i = 0; i < pCut->nLeaves; i++ ) + Result += pCut->ppLeaves[i]->Switching; + return Result; +} + +/**Function************************************************************* + + Synopsis [Computes the array of mapping.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +float Fpga_MappingGetSwitching( Fpga_Man_t * pMan, Fpga_NodeVec_t * vMapping ) +{ + Fpga_Node_t * pNode; + float Switch; + int i; + Switch = 0.0; + for ( i = 0; i < vMapping->nSize; i++ ) + { + pNode = vMapping->pArray[i]; + if ( !Fpga_NodeIsAnd(pNode) ) + continue; + // at least one phase has the best cut assigned + assert( pNode->pCutBest != NULL ); + // at least one phase is used in the mapping + assert( pNode->nRefs > 0 ); + // compute the array due to the supergate + Switch += pNode->Switching; + } + // add buffer for each CO driven by a CI + for ( i = 0; i < pMan->nOutputs; i++ ) + if ( Fpga_NodeIsVar(pMan->pOutputs[i]) && !Fpga_IsComplement(pMan->pOutputs[i]) ) + Switch += pMan->pOutputs[i]->Switching; + return Switch; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/map/fpga/fpgaUtils.c b/src/map/fpga/fpgaUtils.c index 89ef13dc..3ea1f2f1 100644 --- a/src/map/fpga/fpgaUtils.c +++ b/src/map/fpga/fpgaUtils.c @@ -779,43 +779,6 @@ Fpga_NodeVec_t * Fpga_MappingLevelize( Fpga_Man_t * pMan, Fpga_NodeVec_t * vNode } return vLevels; } -/**Function************************************************************* - - Synopsis [Prints the switching activity changes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -float Fpga_MappingPrintSwitching( Fpga_Man_t * p ) -{ - Fpga_Node_t * pNode; - float SwitchTotal = 0.0; - int nNodes = 0; - int i; - for ( i = 0; i < p->vNodesAll->nSize; i++ ) - { - // skip primary inputs - pNode = p->vNodesAll->pArray[i]; -// if ( !Fpga_NodeIsAnd( pNode ) ) -// continue; - // skip a secondary node - if ( pNode->pRepr ) - continue; - // count the switching nodes - if ( pNode->nRefs > 0 ) - { - SwitchTotal += pNode->SwitchProb; - nNodes++; - } - } - if ( p->fVerbose ) - printf( "Total switching = %10.2f. Average switching = %6.4f.\n", SwitchTotal, SwitchTotal/nNodes ); - return SwitchTotal; -} /**Function************************************************************* diff --git a/src/map/fpga/module.make b/src/map/fpga/module.make index 409e4b54..cc3a6573 100644 --- a/src/map/fpga/module.make +++ b/src/map/fpga/module.make @@ -6,6 +6,7 @@ SRC += src/map/fpga/fpga.c \ src/map/fpga/fpgaFanout.c \ src/map/fpga/fpgaLib.c \ src/map/fpga/fpgaMatch.c \ + src/map/fpga/fpgaSwitch.c \ src/map/fpga/fpgaTime.c \ src/map/fpga/fpgaTruth.c \ src/map/fpga/fpgaUtils.c \ diff --git a/src/map/mapper/mapper.h b/src/map/mapper/mapper.h index 1322cdfa..c3f1ce81 100644 --- a/src/map/mapper/mapper.h +++ b/src/map/mapper/mapper.h @@ -101,6 +101,7 @@ extern void Map_ManSetFanoutViolations( Map_Man_t * p, int nVio ); extern void Map_ManSetChoiceNodeNum( Map_Man_t * p, int nChoiceNodes ); extern void Map_ManSetChoiceNum( Map_Man_t * p, int nChoices ); extern void Map_ManSetVerbose( Map_Man_t * p, int fVerbose ); +extern void Map_ManSetSwitching( Map_Man_t * p, int fSwitching ); extern Map_Man_t * Map_NodeReadMan( Map_Node_t * p ); extern char * Map_NodeReadData( Map_Node_t * p, int fPhase ); @@ -113,6 +114,7 @@ extern Map_Node_t * Map_NodeReadTwo( Map_Node_t * p ); extern void Map_NodeSetData( Map_Node_t * p, int fPhase, char * pData ); extern void Map_NodeSetNextE( Map_Node_t * p, Map_Node_t * pNextE ); extern void Map_NodeSetRepr( Map_Node_t * p, Map_Node_t * pRepr ); +extern void Map_NodeSetSwitching( Map_Node_t * p, float Switching ); extern int Map_NodeIsConst( Map_Node_t * p ); extern int Map_NodeIsVar( Map_Node_t * p ); diff --git a/src/map/mapper/mapperCore.c b/src/map/mapper/mapperCore.c index 16cbfd5c..629ba59d 100644 --- a/src/map/mapper/mapperCore.c +++ b/src/map/mapper/mapperCore.c @@ -46,9 +46,10 @@ ***********************************************************************/ int Map_Mapping( Map_Man_t * p ) { + int fShowSwitching = 0; int fUseAreaFlow = 1; - int fUseExactArea = 1; - int fUseExactAreaWithPhase = 1; + int fUseExactArea = !p->fSwitching; + int fUseExactAreaWithPhase = !p->fSwitching; int clk; ////////////////////////////////////////////////////////////////////// @@ -83,8 +84,10 @@ int Map_Mapping( Map_Man_t * p ) p->AreaBase = Map_MappingGetArea( p, p->vMapping ); if ( p->fVerbose ) { -printf( "Delay : Delay = %5.2f Flow = %11.1f Area = %11.1f %4.1f %% ", - p->fRequiredGlo, Map_MappingGetAreaFlow(p), p->AreaBase, 0.0 ); +printf( "Delay : %s = %8.2f Flow = %11.1f Area = %11.1f %4.1f %% ", + fShowSwitching? "Switch" : "Delay", + fShowSwitching? Map_MappingGetSwitching(p,p->vMapping) : p->fRequiredGlo, + Map_MappingGetAreaFlow(p), p->AreaBase, 0.0 ); PRT( "Time", p->timeMatch ); } ////////////////////////////////////////////////////////////////////// @@ -97,7 +100,7 @@ PRT( "Time", p->timeMatch ); clk = clock(); if ( fUseAreaFlow ) { - // compute the required times and the fanouts + // compute the required times Map_TimeComputeRequiredGlobal( p ); // recover area flow p->fMappingMode = 1; @@ -107,8 +110,10 @@ PRT( "Time", p->timeMatch ); p->AreaFinal = Map_MappingGetArea( p, p->vMapping ); if ( p->fVerbose ) { -printf( "AreaFlow : Delay = %5.2f Flow = %11.1f Area = %11.1f %4.1f %% ", - p->fRequiredGlo, Map_MappingGetAreaFlow(p), p->AreaFinal, +printf( "AreaFlow : %s = %8.2f Flow = %11.1f Area = %11.1f %4.1f %% ", + fShowSwitching? "Switch" : "Delay", + fShowSwitching? Map_MappingGetSwitching(p,p->vMapping) : p->fRequiredGlo, + Map_MappingGetAreaFlow(p), p->AreaFinal, 100.0*(p->AreaBase-p->AreaFinal)/p->AreaBase ); PRT( "Time", clock() - clk ); } @@ -121,9 +126,9 @@ PRT( "Time", clock() - clk ); clk = clock(); if ( fUseExactArea ) { - // compute the required times and the fanouts + // compute the required times Map_TimeComputeRequiredGlobal( p ); - // recover area flow + // recover area p->fMappingMode = 2; Map_MappingMatches( p ); // compute the references and collect the nodes used in the mapping @@ -131,8 +136,10 @@ PRT( "Time", clock() - clk ); p->AreaFinal = Map_MappingGetArea( p, p->vMapping ); if ( p->fVerbose ) { -printf( "Area : Delay = %5.2f Flow = %11.1f Area = %11.1f %4.1f %% ", - p->fRequiredGlo, 0.0, p->AreaFinal, +printf( "Area : %s = %8.2f Flow = %11.1f Area = %11.1f %4.1f %% ", + fShowSwitching? "Switch" : "Delay", + fShowSwitching? Map_MappingGetSwitching(p,p->vMapping) : p->fRequiredGlo, + 0.0, p->AreaFinal, 100.0*(p->AreaBase-p->AreaFinal)/p->AreaBase ); PRT( "Time", clock() - clk ); } @@ -145,9 +152,9 @@ PRT( "Time", clock() - clk ); clk = clock(); if ( fUseExactAreaWithPhase ) { - // compute the required times and the fanouts + // compute the required times Map_TimeComputeRequiredGlobal( p ); - // recover area flow + // recover area p->fMappingMode = 3; Map_MappingMatches( p ); // compute the references and collect the nodes used in the mapping @@ -155,8 +162,54 @@ PRT( "Time", clock() - clk ); p->AreaFinal = Map_MappingGetArea( p, p->vMapping ); if ( p->fVerbose ) { -printf( "Area : Delay = %5.2f Flow = %11.1f Area = %11.1f %4.1f %% ", - p->fRequiredGlo, 0.0, p->AreaFinal, +printf( "Area : %s = %8.2f Flow = %11.1f Area = %11.1f %4.1f %% ", + fShowSwitching? "Switch" : "Delay", + fShowSwitching? Map_MappingGetSwitching(p,p->vMapping) : p->fRequiredGlo, + 0.0, p->AreaFinal, + 100.0*(p->AreaBase-p->AreaFinal)/p->AreaBase ); +PRT( "Time", clock() - clk ); +} + } + p->timeArea += clock() - clk; + ////////////////////////////////////////////////////////////////////// + + ////////////////////////////////////////////////////////////////////// + // perform area recovery using exact area + clk = clock(); + if ( p->fSwitching ) + { + // compute the required times + Map_TimeComputeRequiredGlobal( p ); + // recover switching activity + p->fMappingMode = 4; + Map_MappingMatches( p ); + // compute the references and collect the nodes used in the mapping + Map_MappingSetRefs( p ); + p->AreaFinal = Map_MappingGetArea( p, p->vMapping ); +if ( p->fVerbose ) +{ +printf( "Switching: %s = %8.2f Flow = %11.1f Area = %11.1f %4.1f %% ", + fShowSwitching? "Switch" : "Delay", + fShowSwitching? Map_MappingGetSwitching(p,p->vMapping) : p->fRequiredGlo, + 0.0, p->AreaFinal, + 100.0*(p->AreaBase-p->AreaFinal)/p->AreaBase ); +PRT( "Time", clock() - clk ); +} + + // compute the required times + Map_TimeComputeRequiredGlobal( p ); + // recover switching activity + p->fMappingMode = 4; + Map_MappingMatches( p ); + // compute the references and collect the nodes used in the mapping + Map_MappingSetRefs( p ); + p->AreaFinal = Map_MappingGetArea( p, p->vMapping ); +if ( p->fVerbose ) +{ +printf( "Switching: %s = %8.2f Flow = %11.1f Area = %11.1f %4.1f %% ", + fShowSwitching? "Switch" : "Delay", + fShowSwitching? Map_MappingGetSwitching(p,p->vMapping) : p->fRequiredGlo, + 0.0, p->AreaFinal, 100.0*(p->AreaBase-p->AreaFinal)/p->AreaBase ); PRT( "Time", clock() - clk ); } diff --git a/src/map/mapper/mapperCreate.c b/src/map/mapper/mapperCreate.c index 738d099c..31fbf0ea 100644 --- a/src/map/mapper/mapperCreate.c +++ b/src/map/mapper/mapperCreate.c @@ -69,6 +69,7 @@ void Map_ManSetFanoutViolations( Map_Man_t * p, int nVio ) { p->nFa void Map_ManSetChoiceNodeNum( Map_Man_t * p, int nChoiceNodes ) { p->nChoiceNodes = nChoiceNodes; } void Map_ManSetChoiceNum( Map_Man_t * p, int nChoices ) { p->nChoices = nChoices; } void Map_ManSetVerbose( Map_Man_t * p, int fVerbose ) { p->fVerbose = fVerbose; } +void Map_ManSetSwitching( Map_Man_t * p, int fSwitching ) { p->fSwitching = fSwitching; } /**Function************************************************************* @@ -90,8 +91,9 @@ Map_Cut_t * Map_NodeReadCutBest( Map_Node_t * p, int fPhase ) { return p Map_Node_t * Map_NodeReadOne( Map_Node_t * p ) { return p->p1; } Map_Node_t * Map_NodeReadTwo( Map_Node_t * p ) { return p->p2; } void Map_NodeSetData( Map_Node_t * p, int fPhase, char * pData ) { if (fPhase) p->pData1 = pData; else p->pData0 = pData; } -void Map_NodeSetNextE( Map_Node_t * p, Map_Node_t * pNextE ) { p->pNextE = pNextE; } -void Map_NodeSetRepr( Map_Node_t * p, Map_Node_t * pRepr ) { p->pRepr = pRepr; } +void Map_NodeSetNextE( Map_Node_t * p, Map_Node_t * pNextE ) { p->pNextE = pNextE; } +void Map_NodeSetRepr( Map_Node_t * p, Map_Node_t * pRepr ) { p->pRepr = pRepr; } +void Map_NodeSetSwitching( Map_Node_t * p, float Switching ) { p->Switching = Switching; } /**Function************************************************************* diff --git a/src/map/mapper/mapperInt.h b/src/map/mapper/mapperInt.h index 7d63a804..0acca56c 100644 --- a/src/map/mapper/mapperInt.h +++ b/src/map/mapper/mapperInt.h @@ -117,6 +117,7 @@ struct Map_ManStruct_t_ bool fObeyFanoutLimits;// Should mapper try to obey fanout limits or not float DelayTarget; // the required times set by the user int nTravIds; // the traversal counter + bool fSwitching; // Should mapper try to obey fanout limits or not // the supergate library Map_SuperLib_t * pSuperLib; // the current supergate library @@ -184,6 +185,7 @@ struct Map_SuperLibStruct_t_ Mio_Gate_t * pGateInv; // the pointer to the intertor gate Map_Time_t tDelayInv; // the delay of the inverter float AreaInv; // the area of the inverter + float AreaBuf; // the area of the buffer Map_Super_t * pSuperInv; // the supergate representing the inverter // the memory manager for the internal table @@ -210,6 +212,7 @@ struct Map_NodeStruct_t_ unsigned NumTemp:10; // the level of the given node int nRefAct[3]; // estimated fanout for current covering phase, neg and pos and sum float nRefEst[3]; // actual fanout for previous covering phase, neg and pos and sum + float Switching; // the probability of switching // connectivity Map_Node_t * p1; // the first child @@ -378,6 +381,11 @@ extern int Map_MappingMatches( Map_Man_t * p ); extern float Map_MappingCombinePhases( Map_Man_t * p ); extern void Map_MatchClean( Map_Match_t * pMatch ); extern int Map_MatchCompare( Map_Man_t * pMan, Map_Match_t * pM1, Map_Match_t * pM2, int fDoingArea ); +/*=== mapperPower.c =============================================================*/ +extern float Map_SwitchCutGetDerefed( Map_Node_t * pNode, Map_Cut_t * pCut, int fPhase ); +extern float Map_SwitchCutRef( Map_Node_t * pNode, Map_Cut_t * pCut, int fPhase ); +extern float Map_SwitchCutDeref( Map_Node_t * pNode, Map_Cut_t * pCut, int fPhase ); +extern float Map_MappingGetSwitching( Map_Man_t * pMan, Map_NodeVec_t * vMapping ); /*=== mapperRefs.c =============================================================*/ extern int Map_NodeReadRefPhaseAct( Map_Node_t * pNode, int fPhase ); extern float Map_NodeReadRefPhaseEst( Map_Node_t * pNode, int fPhase ); diff --git a/src/map/mapper/mapperLib.c b/src/map/mapper/mapperLib.c index f9b280fe..5fea1f00 100644 --- a/src/map/mapper/mapperLib.c +++ b/src/map/mapper/mapperLib.c @@ -102,6 +102,7 @@ if ( fVerbose ) { p->tDelayInv.Fall = Mio_LibraryReadDelayInvFall( p->pGenlib ); p->tDelayInv.Worst = MAP_MAX( p->tDelayInv.Rise, p->tDelayInv.Fall ); p->AreaInv = Mio_LibraryReadAreaInv( p->pGenlib ); + p->AreaBuf = Mio_LibraryReadAreaBuf( p->pGenlib ); // assign the interver supergate p->pSuperInv = (Map_Super_t *)Extra_MmFixedEntryFetch( p->mmSupers ); diff --git a/src/map/mapper/mapperMatch.c b/src/map/mapper/mapperMatch.c index 5b72311c..ddb9ebb7 100644 --- a/src/map/mapper/mapperMatch.c +++ b/src/map/mapper/mapperMatch.c @@ -65,7 +65,7 @@ int Map_MappingMatches( Map_Man_t * p ) Map_Node_t * pNode; int i; - assert( p->fMappingMode >= 0 && p->fMappingMode <= 3 ); + assert( p->fMappingMode >= 0 && p->fMappingMode <= 4 ); // use the externally given PI arrival times if ( p->fMappingMode == 0 ) @@ -158,7 +158,7 @@ int Map_MatchNodePhase( Map_Man_t * p, Map_Node_t * pNode, int fPhase ) // recompute the exact area of the current best match // because the exact area of the fanins may have changed // as a result of remapping fanins in the topological order - if ( p->fMappingMode >= 2 ) + if ( p->fMappingMode == 2 || p->fMappingMode == 3 ) { pMatch = pCutBest->M + fPhase; if ( pNode->nRefAct[fPhase] > 0 || @@ -167,6 +167,15 @@ int Map_MatchNodePhase( Map_Man_t * p, Map_Node_t * pNode, int fPhase ) else pMatch->AreaFlow = Area1 = Map_CutGetAreaDerefed( pCutBest, fPhase ); } + else if ( p->fMappingMode == 4 ) + { + pMatch = pCutBest->M + fPhase; + if ( pNode->nRefAct[fPhase] > 0 || + (pNode->pCutBest[!fPhase] == NULL && pNode->nRefAct[!fPhase] > 0) ) + pMatch->AreaFlow = Area1 = Map_SwitchCutDeref( pNode, pCutBest, fPhase ); + else + pMatch->AreaFlow = Area1 = Map_SwitchCutGetDerefed( pNode, pCutBest, fPhase ); + } // save the old mapping if ( pCutBest ) @@ -210,7 +219,12 @@ int Map_MatchNodePhase( Map_Man_t * p, Map_Node_t * pNode, int fPhase ) (pNode->nRefAct[fPhase] > 0 || (pNode->pCutBest[!fPhase] == NULL && pNode->nRefAct[!fPhase] > 0)) ) { - Area2 = Map_CutRef( pNode->pCutBest[fPhase], fPhase ); + if ( p->fMappingMode == 2 || p->fMappingMode == 3 ) + Area2 = Map_CutRef( pNode->pCutBest[fPhase], fPhase ); + else if ( p->fMappingMode == 4 ) + Area2 = Map_SwitchCutRef( pNode, pNode->pCutBest[fPhase], fPhase ); + else + assert( 0 ); assert( Area2 < Area1 + p->fEpsilon ); } @@ -273,9 +287,11 @@ int Map_MatchNodeCut( Map_Man_t * p, Map_Node_t * pNode, Map_Cut_t * pCut, int f else { // get the area (area flow) - if ( p->fMappingMode >= 2 ) + if ( p->fMappingMode == 2 || p->fMappingMode == 3 ) pMatch->AreaFlow = Map_CutGetAreaDerefed( pCut, fPhase ); - else + else if ( p->fMappingMode == 4 ) + pMatch->AreaFlow = Map_SwitchCutGetDerefed( pNode, pCut, fPhase ); + else pMatch->AreaFlow = Map_CutGetAreaFlow( pCut, fPhase ); // skip if the cut is too large if ( pMatch->AreaFlow > MatchBest.AreaFlow + p->fEpsilon ) @@ -304,9 +320,11 @@ int Map_MatchNodeCut( Map_Man_t * p, Map_Node_t * pNode, Map_Cut_t * pCut, int f if ( pMatch->pSuperBest ) { Map_TimeCutComputeArrival( pNode, pCut, fPhase, MAP_FLOAT_LARGE ); - if ( p->fMappingMode >= 2 ) + if ( p->fMappingMode == 2 || p->fMappingMode == 3 ) pMatch->AreaFlow = Map_CutGetAreaDerefed( pCut, fPhase ); - else + else if ( p->fMappingMode == 4 ) + pMatch->AreaFlow = Map_SwitchCutGetDerefed( pNode, pCut, fPhase ); + else pMatch->AreaFlow = Map_CutGetAreaFlow( pCut, fPhase ); } return 1; @@ -482,7 +500,7 @@ void Map_NodeTryDroppingOnePhase( Map_Man_t * p, Map_Node_t * pNode ) fUsePhase0 = (pNode->tRequired[1].Worst > tWorst1Using0 + 3*p->pSuperLib->tDelayInv.Worst + p->fEpsilon); fUsePhase1 = (pNode->tRequired[0].Worst > tWorst0Using1 + 3*p->pSuperLib->tDelayInv.Worst + p->fEpsilon); } - else if ( p->fMappingMode == 3 ) + else if ( p->fMappingMode == 3 || p->fMappingMode == 4 ) { fUsePhase0 = (pNode->tRequired[1].Worst > tWorst1Using0 + p->fEpsilon); fUsePhase1 = (pNode->tRequired[0].Worst > tWorst0Using1 + p->fEpsilon); diff --git a/src/map/mapper/mapperRefs.c b/src/map/mapper/mapperRefs.c index e74bab9a..e4adadae 100644 --- a/src/map/mapper/mapperRefs.c +++ b/src/map/mapper/mapperRefs.c @@ -279,7 +279,7 @@ float Map_CutRef( Map_Cut_t * pCut, int fPhase ) /**function************************************************************* - synopsis [References the cut.] + synopsis [Dereferences the cut.] description [] @@ -298,8 +298,7 @@ float Map_CutDeref( Map_Cut_t * pCut, int fPhase ) synopsis [References or dereferences the cut.] description [This reference part is similar to Cudd_NodeReclaim(). - The dereference part is similar to Cudd_RecursiveDeref(). The - area of the inverter is not counted.] + The dereference part is similar to Cudd_RecursiveDeref().] sideeffects [] @@ -543,10 +542,10 @@ float Map_MappingGetArea( Map_Man_t * pMan, Map_NodeVec_t * vMapping ) (pNode->pCutBest[1] == NULL && pNode->nRefAct[1] > 0) ) Area += pMan->pSuperLib->AreaInv; } - // add two inverters for each PO buffer + // add buffer for each CO driven by a CI for ( i = 0; i < pMan->nOutputs; i++ ) if ( Map_NodeIsVar(pMan->pOutputs[i]) && !Map_IsComplement(pMan->pOutputs[i]) ) - Area += 2 * pMan->pSuperLib->AreaInv; + Area += pMan->pSuperLib->AreaBuf; return Area; } diff --git a/src/map/mapper/mapperSwitch.c b/src/map/mapper/mapperSwitch.c new file mode 100644 index 00000000..02f38396 --- /dev/null +++ b/src/map/mapper/mapperSwitch.c @@ -0,0 +1,243 @@ +/**CFile**************************************************************** + + FileName [mapperSwitch.c] + + PackageName [MVSIS 1.3: Multi-valued logic synthesis system.] + + Synopsis [Generic technology mapping engine.] + + Author [MVSIS Group] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - September 8, 2003.] + + Revision [$Id: mapperSwitch.h,v 1.0 2003/09/08 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "mapperInt.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static float Map_SwitchCutRefDeref( Map_Node_t * pNode, Map_Cut_t * pCut, int fPhase, int fReference ); +static float Map_CutGetSwitching( Map_Cut_t * pCut ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**function************************************************************* + + synopsis [Computes the exact area associated with the cut.] + + description [] + + sideeffects [] + + seealso [] + +***********************************************************************/ +float Map_SwitchCutGetDerefed( Map_Node_t * pNode, Map_Cut_t * pCut, int fPhase ) +{ + float aResult, aResult2; +// assert( pNode->Switching > 0 ); + aResult2 = Map_SwitchCutRefDeref( pNode, pCut, fPhase, 1 ); // reference + aResult = Map_SwitchCutRefDeref( pNode, pCut, fPhase, 0 ); // dereference +// assert( aResult == aResult2 ); + return aResult; +} + +/**function************************************************************* + + synopsis [References the cut.] + + description [] + + sideeffects [] + + seealso [] + +***********************************************************************/ +float Map_SwitchCutRef( Map_Node_t * pNode, Map_Cut_t * pCut, int fPhase ) +{ + return Map_SwitchCutRefDeref( pNode, pCut, fPhase, 1 ); // reference +} + +/**function************************************************************* + + synopsis [References the cut.] + + description [] + + sideeffects [] + + seealso [] + +***********************************************************************/ +float Map_SwitchCutDeref( Map_Node_t * pNode, Map_Cut_t * pCut, int fPhase ) +{ + return Map_SwitchCutRefDeref( pNode, pCut, fPhase, 0 ); // dereference +} + +/**function************************************************************* + + synopsis [References or dereferences the cut.] + + description [This reference part is similar to Cudd_NodeReclaim(). + The dereference part is similar to Cudd_RecursiveDeref().] + + sideeffects [] + + seealso [] + +***********************************************************************/ +float Map_SwitchCutRefDeref( Map_Node_t * pNode, Map_Cut_t * pCut, int fPhase, int fReference ) +{ + Map_Node_t * pNodeChild; + Map_Cut_t * pCutChild; + float aSwitchActivity; + int i, fPhaseChild; + // consider the elementary variable + if ( pCut->nLeaves == 1 ) + return 0; + // start the area of this cut + aSwitchActivity = Map_CutGetSwitching( pCut ); + // go through the children + assert( pCut->M[fPhase].pSuperBest ); + for ( i = 0; i < pCut->nLeaves; i++ ) + { + pNodeChild = pCut->ppLeaves[i]; + fPhaseChild = Map_CutGetLeafPhase( pCut, fPhase, i ); + // get the reference counter of the child + + if ( fReference ) + { + if ( pNodeChild->pCutBest[0] && pNodeChild->pCutBest[1] ) // both phases are present + { + // if this phase of the node is referenced, there is no recursive call + pNodeChild->nRefAct[2]++; + if ( pNodeChild->nRefAct[fPhaseChild]++ > 0 ) + continue; + } + else // only one phase is present + { + // inverter should be added if the phase + // (a) has no reference and (b) is implemented using other phase + if ( pNodeChild->nRefAct[fPhaseChild]++ == 0 && pNodeChild->pCutBest[fPhaseChild] == NULL ) + aSwitchActivity += pNodeChild->Switching; + // if the node is referenced, there is no recursive call + if ( pNodeChild->nRefAct[2]++ > 0 ) + continue; + } + } + else + { + if ( pNodeChild->pCutBest[0] && pNodeChild->pCutBest[1] ) // both phases are present + { + // if this phase of the node is referenced, there is no recursive call + --pNodeChild->nRefAct[2]; + if ( --pNodeChild->nRefAct[fPhaseChild] > 0 ) + continue; + } + else // only one phase is present + { + // inverter should be added if the phase + // (a) has no reference and (b) is implemented using other phase + if ( --pNodeChild->nRefAct[fPhaseChild] == 0 && pNodeChild->pCutBest[fPhaseChild] == NULL ) + aSwitchActivity += pNodeChild->Switching; + // if the node is referenced, there is no recursive call + if ( --pNodeChild->nRefAct[2] > 0 ) + continue; + } + assert( pNodeChild->nRefAct[fPhaseChild] >= 0 ); + } + + // get the child cut + pCutChild = pNodeChild->pCutBest[fPhaseChild]; + // if the child does not have this phase mapped, take the opposite phase + if ( pCutChild == NULL ) + { + fPhaseChild = !fPhaseChild; + pCutChild = pNodeChild->pCutBest[fPhaseChild]; + } + // reference and compute area recursively + aSwitchActivity += Map_SwitchCutRefDeref( pNodeChild, pCutChild, fPhaseChild, fReference ); + } + return aSwitchActivity; +} + +/**function************************************************************* + + synopsis [Computes the exact area associated with the cut.] + + description [] + + sideeffects [] + + seealso [] + +***********************************************************************/ +float Map_CutGetSwitching( Map_Cut_t * pCut ) +{ + float Result; + int i; + Result = 0.0; + for ( i = 0; i < pCut->nLeaves; i++ ) + Result += pCut->ppLeaves[i]->Switching; + return Result; +} + +/**Function************************************************************* + + Synopsis [Computes the array of mapping.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +float Map_MappingGetSwitching( Map_Man_t * pMan, Map_NodeVec_t * vMapping ) +{ + Map_Node_t * pNode; + float Switch; + int i; + Switch = 0.0; + for ( i = 0; i < vMapping->nSize; i++ ) + { + pNode = vMapping->pArray[i]; + // at least one phase has the best cut assigned + assert( pNode->pCutBest[0] != NULL || pNode->pCutBest[1] != NULL ); + // at least one phase is used in the mapping + assert( pNode->nRefAct[0] > 0 || pNode->nRefAct[1] > 0 ); + // compute the array due to the supergate + if ( Map_NodeIsAnd(pNode) ) + { + // count switching of the negative phase + if ( pNode->pCutBest[0] && (pNode->nRefAct[0] > 0 || pNode->pCutBest[1] == NULL) ) + Switch += pNode->Switching; + // count switching of the positive phase + if ( pNode->pCutBest[1] && (pNode->nRefAct[1] > 0 || pNode->pCutBest[0] == NULL) ) + Switch += pNode->Switching; + } + // count switching of the interver if we need to implement one phase with another phase + if ( (pNode->pCutBest[0] == NULL && pNode->nRefAct[0] > 0) || + (pNode->pCutBest[1] == NULL && pNode->nRefAct[1] > 0) ) + Switch += pNode->Switching; + } + // add buffer for each CO driven by a CI + for ( i = 0; i < pMan->nOutputs; i++ ) + if ( Map_NodeIsVar(pMan->pOutputs[i]) && !Map_IsComplement(pMan->pOutputs[i]) ) + Switch += pMan->pOutputs[i]->Switching; + return Switch; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/map/mapper/module.make b/src/map/mapper/module.make index 1d3b8867..bd6447d8 100644 --- a/src/map/mapper/module.make +++ b/src/map/mapper/module.make @@ -9,6 +9,7 @@ SRC += src/map/mapper/mapper.c \ src/map/mapper/mapperMatch.c \ src/map/mapper/mapperRefs.c \ src/map/mapper/mapperSuper.c \ + src/map/mapper/mapperSwitch.c \ src/map/mapper/mapperTable.c \ src/map/mapper/mapperTime.c \ src/map/mapper/mapperTree.c \ diff --git a/src/map/mio/mio.h b/src/map/mio/mio.h index 3347bba8..f9f4973d 100644 --- a/src/map/mio/mio.h +++ b/src/map/mio/mio.h @@ -90,6 +90,7 @@ extern float Mio_LibraryReadDelayNand2Rise( Mio_Library_t * pLib ); extern float Mio_LibraryReadDelayNand2Fall( Mio_Library_t * pLib ); extern float Mio_LibraryReadDelayNand2Max( Mio_Library_t * pLib ); extern float Mio_LibraryReadAreaInv ( Mio_Library_t * pLib ); +extern float Mio_LibraryReadAreaBuf ( Mio_Library_t * pLib ); extern float Mio_LibraryReadAreaNand2 ( Mio_Library_t * pLib ); extern char * Mio_GateReadName ( Mio_Gate_t * pGate ); extern char * Mio_GateReadOutName ( Mio_Gate_t * pGate ); diff --git a/src/map/mio/mioApi.c b/src/map/mio/mioApi.c index 50d60fe9..a39c6288 100644 --- a/src/map/mio/mioApi.c +++ b/src/map/mio/mioApi.c @@ -46,14 +46,15 @@ Mio_Gate_t * Mio_LibraryReadInv ( Mio_Library_t * pLib ) { retur Mio_Gate_t * Mio_LibraryReadConst0 ( Mio_Library_t * pLib ) { return pLib->pGate0; } Mio_Gate_t * Mio_LibraryReadConst1 ( Mio_Library_t * pLib ) { return pLib->pGate1; } Mio_Gate_t * Mio_LibraryReadNand2 ( Mio_Library_t * pLib ) { return pLib->pGateNand2; } -float Mio_LibraryReadDelayInvRise ( Mio_Library_t * pLib ) { return (float)pLib->pGateInv->pPins->dDelayBlockRise; } -float Mio_LibraryReadDelayInvFall ( Mio_Library_t * pLib ) { return (float)pLib->pGateInv->pPins->dDelayBlockFall; } -float Mio_LibraryReadDelayInvMax ( Mio_Library_t * pLib ) { return (float)pLib->pGateInv->pPins->dDelayBlockMax; } -float Mio_LibraryReadDelayNand2Rise( Mio_Library_t * pLib ) { return (float)pLib->pGateNand2->pPins->dDelayBlockRise; } -float Mio_LibraryReadDelayNand2Fall( Mio_Library_t * pLib ) { return (float)pLib->pGateNand2->pPins->dDelayBlockFall; } -float Mio_LibraryReadDelayNand2Max ( Mio_Library_t * pLib ) { return (float)pLib->pGateNand2->pPins->dDelayBlockMax; } -float Mio_LibraryReadAreaInv ( Mio_Library_t * pLib ) { return (float)pLib->pGateInv->dArea; } -float Mio_LibraryReadAreaNand2 ( Mio_Library_t * pLib ) { return (float)pLib->pGateNand2->dArea; } +float Mio_LibraryReadDelayInvRise ( Mio_Library_t * pLib ) { return (float)(pLib->pGateInv? pLib->pGateInv->pPins->dDelayBlockRise : 0.0); } +float Mio_LibraryReadDelayInvFall ( Mio_Library_t * pLib ) { return (float)(pLib->pGateInv? pLib->pGateInv->pPins->dDelayBlockFall : 0.0); } +float Mio_LibraryReadDelayInvMax ( Mio_Library_t * pLib ) { return (float)(pLib->pGateInv? pLib->pGateInv->pPins->dDelayBlockMax : 0.0); } +float Mio_LibraryReadDelayNand2Rise( Mio_Library_t * pLib ) { return (float)(pLib->pGateNand2? pLib->pGateNand2->pPins->dDelayBlockRise : 0.0); } +float Mio_LibraryReadDelayNand2Fall( Mio_Library_t * pLib ) { return (float)(pLib->pGateNand2? pLib->pGateNand2->pPins->dDelayBlockFall : 0.0); } +float Mio_LibraryReadDelayNand2Max ( Mio_Library_t * pLib ) { return (float)(pLib->pGateNand2? pLib->pGateNand2->pPins->dDelayBlockMax : 0.0); } +float Mio_LibraryReadAreaInv ( Mio_Library_t * pLib ) { return (float)(pLib->pGateInv? pLib->pGateInv->dArea : 0.0); } +float Mio_LibraryReadAreaBuf ( Mio_Library_t * pLib ) { return (float)(pLib->pGateBuf? pLib->pGateBuf->dArea : 0.0); } +float Mio_LibraryReadAreaNand2 ( Mio_Library_t * pLib ) { return (float)(pLib->pGateNand2? pLib->pGateNand2->dArea : 0.0); } /**Function************************************************************* diff --git a/src/misc/mvc/module.make b/src/misc/mvc/module.make new file mode 100644 index 00000000..23735ca2 --- /dev/null +++ b/src/misc/mvc/module.make @@ -0,0 +1,16 @@ +SRC += src/misc/mvc/mvc.c \ + src/misc/mvc/mvcApi.c \ + src/misc/mvc/mvcCompare.c \ + src/misc/mvc/mvcContain.c \ + src/misc/mvc/mvcCover.c \ + src/misc/mvc/mvcCube.c \ + src/misc/mvc/mvcDivide.c \ + src/misc/mvc/mvcDivisor.c \ + src/misc/mvc/mvcList.c \ + src/misc/mvc/mvcLits.c \ + src/misc/mvc/mvcMan.c \ + src/misc/mvc/mvcOpAlg.c \ + src/misc/mvc/mvcOpBool.c \ + src/misc/mvc/mvcPrint.c \ + src/misc/mvc/mvcSort.c \ + src/misc/mvc/mvcUtils.c diff --git a/src/misc/mvc/mvc.c b/src/misc/mvc/mvc.c new file mode 100644 index 00000000..9430276c --- /dev/null +++ b/src/misc/mvc/mvc.c @@ -0,0 +1,46 @@ +/**CFile**************************************************************** + + FileName [mvc.c] + + PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] + + Synopsis [] + + Author [MVSIS Group] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - February 1, 2003.] + + Revision [$Id: mvc.c,v 1.3 2003/03/19 19:50:26 alanmi Exp $] + +***********************************************************************/ + +#include "mvc.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/misc/mvc/mvc.h b/src/misc/mvc/mvc.h new file mode 100644 index 00000000..ee8c31be --- /dev/null +++ b/src/misc/mvc/mvc.h @@ -0,0 +1,733 @@ +/**CFile**************************************************************** + + FileName [mvc.h] + + PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] + + Synopsis [Data structure for MV cube/cover manipulation.] + + Author [MVSIS Group] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - February 1, 2003.] + + Revision [$Id: mvc.h,v 1.10 2003/05/02 23:23:59 wjiang Exp $] + +***********************************************************************/ + +#ifndef __MVC_H__ +#define __MVC_H__ + +//////////////////////////////////////////////////////////////////////// +/// INCLUDES /// +//////////////////////////////////////////////////////////////////////// + +#include +#include "util.h" +#include "extra.h" +//#include "vm.h" + +//////////////////////////////////////////////////////////////////////// +/// PARAMETERS /// +//////////////////////////////////////////////////////////////////////// + +// this is the only part of Mvc package, which should be modified +// when compiling the package for other platforms + +// these parameters can be computed but setting them manually makes it faster +#define BITS_PER_WORD 32 // sizeof(Mvc_CubeWord_t) * 8 +#define BITS_PER_WORD_MINUS 31 // the same minus 1 +#define BITS_PER_WORD_LOG 5 // log2(sizeof(Mvc_CubeWord_t) * 8) +#define BITS_DISJOINT ((Mvc_CubeWord_t)0x55555555) // the mask of the type "01010101" +#define BITS_FULL ((Mvc_CubeWord_t)0xffffffff) // the mask of the type "11111111" + +// uncomment this macro to switch to standard memory management +//#define USE_SYSTEM_MEMORY_MANAGEMENT + +//////////////////////////////////////////////////////////////////////// +/// STRUCTURE DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +// cube/list/cover/data +typedef unsigned long Mvc_CubeWord_t; +typedef struct MvcCubeStruct Mvc_Cube_t; +typedef struct MvcListStruct Mvc_List_t; +typedef struct MvcCoverStruct Mvc_Cover_t; +typedef struct MvcDataStruct Mvc_Data_t; +typedef struct MvcManagerStruct Mvc_Manager_t; + +// the cube data structure +struct MvcCubeStruct +{ + Mvc_Cube_t * pNext; // the next cube in the linked list + unsigned iLast : 8; // the index of the last word + unsigned nUnused : 6; // the number of unused bits in the last word + unsigned fPrime : 1; // marks the prime cube + unsigned fEssen : 1; // marks the essential cube + unsigned nOnes : 16; // the number of 1's in the bit data + Mvc_CubeWord_t pData[1]; // the first Mvc_CubeWord_t filled with bit data +}; + +// the single-linked list of cubes in the cover +struct MvcListStruct +{ + Mvc_Cube_t * pHead; // the first cube in the list + Mvc_Cube_t * pTail; // the last cube in the list + int nItems; // the number of cubes in the list +}; + +// the cover data structure +struct MvcCoverStruct +{ + char nWords; // the number of machine words + char nUnused; // the number of unused bits in the last word + short nBits; // the number of used data bits in the cube + Mvc_List_t lCubes; // the single-linked list of cubes + Mvc_Cube_t ** pCubes; // the array of cubes (for sorting) + int nCubesAlloc; // the size of allocated storage + int * pLits; // the counter of lit occurrances in cubes + Mvc_Cube_t * pMask; // the multipurpose mask + Mvc_Manager_t * pMem; // the memory manager +}; + +// data structure to store information about MV variables +struct MvcDataStruct +{ + Mvc_Manager_t * pMan; // the memory manager +// Vm_VarMap_t * pVm; // the MV variable data + int nBinVars; // the number of binary variables + Mvc_Cube_t * pMaskBin; // the mask to select the binary bits only + Mvc_Cube_t ** ppMasks; // the mask to select each MV variable + Mvc_Cube_t * ppTemp[3]; // the temporary cubes +}; + +// the manager of covers and cubes (as of today, only managing memory) +struct MvcManagerStruct +{ + Extra_MmFixed_t * pManC; // the manager for covers + Extra_MmFixed_t * pMan1; // the manager for 1-word cubes + Extra_MmFixed_t * pMan2; // the manager for 2-word cubes + Extra_MmFixed_t * pMan4; // the manager for 3-word cubes +}; + +//////////////////////////////////////////////////////////////////////// +/// MACRO DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +// reading data from the header of the cube +#define Mvc_CubeReadNext(Cube) ((Cube)->pNext) +#define Mvc_CubeReadNextP(Cube) (&(Cube)->pNext) +#define Mvc_CubeReadLast(Cube) ((Cube)->iLast) +#define Mvc_CubeReadSize(Cube) ((Cube)->nOnes) +// setting data to the header of the cube +#define Mvc_CubeSetNext(Cube,Next) ((Cube)->pNext = (Next)) +#define Mvc_CubeSetLast(Cube,Last) ((Cube)->iLast = (Last)) +#define Mvc_CubeSetSize(Cube,Size) ((Cube)->nOnes = (Size)) +// checking the number of words + +#define Mvc_Cube1Words(Cube) ((Cube)->iLast == 0) +#define Mvc_Cube2Words(Cube) ((Cube)->iLast == 1) +#define Mvc_CubeNWords(Cube) ((Cube)->iLast > 1) +// getting one data bit +#define Mvc_CubeWhichWord(Bit) ((Bit) >> BITS_PER_WORD_LOG) +#define Mvc_CubeWhichBit(Bit) ((Bit) & BITS_PER_WORD_MINUS) +// accessing individual bits +#define Mvc_CubeBitValue(Cube, Bit) (((Cube)->pData[Mvc_CubeWhichWord(Bit)] & (((Mvc_CubeWord_t)1)<<(Mvc_CubeWhichBit(Bit)))) > 0) +#define Mvc_CubeBitInsert(Cube, Bit) ((Cube)->pData[Mvc_CubeWhichWord(Bit)] |= (((Mvc_CubeWord_t)1)<<(Mvc_CubeWhichBit(Bit)))) +#define Mvc_CubeBitRemove(Cube, Bit) ((Cube)->pData[Mvc_CubeWhichWord(Bit)] &= ~(((Mvc_CubeWord_t)1)<<(Mvc_CubeWhichBit(Bit)))) +// accessing values of the binary variables +#define Mvc_CubeVarValue(Cube, Var) (((Cube)->pData[Mvc_CubeWhichWord(2*(Var))] >> (Mvc_CubeWhichBit(2*(Var)))) & ((Mvc_CubeWord_t)3)) + +// various macros + +// cleaning the data bits of the cube +#define Mvc_Cube1BitClean( Cube )\ + ((Cube)->pData[0] = 0) +#define Mvc_Cube2BitClean( Cube )\ + (((Cube)->pData[0] = 0),\ + ((Cube)->pData[1] = 0)) +#define Mvc_CubeNBitClean( Cube )\ +{\ + int _i_;\ + for( _i_ = (Cube)->iLast; _i_ >= 0; _i_--)\ + (Cube)->pData[_i_] = 0;\ +} + +// cleaning the unused part of the lat word +#define Mvc_CubeBitCleanUnused( Cube )\ + ((Cube)->pData[(Cube)->iLast] &= (BITS_FULL >> (Cube)->nUnused)) + +// filling the used data bits with 1's +#define Mvc_Cube1BitFill( Cube )\ + (Cube)->pData[0] = (BITS_FULL >> (Cube)->nUnused); +#define Mvc_Cube2BitFill( Cube )\ + (((Cube)->pData[0] = BITS_FULL),\ + ((Cube)->pData[1] = (BITS_FULL >> (Cube)->nUnused))) +#define Mvc_CubeNBitFill( Cube )\ +{\ + int _i_;\ + (Cube)->pData[(Cube)->iLast] = (BITS_FULL >> (Cube)->nUnused);\ + for( _i_ = (Cube)->iLast - 1; _i_ >= 0; _i_-- )\ + (Cube)->pData[_i_] = BITS_FULL;\ +} + +// complementing the data bits +#define Mvc_Cube1BitNot( Cube )\ + ((Cube)->pData[0] ^= (BITS_FULL >> (Cube)->nUnused)) +#define Mvc_Cube2BitNot( Cube )\ + (((Cube)->pData[0] ^= BITS_FULL),\ + ((Cube)->pData[1] ^= (BITS_FULL >> (Cube)->nUnused))) +#define Mvc_CubeNBitNot( Cube )\ +{\ + int _i_;\ + (Cube)->pData[(Cube)->iLast] ^= (BITS_FULL >> (Cube)->nUnused);\ + for( _i_ = (Cube)->iLast - 1; _i_ >= 0; _i_-- )\ + (Cube)->pData[_i_] ^= BITS_FULL;\ +} + +#define Mvc_Cube1BitCopy( Cube1, Cube2 )\ + (((Cube1)->pData[0]) = ((Cube2)->pData[0])) +#define Mvc_Cube2BitCopy( Cube1, Cube2 )\ + ((((Cube1)->pData[0]) = ((Cube2)->pData[0])),\ + (((Cube1)->pData[1])= ((Cube2)->pData[1]))) +#define Mvc_CubeNBitCopy( Cube1, Cube2 )\ +{\ + int _i_;\ + for (_i_ = (Cube1)->iLast; _i_ >= 0; _i_--)\ + ((Cube1)->pData[_i_]) = ((Cube2)->pData[_i_]);\ +} + +#define Mvc_Cube1BitOr( CubeR, Cube1, Cube2 )\ + (((CubeR)->pData[0]) = ((Cube1)->pData[0] | (Cube2)->pData[0])) +#define Mvc_Cube2BitOr( CubeR, Cube1, Cube2 )\ + ((((CubeR)->pData[0]) = ((Cube1)->pData[0] | (Cube2)->pData[0])),\ + (((CubeR)->pData[1]) = ((Cube1)->pData[1] | (Cube2)->pData[1]))) +#define Mvc_CubeNBitOr( CubeR, Cube1, Cube2 )\ +{\ + int _i_;\ + for (_i_ = (Cube1)->iLast; _i_ >= 0; _i_--)\ + (((CubeR)->pData[_i_]) = ((Cube1)->pData[_i_] | (Cube2)->pData[_i_]));\ +} + +#define Mvc_Cube1BitExor( CubeR, Cube1, Cube2 )\ + (((CubeR)->pData[0]) = ((Cube1)->pData[0] ^ (Cube2)->pData[0])) +#define Mvc_Cube2BitExor( CubeR, Cube1, Cube2 )\ + ((((CubeR)->pData[0]) = ((Cube1)->pData[0] ^ (Cube2)->pData[0])),\ + (((CubeR)->pData[1]) = ((Cube1)->pData[1] ^ (Cube2)->pData[1]))) +#define Mvc_CubeNBitExor( CubeR, Cube1, Cube2 )\ +{\ + int _i_;\ + for (_i_ = (Cube1)->iLast; _i_ >= 0; _i_--)\ + (((CubeR)->pData[_i_]) = ((Cube1)->pData[_i_] ^ (Cube2)->pData[_i_]));\ +} + +#define Mvc_Cube1BitAnd( CubeR, Cube1, Cube2 )\ + (((CubeR)->pData[0]) = ((Cube1)->pData[0] & (Cube2)->pData[0])) +#define Mvc_Cube2BitAnd( CubeR, Cube1, Cube2 )\ + ((((CubeR)->pData[0]) = ((Cube1)->pData[0] & (Cube2)->pData[0])),\ + (((CubeR)->pData[1]) = ((Cube1)->pData[1] & (Cube2)->pData[1]))) +#define Mvc_CubeNBitAnd( CubeR, Cube1, Cube2 )\ +{\ + int _i_;\ + for (_i_ = (Cube1)->iLast; _i_ >= 0; _i_--)\ + (((CubeR)->pData[_i_]) = ((Cube1)->pData[_i_] & (Cube2)->pData[_i_]));\ +} + +#define Mvc_Cube1BitSharp( CubeR, Cube1, Cube2 )\ + (((CubeR)->pData[0]) = ((Cube1)->pData[0] & ~((Cube2)->pData[0]))) +#define Mvc_Cube2BitSharp( CubeR, Cube1, Cube2 )\ + ((((CubeR)->pData[0]) = ((Cube1)->pData[0] & ~((Cube2)->pData[0]))),\ + (((CubeR)->pData[1]) = ((Cube1)->pData[1] & ~((Cube2)->pData[1])))) +#define Mvc_CubeNBitSharp( CubeR, Cube1, Cube2 )\ +{\ + int _i_;\ + for (_i_ = (Cube1)->iLast; _i_ >= 0; _i_--)\ + (((CubeR)->pData[_i_]) = ((Cube1)->pData[_i_] & ~(Cube2)->pData[_i_]));\ +} + +#define Mvc_Cube1BitEmpty( Res, Cube )\ + (Res = ((Cube)->pData[0] == 0)) +#define Mvc_Cube2BitEmpty( Res, Cube )\ + (Res = ((Cube)->pData[0] == 0 && (Cube)->pData[1] == 0)) +#define Mvc_CubeNBitEmpty( Res, Cube )\ +{\ + int _i_; Res = 1;\ + for (_i_ = (Cube)->iLast; _i_ >= 0; _i_--)\ + if ( (Cube)->pData[_i_] )\ + { Res = 0; break; }\ +} + +#define Mvc_Cube1BitEqual( Res, Cube1, Cube2 )\ + (Res = (((Cube1)->pData[0]) == ((Cube2)->pData[0]))) +#define Mvc_Cube2BitEqual( Res, Cube1, Cube2 )\ + (Res = ((((Cube1)->pData[0]) == ((Cube2)->pData[0])) &&\ + (((Cube1)->pData[1]) == ((Cube2)->pData[1])))) +#define Mvc_CubeNBitEqual( Res, Cube1, Cube2 )\ +{\ + int _i_; Res = 1;\ + for (_i_ = (Cube1)->iLast; _i_ >= 0; _i_--)\ + if (((Cube1)->pData[_i_]) != ((Cube2)->pData[_i_]))\ + { Res = 0; break; }\ +} + +#define Mvc_Cube1BitLess( Res, Cube1, Cube2 )\ + (Res = (((Cube1)->pData[0]) < ((Cube2)->pData[0]))) +#define Mvc_Cube2BitLess( Res, Cube1, Cube2 )\ + (Res = ((((Cube1)->pData[0]) < ((Cube2)->pData[0])) ||\ + ((((Cube1)->pData[0]) == ((Cube2)->pData[0])) && (((Cube1)->pData[1]) < ((Cube2)->pData[1]))))) +#define Mvc_CubeNBitLess( Res, Cube1, Cube2 )\ +{\ + int _i_; Res = 1;\ + for (_i_ = (Cube1)->iLast; _i_ >= 0; _i_--)\ + if (((Cube1)->pData[_i_]) >= ((Cube2)->pData[_i_]))\ + { Res = 0; break; }\ +} + +#define Mvc_Cube1BitMore( Res, Cube1, Cube2 )\ + (Res = (((Cube1)->pData[0]) > ((Cube2)->pData[0]))) +#define Mvc_Cube2BitMore( Res, Cube1, Cube2 )\ + (Res = ((((Cube1)->pData[0]) > ((Cube2)->pData[0])) ||\ + ((((Cube1)->pData[0]) == ((Cube2)->pData[0])) && (((Cube1)->pData[1]) > ((Cube2)->pData[1]))))) +#define Mvc_CubeNBitMore( Res, Cube1, Cube2 )\ +{\ + int _i_; Res = 1;\ + for (_i_ = (Cube1)->iLast; _i_ >= 0; _i_--)\ + if (((Cube1)->pData[_i_]) <= ((Cube2)->pData[_i_]))\ + { Res = 0; break; }\ +} + +#define Mvc_Cube1BitNotImpl( Res, Cube1, Cube2 )\ + (Res = (((Cube1)->pData[0]) & ~((Cube2)->pData[0]))) +#define Mvc_Cube2BitNotImpl( Res, Cube1, Cube2 )\ + (Res = ((((Cube1)->pData[0]) & ~((Cube2)->pData[0])) ||\ + (((Cube1)->pData[1]) & ~((Cube2)->pData[1])))) +#define Mvc_CubeNBitNotImpl( Res, Cube1, Cube2 )\ +{\ + int _i_; Res = 0;\ + for (_i_ = (Cube1)->iLast; _i_ >= 0; _i_--)\ + if (((Cube1)->pData[_i_]) & ~((Cube2)->pData[_i_]))\ + { Res = 1; break; }\ +} + +#define Mvc_Cube1BitDisjoint( Res, Cube1, Cube2 )\ + (Res = ((((Cube1)->pData[0]) & ((Cube2)->pData[0])) == 0 )) +#define Mvc_Cube2BitDisjoint( Res, Cube1, Cube2 )\ + (Res = (((((Cube1)->pData[0]) & ((Cube2)->pData[0])) == 0 ) &&\ + ((((Cube1)->pData[1]) & ((Cube2)->pData[1])) == 0 ))) +#define Mvc_CubeNBitDisjoint( Res, Cube1, Cube2 )\ +{\ + int _i_; Res = 1;\ + for (_i_ = (Cube1)->iLast; _i_ >= 0; _i_--)\ + if (((Cube1)->pData[_i_]) & ((Cube2)->pData[_i_]))\ + { Res = 0; break; }\ +} + +#define Mvc_Cube1BitEqualUnderMask( Res, Cube1, Cube2, Mask )\ + (Res = ((((Cube1)->pData[0]) & ((Mask)->pData[0])) == (((Cube2)->pData[0]) & ((Mask)->pData[0])))) +#define Mvc_Cube2BitEqualUnderMask( Res, Cube1, Cube2, Mask )\ + (Res = (((((Cube1)->pData[0]) & ((Mask)->pData[0])) == (((Cube2)->pData[0]) & ((Mask)->pData[0]))) &&\ + ((((Cube1)->pData[1]) & ((Mask)->pData[1])) == (((Cube2)->pData[1]) & ((Mask)->pData[1]))))) +#define Mvc_CubeNBitEqualUnderMask( Res, Cube1, Cube2, Mask )\ +{\ + int _i_; Res = 1;\ + for (_i_ = (Cube1)->iLast; _i_ >= 0; _i_--)\ + if ((((Cube1)->pData[_i_]) & ((Mask)->pData[_i_])) != (((Cube2)->pData[_i_]) & ((Mask)->pData[_i_])))\ + { Res = 0; break; }\ +} + +#define Mvc_Cube1BitEqualOutsideMask( Res, Cube1, Cube2, Mask )\ + (Res = ((((Cube1)->pData[0]) | ((Mask)->pData[0])) == (((Cube2)->pData[0]) | ((Mask)->pData[0])))) +#define Mvc_Cube2BitEqualOutsideMask( Res, Cube1, Cube2, Mask )\ + (Res = (((((Cube1)->pData[0]) | ((Mask)->pData[0])) == (((Cube2)->pData[0]) | ((Mask)->pData[0]))) &&\ + ((((Cube1)->pData[1]) | ((Mask)->pData[1])) == (((Cube2)->pData[1]) | ((Mask)->pData[1]))))) +#define Mvc_CubeNBitEqualOutsideMask( Res, Cube1, Cube2, Mask )\ +{\ + int _i_; Res = 1;\ + for (_i_ = (Cube1)->iLast; _i_ >= 0; _i_--)\ + if ((((Cube1)->pData[_i_]) | ((Mask)->pData[_i_])) != (((Cube2)->pData[_i_]) | ((Mask)->pData[_i_])))\ + { Res = 0; break; }\ +} + +#define Mvc_Cube1BitIntersectUnderMask( Res, Cube1, Cube2, Mask)\ + (Res = ((((Cube1)->pData[0]) & ((Cube2)->pData[0]) & ((Mask)->pData[0])) > 0)) +#define Mvc_Cube2BitIntersectUnderMask( Res, Cube1, Cube2, Mask)\ + (Res = (((((Cube1)->pData[0]) & ((Cube2)->pData[0]) & ((Mask)->pData[0])) > 0) ||\ + ((((Cube1)->pData[1]) & ((Cube2)->pData[1]) & ((Mask)->pData[1])) > 0))) +#define Mvc_CubeNBitIntersectUnderMask( Res, Cube1, Cube2, Mask)\ +{\ + int _i_; Res = 0;\ + for (_i_ = (Cube1)->iLast; _i_ >= 0; _i_--)\ + if (((Cube1)->pData[_i_]) & ((Cube2)->pData[_i_]) & ((Mask)->pData[_i_]))\ + { Res = 1; break; }\ +} + +#define Mvc_Cube1BitNotImplUnderMask( Res, Cube1, Cube2, Mask )\ + (Res = (((Mask)->pData[0]) & ((Cube1)->pData[0]) & ~((Cube2)->pData[0]))) +#define Mvc_Cube2BitNotImplUnderMask( Res, Cube1, Cube2, Mask )\ + (Res = ((((Mask)->pData[0]) & ((Cube1)->pData[0]) & ~((Cube2)->pData[0])) ||\ + (((Mask)->pData[1]) & ((Cube1)->pData[1]) & ~((Cube2)->pData[1])))) +#define Mvc_CubeNBitNotImplUnderMask( Res, Cube1, Cube2, Mask )\ +{\ + int _i_; Res = 0;\ + for (_i_ = (Cube1)->iLast; _i_ >= 0; _i_--)\ + if (((Mask)->pData[_i_]) & ((Cube1)->pData[_i_]) & ~((Cube2)->pData[_i_]))\ + { Res = 1; break; }\ +} + +// the following macros make no assumption about the cube's bitset size +#define Mvc_CubeBitClean( Cube )\ + if ( Mvc_Cube1Words(Cube) ) { Mvc_Cube1BitClean( Cube ); }\ + else if ( Mvc_Cube2Words(Cube) ) { Mvc_Cube2BitClean( Cube ); }\ + else { Mvc_CubeNBitClean( Cube ); } +#define Mvc_CubeBitFill( Cube )\ + if ( Mvc_Cube1Words(Cube) ) { Mvc_Cube1BitFill( Cube ); }\ + else if ( Mvc_Cube2Words(Cube) ) { Mvc_Cube2BitFill( Cube ); }\ + else { Mvc_CubeNBitFill( Cube ); } +#define Mvc_CubeBitNot( Cube )\ + if ( Mvc_Cube1Words(Cube) ) { Mvc_Cube1BitNot( Cube ); }\ + else if ( Mvc_Cube2Words(Cube) ) { Mvc_Cube2BitNot( Cube ); }\ + else { Mvc_CubeNBitNot( Cube ); } +#define Mvc_CubeBitCopy( Cube1, Cube2 )\ + if ( Mvc_Cube1Words(Cube1) ) { Mvc_Cube1BitCopy( Cube1, Cube2 ); }\ + else if ( Mvc_Cube2Words(Cube1) ){ Mvc_Cube2BitCopy( Cube1, Cube2 ); }\ + else { Mvc_CubeNBitCopy( Cube1, Cube2 ); } +#define Mvc_CubeBitOr( CubeR, Cube1, Cube2 )\ + if ( Mvc_Cube1Words(Cube1) ) { Mvc_Cube1BitOr( CubeR, Cube1, Cube2 ); }\ + else if ( Mvc_Cube2Words(Cube1) ){ Mvc_Cube2BitOr( CubeR, Cube1, Cube2 ); }\ + else { Mvc_CubeNBitOr( CubeR, Cube1, Cube2 ); } +#define Mvc_CubeBitExor( CubeR, Cube1, Cube2 )\ + if ( Mvc_Cube1Words(Cube1) ) { Mvc_Cube1BitExor( CubeR, Cube1, Cube2 ); }\ + else if ( Mvc_Cube2Words(Cube1) ){ Mvc_Cube2BitExor( CubeR, Cube1, Cube2 ); }\ + else { Mvc_CubeNBitExor( CubeR, Cube1, Cube2 ); } +#define Mvc_CubeBitAnd( CubeR, Cube1, Cube2 )\ + if ( Mvc_Cube1Words(Cube1) ) { Mvc_Cube1BitAnd( CubeR, Cube1, Cube2 ); }\ + else if ( Mvc_Cube2Words(Cube1) ){ Mvc_Cube2BitAnd( CubeR, Cube1, Cube2 ); }\ + else { Mvc_CubeNBitAnd( CubeR, Cube1, Cube2 ); } +#define Mvc_CubeBitSharp( CubeR, Cube1, Cube2 )\ + if ( Mvc_Cube1Words(Cube1) ) { Mvc_Cube1BitSharp( CubeR, Cube1, Cube2 ); }\ + else if ( Mvc_Cube2Words(Cube1) ){ Mvc_Cube2BitSharp( CubeR, Cube1, Cube2 ); }\ + else { Mvc_CubeNBitSharp( CubeR, Cube1, Cube2 ); } +#define Mvc_CubeBitEmpty( Res, Cube )\ + if ( Mvc_Cube1Words(Cube) ) { Mvc_Cube1BitEmpty( Res, Cube ); }\ + else if ( Mvc_Cube2Words(Cube) ) { Mvc_Cube2BitEmpty( Res, Cube ); }\ + else { Mvc_CubeNBitEmpty( Res, Cube ); } +#define Mvc_CubeBitEqual( Res, Cube1, Cube2 )\ + if ( Mvc_Cube1Words(Cube1) ) { Mvc_Cube1BitEqual( Res, Cube1, Cube2 ); }\ + else if ( Mvc_Cube2Words(Cube1) ){ Mvc_Cube2BitEqual( Res, Cube1, Cube2 ); }\ + else { Mvc_CubeNBitEqual( Res, Cube1, Cube2 ); } +#define Mvc_CubeBitLess( Res, Cube1, Cube2 )\ + if ( Mvc_Cube1Words(Cube1) ) { Mvc_Cube1BitLess( Res, Cube1, Cube2 ); }\ + else if ( Mvc_Cube2Words(Cube1) ){ Mvc_Cube2BitLess( Res, Cube1, Cube2 ); }\ + else { Mvc_CubeNBitLess( Res, Cube1, Cube2 ); } +#define Mvc_CubeBitMore( Res, Cube1, Cube2 )\ + if ( Mvc_Cube1Words(Cube1) ) { Mvc_Cube1BitMore( Res, Cube1, Cube2 ); }\ + else if ( Mvc_Cube2Words(Cube1) ){ Mvc_Cube2BitMore( Res, Cube1, Cube2 ); }\ + else { Mvc_CubeNBitMore( Res, Cube1, Cube2 ); } +#define Mvc_CubeBitNotImpl( Res, Cube1, Cube2 )\ + if ( Mvc_Cube1Words(Cube1) ) { Mvc_Cube1BitNotImpl( Res, Cube1, Cube2 ); }\ + else if ( Mvc_Cube2Words(Cube1) ){ Mvc_Cube2BitNotImpl( Res, Cube1, Cube2 ); }\ + else { Mvc_CubeNBitNotImpl( Res, Cube1, Cube2 ); } +#define Mvc_CubeBitDisjoint( Res, Cube1, Cube2 )\ + if ( Mvc_Cube1Words(Cube1) ) { Mvc_Cube1BitDisjoint( Res, Cube1, Cube2 ); }\ + else if ( Mvc_Cube2Words(Cube1) ){ Mvc_Cube2BitDisjoint( Res, Cube1, Cube2 ); }\ + else { Mvc_CubeNBitDisjoint( Res, Cube1, Cube2 ); } +#define Mvc_CubeBitEqualUnderMask( Res, Cube1, Cube2, Mask )\ + if ( Mvc_Cube1Words(Cube1) ) { Mvc_Cube1BitEqualUnderMask( Res, Cube1, Cube2, Mask ); }\ + else if ( Mvc_Cube2Words(Cube1) ){ Mvc_Cube2BitEqualUnderMask( Res, Cube1, Cube2, Mask ); }\ + else { Mvc_CubeNBitEqualUnderMask( Res, Cube1, Cube2, Mask ); } +#define Mvc_CubeBitEqualOutsideMask( Res, Cube1, Cube2, Mask )\ + if ( Mvc_Cube1Words(Cube1) ) { Mvc_Cube1BitEqualOutsideMask( Res, Cube1, Cube2, Mask ); }\ + else if ( Mvc_Cube2Words(Cube1) ){ Mvc_Cube2BitEqualOutsideMask( Res, Cube1, Cube2, Mask ); }\ + else { Mvc_CubeNBitEqualOutsideMask( Res, Cube1, Cube2, Mask ); } +#define Mvc_CubeBitIntersectUnderMask( Res, Cube1, Cube2, Mask )\ + if ( Mvc_Cube1Words(Cube1) ) { Mvc_Cube1BitIntersectUnderMask( Res, Cube1, Cube2, Mask ); }\ + else if ( Mvc_Cube2Words(Cube1) ){ Mvc_Cube2BitIntersectUnderMask( Res, Cube1, Cube2, Mask ); }\ + else { Mvc_CubeNBitIntersectUnderMask( Res, Cube1, Cube2, Mask ); } +#define Mvc_CubeBitNotImplUnderMask( Res, Cube1, Cube2, Mask )\ + if ( Mvc_Cube1Words(Cube1) ) { Mvc_Cube1BitNotImplUnderMask( Res, Cube1, Cube2, Mask ); }\ + else if ( Mvc_Cube2Words(Cube1) ){ Mvc_Cube2BitNotImplUnderMask( Res, Cube1, Cube2, Mask ); }\ + else { Mvc_CubeNBitNotImplUnderMask( Res, Cube1, Cube2, Mask ); } + + +// managing linked lists +#define Mvc_ListAddCubeHead( pList, pCube )\ + {\ + if ( pList->pHead == NULL )\ + {\ + Mvc_CubeSetNext( pCube, NULL );\ + pList->pHead = pCube;\ + pList->pTail = pCube;\ + }\ + else\ + {\ + Mvc_CubeSetNext( pCube, pList->pHead );\ + pList->pHead = pCube;\ + }\ + pList->nItems++;\ + } +#define Mvc_ListAddCubeTail( pList, pCube )\ + {\ + if ( pList->pHead == NULL )\ + pList->pHead = pCube;\ + else\ + Mvc_CubeSetNext( pList->pTail, pCube );\ + pList->pTail = pCube;\ + Mvc_CubeSetNext( pCube, NULL );\ + pList->nItems++;\ + } +#define Mvc_ListDeleteCube( pList, pPrev, pCube )\ +{\ + if ( pPrev == NULL )\ + pList->pHead = pCube->pNext;\ + else\ + pPrev->pNext = pCube->pNext;\ + if ( pList->pTail == pCube )\ + {\ + assert( pCube->pNext == NULL );\ + pList->pTail = pPrev;\ + }\ + pList->nItems--;\ +} + +// managing linked lists inside the cover +#define Mvc_CoverAddCubeHead( pCover, pCube )\ +{\ + Mvc_List_t * pList = &pCover->lCubes;\ + Mvc_ListAddCubeHead( pList, pCube );\ +} +#define Mvc_CoverAddCubeTail( pCover, pCube )\ +{\ + Mvc_List_t * pList = &pCover->lCubes;\ + Mvc_ListAddCubeTail( pList, pCube );\ +} +#define Mvc_CoverDeleteCube( pCover, pPrev, pCube )\ +{\ + Mvc_List_t * pList = &pCover->lCubes;\ + Mvc_ListDeleteCube( pList, pPrev, pCube );\ +} + + + + + + +// iterator through the cubes in the cube list +#define Mvc_ListForEachCube( List, Cube )\ + for ( Cube = List->pHead;\ + Cube;\ + Cube = Cube->pNext ) +#define Mvc_ListForEachCubeSafe( List, Cube, Cube2 )\ + for ( Cube = List->pHead, Cube2 = (Cube? Cube->pNext: NULL);\ + Cube;\ + Cube = Cube2, Cube2 = (Cube? Cube->pNext: NULL) ) + +// iterator through cubes in the cover +#define Mvc_CoverForEachCube( Cover, Cube )\ + for ( Cube = (Cover)->lCubes.pHead;\ + Cube;\ + Cube = Cube->pNext ) +#define Mvc_CoverForEachCubeWithIndex( Cover, Cube, Index )\ + for ( Index = 0, Cube = (Cover)->lCubes.pHead;\ + Cube;\ + Index++, Cube = Cube->pNext ) +#define Mvc_CoverForEachCubeSafe( Cover, Cube, Cube2 )\ + for ( Cube = (Cover)->lCubes.pHead, Cube2 = (Cube? Cube->pNext: NULL);\ + Cube;\ + Cube = Cube2, Cube2 = (Cube? Cube->pNext: NULL) ) + +// iterator which starts from the given cube +#define Mvc_CoverForEachCubeStart( Start, Cube )\ + for ( Cube = Start;\ + Cube;\ + Cube = Cube->pNext ) +#define Mvc_CoverForEachCubeStartSafe( Start, Cube, Cube2 )\ + for ( Cube = Start, Cube2 = (Cube? Cube->pNext: NULL);\ + Cube;\ + Cube = Cube2, Cube2 = (Cube? Cube->pNext: NULL) ) + + +// iterator through literals of the cube +#define Mvc_CubeForEachBit( Cover, Cube, iBit, Value )\ + for ( iBit = 0;\ + iBit < Cover->nBits && ((Value = Mvc_CubeBitValue(Cube,iBit))>=0);\ + iBit++ ) +// iterator through values of binary variables +#define Mvc_CubeForEachVarValue( Cover, Cube, iVar, Value )\ + for ( iVar = 0;\ + iVar < Cover->nBits/2 && (Value = Mvc_CubeVarValue(Cube,iVar));\ + iVar++ ) + + +// macros which work 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) +#define MEM_ALLOC( Manager, Type, Size ) ((Type *)malloc( (Size) * sizeof(Type) )) +#define MEM_FREE( Manager, Type, Size, Pointer ) if ( Pointer ) { free(Pointer); Pointer = NULL; } + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/*=== mvcApi.c ====================================================*/ +extern int Mvc_CoverReadWordNum( Mvc_Cover_t * pCover ); +extern int Mvc_CoverReadBitNum( Mvc_Cover_t * pCover ); +extern int Mvc_CoverReadCubeNum( Mvc_Cover_t * pCover ); +extern Mvc_Cube_t * Mvc_CoverReadCubeHead( Mvc_Cover_t * pCover ); +extern Mvc_Cube_t * Mvc_CoverReadCubeTail( Mvc_Cover_t * pCover ); +extern Mvc_List_t * Mvc_CoverReadCubeList( Mvc_Cover_t * pCover ); +extern int Mvc_ListReadCubeNum( Mvc_List_t * pList ); +extern Mvc_Cube_t * Mvc_ListReadCubeHead( Mvc_List_t * pList ); +extern Mvc_Cube_t * Mvc_ListReadCubeTail( Mvc_List_t * pList ); +extern void Mvc_CoverSetCubeNum( Mvc_Cover_t * pCover,int nItems ); +extern void Mvc_CoverSetCubeHead( Mvc_Cover_t * pCover, Mvc_Cube_t * pCube ); +extern void Mvc_CoverSetCubeTail( Mvc_Cover_t * pCover, Mvc_Cube_t * pCube ); +extern void Mvc_CoverSetCubeList( Mvc_Cover_t * pCover, Mvc_List_t * pList ); +extern int Mvc_CoverIsEmpty( Mvc_Cover_t * pCover ); +extern int Mvc_CoverIsTautology( Mvc_Cover_t * pCover ); +extern int Mvc_CoverIsBinaryBuffer( Mvc_Cover_t * pCover ); +extern void Mvc_CoverMakeEmpty( Mvc_Cover_t * pCover ); +extern void Mvc_CoverMakeTautology( Mvc_Cover_t * pCover ); +extern Mvc_Cover_t * Mvc_CoverCreateEmpty( Mvc_Cover_t * pCover ); +extern Mvc_Cover_t * Mvc_CoverCreateTautology( Mvc_Cover_t * pCover ); +/*=== mvcCover.c ====================================================*/ +extern Mvc_Cover_t * Mvc_CoverAlloc( Mvc_Manager_t * pMem, int nBits ); +extern Mvc_Cover_t * Mvc_CoverCreateConst( Mvc_Manager_t * pMem, int nBits, int Phase ); +extern Mvc_Cover_t * Mvc_CoverClone( Mvc_Cover_t * pCover ); +extern Mvc_Cover_t * Mvc_CoverDup( Mvc_Cover_t * pCover ); +extern void Mvc_CoverFree( Mvc_Cover_t * pCover ); +extern void Mvc_CoverAllocateMask( Mvc_Cover_t * pCover ); +extern void Mvc_CoverAllocateArrayLits( Mvc_Cover_t * pCover ); +extern void Mvc_CoverAllocateArrayCubes( Mvc_Cover_t * pCover ); +extern void Mvc_CoverDeallocateMask( Mvc_Cover_t * pCover ); +extern void Mvc_CoverDeallocateArrayLits( Mvc_Cover_t * pCover ); +/*=== mvcCube.c ====================================================*/ +extern Mvc_Cube_t * Mvc_CubeAlloc( Mvc_Cover_t * pCover ); +extern Mvc_Cube_t * Mvc_CubeDup( Mvc_Cover_t * pCover, Mvc_Cube_t * pCube ); +extern void Mvc_CubeFree( Mvc_Cover_t * pCover, Mvc_Cube_t * pCube ); +extern void Mvc_CubeBitRemoveDcs( Mvc_Cube_t * pCube ); +/*=== mvcCompare.c ====================================================*/ +extern int Mvc_CubeCompareInt( Mvc_Cube_t * pC1, Mvc_Cube_t * pC2, Mvc_Cube_t * pMask ); +extern int Mvc_CubeCompareSizeAndInt( Mvc_Cube_t * pC1, Mvc_Cube_t * pC2, Mvc_Cube_t * pMask ); +extern int Mvc_CubeCompareIntUnderMask( Mvc_Cube_t * pC1, Mvc_Cube_t * pC2, Mvc_Cube_t * pMask ); +extern int Mvc_CubeCompareIntOutsideMask( Mvc_Cube_t * pC1, Mvc_Cube_t * pC2, Mvc_Cube_t * pMask ); +extern int Mvc_CubeCompareIntOutsideAndUnderMask( Mvc_Cube_t * pC1, Mvc_Cube_t * pC2, Mvc_Cube_t * pMask ); +/*=== mvcDd.c ====================================================*/ +/* +extern DdNode * Mvc_CoverConvertToBdd( DdManager * dd, Mvc_Cover_t * pCover ); +extern DdNode * Mvc_CoverConvertToZdd( DdManager * dd, Mvc_Cover_t * pCover ); +extern DdNode * Mvc_CoverConvertToZdd2( DdManager * dd, Mvc_Cover_t * pCover ); +extern DdNode * Mvc_CubeConvertToBdd( DdManager * dd, Mvc_Cube_t * pCube ); +extern DdNode * Mvc_CubeConvertToZdd( DdManager * dd, Mvc_Cube_t * pCube ); +extern DdNode * Mvc_CubeConvertToZdd2( DdManager * dd, Mvc_Cube_t * pCube ); +*/ +/*=== mvcDivisor.c ====================================================*/ +extern Mvc_Cover_t * Mvc_CoverDivisor( Mvc_Cover_t * pCover ); +/*=== mvcDivide.c ====================================================*/ +extern void Mvc_CoverDivide( Mvc_Cover_t * pCover, Mvc_Cover_t * pDiv, Mvc_Cover_t ** ppQuo, Mvc_Cover_t ** ppRem ); +extern void Mvc_CoverDivideInternal( Mvc_Cover_t * pCover, Mvc_Cover_t * pDiv, Mvc_Cover_t ** ppQuo, Mvc_Cover_t ** ppRem ); +extern void Mvc_CoverDivideByLiteral( Mvc_Cover_t * pCover, Mvc_Cover_t * pDiv, Mvc_Cover_t ** ppQuo, Mvc_Cover_t ** ppRem ); +extern void Mvc_CoverDivideByCube( Mvc_Cover_t * pCover, Mvc_Cover_t * pDiv, Mvc_Cover_t ** ppQuo, Mvc_Cover_t ** ppRem ); +extern void Mvc_CoverDivideByLiteralQuo( Mvc_Cover_t * pCover, int iLit ); +/*=== mvcList.c ====================================================*/ +// these functions are available as macros +extern void Mvc_ListAddCubeHead_( Mvc_List_t * pList, Mvc_Cube_t * pCube ); +extern void Mvc_ListAddCubeTail_( Mvc_List_t * pList, Mvc_Cube_t * pCube ); +extern void Mvc_ListDeleteCube_( Mvc_List_t * pList, Mvc_Cube_t * pPrev, Mvc_Cube_t * pCube ); +extern void Mvc_CoverAddCubeHead_( Mvc_Cover_t * pCover, Mvc_Cube_t * pCube ); +extern void Mvc_CoverAddCubeTail_( Mvc_Cover_t * pCover, Mvc_Cube_t * pCube ); +extern void Mvc_CoverDeleteCube_( Mvc_Cover_t * pCover, Mvc_Cube_t * pPrev, Mvc_Cube_t * pCube ); +extern void Mvc_CoverAddDupCubeHead( Mvc_Cover_t * pCover, Mvc_Cube_t * pCube ); +extern void Mvc_CoverAddDupCubeTail( Mvc_Cover_t * pCover, Mvc_Cube_t * pCube ); +// other functions +extern void Mvc_CoverAddLiteralsOfCube( Mvc_Cover_t * pCover, Mvc_Cube_t * pCube ); +extern void Mvc_CoverDeleteLiteralsOfCube( Mvc_Cover_t * pCover, Mvc_Cube_t * pCube ); +extern void Mvc_CoverList2Array( Mvc_Cover_t * pCover ); +extern void Mvc_CoverArray2List( Mvc_Cover_t * pCover ); +extern Mvc_Cube_t * Mvc_ListGetTailFromHead( Mvc_Cube_t * pHead ); +/*=== mvcPrint.c ====================================================*/ +extern void Mvc_CoverPrint( Mvc_Cover_t * pCover ); +extern void Mvc_CubePrint( Mvc_Cover_t * pCover, Mvc_Cube_t * pCube ); +extern void Mvc_CoverPrintMv( Mvc_Data_t * pData, Mvc_Cover_t * pCover ); +extern void Mvc_CubePrintMv( Mvc_Data_t * pData, Mvc_Cover_t * pCover, Mvc_Cube_t * pCube ); +/*=== mvcSort.c ====================================================*/ +extern void Mvc_CoverSort( Mvc_Cover_t * pCover, Mvc_Cube_t * pMask, int (* pCompareFunc)(Mvc_Cube_t *, Mvc_Cube_t *, Mvc_Cube_t *) ); +/*=== mvcUtils.c ====================================================*/ +extern void Mvc_CoverSupport( Mvc_Cover_t * pCover, Mvc_Cube_t * pSupp ); +extern int Mvc_CoverSupportSizeBinary( Mvc_Cover_t * pCover ); +extern int Mvc_CoverSupportVarBelongs( Mvc_Cover_t * pCover, int iVar ); +extern void Mvc_CoverCommonCube( Mvc_Cover_t * pCover, Mvc_Cube_t * pComCube ); +extern int Mvc_CoverIsCubeFree( Mvc_Cover_t * pCover ); +extern void Mvc_CoverMakeCubeFree( Mvc_Cover_t * pCover ); +extern Mvc_Cover_t * Mvc_CoverCommonCubeCover( Mvc_Cover_t * pCover ); +extern int Mvc_CoverCheckSuppContainment( Mvc_Cover_t * pCover1, Mvc_Cover_t * pCover2 ); +extern int Mvc_CoverSetCubeSizes( Mvc_Cover_t * pCover ); +extern int Mvc_CoverGetCubeSize( Mvc_Cube_t * pCube ); +extern int Mvc_CoverCountCubePairDiffs( Mvc_Cover_t * pCover, unsigned char pDiffs[] ); +extern Mvc_Cover_t * Mvc_CoverRemap( Mvc_Cover_t * pCover, int * pVarsRem, int nVarsRem ); +extern void Mvc_CoverInverse( Mvc_Cover_t * pCover ); +extern Mvc_Cover_t * Mvc_CoverRemoveDontCareLits( Mvc_Cover_t * pCover ); +extern Mvc_Cover_t * Mvc_CoverCofactor( Mvc_Cover_t * pCover, int iValue, int iValueOther ); +extern Mvc_Cover_t * Mvc_CoverFlipVar( Mvc_Cover_t * pCover, int iValue0, int iValue1 ); +extern Mvc_Cover_t * Mvc_CoverUnivQuantify( Mvc_Cover_t * p, int iValueA0, int iValueA1, int iValueB0, int iValueB1 ); +extern Mvc_Cover_t ** Mvc_CoverCofactors( Mvc_Data_t * pData, Mvc_Cover_t * pCover, int iVar ); +extern int Mvr_CoverCountLitsWithValue( Mvc_Data_t * pData, Mvc_Cover_t * pCover, int iVar, int iValue ); +//extern Mvc_Cover_t * Mvc_CoverCreateExpanded( Mvc_Cover_t * pCover, Vm_VarMap_t * pVmNew ); +extern Mvc_Cover_t * Mvc_CoverTranspose( Mvc_Cover_t * pCover ); +extern int Mvc_UtilsCheckUnusedZeros( Mvc_Cover_t * pCover ); +/*=== mvcLits.c ====================================================*/ +extern int Mvc_CoverAnyLiteral( Mvc_Cover_t * pCover, Mvc_Cube_t * pMask ); +extern int Mvc_CoverBestLiteral( Mvc_Cover_t * pCover, Mvc_Cube_t * pMask ); +extern int Mvc_CoverWorstLiteral( Mvc_Cover_t * pCover, Mvc_Cube_t * pMask ); +extern Mvc_Cover_t * Mvc_CoverBestLiteralCover( Mvc_Cover_t * pCover, Mvc_Cover_t * pSimple ); +extern int Mvc_CoverFirstCubeFirstLit( Mvc_Cover_t * pCover ); +extern int Mvc_CoverCountLiterals( Mvc_Cover_t * pCover ); +extern int Mvc_CoverIsOneLiteral( Mvc_Cover_t * pCover ); +/*=== mvcOpAlg.c ====================================================*/ +extern Mvc_Cover_t * Mvc_CoverAlgebraicMultiply( Mvc_Cover_t * pCover1, Mvc_Cover_t * pCover2 ); +extern Mvc_Cover_t * Mvc_CoverAlgebraicSubtract( Mvc_Cover_t * pCover1, Mvc_Cover_t * pCover2 ); +extern int Mvc_CoverAlgebraicEqual( Mvc_Cover_t * pCover1, Mvc_Cover_t * pCover2 ); +/*=== mvcOpBool.c ====================================================*/ +extern Mvc_Cover_t * Mvc_CoverBooleanOr( Mvc_Cover_t * pCover1, Mvc_Cover_t * pCover2 ); +extern Mvc_Cover_t * Mvc_CoverBooleanAnd( Mvc_Data_t * p, Mvc_Cover_t * pCover1, Mvc_Cover_t * pCover2 ); +extern int Mvc_CoverBooleanEqual( Mvc_Data_t * p, Mvc_Cover_t * pCover1, Mvc_Cover_t * pCover2 ); + +/*=== mvcContain.c ====================================================*/ +extern int Mvc_CoverContain( Mvc_Cover_t * pCover ); +/*=== mvcTau.c ====================================================*/ +extern int Mvc_CoverTautology( Mvc_Data_t * p, Mvc_Cover_t * pCover ); +/*=== mvcCompl.c ====================================================*/ +extern Mvc_Cover_t * Mvc_CoverComplement( Mvc_Data_t * p, Mvc_Cover_t * pCover ); +/*=== mvcSharp.c ====================================================*/ +extern Mvc_Cover_t * Mvc_CoverSharp( Mvc_Data_t * p, Mvc_Cover_t * pA, Mvc_Cover_t * pB ); +extern int Mvc_CoverDist0Cubes( Mvc_Data_t * pData, Mvc_Cube_t * pA, Mvc_Cube_t * pB ); +extern void Mvc_CoverIntersectCubes( Mvc_Data_t * pData, Mvc_Cover_t * pC1, Mvc_Cover_t * pC2 ); +extern int Mvc_CoverIsIntersecting( Mvc_Data_t * pData, Mvc_Cover_t * pC1, Mvc_Cover_t * pC2 ); +extern void Mvc_CoverAppendCubes( Mvc_Cover_t * pC1, Mvc_Cover_t * pC2 ); +extern void Mvc_CoverCopyAndAppendCubes( Mvc_Cover_t * pC1, Mvc_Cover_t * pC2 ); +extern void Mvc_CoverRemoveCubes( Mvc_Cover_t * pC ); + +/*=== mvcReshape.c ====================================================*/ +extern void Mvc_CoverMinimizeByReshape( Mvc_Data_t * pData, Mvc_Cover_t * pCover ); + +/*=== mvcMerge.c ====================================================*/ +extern void Mvc_CoverDist1Merge( Mvc_Data_t * p, Mvc_Cover_t * pCover ); + +/*=== mvcData.c ====================================================*/ +//extern Mvc_Data_t * Mvc_CoverDataAlloc( Vm_VarMap_t * pVm, Mvc_Cover_t * pCover ); +//extern void Mvc_CoverDataFree( Mvc_Data_t * p, Mvc_Cover_t * pCover ); + +/*=== mvcMan.c ====================================================*/ +extern void Mvc_ManagerFree( Mvc_Manager_t * p ); +extern Mvc_Manager_t * Mvc_ManagerStart(); +extern Mvc_Manager_t * Mvc_ManagerAllocCover(); +extern Mvc_Manager_t * Mvc_ManagerAllocCube( int nWords ); +extern Mvc_Manager_t * Mvc_ManagerFreeCover( Mvc_Cover_t * pCover ); +extern Mvc_Manager_t * Mvc_ManagerFreeCube( Mvc_Cover_t * pCube, int nWords ); + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + +#endif + diff --git a/src/misc/mvc/mvcApi.c b/src/misc/mvc/mvcApi.c new file mode 100644 index 00000000..1f51a235 --- /dev/null +++ b/src/misc/mvc/mvcApi.c @@ -0,0 +1,233 @@ +/**CFile**************************************************************** + + FileName [mvcApi.c] + + PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] + + Synopsis [] + + Author [MVSIS Group] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - February 1, 2003.] + + Revision [$Id: mvcApi.c,v 1.4 2003/04/03 06:31:48 alanmi Exp $] + +***********************************************************************/ + +#include "mvc.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Mvc_CoverReadWordNum( Mvc_Cover_t * pCover ) { return pCover->nWords; } +int Mvc_CoverReadBitNum( Mvc_Cover_t * pCover ) { return pCover->nBits; } +int Mvc_CoverReadCubeNum( Mvc_Cover_t * pCover ) { return pCover->lCubes.nItems; } +Mvc_Cube_t * Mvc_CoverReadCubeHead( Mvc_Cover_t * pCover ) { return pCover->lCubes.pHead; } +Mvc_Cube_t * Mvc_CoverReadCubeTail( Mvc_Cover_t * pCover ) { return pCover->lCubes.pTail; } +Mvc_List_t * Mvc_CoverReadCubeList( Mvc_Cover_t * pCover ) { return &pCover->lCubes; } + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Mvc_ListReadCubeNum( Mvc_List_t * pList ) { return pList->nItems; } +Mvc_Cube_t * Mvc_ListReadCubeHead( Mvc_List_t * pList ) { return pList->pHead; } +Mvc_Cube_t * Mvc_ListReadCubeTail( Mvc_List_t * pList ) { return pList->pTail; } + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Mvc_CoverSetCubeNum( Mvc_Cover_t * pCover,int nItems ) { pCover->lCubes.nItems = nItems; } +void Mvc_CoverSetCubeHead( Mvc_Cover_t * pCover, Mvc_Cube_t * pCube ) { pCover->lCubes.pHead = pCube; } +void Mvc_CoverSetCubeTail( Mvc_Cover_t * pCover, Mvc_Cube_t * pCube ) { pCover->lCubes.pTail = pCube; } +void Mvc_CoverSetCubeList( Mvc_Cover_t * pCover, Mvc_List_t * pList ) { pCover->lCubes = *pList; } + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Mvc_CoverIsEmpty( Mvc_Cover_t * pCover ) +{ + return Mvc_CoverReadCubeNum(pCover) == 0; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Mvc_CoverIsTautology( Mvc_Cover_t * pCover ) +{ + Mvc_Cube_t * pCube; + int iBit, Value; + + if ( Mvc_CoverReadCubeNum(pCover) != 1 ) + return 0; + + pCube = Mvc_CoverReadCubeHead( pCover ); + Mvc_CubeForEachBit( pCover, pCube, iBit, Value ) + if ( Value == 0 ) + return 0; + return 1; +} + +/**Function************************************************************* + + Synopsis [Returns 1 if the cover is a binary buffer.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Mvc_CoverIsBinaryBuffer( Mvc_Cover_t * pCover ) +{ + Mvc_Cube_t * pCube; + if ( pCover->nBits != 2 ) + return 0; + if ( Mvc_CoverReadCubeNum(pCover) != 1 ) + return 0; + pCube = pCover->lCubes.pHead; + if ( Mvc_CubeBitValue(pCube, 0) == 0 && Mvc_CubeBitValue(pCube, 1) == 1 ) + return 1; + return 0; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Mvc_CoverMakeEmpty( Mvc_Cover_t * pCover ) +{ + Mvc_Cube_t * pCube, * pCube2; + Mvc_CoverForEachCubeSafe( pCover, pCube, pCube2 ) + Mvc_CubeFree( pCover, pCube ); + pCover->lCubes.nItems = 0; + pCover->lCubes.pHead = NULL; + pCover->lCubes.pTail = NULL; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Mvc_CoverMakeTautology( Mvc_Cover_t * pCover ) +{ + Mvc_Cube_t * pCubeNew; + Mvc_CoverMakeEmpty( pCover ); + pCubeNew = Mvc_CubeAlloc( pCover ); + Mvc_CubeBitFill( pCubeNew ); + Mvc_CoverAddCubeTail( pCover, pCubeNew ); +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Mvc_Cover_t * Mvc_CoverCreateEmpty( Mvc_Cover_t * pCover ) +{ + Mvc_Cover_t * pCoverNew; + pCoverNew = Mvc_CoverAlloc( pCover->pMem, pCover->nBits ); + return pCoverNew; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Mvc_Cover_t * Mvc_CoverCreateTautology( Mvc_Cover_t * pCover ) +{ + Mvc_Cube_t * pCubeNew; + Mvc_Cover_t * pCoverNew; + pCoverNew = Mvc_CoverAlloc( pCover->pMem, pCover->nBits ); + pCubeNew = Mvc_CubeAlloc( pCoverNew ); + Mvc_CubeBitFill( pCubeNew ); + Mvc_CoverAddCubeTail( pCoverNew, pCubeNew ); + return pCoverNew; +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/misc/mvc/mvcCompare.c b/src/misc/mvc/mvcCompare.c new file mode 100644 index 00000000..c7999d40 --- /dev/null +++ b/src/misc/mvc/mvcCompare.c @@ -0,0 +1,369 @@ +/**CFile**************************************************************** + + FileName [mvcCompare.c] + + PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] + + Synopsis [Various cube comparison functions.] + + Author [MVSIS Group] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - February 1, 2003.] + + Revision [$Id: mvcCompare.c,v 1.5 2003/04/03 23:25:41 alanmi Exp $] + +***********************************************************************/ + +#include "mvc.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Compares two cubes according to their integer value.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Mvc_CubeCompareInt( Mvc_Cube_t * pC1, Mvc_Cube_t * pC2, Mvc_Cube_t * pMask ) +{ + if ( Mvc_Cube1Words(pC1) ) + { + if ( pC1->pData[0] < pC2->pData[0] ) + return -1; + if ( pC1->pData[0] > pC2->pData[0] ) + return 1; + return 0; + } + else if ( Mvc_Cube2Words(pC1) ) + { + if ( pC1->pData[1] < pC2->pData[1] ) + return -1; + if ( pC1->pData[1] > pC2->pData[1] ) + return 1; + if ( pC1->pData[0] < pC2->pData[0] ) + return -1; + if ( pC1->pData[0] > pC2->pData[0] ) + return 1; + return 0; + } + else + { + int i = Mvc_CubeReadLast(pC1); + for(; i >= 0; i--) + { + if ( pC1->pData[i] < pC2->pData[i] ) + return -1; + if ( pC1->pData[i] > pC2->pData[i] ) + return 1; + } + return 0; + } +} + + +/**Function************************************************************* + + Synopsis [Compares the cubes (1) by size, (2) by integer value.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Mvc_CubeCompareSizeAndInt( Mvc_Cube_t * pC1, Mvc_Cube_t * pC2, Mvc_Cube_t * pMask ) +{ + // compare the cubes by size + if ( Mvc_CubeReadSize( pC1 ) < Mvc_CubeReadSize( pC2 ) ) + return 1; + if ( Mvc_CubeReadSize( pC1 ) > Mvc_CubeReadSize( pC2 ) ) + return -1; + // the cubes have the same size + + // compare the cubes as integers + if ( Mvc_Cube1Words( pC1 ) ) + { + if ( pC1->pData[0] < pC2->pData[0] ) + return -1; + if ( pC1->pData[0] > pC2->pData[0] ) + return 1; + return 0; + } + else if ( Mvc_Cube2Words( pC1 ) ) + { + if ( pC1->pData[1] < pC2->pData[1] ) + return -1; + if ( pC1->pData[1] > pC2->pData[1] ) + return 1; + if ( pC1->pData[0] < pC2->pData[0] ) + return -1; + if ( pC1->pData[0] > pC2->pData[0] ) + return 1; + return 0; + } + else + { + int i = Mvc_CubeReadLast( pC1 ); + for(; i >= 0; i--) + { + if ( pC1->pData[i] < pC2->pData[i] ) + return -1; + if ( pC1->pData[i] > pC2->pData[i] ) + return 1; + } + return 0; + } +} + +/**Function************************************************************* + + Synopsis [Compares two cubes under the mask.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Mvc_CubeCompareIntUnderMask( Mvc_Cube_t * pC1, Mvc_Cube_t * pC2, Mvc_Cube_t * pMask ) +{ + unsigned uBits1, uBits2; + + // compare the cubes under the mask + if ( Mvc_Cube1Words(pC1) ) + { + uBits1 = pC1->pData[0] & pMask->pData[0]; + uBits2 = pC2->pData[0] & pMask->pData[0]; + if ( uBits1 < uBits2 ) + return -1; + if ( uBits1 > uBits2 ) + return 1; + // cubes are equal + return 0; + } + else if ( Mvc_Cube2Words(pC1) ) + { + uBits1 = pC1->pData[1] & pMask->pData[1]; + uBits2 = pC2->pData[1] & pMask->pData[1]; + if ( uBits1 < uBits2 ) + return -1; + if ( uBits1 > uBits2 ) + return 1; + uBits1 = pC1->pData[0] & pMask->pData[0]; + uBits2 = pC2->pData[0] & pMask->pData[0]; + if ( uBits1 < uBits2 ) + return -1; + if ( uBits1 > uBits2 ) + return 1; + return 0; + } + else + { + int i = Mvc_CubeReadLast(pC1); + for(; i >= 0; i--) + { + uBits1 = pC1->pData[i] & pMask->pData[i]; + uBits2 = pC2->pData[i] & pMask->pData[i]; + if ( uBits1 < uBits2 ) + return -1; + if ( uBits1 > uBits2 ) + return 1; + } + return 0; + } +} + +/**Function************************************************************* + + Synopsis [Compares two cubes under the mask.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Mvc_CubeCompareIntOutsideMask( Mvc_Cube_t * pC1, Mvc_Cube_t * pC2, Mvc_Cube_t * pMask ) +{ + unsigned uBits1, uBits2; + + // compare the cubes under the mask + if ( Mvc_Cube1Words(pC1) ) + { + uBits1 = pC1->pData[0] | pMask->pData[0]; + uBits2 = pC2->pData[0] | pMask->pData[0]; + if ( uBits1 < uBits2 ) + return -1; + if ( uBits1 > uBits2 ) + return 1; + // cubes are equal + return 0; + } + else if ( Mvc_Cube2Words(pC1) ) + { + uBits1 = pC1->pData[1] | pMask->pData[1]; + uBits2 = pC2->pData[1] | pMask->pData[1]; + if ( uBits1 < uBits2 ) + return -1; + if ( uBits1 > uBits2 ) + return 1; + uBits1 = pC1->pData[0] | pMask->pData[0]; + uBits2 = pC2->pData[0] | pMask->pData[0]; + if ( uBits1 < uBits2 ) + return -1; + if ( uBits1 > uBits2 ) + return 1; + return 0; + } + else + { + int i = Mvc_CubeReadLast(pC1); + for(; i >= 0; i--) + { + uBits1 = pC1->pData[i] | pMask->pData[i]; + uBits2 = pC2->pData[i] | pMask->pData[i]; + if ( uBits1 < uBits2 ) + return -1; + if ( uBits1 > uBits2 ) + return 1; + } + return 0; + } +} + + +/**Function************************************************************* + + Synopsis [Compares the cubes (1) outside the mask, (2) under the mask.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Mvc_CubeCompareIntOutsideAndUnderMask( Mvc_Cube_t * pC1, Mvc_Cube_t * pC2, Mvc_Cube_t * pMask ) +{ + unsigned uBits1, uBits2; + + if ( Mvc_Cube1Words(pC1) ) + { + // compare the cubes outside the mask + uBits1 = pC1->pData[0] & ~(pMask->pData[0]); + uBits2 = pC2->pData[0] & ~(pMask->pData[0]); + if ( uBits1 < uBits2 ) + return -1; + if ( uBits1 > uBits2 ) + return 1; + + // compare the cubes under the mask + uBits1 = pC1->pData[0] & pMask->pData[0]; + uBits2 = pC2->pData[0] & pMask->pData[0]; + if ( uBits1 < uBits2 ) + return -1; + if ( uBits1 > uBits2 ) + return 1; + // cubes are equal + // should never happen + assert( 0 ); + return 0; + } + else if ( Mvc_Cube2Words(pC1) ) + { + // compare the cubes outside the mask + uBits1 = pC1->pData[1] & ~(pMask->pData[1]); + uBits2 = pC2->pData[1] & ~(pMask->pData[1]); + if ( uBits1 < uBits2 ) + return -1; + if ( uBits1 > uBits2 ) + return 1; + + uBits1 = pC1->pData[0] & ~(pMask->pData[0]); + uBits2 = pC2->pData[0] & ~(pMask->pData[0]); + if ( uBits1 < uBits2 ) + return -1; + if ( uBits1 > uBits2 ) + return 1; + + // compare the cubes under the mask + uBits1 = pC1->pData[1] & pMask->pData[1]; + uBits2 = pC2->pData[1] & pMask->pData[1]; + if ( uBits1 < uBits2 ) + return -1; + if ( uBits1 > uBits2 ) + return 1; + + uBits1 = pC1->pData[0] & pMask->pData[0]; + uBits2 = pC2->pData[0] & pMask->pData[0]; + if ( uBits1 < uBits2 ) + return -1; + if ( uBits1 > uBits2 ) + return 1; + + // cubes are equal + // should never happen + assert( 0 ); + return 0; + } + else + { + int i; + + // compare the cubes outside the mask + for( i = Mvc_CubeReadLast(pC1); i >= 0; i-- ) + { + uBits1 = pC1->pData[i] & ~(pMask->pData[i]); + uBits2 = pC2->pData[i] & ~(pMask->pData[i]); + if ( uBits1 < uBits2 ) + return -1; + if ( uBits1 > uBits2 ) + return 1; + } + // compare the cubes under the mask + for( i = Mvc_CubeReadLast(pC1); i >= 0; i-- ) + { + uBits1 = pC1->pData[i] & pMask->pData[i]; + uBits2 = pC2->pData[i] & pMask->pData[i]; + if ( uBits1 < uBits2 ) + return -1; + if ( uBits1 > uBits2 ) + return 1; + } +/* + { + Mvc_Cover_t * pCover; + pCover = Mvc_CoverAlloc( NULL, 96 ); + Mvc_CubePrint( pCover, pC1 ); + Mvc_CubePrint( pCover, pC2 ); + Mvc_CubePrint( pCover, pMask ); + } +*/ + // cubes are equal + // should never happen + assert( 0 ); + return 0; + } +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/misc/mvc/mvcContain.c b/src/misc/mvc/mvcContain.c new file mode 100644 index 00000000..37b933b8 --- /dev/null +++ b/src/misc/mvc/mvcContain.c @@ -0,0 +1,173 @@ +/**CFile**************************************************************** + + FileName [mvcContain.c] + + PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] + + Synopsis [Making the cover single-cube containment free.] + + Author [MVSIS Group] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - February 1, 2003.] + + Revision [$Id: mvcContain.c,v 1.4 2003/04/03 23:25:42 alanmi Exp $] + +***********************************************************************/ + +#include "mvc.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static void Mvc_CoverRemoveDuplicates( Mvc_Cover_t * pCover ); +static void Mvc_CoverRemoveContained( Mvc_Cover_t * pCover ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + + +/**Function************************************************************* + + Synopsis [Removes the contained cubes.] + + Description [Returns 1 if the cover has been changed.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Mvc_CoverContain( Mvc_Cover_t * pCover ) +{ + int nCubes; + nCubes = Mvc_CoverReadCubeNum( pCover ); + if ( nCubes < 2 ) + return 0; + Mvc_CoverSetCubeSizes(pCover); + Mvc_CoverSort( pCover, NULL, Mvc_CubeCompareSizeAndInt ); + Mvc_CoverRemoveDuplicates( pCover ); + if ( nCubes > 1 ) + Mvc_CoverRemoveContained( pCover ); + return (nCubes != Mvc_CoverReadCubeNum(pCover)); +} + +/**Function************************************************************* + + Synopsis [Removes adjacent duplicated cubes from the cube list.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Mvc_CoverRemoveDuplicates( Mvc_Cover_t * pCover ) +{ + Mvc_Cube_t * pPrev, * pCube, * pCube2; + int fEqual; + + // set the first cube of the cover + pPrev = Mvc_CoverReadCubeHead(pCover); + // go through all the cubes after this one + Mvc_CoverForEachCubeStartSafe( Mvc_CubeReadNext(pPrev), pCube, pCube2 ) + { + // compare the current cube with the prev cube + Mvc_CubeBitEqual( fEqual, pPrev, pCube ); + if ( fEqual ) + { // they are equal - remove the current cube + Mvc_CoverDeleteCube( pCover, pPrev, pCube ); + Mvc_CubeFree( pCover, pCube ); + // don't change the previous cube cube + } + else + { // they are not equal - update the previous cube + pPrev = pCube; + } + } +} + +/**Function************************************************************* + + Synopsis [Removes contained cubes from the sorted cube list.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Mvc_CoverRemoveContained( Mvc_Cover_t * pCover ) +{ + Mvc_Cube_t * pCubeBeg, * pCubeEnd, * pCubeLarge; + Mvc_Cube_t * pCube, * pCube2, * pPrev; + unsigned sizeCur; + int Result; + + // since the cubes are sorted by size, it is sufficient + // to compare each cube with other cubes that have larger sizes + // if the given cube implies a larger cube, the larger cube is removed + pCubeBeg = Mvc_CoverReadCubeHead(pCover); + do + { + // get the current cube size + sizeCur = Mvc_CubeReadSize(pCubeBeg); + + // initialize the end of the given size group + pCubeEnd = pCubeBeg; + // find the beginning of the next size group + Mvc_CoverForEachCubeStart( Mvc_CubeReadNext(pCubeBeg), pCube ) + { + if ( sizeCur == Mvc_CubeReadSize(pCube) ) + pCubeEnd = pCube; + else // pCube is the first cube in the new size group + break; + } + // if we could not find the next size group + // the containment check is finished + if ( pCube == NULL ) + break; + // otherwise, pCubeBeg/pCubeEnd are the first/last cubes of the group + + // go through all the cubes between pCubeBeg and pCubeEnd, inclusive, + // and for each of them, try removing cubes after pCubeEnd + Mvc_CoverForEachCubeStart( pCubeBeg, pCubeLarge ) + { + pPrev = pCubeEnd; + Mvc_CoverForEachCubeStartSafe( Mvc_CubeReadNext(pCubeEnd), pCube, pCube2 ) + { + // check containment + Mvc_CubeBitNotImpl( Result, pCube, pCubeLarge ); + if ( !Result ) + { // pCubeLarge implies pCube - remove pCube + Mvc_CoverDeleteCube( pCover, pPrev, pCube ); + Mvc_CubeFree( pCover, pCube ); + // don't update the previous cube + } + else + { // update the previous cube + pPrev = pCube; + } + } + // quit, if the main cube was the last one of this size + if ( pCubeLarge == pCubeEnd ) + break; + } + + // set the beginning of the next group + pCubeBeg = Mvc_CubeReadNext(pCubeEnd); + } + while ( pCubeBeg ); +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/misc/mvc/mvcCover.c b/src/misc/mvc/mvcCover.c new file mode 100644 index 00000000..bd9c4412 --- /dev/null +++ b/src/misc/mvc/mvcCover.c @@ -0,0 +1,251 @@ +/**CFile**************************************************************** + + FileName [mvcCover.c] + + PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] + + Synopsis [Basic procedures to manipulate unate cube covers.] + + Author [MVSIS Group] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - February 1, 2003.] + + Revision [$Id: mvcCover.c,v 1.5 2003/04/09 18:02:05 alanmi Exp $] + +***********************************************************************/ + +#include "mvc.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Mvc_Cover_t * Mvc_CoverAlloc( Mvc_Manager_t * pMem, int nBits ) +{ + Mvc_Cover_t * p; + int nBitsInUnsigned; + + nBitsInUnsigned = 8 * sizeof(Mvc_CubeWord_t); +#ifdef USE_SYSTEM_MEMORY_MANAGEMENT + p = (Mvc_Cover_t *)malloc( sizeof(Mvc_Cover_t) ); +#else + p = (Mvc_Cover_t *)Extra_MmFixedEntryFetch( pMem->pManC ); +#endif + p->pMem = pMem; + p->nBits = nBits; + p->nWords = nBits / nBitsInUnsigned + (int)(nBits % nBitsInUnsigned > 0); + p->nUnused = p->nWords * nBitsInUnsigned - p->nBits; + p->lCubes.nItems = 0; + p->lCubes.pHead = NULL; + p->lCubes.pTail = NULL; + p->nCubesAlloc = 0; + p->pCubes = NULL; + p->pMask = NULL; + p->pLits = NULL; + return p; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Mvc_Cover_t * Mvc_CoverClone( Mvc_Cover_t * p ) +{ + Mvc_Cover_t * pCover; +#ifdef USE_SYSTEM_MEMORY_MANAGEMENT + pCover = (Mvc_Cover_t *)malloc( sizeof(Mvc_Cover_t) ); +#else + pCover = (Mvc_Cover_t *)Extra_MmFixedEntryFetch( p->pMem->pManC ); +#endif + pCover->pMem = p->pMem; + pCover->nBits = p->nBits; + pCover->nWords = p->nWords; + pCover->nUnused = p->nUnused; + pCover->lCubes.nItems = 0; + pCover->lCubes.pHead = NULL; + pCover->lCubes.pTail = NULL; + pCover->nCubesAlloc = 0; + pCover->pCubes = NULL; + pCover->pMask = NULL; + pCover->pLits = NULL; + return pCover; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Mvc_Cover_t * Mvc_CoverDup( Mvc_Cover_t * p ) +{ + Mvc_Cover_t * pCover; + Mvc_Cube_t * pCube, * pCubeCopy; + // clone the cover + pCover = Mvc_CoverClone( p ); + // copy the cube list + Mvc_CoverForEachCube( p, pCube ) + { + pCubeCopy = Mvc_CubeDup( p, pCube ); + Mvc_CoverAddCubeTail( pCover, pCubeCopy ); + } + return pCover; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Mvc_CoverFree( Mvc_Cover_t * p ) +{ + Mvc_Cube_t * pCube, * pCube2; + // recycle cube list + Mvc_CoverForEachCubeSafe( p, pCube, pCube2 ) + Mvc_CubeFree( p, pCube ); + // recycle other pointers + Mvc_CubeFree( p, p->pMask ); + MEM_FREE( p->pMem, Mvc_Cube_t *, p->nCubesAlloc, p->pCubes ); + MEM_FREE( p->pMem, int, p->nBits, p->pLits ); + +#ifdef USE_SYSTEM_MEMORY_MANAGEMENT + free( p ); +#else + Extra_MmFixedEntryRecycle( p->pMem->pManC, (char *)p ); +#endif +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Mvc_CoverAllocateMask( Mvc_Cover_t * pCover ) +{ + if ( pCover->pMask == NULL ) + pCover->pMask = Mvc_CubeAlloc( pCover ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Mvc_CoverAllocateArrayLits( Mvc_Cover_t * pCover ) +{ + if ( pCover->pLits == NULL ) + pCover->pLits = MEM_ALLOC( pCover->pMem, int, pCover->nBits ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Mvc_CoverAllocateArrayCubes( Mvc_Cover_t * pCover ) +{ + if ( pCover->nCubesAlloc < pCover->lCubes.nItems ) + { + if ( pCover->nCubesAlloc > 0 ) + MEM_FREE( pCover->pMem, Mvc_Cube_t *, pCover->nCubesAlloc, pCover->pCubes ); + pCover->nCubesAlloc = pCover->lCubes.nItems; + pCover->pCubes = MEM_ALLOC( pCover->pMem, Mvc_Cube_t *, pCover->nCubesAlloc ); + } +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Mvc_CoverDeallocateMask( Mvc_Cover_t * pCover ) +{ + Mvc_CubeFree( pCover, pCover->pMask ); + pCover->pMask = NULL; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Mvc_CoverDeallocateArrayLits( Mvc_Cover_t * pCover ) +{ + if ( pCover->pLits ) + { + MEM_FREE( pCover->pMem, int, pCover->nBits, pCover->pLits ); + pCover->pLits = NULL; + } +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/misc/mvc/mvcCube.c b/src/misc/mvc/mvcCube.c new file mode 100644 index 00000000..d02fa270 --- /dev/null +++ b/src/misc/mvc/mvcCube.c @@ -0,0 +1,175 @@ +/**CFile**************************************************************** + + FileName [mvcCube.c] + + PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] + + Synopsis [Manipulating unate cubes.] + + Author [MVSIS Group] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - February 1, 2003.] + + Revision [$Id: mvcCube.c,v 1.4 2003/04/03 06:31:49 alanmi Exp $] + +***********************************************************************/ + +#include "mvc.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Mvc_Cube_t * Mvc_CubeAlloc( Mvc_Cover_t * pCover ) +{ + Mvc_Cube_t * pCube; + + assert( pCover->nWords >= 0 ); + // allocate the cube +#ifdef USE_SYSTEM_MEMORY_MANAGEMENT + if ( pCover->nWords == 0 ) + pCube = (Mvc_Cube_t *)malloc( sizeof(Mvc_Cube_t) ); + else + pCube = (Mvc_Cube_t *)malloc( sizeof(Mvc_Cube_t) + sizeof(Mvc_CubeWord_t) * (pCover->nWords - 1) ); +#else + switch( pCover->nWords ) + { + case 0: + case 1: + pCube = (Mvc_Cube_t *)Extra_MmFixedEntryFetch( pCover->pMem->pMan1 ); + break; + case 2: + pCube = (Mvc_Cube_t *)Extra_MmFixedEntryFetch( pCover->pMem->pMan2 ); + break; + case 3: + case 4: + pCube = (Mvc_Cube_t *)Extra_MmFixedEntryFetch( pCover->pMem->pMan4 ); + break; + default: + pCube = (Mvc_Cube_t *)malloc( sizeof(Mvc_Cube_t) + sizeof(Mvc_CubeWord_t) * (pCover->nWords - 1) ); + break; + } +#endif + // set the parameters charactering this cube + if ( pCover->nWords == 0 ) + pCube->iLast = pCover->nWords; + else + pCube->iLast = pCover->nWords - 1; + pCube->nUnused = pCover->nUnused; + return pCube; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Mvc_Cube_t * Mvc_CubeDup( Mvc_Cover_t * pCover, Mvc_Cube_t * pCube ) +{ + Mvc_Cube_t * pCubeCopy; + pCubeCopy = Mvc_CubeAlloc( pCover ); + Mvc_CubeBitCopy( pCubeCopy, pCube ); + return pCubeCopy; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Mvc_CubeFree( Mvc_Cover_t * pCover, Mvc_Cube_t * pCube ) +{ + if ( pCube == NULL ) + return; + + // verify the parameters charactering this cube + assert( pCube->iLast == 0 || ((int)pCube->iLast) == pCover->nWords - 1 ); + assert( ((int)pCube->nUnused) == pCover->nUnused ); + + // deallocate the cube +#ifdef USE_SYSTEM_MEMORY_MANAGEMENT + free( pCube ); +#else + switch( pCover->nWords ) + { + case 0: + case 1: + Extra_MmFixedEntryRecycle( pCover->pMem->pMan1, (char *)pCube ); + break; + case 2: + Extra_MmFixedEntryRecycle( pCover->pMem->pMan2, (char *)pCube ); + break; + case 3: + case 4: + Extra_MmFixedEntryRecycle( pCover->pMem->pMan4, (char *)pCube ); + break; + default: + free( pCube ); + break; + } +#endif +} + + +/**Function************************************************************* + + Synopsis [Removes the don't-care variable from the cube.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Mvc_CubeBitRemoveDcs( Mvc_Cube_t * pCube ) +{ + unsigned Mask; + int i; + for ( i = Mvc_CubeReadLast(pCube); i >= 0; i-- ) + { + // detect those variables that are different (not DCs) + Mask = (pCube->pData[i] ^ (pCube->pData[i] >> 1)) & BITS_DISJOINT; + // create the mask of all that are different + Mask |= (Mask << 1); + // remove other bits from the set + pCube->pData[i] &= Mask; + } +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/misc/mvc/mvcDivide.c b/src/misc/mvc/mvcDivide.c new file mode 100644 index 00000000..6aa3d58d --- /dev/null +++ b/src/misc/mvc/mvcDivide.c @@ -0,0 +1,436 @@ +/**CFile**************************************************************** + + FileName [mvcDivide.c] + + PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] + + Synopsis [Procedures for algebraic division.] + + Author [MVSIS Group] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - February 1, 2003.] + + Revision [$Id: mvcDivide.c,v 1.5 2003/04/26 20:41:36 alanmi Exp $] + +***********************************************************************/ + +#include "mvc.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static void Mvc_CoverVerifyDivision( Mvc_Cover_t * pCover, Mvc_Cover_t * pDiv, Mvc_Cover_t * pQuo, Mvc_Cover_t * pRem ); + +int s_fVerbose = 0; + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Mvc_CoverDivide( Mvc_Cover_t * pCover, Mvc_Cover_t * pDiv, Mvc_Cover_t ** ppQuo, Mvc_Cover_t ** ppRem ) +{ + // check the number of cubes + if ( Mvc_CoverReadCubeNum( pCover ) < Mvc_CoverReadCubeNum( pDiv ) ) + { + *ppQuo = NULL; + *ppRem = NULL; + return; + } + + // make sure that support of pCover contains that of pDiv + if ( !Mvc_CoverCheckSuppContainment( pCover, pDiv ) ) + { + *ppQuo = NULL; + *ppRem = NULL; + return; + } + + // perform the general division + Mvc_CoverDivideInternal( pCover, pDiv, ppQuo, ppRem ); +} + + +/**Function************************************************************* + + Synopsis [Merge the cubes inside the groups.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Mvc_CoverDivideInternal( Mvc_Cover_t * pCover, Mvc_Cover_t * pDiv, Mvc_Cover_t ** ppQuo, Mvc_Cover_t ** ppRem ) +{ + Mvc_Cover_t * pQuo, * pRem; + Mvc_Cube_t * pCubeC, * pCubeD, * pCubeCopy; + Mvc_Cube_t * pCube1, * pCube2; + int * pGroups, nGroups; // the cube groups + int nCubesC, nCubesD, nMerges, iCubeC, iCubeD, iMerge; + int fSkipG, GroupSize, g, c, RetValue; + int nCubes; + + // get cover sizes + nCubesD = Mvc_CoverReadCubeNum( pDiv ); + nCubesC = Mvc_CoverReadCubeNum( pCover ); + + // check trivial cases + if ( nCubesD == 1 ) + { + if ( Mvc_CoverIsOneLiteral( pDiv ) ) + Mvc_CoverDivideByLiteral( pCover, pDiv, ppQuo, ppRem ); + else + Mvc_CoverDivideByCube( pCover, pDiv, ppQuo, ppRem ); + return; + } + + // create the divisor and the remainder + pQuo = Mvc_CoverAlloc( pCover->pMem, pCover->nBits ); + pRem = Mvc_CoverAlloc( pCover->pMem, pCover->nBits ); + + // get the support of the divisor + Mvc_CoverAllocateMask( pDiv ); + Mvc_CoverSupport( pDiv, pDiv->pMask ); + + // sort the cubes of the divisor + Mvc_CoverSort( pDiv, NULL, Mvc_CubeCompareInt ); + // sort the cubes of the cover + Mvc_CoverSort( pCover, pDiv->pMask, Mvc_CubeCompareIntOutsideAndUnderMask ); + + // allocate storage for cube groups + pGroups = MEM_ALLOC( pCover->pMem, int, nCubesC + 1 ); + + // mask contains variables in the support of Div + // split the cubes into groups using the mask + Mvc_CoverList2Array( pCover ); + Mvc_CoverList2Array( pDiv ); + pGroups[0] = 0; + nGroups = 1; + for ( c = 1; c < nCubesC; c++ ) + { + // get the cubes + pCube1 = pCover->pCubes[c-1]; + pCube2 = pCover->pCubes[c ]; + // compare the cubes + Mvc_CubeBitEqualOutsideMask( RetValue, pCube1, pCube2, pDiv->pMask ); + if ( !RetValue ) + pGroups[nGroups++] = c; + } + // finish off the last group + pGroups[nGroups] = nCubesC; + + // consider each group separately and decide + // whether it can produce a quotient cube + nCubes = 0; + for ( g = 0; g < nGroups; g++ ) + { + // if the group has less than nCubesD cubes, + // there is no way it can produce the quotient cube + // copy the cubes to the remainder + GroupSize = pGroups[g+1] - pGroups[g]; + if ( GroupSize < nCubesD ) + { + for ( c = pGroups[g]; c < pGroups[g+1]; c++ ) + { + pCubeCopy = Mvc_CubeDup( pRem, pCover->pCubes[c] ); + Mvc_CoverAddCubeTail( pRem, pCubeCopy ); + nCubes++; + } + continue; + } + + // mark the cubes as those that should be added to the remainder + for ( c = pGroups[g]; c < pGroups[g+1]; c++ ) + Mvc_CubeSetSize( pCover->pCubes[c], 1 ); + + // go through the cubes in the group and at the same time + // go through the cubes in the divisor + iCubeD = 0; + iCubeC = 0; + pCubeD = pDiv->pCubes[iCubeD++]; + pCubeC = pCover->pCubes[pGroups[g]+iCubeC++]; + fSkipG = 0; + nMerges = 0; + + while ( 1 ) + { + // compare the topmost cubes in F and in D + RetValue = Mvc_CubeCompareIntUnderMask( pCubeC, pCubeD, pDiv->pMask ); + // cube are ordered in increasing order of their int value + if ( RetValue == -1 ) // pCubeC is above pCubeD + { // cube in C should be added to the remainder + // check that there is enough cubes in the group + if ( GroupSize - iCubeC < nCubesD - nMerges ) + { + fSkipG = 1; + break; + } + // get the next cube in the cover + pCubeC = pCover->pCubes[pGroups[g]+iCubeC++]; + continue; + } + if ( RetValue == 1 ) // pCubeD is above pCubeC + { // given cube in D does not have a corresponding cube in the cover + fSkipG = 1; + break; + } + // mark the cube as the one that should NOT be added to the remainder + Mvc_CubeSetSize( pCubeC, 0 ); + // remember this merged cube + iMerge = iCubeC-1; + nMerges++; + + // stop if we considered the last cube of the group + if ( iCubeD == nCubesD ) + break; + + // advance the cube of the divisor + assert( iCubeD < nCubesD ); + pCubeD = pDiv->pCubes[iCubeD++]; + + // advance the cube of the group + assert( pGroups[g]+iCubeC < nCubesC ); + pCubeC = pCover->pCubes[pGroups[g]+iCubeC++]; + } + + if ( fSkipG ) + { + // the group has failed, add all the cubes to the remainder + for ( c = pGroups[g]; c < pGroups[g+1]; c++ ) + { + pCubeCopy = Mvc_CubeDup( pRem, pCover->pCubes[c] ); + Mvc_CoverAddCubeTail( pRem, pCubeCopy ); + nCubes++; + } + continue; + } + + // the group has worked, add left-over cubes to the remainder + for ( c = pGroups[g]; c < pGroups[g+1]; c++ ) + { + pCubeC = pCover->pCubes[c]; + if ( Mvc_CubeReadSize(pCubeC) ) + { + pCubeCopy = Mvc_CubeDup( pRem, pCubeC ); + Mvc_CoverAddCubeTail( pRem, pCubeCopy ); + nCubes++; + } + } + + // create the quotient cube + pCube1 = Mvc_CubeAlloc( pQuo ); + Mvc_CubeBitSharp( pCube1, pCover->pCubes[pGroups[g]+iMerge], pDiv->pMask ); + // add the cube to the quotient + Mvc_CoverAddCubeTail( pQuo, pCube1 ); + nCubes += nCubesD; + } + assert( nCubes == nCubesC ); + + // deallocate the memory + MEM_FREE( pCover->pMem, int, nCubesC + 1, pGroups ); + + // return the results + *ppRem = pRem; + *ppQuo = pQuo; +// Mvc_CoverVerifyDivision( pCover, pDiv, pQuo, pRem ); +} + + +/**Function************************************************************* + + Synopsis [Divides the cover by a cube.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Mvc_CoverDivideByCube( Mvc_Cover_t * pCover, Mvc_Cover_t * pDiv, Mvc_Cover_t ** ppQuo, Mvc_Cover_t ** ppRem ) +{ + Mvc_Cover_t * pQuo, * pRem; + Mvc_Cube_t * pCubeC, * pCubeD, * pCubeCopy; + int CompResult; + + // get the only cube of D + assert( Mvc_CoverReadCubeNum(pDiv) == 1 ); + + // start the quotient and the remainder + pQuo = Mvc_CoverAlloc( pCover->pMem, pCover->nBits ); + pRem = Mvc_CoverAlloc( pCover->pMem, pCover->nBits ); + + // get the first and only cube of the divisor + pCubeD = Mvc_CoverReadCubeHead( pDiv ); + + // iterate through the cubes in the cover + Mvc_CoverForEachCube( pCover, pCubeC ) + { + // check the containment of literals from pCubeD in pCube + Mvc_Cube2BitNotImpl( CompResult, pCubeD, pCubeC ); + if ( !CompResult ) + { // this cube belongs to the quotient + // alloc the cube + pCubeCopy = Mvc_CubeAlloc( pQuo ); + // clean the support of D + Mvc_CubeBitSharp( pCubeCopy, pCubeC, pCubeD ); + // add the cube to the quotient + Mvc_CoverAddCubeTail( pQuo, pCubeCopy ); + } + else + { + // copy the cube + pCubeCopy = Mvc_CubeDup( pRem, pCubeC ); + // add the cube to the remainder + Mvc_CoverAddCubeTail( pRem, pCubeCopy ); + } + } + // return the results + *ppRem = pRem; + *ppQuo = pQuo; +} + +/**Function************************************************************* + + Synopsis [Divides the cover by a literal.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Mvc_CoverDivideByLiteral( Mvc_Cover_t * pCover, Mvc_Cover_t * pDiv, Mvc_Cover_t ** ppQuo, Mvc_Cover_t ** ppRem ) +{ + Mvc_Cover_t * pQuo, * pRem; + Mvc_Cube_t * pCubeC, * pCubeCopy; + int iLit; + + // get the only cube of D + assert( Mvc_CoverReadCubeNum(pDiv) == 1 ); + + // start the quotient and the remainder + pQuo = Mvc_CoverAlloc( pCover->pMem, pCover->nBits ); + pRem = Mvc_CoverAlloc( pCover->pMem, pCover->nBits ); + + // get the first and only literal in the divisor cube + iLit = Mvc_CoverFirstCubeFirstLit( pDiv ); + + // iterate through the cubes in the cover + Mvc_CoverForEachCube( pCover, pCubeC ) + { + // copy the cube + pCubeCopy = Mvc_CubeDup( pCover, pCubeC ); + // add the cube to the quotient or to the remainder depending on the literal + if ( Mvc_CubeBitValue( pCubeCopy, iLit ) ) + { // remove the literal + Mvc_CubeBitRemove( pCubeCopy, iLit ); + // add the cube ot the quotient + Mvc_CoverAddCubeTail( pQuo, pCubeCopy ); + } + else + { // add the cube ot the remainder + Mvc_CoverAddCubeTail( pRem, pCubeCopy ); + } + } + // return the results + *ppRem = pRem; + *ppQuo = pQuo; +} + + +/**Function************************************************************* + + Synopsis [Derives the quotient of division by literal.] + + Description [Reduces the cover to be the equal to the result of + division of the given cover by the literal.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Mvc_CoverDivideByLiteralQuo( Mvc_Cover_t * pCover, int iLit ) +{ + Mvc_Cube_t * pCube, * pCube2, * pPrev; + // delete those cubes that do not have this literal + // remove this literal from other cubes + pPrev = NULL; + Mvc_CoverForEachCubeSafe( pCover, pCube, pCube2 ) + { + if ( Mvc_CubeBitValue( pCube, iLit ) == 0 ) + { // delete the cube from the cover + Mvc_CoverDeleteCube( pCover, pPrev, pCube ); + Mvc_CubeFree( pCover, pCube ); + // don't update the previous cube + } + else + { // delete this literal from the cube + Mvc_CubeBitRemove( pCube, iLit ); + // update the previous cube + pPrev = pCube; + } + } +} + + +/**Function************************************************************* + + Synopsis [Verifies that the result of algebraic division is correct.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Mvc_CoverVerifyDivision( Mvc_Cover_t * pCover, Mvc_Cover_t * pDiv, Mvc_Cover_t * pQuo, Mvc_Cover_t * pRem ) +{ + Mvc_Cover_t * pProd; + Mvc_Cover_t * pDiff; + + pProd = Mvc_CoverAlgebraicMultiply( pDiv, pQuo ); + pDiff = Mvc_CoverAlgebraicSubtract( pCover, pProd ); + + if ( Mvc_CoverAlgebraicEqual( pDiff, pRem ) ) + printf( "Verification OKAY!\n" ); + else + { + printf( "Verification FAILED!\n" ); + printf( "pCover:\n" ); + Mvc_CoverPrint( pCover ); + printf( "pDiv:\n" ); + Mvc_CoverPrint( pDiv ); + printf( "pRem:\n" ); + Mvc_CoverPrint( pRem ); + printf( "pQuo:\n" ); + Mvc_CoverPrint( pQuo ); + } + + Mvc_CoverFree( pProd ); + Mvc_CoverFree( pDiff ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/misc/mvc/mvcDivisor.c b/src/misc/mvc/mvcDivisor.c new file mode 100644 index 00000000..e92c3a65 --- /dev/null +++ b/src/misc/mvc/mvcDivisor.c @@ -0,0 +1,90 @@ +/**CFile**************************************************************** + + FileName [mvcDivisor.c] + + PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] + + Synopsis [Procedures for compute the quick divisor.] + + Author [MVSIS Group] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - February 1, 2003.] + + Revision [$Id: mvcDivisor.c,v 1.1 2003/04/03 15:34:08 alanmi Exp $] + +***********************************************************************/ + +#include "mvc.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static void Mvc_CoverDivisorZeroKernel( Mvc_Cover_t * pCover ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Returns the quick divisor of the cover.] + + Description [Returns NULL, if there is not divisor other than + trivial.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Mvc_Cover_t * Mvc_CoverDivisor( Mvc_Cover_t * pCover ) +{ + Mvc_Cover_t * pKernel; + if ( Mvc_CoverReadCubeNum(pCover) <= 1 ) + return NULL; + // allocate the literal array and count literals + if ( Mvc_CoverAnyLiteral( pCover, NULL ) == -1 ) + return NULL; + // duplicate the cover + pKernel = Mvc_CoverDup(pCover); + // perform the kerneling + Mvc_CoverDivisorZeroKernel( pKernel ); + assert( Mvc_CoverReadCubeNum(pKernel) ); + return pKernel; +} + +/**Function************************************************************* + + Synopsis [Computes a level-zero kernel.] + + Description [Modifies the cover to contain one level-zero kernel.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Mvc_CoverDivisorZeroKernel( Mvc_Cover_t * pCover ) +{ + int iLit; + // find any literal that occurs at least two times +// iLit = Mvc_CoverAnyLiteral( pCover, NULL ); + iLit = Mvc_CoverWorstLiteral( pCover, NULL ); +// iLit = Mvc_CoverBestLiteral( pCover, NULL ); + if ( iLit == -1 ) + return; + // derive the cube-free quotient + Mvc_CoverDivideByLiteralQuo( pCover, iLit ); // the same cover + Mvc_CoverMakeCubeFree( pCover ); // the same cover + // call recursively + Mvc_CoverDivisorZeroKernel( pCover ); // the same cover +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/misc/mvc/mvcList.c b/src/misc/mvc/mvcList.c new file mode 100644 index 00000000..678ae9fd --- /dev/null +++ b/src/misc/mvc/mvcList.c @@ -0,0 +1,362 @@ +/**CFile**************************************************************** + + FileName [mvcList.c] + + PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] + + Synopsis [Manipulating list of cubes in the cover.] + + Author [MVSIS Group] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - February 1, 2003.] + + Revision [$Id: mvcList.c,v 1.4 2003/04/03 06:31:50 alanmi Exp $] + +***********************************************************************/ + +#include "mvc.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Mvc_ListAddCubeHead_( Mvc_List_t * pList, Mvc_Cube_t * pCube ) +{ + if ( pList->pHead == NULL ) + { + Mvc_CubeSetNext( pCube, NULL ); + pList->pHead = pCube; + pList->pTail = pCube; + } + else + { + Mvc_CubeSetNext( pCube, pList->pHead ); + pList->pHead = pCube; + } + pList->nItems++; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Mvc_ListAddCubeTail_( Mvc_List_t * pList, Mvc_Cube_t * pCube ) +{ + if ( pList->pHead == NULL ) + pList->pHead = pCube; + else + Mvc_CubeSetNext( pList->pTail, pCube ); + pList->pTail = pCube; + Mvc_CubeSetNext( pCube, NULL ); + pList->nItems++; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Mvc_ListDeleteCube_( Mvc_List_t * pList, Mvc_Cube_t * pPrev, Mvc_Cube_t * pCube ) +{ + if ( pPrev == NULL ) // deleting the head cube + pList->pHead = Mvc_CubeReadNext(pCube); + else + pPrev->pNext = pCube->pNext; + if ( pList->pTail == pCube ) // deleting the tail cube + { + assert( Mvc_CubeReadNext(pCube) == NULL ); + pList->pTail = pPrev; + } + pList->nItems--; +} + + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Mvc_CoverAddCubeHead_( Mvc_Cover_t * pCover, Mvc_Cube_t * pCube ) +{ + Mvc_List_t * pList = &pCover->lCubes; + if ( pList->pHead == NULL ) + { + Mvc_CubeSetNext( pCube, NULL ); + pList->pHead = pCube; + pList->pTail = pCube; + } + else + { + Mvc_CubeSetNext( pCube, pList->pHead ); + pList->pHead = pCube; + } + pList->nItems++; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Mvc_CoverAddCubeTail_( Mvc_Cover_t * pCover, Mvc_Cube_t * pCube ) +{ + Mvc_List_t * pList = &pCover->lCubes; + + if ( pList->pHead == NULL ) + pList->pHead = pCube; + else + Mvc_CubeSetNext( pList->pTail, pCube ); + pList->pTail = pCube; + Mvc_CubeSetNext( pCube, NULL ); + pList->nItems++; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Mvc_CoverDeleteCube_( Mvc_Cover_t * pCover, Mvc_Cube_t * pPrev, Mvc_Cube_t * pCube ) +{ + Mvc_List_t * pList = &pCover->lCubes; + + if ( pPrev == NULL ) // deleting the head cube + pList->pHead = Mvc_CubeReadNext(pCube); + else + pPrev->pNext = pCube->pNext; + if ( pList->pTail == pCube ) // deleting the tail cube + { + assert( Mvc_CubeReadNext(pCube) == NULL ); + pList->pTail = pPrev; + } + pList->nItems--; +} + + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Mvc_CoverAddDupCubeHead( Mvc_Cover_t * pCover, Mvc_Cube_t * pCube ) +{ + Mvc_Cube_t * pCubeNew; + pCubeNew = Mvc_CubeAlloc( pCover ); + Mvc_CubeBitCopy( pCubeNew, pCube ); + Mvc_CoverAddCubeHead( pCover, pCubeNew ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Mvc_CoverAddDupCubeTail( Mvc_Cover_t * pCover, Mvc_Cube_t * pCube ) +{ + Mvc_Cube_t * pCubeNew; + // copy the cube as part of this cover + pCubeNew = Mvc_CubeAlloc( pCover ); + Mvc_CubeBitCopy( pCubeNew, pCube ); + // clean the last bits of the new cube +// pCubeNew->pData[pCubeNew->iLast] &= (BITS_FULL >> pCubeNew->nUnused); + // add the cube at the end + Mvc_CoverAddCubeTail( pCover, pCubeNew ); +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Mvc_CoverAddLiteralsOfCube( Mvc_Cover_t * pCover, Mvc_Cube_t * pCube ) +{ +// int iBit, Value; +// assert( pCover->pLits ); +// Mvc_CubeForEachBit( pCover, pCube, iBit, Value ) +// if ( Value ) +// pCover->pLits[iBit] += Value; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Mvc_CoverDeleteLiteralsOfCube( Mvc_Cover_t * pCover, Mvc_Cube_t * pCube ) +{ +// int iBit, Value; +// assert( pCover->pLits ); +// Mvc_CubeForEachBit( pCover, pCube, iBit, Value ) +// if ( Value ) +// pCover->pLits[iBit] -= Value; +} + + +/**Function************************************************************* + + Synopsis [Transfers the cubes from the list into the array.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Mvc_CoverList2Array( Mvc_Cover_t * pCover ) +{ + Mvc_Cube_t * pCube; + int Counter; + // resize storage if necessary + Mvc_CoverAllocateArrayCubes( pCover ); + // iterate through the cubes + Counter = 0; + Mvc_CoverForEachCube( pCover, pCube ) + pCover->pCubes[ Counter++ ] = pCube; + assert( Counter == Mvc_CoverReadCubeNum(pCover) ); +} + +/**Function************************************************************* + + Synopsis [Transfers the cubes from the array into list.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Mvc_CoverArray2List( Mvc_Cover_t * pCover ) +{ + Mvc_Cube_t * pCube; + int nCubes, i; + + assert( pCover->pCubes ); + + nCubes = Mvc_CoverReadCubeNum(pCover); + if ( nCubes == 0 ) + return; + if ( nCubes == 1 ) + { + pCube = pCover->pCubes[0]; + pCube->pNext = NULL; + pCover->lCubes.pHead = pCover->lCubes.pTail = pCube; + return; + } + // set up the first cube + pCube = pCover->pCubes[0]; + pCover->lCubes.pHead = pCube; + // set up the last cube + pCube = pCover->pCubes[nCubes-1]; + pCube->pNext = NULL; + pCover->lCubes.pTail = pCube; + + // link all cubes starting from the first one + for ( i = 0; i < nCubes - 1; i++ ) + pCover->pCubes[i]->pNext = pCover->pCubes[i+1]; +} + +/**Function************************************************************* + + Synopsis [Returns the tail of the linked list given by the head.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Mvc_Cube_t * Mvc_ListGetTailFromHead( Mvc_Cube_t * pHead ) +{ + Mvc_Cube_t * pCube, * pTail; + for ( pTail = pCube = pHead; + pCube; + pTail = pCube, pCube = Mvc_CubeReadNext(pCube) ); + return pTail; +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/misc/mvc/mvcLits.c b/src/misc/mvc/mvcLits.c new file mode 100644 index 00000000..98211719 --- /dev/null +++ b/src/misc/mvc/mvcLits.c @@ -0,0 +1,345 @@ +/**CFile**************************************************************** + + FileName [mvcLits.c] + + PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] + + Synopsis [Literal counting/updating procedures.] + + Author [MVSIS Group] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - February 1, 2003.] + + Revision [$Id: mvcLits.c,v 1.4 2003/04/03 06:31:50 alanmi Exp $] + +***********************************************************************/ + +#include "mvc.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Find the any literal that occurs more than once.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Mvc_CoverAnyLiteral( Mvc_Cover_t * pCover, Mvc_Cube_t * pMask ) +{ + Mvc_Cube_t * pCube; + int nWord, nBit, i; + int nLitsCur; + int fUseFirst = 0; + + // go through each literal + if ( fUseFirst ) + { + for ( i = 0; i < pCover->nBits; i++ ) + if ( !pMask || Mvc_CubeBitValue(pMask,i) ) + { + // get the word and bit of this literal + nWord = Mvc_CubeWhichWord(i); + nBit = Mvc_CubeWhichBit(i); + // go through all the cubes + nLitsCur = 0; + Mvc_CoverForEachCube( pCover, pCube ) + if ( pCube->pData[nWord] & (1< 1 ) + return i; + } + } + } + else + { + for ( i = pCover->nBits - 1; i >=0; i-- ) + if ( !pMask || Mvc_CubeBitValue(pMask,i) ) + { + // get the word and bit of this literal + nWord = Mvc_CubeWhichWord(i); + nBit = Mvc_CubeWhichBit(i); + // go through all the cubes + nLitsCur = 0; + Mvc_CoverForEachCube( pCover, pCube ) + if ( pCube->pData[nWord] & (1< 1 ) + return i; + } + } + } + return -1; +} + +/**Function************************************************************* + + Synopsis [Find the most often occurring literal.] + + Description [Find the most often occurring literal among those + that occur more than once.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Mvc_CoverBestLiteral( Mvc_Cover_t * pCover, Mvc_Cube_t * pMask ) +{ + Mvc_Cube_t * pCube; + int nWord, nBit; + int i, iMax, nLitsMax, nLitsCur; + int fUseFirst = 1; + + // go through each literal + iMax = -1; + nLitsMax = -1; + for ( i = 0; i < pCover->nBits; i++ ) + if ( !pMask || Mvc_CubeBitValue(pMask,i) ) + { + // get the word and bit of this literal + nWord = Mvc_CubeWhichWord(i); + nBit = Mvc_CubeWhichBit(i); + // go through all the cubes + nLitsCur = 0; + Mvc_CoverForEachCube( pCover, pCube ) + if ( pCube->pData[nWord] & (1< 1 ) + return iMax; + return -1; +} + +/**Function************************************************************* + + Synopsis [Find the most often occurring literal.] + + Description [Find the most often occurring literal among those + that occur more than once.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Mvc_CoverWorstLiteral( Mvc_Cover_t * pCover, Mvc_Cube_t * pMask ) +{ + Mvc_Cube_t * pCube; + int nWord, nBit; + int i, iMin, nLitsMin, nLitsCur; + int fUseFirst = 1; + + // go through each literal + iMin = -1; + nLitsMin = 1000000; + for ( i = 0; i < pCover->nBits; i++ ) + if ( !pMask || Mvc_CubeBitValue(pMask,i) ) + { + // get the word and bit of this literal + nWord = Mvc_CubeWhichWord(i); + nBit = Mvc_CubeWhichBit(i); + // go through all the cubes + nLitsCur = 0; + Mvc_CoverForEachCube( pCover, pCube ) + if ( pCube->pData[nWord] & (1< nLitsCur ) + { + nLitsMin = nLitsCur; + iMin = i; + } + } + else + { + if ( nLitsMin >= nLitsCur ) + { + nLitsMin = nLitsCur; + iMin = i; + } + } + } + + if ( nLitsMin < 1000000 ) + return iMin; + return -1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Mvc_Cover_t * Mvc_CoverBestLiteralCover( Mvc_Cover_t * pCover, Mvc_Cover_t * pSimple ) +{ + Mvc_Cover_t * pCoverNew; + Mvc_Cube_t * pCubeNew; + Mvc_Cube_t * pCubeS; + int iLitBest; + + // create the new cover + pCoverNew = Mvc_CoverClone( pCover ); + // get the new cube + pCubeNew = Mvc_CubeAlloc( pCoverNew ); + // clean the cube + Mvc_CubeBitClean( pCubeNew ); + + // get the first cube of pSimple + assert( Mvc_CoverReadCubeNum(pSimple) == 1 ); + pCubeS = Mvc_CoverReadCubeHead( pSimple ); + // find the best literal among those of pCubeS + iLitBest = Mvc_CoverBestLiteral( pCover, pCubeS ); + + // insert this literal into the cube + Mvc_CubeBitInsert( pCubeNew, iLitBest ); + // add the cube to the cover + Mvc_CoverAddCubeTail( pCoverNew, pCubeNew ); + return pCoverNew; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Mvc_CoverFirstCubeFirstLit( Mvc_Cover_t * pCover ) +{ + Mvc_Cube_t * pCube; + int iBit, Value; + + // get the first cube + pCube = Mvc_CoverReadCubeHead( pCover ); + // get the first literal + Mvc_CubeForEachBit( pCover, pCube, iBit, Value ) + if ( Value ) + return iBit; + return -1; +} + +/**Function************************************************************* + + Synopsis [Returns the number of literals in the cover.] + + Description [Allocates storage for literal counters and fills it up + using the current information.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Mvc_CoverCountLiterals( Mvc_Cover_t * pCover ) +{ + Mvc_Cube_t * pCube; + int nWord, nBit; + int i, CounterTot, CounterCur; + + // allocate/clean the storage for literals +// Mvc_CoverAllocateArrayLits( pCover ); +// memset( pCover->pLits, 0, pCover->nBits * sizeof(int) ); + // go through each literal + CounterTot = 0; + for ( i = 0; i < pCover->nBits; i++ ) + { + // get the word and bit of this literal + nWord = Mvc_CubeWhichWord(i); + nBit = Mvc_CubeWhichBit(i); + // go through all the cubes + CounterCur = 0; + Mvc_CoverForEachCube( pCover, pCube ) + if ( pCube->pData[nWord] & (1< +#include "mvc.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Mvc_Manager_t * Mvc_ManagerStart() +{ + Mvc_Manager_t * p; + p = ALLOC( Mvc_Manager_t, 1 ); + memset( p, 0, sizeof(Mvc_Manager_t) ); + p->pMan1 = Extra_MmFixedStart( sizeof(Mvc_Cube_t) ); + p->pMan2 = Extra_MmFixedStart( sizeof(Mvc_Cube_t) + sizeof(Mvc_CubeWord_t) ); + p->pMan4 = Extra_MmFixedStart( sizeof(Mvc_Cube_t) + 3 * sizeof(Mvc_CubeWord_t) ); + p->pManC = Extra_MmFixedStart( sizeof(Mvc_Cover_t) ); + return p; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Mvc_ManagerFree( Mvc_Manager_t * p ) +{ + Extra_MmFixedStop( p->pMan1, 0 ); + Extra_MmFixedStop( p->pMan2, 0 ); + Extra_MmFixedStop( p->pMan4, 0 ); + Extra_MmFixedStop( p->pManC, 0 ); + free( p ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/misc/mvc/mvcOpAlg.c b/src/misc/mvc/mvcOpAlg.c new file mode 100644 index 00000000..befccb70 --- /dev/null +++ b/src/misc/mvc/mvcOpAlg.c @@ -0,0 +1,163 @@ +/**CFile**************************************************************** + + FileName [mvcOperAlg.c] + + PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] + + Synopsis [Miscellaneous operations on covers.] + + Author [MVSIS Group] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - February 1, 2003.] + + Revision [$Id: mvcOpAlg.c,v 1.4 2003/04/26 20:41:36 alanmi Exp $] + +***********************************************************************/ + +#include "mvc.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Multiplies two disjoint-support covers.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Mvc_Cover_t * Mvc_CoverAlgebraicMultiply( Mvc_Cover_t * pCover1, Mvc_Cover_t * pCover2 ) +{ + Mvc_Cover_t * pCover; + Mvc_Cube_t * pCube1, * pCube2, * pCube; + int CompResult; + + // covers should be the same base + assert( pCover1->nBits == pCover2->nBits ); + // make sure that supports do not overlap + Mvc_CoverAllocateMask( pCover1 ); + Mvc_CoverAllocateMask( pCover2 ); + Mvc_CoverSupport( pCover1, pCover1->pMask ); + Mvc_CoverSupport( pCover2, pCover2->pMask ); + // check if the cubes are bit-wise disjoint + Mvc_CubeBitDisjoint( CompResult, pCover1->pMask, pCover2->pMask ); + if ( !CompResult ) + printf( "Mvc_CoverMultiply(): Cover supports are not disjoint!\n" ); + + // iterate through the cubes + pCover = Mvc_CoverClone( pCover1 ); + Mvc_CoverForEachCube( pCover1, pCube1 ) + Mvc_CoverForEachCube( pCover2, pCube2 ) + { + // create the product cube + pCube = Mvc_CubeAlloc( pCover ); + // set the product cube equal to the product of the two cubes + Mvc_CubeBitOr( pCube, pCube1, pCube2 ); + // add the cube to the cover + Mvc_CoverAddCubeTail( pCover, pCube ); + } + return pCover; +} + + +/**Function************************************************************* + + Synopsis [Subtracts the second cover from the first.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Mvc_Cover_t * Mvc_CoverAlgebraicSubtract( Mvc_Cover_t * pCover1, Mvc_Cover_t * pCover2 ) +{ + Mvc_Cover_t * pCover; + Mvc_Cube_t * pCube1, * pCube2, * pCube; + int fFound; + int CompResult; + + // covers should be the same base + assert( pCover1->nBits == pCover2->nBits ); + + // iterate through the cubes + pCover = Mvc_CoverClone( pCover1 ); + Mvc_CoverForEachCube( pCover1, pCube1 ) + { + fFound = 0; + Mvc_CoverForEachCube( pCover2, pCube2 ) + { + Mvc_CubeBitEqual( CompResult, pCube1, pCube2 ); + if ( CompResult ) + { + fFound = 1; + break; + } + } + if ( !fFound ) + { + // create the copy of the cube + pCube = Mvc_CubeDup( pCover, pCube1 ); + // add the cube copy to the cover + Mvc_CoverAddCubeTail( pCover, pCube ); + } + } + return pCover; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Mvc_CoverAlgebraicEqual( Mvc_Cover_t * pCover1, Mvc_Cover_t * pCover2 ) +{ + Mvc_Cube_t * pCube1, * pCube2; + int fFound; + int CompResult; + + // covers should be the same base + assert( pCover1->nBits == pCover2->nBits ); + // iterate through the cubes + Mvc_CoverForEachCube( pCover1, pCube1 ) + { + fFound = 0; + Mvc_CoverForEachCube( pCover2, pCube2 ) + { + Mvc_CubeBitEqual( CompResult, pCube1, pCube2 ); + if ( CompResult ) + { + fFound = 1; + break; + } + } + if ( !fFound ) + return 0; + } + return 1; +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/misc/mvc/mvcOpBool.c b/src/misc/mvc/mvcOpBool.c new file mode 100644 index 00000000..57b1a968 --- /dev/null +++ b/src/misc/mvc/mvcOpBool.c @@ -0,0 +1,151 @@ +/**CFile**************************************************************** + + FileName [mvcProc.c] + + PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] + + Synopsis [Various boolean procedures working with covers.] + + Author [MVSIS Group] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - February 1, 2003.] + + Revision [$Id: mvcOpBool.c,v 1.4 2003/04/16 01:55:37 alanmi Exp $] + +***********************************************************************/ + +#include "mvc.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Mvc_Cover_t * Mvc_CoverBooleanOr( Mvc_Cover_t * pCover1, Mvc_Cover_t * pCover2 ) +{ + Mvc_Cover_t * pCover; + Mvc_Cube_t * pCube, * pCubeCopy; + // make sure the covers are compatible + assert( pCover1->nBits == pCover2->nBits ); + // clone the cover + pCover = Mvc_CoverClone( pCover1 ); + // create the cubes by making pair-wise products + // of cubes in pCover1 and pCover2 + Mvc_CoverForEachCube( pCover1, pCube ) + { + pCubeCopy = Mvc_CubeDup( pCover, pCube ); + Mvc_CoverAddCubeTail( pCover, pCubeCopy ); + } + Mvc_CoverForEachCube( pCover2, pCube ) + { + pCubeCopy = Mvc_CubeDup( pCover, pCube ); + Mvc_CoverAddCubeTail( pCover, pCubeCopy ); + } + return pCover; +} + +#if 0 + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Mvc_Cover_t * Mvc_CoverBooleanAnd( Mvc_Data_t * p, Mvc_Cover_t * pCover1, Mvc_Cover_t * pCover2 ) +{ + Mvc_Cover_t * pCover; + Mvc_Cube_t * pCube1, * pCube2, * pCubeCopy; + // make sure the covers are compatible + assert( pCover1->nBits == pCover2->nBits ); + // clone the cover + pCover = Mvc_CoverClone( pCover1 ); + // create the cubes by making pair-wise products + // of cubes in pCover1 and pCover2 + Mvc_CoverForEachCube( pCover1, pCube1 ) + { + Mvc_CoverForEachCube( pCover2, pCube2 ) + { + if ( Mvc_CoverDist0Cubes( p, pCube1, pCube2 ) ) + { + pCubeCopy = Mvc_CubeAlloc( pCover ); + Mvc_CubeBitAnd( pCubeCopy, pCube1, pCube2 ); + Mvc_CoverAddCubeTail( pCover, pCubeCopy ); + } + } + // if the number of cubes in the new cover is too large + // try compressing them + if ( Mvc_CoverReadCubeNum( pCover ) > 500 ) + Mvc_CoverContain( pCover ); + } + return pCover; +} + +/**Function************************************************************* + + Synopsis [Returns 1 if the two covers are equal.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Mvc_CoverBooleanEqual( Mvc_Data_t * p, Mvc_Cover_t * pCover1, Mvc_Cover_t * pCover2 ) +{ + Mvc_Cover_t * pSharp; + + pSharp = Mvc_CoverSharp( p, pCover1, pCover2 ); + if ( Mvc_CoverReadCubeNum( pSharp ) ) + { +Mvc_CoverContain( pSharp ); +printf( "Sharp \n" ); +Mvc_CoverPrint( pSharp ); + Mvc_CoverFree( pSharp ); + return 0; + } + Mvc_CoverFree( pSharp ); + + pSharp = Mvc_CoverSharp( p, pCover2, pCover1 ); + if ( Mvc_CoverReadCubeNum( pSharp ) ) + { +Mvc_CoverContain( pSharp ); +printf( "Sharp \n" ); +Mvc_CoverPrint( pSharp ); + Mvc_CoverFree( pSharp ); + return 0; + } + Mvc_CoverFree( pSharp ); + + return 1; +} + +#endif + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/misc/mvc/mvcPrint.c b/src/misc/mvc/mvcPrint.c new file mode 100644 index 00000000..3a31235b --- /dev/null +++ b/src/misc/mvc/mvcPrint.c @@ -0,0 +1,220 @@ +/**CFile**************************************************************** + + FileName [mvcPrint.c] + + PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] + + Synopsis [Printing cubes and covers.] + + Author [MVSIS Group] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - February 1, 2003.] + + Revision [$Id: mvcPrint.c,v 1.6 2003/04/09 18:02:06 alanmi Exp $] + +***********************************************************************/ + +#include "mvc.h" +//#include "vm.h" +//#include "vmInt.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static void Mvc_CubePrintBinary( Mvc_Cover_t * pCover, Mvc_Cube_t * pCube ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Mvc_CoverPrint( Mvc_Cover_t * pCover ) +{ + Mvc_Cube_t * pCube; + int i; + // print general statistics + printf( "The cover contains %d cubes (%d bits and %d words)\n", + pCover->lCubes.nItems, pCover->nBits, pCover->nWords ); + // iterate through the cubes + Mvc_CoverForEachCube( pCover, pCube ) + Mvc_CubePrint( pCover, pCube ); + + if ( pCover->pLits ) + { + for ( i = 0; i < pCover->nBits; i++ ) + printf( " %d", pCover->pLits[i] ); + printf( "\n" ); + } + printf( "End of cover printout\n" ); +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Mvc_CubePrint( Mvc_Cover_t * pCover, Mvc_Cube_t * pCube ) +{ + int iBit, Value; + // iterate through the literals +// printf( "Size = %2d ", Mvc_CubeReadSize(pCube) ); + Mvc_CubeForEachBit( pCover, pCube, iBit, Value ) + printf( "%c", '0' + Value ); + printf( "\n" ); +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Mvc_CoverPrintBinary( Mvc_Cover_t * pCover ) +{ + Mvc_Cube_t * pCube; + int i; + // print general statistics + printf( "The cover contains %d cubes (%d bits and %d words)\n", + pCover->lCubes.nItems, pCover->nBits, pCover->nWords ); + // iterate through the cubes + Mvc_CoverForEachCube( pCover, pCube ) + Mvc_CubePrintBinary( pCover, pCube ); + + if ( pCover->pLits ) + { + for ( i = 0; i < pCover->nBits; i++ ) + printf( " %d", pCover->pLits[i] ); + printf( "\n" ); + } + printf( "End of cover printout\n" ); +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Mvc_CubePrintBinary( Mvc_Cover_t * pCover, Mvc_Cube_t * pCube ) +{ + int iVar, Value; + // iterate through the literals +// printf( "Size = %2d ", Mvc_CubeReadSize(pCube) ); + Mvc_CubeForEachVarValue( pCover, pCube, iVar, Value ) + { + assert( Value != 0 ); + if ( Value == 3 ) + printf( "-" ); + else if ( Value == 1 ) + printf( "0" ); + else + printf( "1" ); + } + printf( "\n" ); +} + +#if 0 + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Mvc_CoverPrintMv( Mvc_Data_t * pData, Mvc_Cover_t * pCover ) +{ + Mvc_Cube_t * pCube; + int i; + // print general statistics + printf( "The cover contains %d cubes (%d bits and %d words)\n", + pCover->lCubes.nItems, pCover->nBits, pCover->nWords ); + // iterate through the cubes + Mvc_CoverForEachCube( pCover, pCube ) + Mvc_CubePrintMv( pData, pCover, pCube ); + + if ( pCover->pLits ) + { + for ( i = 0; i < pCover->nBits; i++ ) + printf( " %d", pCover->pLits[i] ); + printf( "\n" ); + } + printf( "End of cover printout\n" ); +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Mvc_CubePrintMv( Mvc_Data_t * pData, Mvc_Cover_t * pCover, Mvc_Cube_t * pCube ) +{ + int iLit, iVar; + // iterate through the literals + printf( "Size = %2d ", Mvc_CubeReadSize(pCube) ); + iVar = 0; + for ( iLit = 0; iLit < pData->pVm->nValuesIn; iLit++ ) + { + if ( iLit == pData->pVm->pValuesFirst[iVar+1] ) + { + printf( " " ); + iVar++; + } + if ( Mvc_CubeBitValue( pCube, iLit ) ) + printf( "%c", '0' + iLit - pData->pVm->pValuesFirst[iVar] ); + else + printf( "-" ); + } + printf( "\n" ); +} + +#endif + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/misc/mvc/mvcSort.c b/src/misc/mvc/mvcSort.c new file mode 100644 index 00000000..1126b22a --- /dev/null +++ b/src/misc/mvc/mvcSort.c @@ -0,0 +1,141 @@ +/**CFile**************************************************************** + + FileName [mvcSort.c] + + PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] + + Synopsis [Sorting cubes in the cover with the mask.] + + Author [MVSIS Group] + + Affiliation [uC Berkeley] + + Date [Ver. 1.0. Started - February 1, 2003.] + + Revision [$Id: mvcSort.c,v 1.5 2003/04/27 01:03:45 wjiang Exp $] + +***********************************************************************/ + +#include "mvc.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + + +Mvc_Cube_t * Mvc_CoverSort_rec( Mvc_Cube_t * pList, int nItems, Mvc_Cube_t * pMask, int (* pCompareFunc)(Mvc_Cube_t *, Mvc_Cube_t *, Mvc_Cube_t *) ); +Mvc_Cube_t * Mvc_CoverSortMerge( Mvc_Cube_t * pList1, Mvc_Cube_t * pList2, Mvc_Cube_t * pMask, int (* pCompareFunc)(Mvc_Cube_t *, Mvc_Cube_t *, Mvc_Cube_t *) ); + +//////////////////////////////////////////////////////////////////////// +/// FuNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Sorts cubes using the given cost function.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Mvc_CoverSort( Mvc_Cover_t * pCover, Mvc_Cube_t * pMask, int (* pCompareFunc)(Mvc_Cube_t *, Mvc_Cube_t *, Mvc_Cube_t *) ) +{ + Mvc_Cube_t * pHead; + int nCubes; + // one cube does not need sorting + nCubes = Mvc_CoverReadCubeNum(pCover); + if ( nCubes <= 1 ) + return; + // sort the cubes + pHead = Mvc_CoverSort_rec( Mvc_CoverReadCubeHead(pCover), nCubes, pMask, pCompareFunc ); + // insert the sorted list into the cover + Mvc_CoverSetCubeHead( pCover, pHead ); + Mvc_CoverSetCubeTail( pCover, Mvc_ListGetTailFromHead(pHead) ); + // make sure that the list is sorted in the increasing order + assert( pCompareFunc( Mvc_CoverReadCubeHead(pCover), Mvc_CoverReadCubeTail(pCover), pMask ) <= 0 ); +} + +/**Function************************************************************* + + Synopsis [Recursive part of Mvc_CoverSort()] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Mvc_Cube_t * Mvc_CoverSort_rec( Mvc_Cube_t * pList, int nItems, Mvc_Cube_t * pMask, int (* pCompareFunc)(Mvc_Cube_t *, Mvc_Cube_t *, Mvc_Cube_t *) ) +{ + Mvc_Cube_t * pList1, * pList2; + int nItems1, nItems2, i; + + // trivial case + if ( nItems == 1 ) + { + Mvc_CubeSetNext( pList, NULL ); + return pList; + } + + // select the new sizes + nItems1 = nItems/2; + nItems2 = nItems - nItems1; + + // set the new beginnings + pList1 = pList2 = pList; + for ( i = 0; i < nItems1; i++ ) + pList2 = Mvc_CubeReadNext( pList2 ); + + // solve recursively + pList1 = Mvc_CoverSort_rec( pList1, nItems1, pMask, pCompareFunc ); + pList2 = Mvc_CoverSort_rec( pList2, nItems2, pMask, pCompareFunc ); + + // merge + return Mvc_CoverSortMerge( pList1, pList2, pMask, pCompareFunc ); +} + + +/**Function************************************************************* + + Synopsis [Merges two NULL-terminated linked lists.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Mvc_Cube_t * Mvc_CoverSortMerge( Mvc_Cube_t * pList1, Mvc_Cube_t * pList2, Mvc_Cube_t * pMask, int (* pCompareFunc)(Mvc_Cube_t *, Mvc_Cube_t *, Mvc_Cube_t *) ) +{ + Mvc_Cube_t * pList = NULL, ** ppTail = &pList; + Mvc_Cube_t * pCube; + while ( pList1 && pList2 ) + { + if ( pCompareFunc( pList1, pList2, pMask ) < 0 ) + { + pCube = pList1; + pList1 = Mvc_CubeReadNext(pList1); + } + else + { + pCube = pList2; + pList2 = Mvc_CubeReadNext(pList2); + } + *ppTail = pCube; + ppTail = Mvc_CubeReadNextP(pCube); + } + *ppTail = pList1? pList1: pList2; + return pList; +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/misc/mvc/mvcUtils.c b/src/misc/mvc/mvcUtils.c new file mode 100644 index 00000000..3fb57276 --- /dev/null +++ b/src/misc/mvc/mvcUtils.c @@ -0,0 +1,868 @@ +/**CFile**************************************************************** + + FileName [mvcUtils.c] + + PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] + + Synopsis [Various cover handling utilities.] + + Author [MVSIS Group] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - February 1, 2003.] + + Revision [$Id: mvcUtils.c,v 1.7 2003/04/26 20:41:36 alanmi Exp $] + +***********************************************************************/ + +#include "mvc.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static int bit_count[256] = { + 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5, + 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, + 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, + 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, + 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, + 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, + 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, + 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8 +}; + + +static void Mvc_CoverCopyColumn( Mvc_Cover_t * pCoverOld, Mvc_Cover_t * pCoverNew, int iColOld, int iColNew ); + + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Mvc_CoverSupport( Mvc_Cover_t * pCover, Mvc_Cube_t * pSupp ) +{ + Mvc_Cube_t * pCube; + // clean the support + Mvc_CubeBitClean( pSupp ); + // collect the support + Mvc_CoverForEachCube( pCover, pCube ) + Mvc_CubeBitOr( pSupp, pSupp, pCube ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Mvc_CoverSupportAnd( Mvc_Cover_t * pCover, Mvc_Cube_t * pSupp ) +{ + Mvc_Cube_t * pCube; + // clean the support + Mvc_CubeBitFill( pSupp ); + // collect the support + Mvc_CoverForEachCube( pCover, pCube ) + Mvc_CubeBitAnd( pSupp, pSupp, pCube ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Mvc_CoverSupportSizeBinary( Mvc_Cover_t * pCover ) +{ + Mvc_Cube_t * pSupp; + int Counter, i, v0, v1; + // compute the support + pSupp = Mvc_CubeAlloc( pCover ); + Mvc_CoverSupportAnd( pCover, pSupp ); + Counter = pCover->nBits/2; + for ( i = 0; i < pCover->nBits/2; i++ ) + { + v0 = Mvc_CubeBitValue( pSupp, 2*i ); + v1 = Mvc_CubeBitValue( pSupp, 2*i+1 ); + if ( v0 && v1 ) + Counter--; + } + Mvc_CubeFree( pCover, pSupp ); + return Counter; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Mvc_CoverSupportVarBelongs( Mvc_Cover_t * pCover, int iVar ) +{ + Mvc_Cube_t * pSupp; + int RetValue, v0, v1; + // compute the support + pSupp = Mvc_CubeAlloc( pCover ); + Mvc_CoverSupportAnd( pCover, pSupp ); + v0 = Mvc_CubeBitValue( pSupp, 2*iVar ); + v1 = Mvc_CubeBitValue( pSupp, 2*iVar+1 ); + RetValue = (int)( !v0 || !v1 ); + Mvc_CubeFree( pCover, pSupp ); + return RetValue; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Mvc_CoverCommonCube( Mvc_Cover_t * pCover, Mvc_Cube_t * pComCube ) +{ + Mvc_Cube_t * pCube; + // clean the support + Mvc_CubeBitFill( pComCube ); + // collect the support + Mvc_CoverForEachCube( pCover, pCube ) + Mvc_CubeBitAnd( pComCube, pComCube, pCube ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Mvc_CoverIsCubeFree( Mvc_Cover_t * pCover ) +{ + int Result; + // get the common cube + Mvc_CoverAllocateMask( pCover ); + Mvc_CoverCommonCube( pCover, pCover->pMask ); + // check whether the common cube is empty + Mvc_CubeBitEmpty( Result, pCover->pMask ); + return Result; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Mvc_CoverMakeCubeFree( Mvc_Cover_t * pCover ) +{ + Mvc_Cube_t * pCube; + // get the common cube + Mvc_CoverAllocateMask( pCover ); + Mvc_CoverCommonCube( pCover, pCover->pMask ); + // remove this cube from the cubes in the cover + Mvc_CoverForEachCube( pCover, pCube ) + Mvc_CubeBitSharp( pCube, pCube, pCover->pMask ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Mvc_Cover_t * Mvc_CoverCommonCubeCover( Mvc_Cover_t * pCover ) +{ + Mvc_Cover_t * pRes; + Mvc_Cube_t * pCube; + // create the new cover + pRes = Mvc_CoverClone( pCover ); + // get the new cube + pCube = Mvc_CubeAlloc( pRes ); + // get the common cube + Mvc_CoverCommonCube( pCover, pCube ); + // add the cube to the cover + Mvc_CoverAddCubeTail( pRes, pCube ); + return pRes; +} + + +/**Function************************************************************* + + Synopsis [Returns 1 if the support of cover2 is contained in the support of cover1.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Mvc_CoverCheckSuppContainment( Mvc_Cover_t * pCover1, Mvc_Cover_t * pCover2 ) +{ + int Result; + assert( pCover1->nBits == pCover2->nBits ); + // set the supports + Mvc_CoverAllocateMask( pCover1 ); + Mvc_CoverSupport( pCover1, pCover1->pMask ); + Mvc_CoverAllocateMask( pCover2 ); + Mvc_CoverSupport( pCover2, pCover2->pMask ); + // check the containment + Mvc_CubeBitNotImpl( Result, pCover2->pMask, pCover1->pMask ); + return !Result; +} + +/**Function************************************************************* + + Synopsis [Counts the cube sizes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Mvc_CoverSetCubeSizes( Mvc_Cover_t * pCover ) +{ + Mvc_Cube_t * pCube; + unsigned char * pByte, * pByteStart, * pByteStop; + int nBytes, nOnes; + + // get the number of unsigned chars in the cube's bit strings + nBytes = pCover->nBits / (8 * sizeof(unsigned char)) + (int)(pCover->nBits % (8 * sizeof(unsigned char)) > 0); + // iterate through the cubes + Mvc_CoverForEachCube( pCover, pCube ) + { + // clean the counter of ones + nOnes = 0; + // set the starting and stopping positions + pByteStart = (unsigned char *)pCube->pData; + pByteStop = pByteStart + nBytes; + // iterate through the positions + for ( pByte = pByteStart; pByte < pByteStop; pByte++ ) + nOnes += bit_count[*pByte]; + // set the nOnes + Mvc_CubeSetSize( pCube, nOnes ); + } + return 1; +} + +/**Function************************************************************* + + Synopsis [Counts the cube sizes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Mvc_CoverGetCubeSize( Mvc_Cube_t * pCube ) +{ + unsigned char * pByte, * pByteStart, * pByteStop; + int nOnes, nBytes, nBits; + // get the number of unsigned chars in the cube's bit strings + nBits = (pCube->iLast + 1) * sizeof(Mvc_CubeWord_t) * 8 - pCube->nUnused; + nBytes = nBits / (8 * sizeof(unsigned char)) + (int)(nBits % (8 * sizeof(unsigned char)) > 0); + // clean the counter of ones + nOnes = 0; + // set the starting and stopping positions + pByteStart = (unsigned char *)pCube->pData; + pByteStop = pByteStart + nBytes; + // iterate through the positions + for ( pByte = pByteStart; pByte < pByteStop; pByte++ ) + nOnes += bit_count[*pByte]; + return nOnes; +} + +/**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 Mvc_CoverCountCubePairDiffs( Mvc_Cover_t * pCover, unsigned char pDiffs[] ) +{ + Mvc_Cube_t * pCube1; + Mvc_Cube_t * pCube2; + Mvc_Cube_t * pMask; + unsigned char * pByte, * pByteStart, * pByteStop; + int nBytes, nOnes; + int nCubePairs; + + // allocate a temporary mask + pMask = Mvc_CubeAlloc( pCover ); + // get the number of unsigned chars in the cube's bit strings + nBytes = pCover->nBits / (8 * sizeof(unsigned char)) + (int)(pCover->nBits % (8 * sizeof(unsigned char)) > 0); + // iterate through the cubes + nCubePairs = 0; + Mvc_CoverForEachCube( pCover, pCube1 ) + { + Mvc_CoverForEachCubeStart( Mvc_CubeReadNext(pCube1), pCube2 ) + { + // find the bit-wise exor of cubes + Mvc_CubeBitExor( pMask, pCube1, pCube2 ); + // set the starting and stopping positions + pByteStart = (unsigned char *)pMask->pData; + pByteStop = pByteStart + nBytes; + // clean the counter of ones + nOnes = 0; + // iterate through the positions + for ( pByte = pByteStart; pByte < pByteStop; pByte++ ) + nOnes += bit_count[*pByte]; + // set the nOnes + pDiffs[nCubePairs++] = nOnes; + } + } + // deallocate the mask + Mvc_CubeFree( pCover, pMask ); + return 1; +} + + +/**Function************************************************************* + + Synopsis [Creates a new cover containing some literals of the old cover.] + + Description [Creates the new cover containing the given number (nVarsRem) + literals of the old cover. All the bits of the new cover are initialized + to "1". The selected bits from the old cover are copied on top. The numbers + of the selected bits to copy are given in the array pVarsRem. The i-set + entry in this array is the index of the bit in the old cover which goes + to the i-th place in the new cover. If the i-th entry in pVarsRem is -1, + it means that the i-th bit does not change (remains composed of all 1's). + This is a useful feature to speed up remapping covers, which are known + to depend only on a subset of input variables.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Mvc_Cover_t * Mvc_CoverRemap( Mvc_Cover_t * p, int * pVarsRem, int nVarsRem ) +{ + Mvc_Cover_t * pCover; + Mvc_Cube_t * pCube, * pCubeCopy; + int i; + // clone the cover + pCover = Mvc_CoverAlloc( p->pMem, nVarsRem ); + // copy the cube list + Mvc_CoverForEachCube( p, pCube ) + { + pCubeCopy = Mvc_CubeAlloc( pCover ); + //Mvc_CubeBitClean( pCubeCopy ); //changed by wjiang + Mvc_CubeBitFill( pCubeCopy ); //changed by wjiang + Mvc_CoverAddCubeTail( pCover, pCubeCopy ); + } + // copy the corresponding columns + for ( i = 0; i < nVarsRem; i++ ) + { + if (pVarsRem[i] < 0) + continue; //added by wjiang + assert( pVarsRem[i] >= 0 && pVarsRem[i] < p->nBits ); + Mvc_CoverCopyColumn( p, pCover, pVarsRem[i], i ); + } + return pCover; +} + +/**Function************************************************************* + + Synopsis [Copies a column from the old cover to the new cover.] + + Description [Copies the column (iColOld) of the old cover (pCoverOld) + into the column (iColNew) of the new cover (pCoverNew). Assumes that + the number of cubes is the same in both covers. Makes no assuptions + about the current contents of the column in the new cover.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Mvc_CoverCopyColumn( Mvc_Cover_t * pCoverOld, Mvc_Cover_t * pCoverNew, + int iColOld, int iColNew ) +{ + Mvc_Cube_t * pCubeOld, * pCubeNew; + int iWordOld, iWordNew, iBitOld, iBitNew; + + assert( Mvc_CoverReadCubeNum(pCoverOld) == Mvc_CoverReadCubeNum(pCoverNew) ); + + // get the place of the old and new columns + iWordOld = Mvc_CubeWhichWord(iColOld); + iBitOld = Mvc_CubeWhichBit(iColOld); + iWordNew = Mvc_CubeWhichWord(iColNew); + iBitNew = Mvc_CubeWhichBit(iColNew); + + // go through the cubes of both covers + pCubeNew = Mvc_CoverReadCubeHead(pCoverNew); + Mvc_CoverForEachCube( pCoverOld, pCubeOld ) + { + if ( pCubeOld->pData[iWordOld] & (1<pData[iWordNew] |= (1<pData[iWordNew] &= ~(1<pVm, iVar); + nValues = Vm_VarMapReadValues(pData->pVm, iVar); + ppCofs = ALLOC( Mvc_Cover_t *, nValues + 1 ); + for ( i = 0; i <= nValues; i++ ) + ppCofs[i] = Mvc_CoverClone( pCover ); + + // go through the cubes + Mvc_CoverForEachCube( pCover, pCube ) + { + // if the literal if a full literal, add it to last "cofactor" + Mvc_CubeBitEqualUnderMask( Res, pCube, pData->ppMasks[iVar], pData->ppMasks[iVar] ); + if ( Res ) + { + pCubeNew = Mvc_CubeDup(pCover, pCube); + Mvc_CoverAddCubeTail( ppCofs[nValues], pCubeNew ); + continue; + } + + // otherwise, add it to separate values + for ( i = 0; i < nValues; i++ ) + if ( Mvc_CubeBitValue( pCube, iValueFirst + i ) ) + { + pCubeNew = Mvc_CubeDup(pCover, pCube); + Mvc_CubeBitOr( pCubeNew, pCubeNew, pData->ppMasks[iVar] ); + Mvc_CoverAddCubeTail( ppCofs[i], pCubeNew ); + } + } + return ppCofs; +} + +/**Function************************************************************* + + Synopsis [Count the cubes with non-trivial literals with the given value.] + + Description [The data and the cover are given (pData, pCover). Also given + are the variable number and the number of a value of this variable. + This procedure returns the number of cubes having a non-trivial literal + of this variable that have the given value present.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Mvr_CoverCountLitsWithValue( Mvc_Data_t * pData, Mvc_Cover_t * pCover, int iVar, int iValue ) +{ + Mvc_Cube_t * pCube; + int iValueFirst, Res, Counter; + + Counter = 0; + iValueFirst = Vm_VarMapReadValuesFirst( pData->pVm, iVar ); + Mvc_CoverForEachCube( pCover, pCube ) + { + // check if the given literal is the full literal + Mvc_CubeBitEqualUnderMask( Res, pCube, pData->ppMasks[iVar], pData->ppMasks[iVar] ); + if ( Res ) + continue; + // this literal is not a full literal; check if it has this value + Counter += Mvc_CubeBitValue( pCube, iValueFirst + iValue ); + } + return Counter; +} + +/**Function************************************************************* + + Synopsis [Creates the expanded cover.] + + Description [The original cover is expanded by adding some variables. + These variables are the additional variables in pVmNew, compared to + pCvr->pVm. The resulting cover is the same as the original one, except + that it contains the additional variables present as full literals + in every cube.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Mvc_Cover_t * Mvc_CoverCreateExpanded( Mvc_Cover_t * pCover, Vm_VarMap_t * pVmNew ) +{ + Mvc_Cover_t * pCoverNew; + Mvc_Cube_t * pCube, * pCubeNew; + int i, iLast, iLastNew; + + // create the new cover + pCoverNew = Mvc_CoverAlloc( pCover->pMem, Vm_VarMapReadValuesInNum(pVmNew) ); + + // get the cube composed of extra bits + Mvc_CoverAllocateMask( pCoverNew ); + Mvc_CubeBitClean( pCoverNew->pMask ); + for ( i = pCover->nBits; i < pCoverNew->nBits; i++ ) + Mvc_CubeBitInsert( pCoverNew->pMask, i ); + + // get the indexes of the last words in both covers + iLast = pCover->nWords? pCover->nWords - 1: 0; + iLastNew = pCoverNew->nWords? pCoverNew->nWords - 1: 0; + + // create the cubes of the new cover + Mvc_CoverForEachCube( pCover, pCube ) + { + pCubeNew = Mvc_CubeAlloc( pCoverNew ); + Mvc_CubeBitClean( pCubeNew ); + // copy the bits (cannot immediately use Mvc_CubeBitCopy, + // because covers have different numbers of bits) + Mvc_CubeSetLast( pCubeNew, iLast ); + Mvc_CubeBitCopy( pCubeNew, pCube ); + Mvc_CubeSetLast( pCubeNew, iLastNew ); + // add the extra bits + Mvc_CubeBitOr( pCubeNew, pCubeNew, pCoverNew->pMask ); + // add the cube to the new cover + Mvc_CoverAddCubeTail( pCoverNew, pCubeNew ); + } + return pCoverNew; +} + +#endif + +/**Function************************************************************* + + Synopsis [Transposes the cube cover.] + + Description [Returns the cube cover that looks like a transposed + matrix, compared to the matrix derived from the original cover.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Mvc_Cover_t * Mvc_CoverTranspose( Mvc_Cover_t * pCover ) +{ + Mvc_Cover_t * pRes; + Mvc_Cube_t * pCubeRes, * pCube; + int nWord, nBit, i, iCube; + + pRes = Mvc_CoverAlloc( pCover->pMem, Mvc_CoverReadCubeNum(pCover) ); + for ( i = 0; i < pCover->nBits; i++ ) + { + // get the word and bit of this literal + nWord = Mvc_CubeWhichWord(i); + nBit = Mvc_CubeWhichBit(i); + // get the transposed cube + pCubeRes = Mvc_CubeAlloc( pRes ); + Mvc_CubeBitClean( pCubeRes ); + iCube = 0; + Mvc_CoverForEachCube( pCover, pCube ) + { + if ( pCube->pData[nWord] & (1<nUnused == 0 ) + continue; + + Unsigned = ( pCube->pData[pCube->iLast] & + (BITS_FULL << (32-pCube->nUnused)) ); + if( Unsigned ) + { + printf( "Cube %2d out of %2d contains dirty bits.\n", nCubes, + Mvc_CoverReadCubeNum(pCover) ); + } + nCubes++; + } + return 1; +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/misc/vec/vecInt.h b/src/misc/vec/vecInt.h index 793dd567..7556dd87 100644 --- a/src/misc/vec/vecInt.h +++ b/src/misc/vec/vecInt.h @@ -80,6 +80,26 @@ static inline Vec_Int_t * Vec_IntAlloc( int nCap ) return p; } +/**Function************************************************************* + + Synopsis [Allocates a vector with the given size and cleans it.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Vec_Int_t * Vec_IntStart( int nSize ) +{ + Vec_Int_t * p; + p = Vec_IntAlloc( nSize ); + p->nSize = nSize; + memset( p->pArray, 0, sizeof(int) * nSize ); + return p; +} + /**Function************************************************************* Synopsis [Creates the vector from an integer array of the given size.] @@ -435,6 +455,27 @@ static inline void Vec_IntPushOrder( Vec_Int_t * p, int Entry ) p->pArray[i+1] = Entry; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Vec_IntPushUnique( Vec_Int_t * p, int Entry ) +{ + int i; + for ( i = 0; i < p->nSize; i++ ) + if ( p->pArray[i] == Entry ) + return 1; + Vec_IntPush( p, Entry ); + return 0; +} + /**Function************************************************************* Synopsis [Returns the last entry and removes it from the list.] diff --git a/src/misc/vec/vecPtr.h b/src/misc/vec/vecPtr.h index 1d3e0633..b1776441 100644 --- a/src/misc/vec/vecPtr.h +++ b/src/misc/vec/vecPtr.h @@ -53,6 +53,8 @@ struct Vec_Ptr_t_ for ( i = 0; (i < Vec_PtrSize(vVec)) && (((pEntry) = Vec_PtrEntry(vVec, i)), 1); i++ ) #define Vec_PtrForEachEntryStart( vVec, pEntry, i, Start ) \ for ( i = Start; (i < Vec_PtrSize(vVec)) && (((pEntry) = Vec_PtrEntry(vVec, i)), 1); i++ ) +#define Vec_PtrForEachEntryReverse( vVec, pEntry, i ) \ + for ( i = Vec_PtrSize(vVec) - 1; (i >= 0) && (((pEntry) = Vec_PtrEntry(vVec, i)), 1); i-- ) //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFITIONS /// @@ -81,6 +83,26 @@ static inline Vec_Ptr_t * Vec_PtrAlloc( int nCap ) return p; } +/**Function************************************************************* + + Synopsis [Allocates a vector with the given size and cleans it.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Vec_Ptr_t * Vec_PtrStart( int nSize ) +{ + Vec_Ptr_t * p; + p = Vec_PtrAlloc( nSize ); + p->nSize = nSize; + memset( p->pArray, 0, sizeof(void *) * nSize ); + return p; +} + /**Function************************************************************* Synopsis [Creates the vector from an integer array of the given size.] @@ -486,46 +508,6 @@ static inline void Vec_PtrReorder( Vec_Ptr_t * p, int nItems ) memmove( p->pArray, (char **)p->pArray + nItems, p->nSize * sizeof(void*) ); } -/**Function************************************************************* - - Synopsis [Frees the vector of vectors.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Vec_PtrFreeFree( Vec_Ptr_t * p ) -{ - Vec_Ptr_t * vVec; - int i; - Vec_PtrForEachEntry( p, vVec, i ) - Vec_PtrFree( vVec ); - Vec_PtrFree( p ); -} - -/**Function************************************************************* - - Synopsis [Frees the vector of vectors.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Vec_PtrSizeSize( Vec_Ptr_t * p ) -{ - Vec_Ptr_t * vVec; - int i, Counter = 0; - Vec_PtrForEachEntry( p, vVec, i ) - Counter += vVec->nSize; - return Counter; -} - /**Function************************************************************* Synopsis [Sorting the entries by their integer value.] diff --git a/src/misc/vec/vecStr.h b/src/misc/vec/vecStr.h index 4b8e6a1c..311bda91 100644 --- a/src/misc/vec/vecStr.h +++ b/src/misc/vec/vecStr.h @@ -78,6 +78,26 @@ static inline Vec_Str_t * Vec_StrAlloc( int nCap ) return p; } +/**Function************************************************************* + + Synopsis [Allocates a vector with the given size and cleans it.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Vec_Str_t * Vec_StrStart( int nSize ) +{ + Vec_Str_t * p; + p = Vec_StrAlloc( nSize ); + p->nSize = nSize; + memset( p->pArray, 0, sizeof(char) * nSize ); + return p; +} + /**Function************************************************************* Synopsis [Creates the vector from an integer array of the given size.] diff --git a/src/misc/vec/vecVec.h b/src/misc/vec/vecVec.h index af7ca571..0ad5fd1e 100644 --- a/src/misc/vec/vecVec.h +++ b/src/misc/vec/vecVec.h @@ -68,6 +68,9 @@ struct Vec_Vec_t_ #define Vec_VecForEachEntryStartStop( vGlob, pEntry, i, k, LevelStart, LevelStop ) \ for ( i = LevelStart; i <= LevelStop; i++ ) \ Vec_PtrForEachEntry( Vec_VecEntry(vGlob, i), pEntry, k ) +#define Vec_VecForEachEntryReverse( vGlob, pEntry, i, k ) \ + for ( i = 0; i < Vec_VecSize(vGlob); i++ ) \ + Vec_PtrForEachEntryReverse( Vec_VecEntry(vGlob, i), pEntry, k ) //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFITIONS /// diff --git a/src/opt/sim/module.make b/src/opt/sim/module.make new file mode 100644 index 00000000..43d0a125 --- /dev/null +++ b/src/opt/sim/module.make @@ -0,0 +1,9 @@ +SRC += src/opt/sim/simMan.c \ + src/opt/sim/simSat.c \ + src/opt/sim/simSupp.c \ + src/opt/sim/simSwitch.c \ + src/opt/sim/simSym.c \ + src/opt/sim/simSymSat.c \ + src/opt/sim/simSymSim.c \ + src/opt/sim/simSymStr.c \ + src/opt/sim/simUtils.c diff --git a/src/opt/sim/sim.h b/src/opt/sim/sim.h new file mode 100644 index 00000000..9b4d9699 --- /dev/null +++ b/src/opt/sim/sim.h @@ -0,0 +1,190 @@ +/**CFile**************************************************************** + + FileName [sim.h] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Simulation package.] + + Synopsis [External declarations.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: sim.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#ifndef __SIM_H__ +#define __SIM_H__ + +//////////////////////////////////////////////////////////////////////// +/// INCLUDES /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// PARAMETERS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// BASIC TYPES /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Sym_Man_t_ Sym_Man_t; +struct Sym_Man_t_ +{ + // info about the network + Abc_Ntk_t * pNtk; // the network + Vec_Ptr_t * vNodes; // internal nodes in topological order + int nInputs; + int nOutputs; + // internal simulation information + int nSimWords; // the number of bits in simulation info + Vec_Ptr_t * vSim; // simulation info + // support information + Vec_Ptr_t * vSuppFun; // functional supports + // symmetry info for each output + Vec_Ptr_t * vMatrSymms; // symmetric pairs + Vec_Ptr_t * vMatrNonSymms; // non-symmetric pairs + Vec_Int_t * vPairsTotal; // total pairs + Vec_Int_t * vPairsSym; // symmetric pairs + Vec_Int_t * vPairsNonSym; // non-symmetric pairs + // temporary simulation info + unsigned * uPatRand; + unsigned * uPatCol; + unsigned * uPatRow; + // internal data structures + int nSatRuns; + int nSatRunsSat; + int nSatRunsUnsat; + // pairs + int nPairsSymm; + int nPairsSymmStr; + int nPairsNonSymm; + int nPairsTotal; + // runtime statistics + int timeSim; + int timeFraig; + int timeSat; + int timeTotal; +}; + +typedef struct Sim_Man_t_ Sim_Man_t; +struct Sim_Man_t_ +{ + // info about the network + Abc_Ntk_t * pNtk; + int nInputs; + int nOutputs; + // internal simulation information + int nSimBits; // the number of bits in simulation info + int nSimWords; // the number of words in simulation info + Vec_Ptr_t * vSim0; // simulation info 1 + Vec_Ptr_t * vSim1; // simulation info 2 + // support information + int nSuppBits; // the number of bits in support info + int nSuppWords; // the number of words in support info + Vec_Ptr_t * vSuppStr; // structural supports + Vec_Ptr_t * vSuppFun; // functional supports + // simulation targets + Vec_Vec_t * vSuppTargs; // support targets + // internal data structures + Extra_MmFixed_t * pMmPat; + Vec_Ptr_t * vFifo; + Vec_Int_t * vDiffs; + int nSatRuns; + int nSatRunsSat; + int nSatRunsUnsat; + // runtime statistics + int timeSim; + int timeTrav; + int timeFraig; + int timeSat; + int timeTotal; +}; + +typedef struct Sim_Pat_t_ Sim_Pat_t; +struct Sim_Pat_t_ +{ + int Input; // the input which it has detected + int Output; // the output for which it was collected + unsigned * pData; // the simulation data +}; + +//////////////////////////////////////////////////////////////////////// +/// MACRO DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +#define SIM_NUM_WORDS(n) ((n)/32 + (((n)%32) > 0)) +#define SIM_LAST_BITS(n) ((((n)%32) > 0)? (n)%32 : 32) + +#define SIM_MASK_FULL (0xFFFFFFFF) +#define SIM_MASK_BEG(n) (SIM_MASK_FULL >> (32-n)) +#define SIM_MASK_END(n) (SIM_MASK_FULL << (n)) +#define SIM_SET_0_FROM(m,n) ((m) & ~SIM_MASK_BEG(n)) +#define SIM_SET_1_FROM(m,n) ((m) | SIM_MASK_END(n)) + +// generating random unsigned (#define RAND_MAX 0x7fff) +#define SIM_RANDOM_UNSIGNED ((((unsigned)rand()) << 24) ^ (((unsigned)rand()) << 12) ^ ((unsigned)rand())) + +// macros to get hold of bits in a bit string +#define Sim_SetBit(p,i) ((p)[(i)>>5] |= (1<<((i) & 31))) +#define Sim_XorBit(p,i) ((p)[(i)>>5] ^= (1<<((i) & 31))) +#define Sim_HasBit(p,i) (((p)[(i)>>5] & (1<<((i) & 31))) > 0) + +// macros to get hold of the support info +#define Sim_SuppStrSetVar(vSupps,pNode,v) Sim_SetBit((unsigned*)(vSupps)->pArray[(pNode)->Id],(v)) +#define Sim_SuppStrHasVar(vSupps,pNode,v) Sim_HasBit((unsigned*)(vSupps)->pArray[(pNode)->Id],(v)) +#define Sim_SuppFunSetVar(vSupps,Output,v) Sim_SetBit((unsigned*)(vSupps)->pArray[Output],(v)) +#define Sim_SuppFunHasVar(vSupps,Output,v) Sim_HasBit((unsigned*)(vSupps)->pArray[Output],(v)) +#define Sim_SimInfoSetVar(vSupps,pNode,v) Sim_SetBit((unsigned*)(vSupps)->pArray[(pNode)->Id],(v)) +#define Sim_SimInfoHasVar(vSupps,pNode,v) Sim_HasBit((unsigned*)(vSupps)->pArray[(pNode)->Id],(v)) + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +/*=== simMan.c ==========================================================*/ +extern Sym_Man_t * Sym_ManStart( Abc_Ntk_t * pNtk ); +extern void Sym_ManStop( Sym_Man_t * p ); +extern void Sym_ManPrintStats( Sym_Man_t * p ); +extern Sim_Man_t * Sim_ManStart( Abc_Ntk_t * pNtk ); +extern void Sim_ManStop( Sim_Man_t * p ); +extern void Sim_ManPrintStats( Sim_Man_t * p ); +extern Sim_Pat_t * Sim_ManPatAlloc( Sim_Man_t * p ); +extern void Sim_ManPatFree( Sim_Man_t * p, Sim_Pat_t * pPat ); +/*=== simSupp.c ==========================================================*/ +extern Vec_Ptr_t * Sim_ComputeStrSupp( Abc_Ntk_t * pNtk ); +extern Vec_Ptr_t * Sim_ComputeFunSupp( Abc_Ntk_t * pNtk ); +/*=== simSym.c ==========================================================*/ +extern int Sim_ComputeTwoVarSymms( Abc_Ntk_t * pNtk ); +/*=== simSymStr.c ==========================================================*/ +extern void Sim_SymmsStructCompute( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMatrs ); +/*=== simSymSim.c ==========================================================*/ +extern void Sim_SymmsSimulate( Sym_Man_t * p, unsigned * pPatRand, Vec_Ptr_t * vMatrsNonSym ); +/*=== simUtil.c ==========================================================*/ +extern Vec_Ptr_t * Sim_UtilInfoAlloc( int nSize, int nWords, bool fClean ); +extern void Sim_UtilInfoFree( Vec_Ptr_t * p ); +extern void Sim_UtilInfoAdd( unsigned * pInfo1, unsigned * pInfo2, int nWords ); +extern void Sim_UtilInfoDetectDiffs( unsigned * pInfo1, unsigned * pInfo2, int nWords, Vec_Int_t * vDiffs ); +extern void Sim_UtilInfoDetectNews( unsigned * pInfo1, unsigned * pInfo2, int nWords, Vec_Int_t * vDiffs ); +extern void Sim_UtilInfoFlip( Sim_Man_t * p, Abc_Obj_t * pNode ); +extern bool Sim_UtilInfoCompare( Sim_Man_t * p, Abc_Obj_t * pNode ); +extern void Sim_UtilSimulate( Sim_Man_t * p, bool fFirst ); +extern void Sim_UtilSimulateNode( Sim_Man_t * p, Abc_Obj_t * pNode, bool fType, bool fType1, bool fType2 ); +extern void Sim_UtilSimulateNodeOne( Abc_Obj_t * pNode, Vec_Ptr_t * vSimInfo, int nSimWords ); +extern int Sim_UtilCountSuppSizes( Sim_Man_t * p, int fStruct ); +extern int Sim_UtilCountOnes( unsigned * pSimInfo, int nSimWords ); +extern void Sim_UtilGetRandom( unsigned * pPatRand, int nSimWords ); +extern int Sim_UtilCountAllPairs( Vec_Ptr_t * vSuppFun, int nSimWords, Vec_Int_t * vCounters ); +extern int Sim_UtilCountPairs( Vec_Ptr_t * vMatrs, Vec_Int_t * vCounters ); + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + +#endif + diff --git a/src/opt/sim/simMan.c b/src/opt/sim/simMan.c new file mode 100644 index 00000000..02d59343 --- /dev/null +++ b/src/opt/sim/simMan.c @@ -0,0 +1,278 @@ +/**CFile**************************************************************** + + FileName [simMan.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Network and node package.] + + Synopsis [Simulation manager.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: simMan.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abc.h" +#include "sim.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Starts the simulatin manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Sym_Man_t * Sym_ManStart( Abc_Ntk_t * pNtk ) +{ + Sym_Man_t * p; + int i; + // start the manager + p = ALLOC( Sym_Man_t, 1 ); + memset( p, 0, sizeof(Sym_Man_t) ); + p->pNtk = pNtk; + p->vNodes = Abc_NtkDfs( pNtk, 0 ); + p->nInputs = Abc_NtkCiNum(p->pNtk); + p->nOutputs = Abc_NtkCoNum(p->pNtk); + // internal simulation information + p->nSimWords = SIM_NUM_WORDS(p->nInputs); + p->vSim = Sim_UtilInfoAlloc( Abc_NtkObjNumMax(pNtk), p->nSimWords, 0 ); + // symmetry info for each output + p->vMatrSymms = Vec_PtrStart( p->nOutputs ); + p->vMatrNonSymms = Vec_PtrStart( p->nOutputs ); + p->vPairsTotal = Vec_IntStart( p->nOutputs ); + p->vPairsSym = Vec_IntStart( p->nOutputs ); + p->vPairsNonSym = Vec_IntStart( p->nOutputs ); + for ( i = 0; i < p->nOutputs; i++ ) + { + p->vMatrSymms->pArray[i] = Extra_BitMatrixStart( p->nInputs ); + p->vMatrNonSymms->pArray[i] = Extra_BitMatrixStart( p->nInputs ); + } + // temporary patterns + p->uPatRand = ALLOC( unsigned, p->nSimWords ); + p->uPatCol = ALLOC( unsigned, p->nSimWords ); + p->uPatRow = ALLOC( unsigned, p->nSimWords ); + // compute supports + p->vSuppFun = Sim_ComputeFunSupp( pNtk ); + return p; +} + +/**Function************************************************************* + + Synopsis [Stops the simulatin manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Sym_ManStop( Sym_Man_t * p ) +{ + int i; + Sym_ManPrintStats( p ); + if ( p->vSuppFun ) Sim_UtilInfoFree( p->vSuppFun ); + if ( p->vSim ) Sim_UtilInfoFree( p->vSim ); + if ( p->vNodes ) Vec_PtrFree( p->vNodes ); + for ( i = 0; i < p->nOutputs; i++ ) + { + Extra_BitMatrixStop( p->vMatrSymms->pArray[i] ); + Extra_BitMatrixStop( p->vMatrNonSymms->pArray[i] ); + } + Vec_PtrFree( p->vMatrSymms ); + Vec_PtrFree( p->vMatrNonSymms ); + Vec_IntFree( p->vPairsTotal ); + Vec_IntFree( p->vPairsSym ); + Vec_IntFree( p->vPairsNonSym ); + FREE( p->uPatRand ); + FREE( p->uPatCol ); + FREE( p->uPatRow ); + free( p ); +} + +/**Function************************************************************* + + Synopsis [Prints the manager statisticis.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Sym_ManPrintStats( Sym_Man_t * p ) +{ + printf( "Inputs = %d. Outputs = %d. Sim words = %d.\n", + Abc_NtkCiNum(p->pNtk), Abc_NtkCoNum(p->pNtk), p->nSimWords ); +/* + printf( "Total struct supps = %6d.\n", Sim_UtilCountSuppSizes(p, 1) ); + printf( "Total func supps = %6d.\n", Sim_UtilCountSuppSizes(p, 0) ); + printf( "Total targets = %6d.\n", Vec_VecSizeSize(p->vSuppTargs) ); + printf( "Total sim patterns = %6d.\n", Vec_PtrSize(p->vFifo) ); +*/ + printf( "Sat runs SAT = %6d.\n", p->nSatRunsSat ); + printf( "Sat runs UNSAT = %6d.\n", p->nSatRunsUnsat ); + PRT( "Simulation ", p->timeSim ); + PRT( "Fraiging ", p->timeFraig ); + PRT( "SAT ", p->timeSat ); + PRT( "TOTAL ", p->timeTotal ); +} + + + + +/**Function************************************************************* + + Synopsis [Starts the simulatin manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Sim_Man_t * Sim_ManStart( Abc_Ntk_t * pNtk ) +{ + Sim_Man_t * p; + // start the manager + p = ALLOC( Sim_Man_t, 1 ); + memset( p, 0, sizeof(Sim_Man_t) ); + p->pNtk = pNtk; + p->nInputs = Abc_NtkCiNum(p->pNtk); + p->nOutputs = Abc_NtkCoNum(p->pNtk); + // internal simulation information + p->nSimBits = 2048; + p->nSimWords = SIM_NUM_WORDS(p->nSimBits); + p->vSim0 = Sim_UtilInfoAlloc( Abc_NtkObjNumMax(pNtk), p->nSimWords, 0 ); + p->vSim1 = Sim_UtilInfoAlloc( Abc_NtkObjNumMax(pNtk), p->nSimWords, 0 ); + // support information + p->nSuppBits = Abc_NtkCiNum(pNtk); + p->nSuppWords = SIM_NUM_WORDS(p->nSuppBits); + p->vSuppStr = Sim_ComputeStrSupp( pNtk ); + p->vSuppFun = Sim_UtilInfoAlloc( Abc_NtkCoNum(p->pNtk), p->nSuppWords, 1 ); + // other data + p->pMmPat = Extra_MmFixedStart( sizeof(Sim_Pat_t) + p->nSuppWords * sizeof(unsigned) ); + p->vFifo = Vec_PtrAlloc( 100 ); + p->vDiffs = Vec_IntAlloc( 100 ); + // allocate support targets (array of unresolved outputs for each input) + p->vSuppTargs = Vec_VecStart( p->nInputs ); + return p; +} + +/**Function************************************************************* + + Synopsis [Stops the simulatin manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Sim_ManStop( Sim_Man_t * p ) +{ + Sim_ManPrintStats( p ); + if ( p->vSim0 ) Sim_UtilInfoFree( p->vSim0 ); + if ( p->vSim1 ) Sim_UtilInfoFree( p->vSim1 ); + if ( p->vSuppStr ) Sim_UtilInfoFree( p->vSuppStr ); +// if ( p->vSuppFun ) Sim_UtilInfoFree( p->vSuppFun ); + if ( p->vSuppTargs ) Vec_VecFree( p->vSuppTargs ); + if ( p->pMmPat ) Extra_MmFixedStop( p->pMmPat, 0 ); + if ( p->vFifo ) Vec_PtrFree( p->vFifo ); + if ( p->vDiffs ) Vec_IntFree( p->vDiffs ); + free( p ); +} + +/**Function************************************************************* + + Synopsis [Prints the manager statisticis.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Sim_ManPrintStats( Sim_Man_t * p ) +{ + printf( "Inputs = %d. Outputs = %d. Sim words = %d.\n", + Abc_NtkCiNum(p->pNtk), Abc_NtkCoNum(p->pNtk), p->nSimWords ); + printf( "Total struct supps = %6d.\n", Sim_UtilCountSuppSizes(p, 1) ); + printf( "Total func supps = %6d.\n", Sim_UtilCountSuppSizes(p, 0) ); + printf( "Total targets = %6d.\n", Vec_VecSizeSize(p->vSuppTargs) ); + printf( "Total sim patterns = %6d.\n", Vec_PtrSize(p->vFifo) ); + printf( "Sat runs SAT = %6d.\n", p->nSatRunsSat ); + printf( "Sat runs UNSAT = %6d.\n", p->nSatRunsUnsat ); + PRT( "Simulation ", p->timeSim ); + PRT( "Traversal ", p->timeTrav ); + PRT( "Fraiging ", p->timeFraig ); + PRT( "SAT ", p->timeSat ); + PRT( "TOTAL ", p->timeTotal ); +} + + + +/**Function************************************************************* + + Synopsis [Returns one simulation pattern.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Sim_Pat_t * Sim_ManPatAlloc( Sim_Man_t * p ) +{ + Sim_Pat_t * pPat; + pPat = (Sim_Pat_t *)Extra_MmFixedEntryFetch( p->pMmPat ); + pPat->Output = -1; + pPat->pData = (unsigned *)((char *)pPat + sizeof(Sim_Pat_t)); + memset( pPat->pData, 0, p->nSuppWords * sizeof(unsigned) ); + return pPat; +} + +/**Function************************************************************* + + Synopsis [Returns one simulation pattern.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Sim_ManPatFree( Sim_Man_t * p, Sim_Pat_t * pPat ) +{ + Extra_MmFixedEntryRecycle( p->pMmPat, (char *)pPat ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/opt/sim/simSat.c b/src/opt/sim/simSat.c new file mode 100644 index 00000000..b4e080fe --- /dev/null +++ b/src/opt/sim/simSat.c @@ -0,0 +1,48 @@ +/**CFile**************************************************************** + + FileName [simSat.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Network and node package.] + + Synopsis [Simulation to determine functional support.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: simSat.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abc.h" +#include "sim.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/opt/sim/simSupp.c b/src/opt/sim/simSupp.c new file mode 100644 index 00000000..2f380866 --- /dev/null +++ b/src/opt/sim/simSupp.c @@ -0,0 +1,594 @@ +/**CFile**************************************************************** + + FileName [simSupp.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Network and node package.] + + Synopsis [Simulation to determine functional support.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: simSupp.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abc.h" +#include "fraig.h" +#include "sim.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static int Sim_ComputeSuppRound( Sim_Man_t * p, bool fUseTargets ); +static int Sim_ComputeSuppRoundNode( Sim_Man_t * p, int iNumCi, bool fUseTargets ); +static void Sim_ComputeSuppSetTargets( Sim_Man_t * p ); + +static void Sim_UtilAssignRandom( Sim_Man_t * p ); +static void Sim_UtilAssignFromFifo( Sim_Man_t * p ); +static void Sim_SolveTargetsUsingSat( Sim_Man_t * p, int nCounters ); +static int Sim_SolveSuppModelVerify( Abc_Ntk_t * pNtk, int * pModel, int Input, int Output ); + +extern Fraig_Man_t * Abc_NtkToFraig( Abc_Ntk_t * pNtk, Fraig_Params_t * pParams, int fAllNodes ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Computes structural supports.] + + Description [Supports are returned as an array of bit strings, one + for each CO.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Sim_ComputeStrSupp( Abc_Ntk_t * pNtk ) +{ + Vec_Ptr_t * vSuppStr; + Abc_Obj_t * pNode; + unsigned * pSimmNode, * pSimmNode1, * pSimmNode2; + int nSuppWords, i, k; + // allocate room for structural supports + nSuppWords = SIM_NUM_WORDS( Abc_NtkCiNum(pNtk) ); + vSuppStr = Sim_UtilInfoAlloc( Abc_NtkObjNumMax(pNtk), nSuppWords, 1 ); + // assign the structural support to the PIs + Abc_NtkForEachCi( pNtk, pNode, i ) + Sim_SuppStrSetVar( vSuppStr, pNode, i ); + // derive the structural supports of the internal nodes + Abc_NtkForEachNode( pNtk, pNode, i ) + { + if ( Abc_NodeIsConst(pNode) ) + continue; + pSimmNode = vSuppStr->pArray[ pNode->Id ]; + pSimmNode1 = vSuppStr->pArray[ Abc_ObjFaninId0(pNode) ]; + pSimmNode2 = vSuppStr->pArray[ Abc_ObjFaninId1(pNode) ]; + for ( k = 0; k < nSuppWords; k++ ) + pSimmNode[k] = pSimmNode1[k] | pSimmNode2[k]; + } + // set the structural supports of the PO nodes + Abc_NtkForEachCo( pNtk, pNode, i ) + { + pSimmNode = vSuppStr->pArray[ pNode->Id ]; + pSimmNode1 = vSuppStr->pArray[ Abc_ObjFaninId0(pNode) ]; + for ( k = 0; k < nSuppWords; k++ ) + pSimmNode[k] = pSimmNode1[k]; + } + return vSuppStr; +} + +/**Function************************************************************* + + Synopsis [Compute functional supports.] + + Description [Supports are returned as an array of bit strings, one + for each CO.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Sim_ComputeFunSupp( Abc_Ntk_t * pNtk ) +{ + Sim_Man_t * p; + Vec_Ptr_t * vResult; + int nSolved, i, clk = clock(); + +// srand( time(NULL) ); + srand( 0xABC ); + + // start the simulation manager + p = Sim_ManStart( pNtk ); + + // compute functional support using one round of random simulation + Sim_UtilAssignRandom( p ); + Sim_ComputeSuppRound( p, 0 ); + + // set the support targets + Sim_ComputeSuppSetTargets( p ); +printf( "Initial targets = %5d.\n", Vec_VecSizeSize(p->vSuppTargs) ); + if ( Vec_VecSizeSize(p->vSuppTargs) == 0 ) + goto exit; + + for ( i = 0; i < 1; i++ ) + { + // compute patterns using one round of random simulation + Sim_UtilAssignRandom( p ); + nSolved = Sim_ComputeSuppRound( p, 1 ); +printf( "Targets = %5d. Solved = %5d. Fifo = %5d.\n", Vec_VecSizeSize(p->vSuppTargs), nSolved, Vec_PtrSize(p->vFifo) ); + if ( Vec_VecSizeSize(p->vSuppTargs) == 0 ) + goto exit; + } + + + // simulate until saturation + while ( Vec_VecSizeSize(p->vSuppTargs) > 0 ) + { + // solve randomly a given number of targets + Sim_SolveTargetsUsingSat( p, p->nSimWords/p->nSuppWords ); + // compute additional functional support +// Sim_UtilAssignRandom( p ); + Sim_UtilAssignFromFifo( p ); + nSolved = Sim_ComputeSuppRound( p, 1 ); +printf( "Targets = %5d. Solved = %5d. Fifo = %5d. SAT runs = %3d.\n", + Vec_VecSizeSize(p->vSuppTargs), nSolved, Vec_PtrSize(p->vFifo), p->nSatRuns ); + } + +exit: + vResult = p->vSuppFun; + // p->vSuppFun = NULL; + Sim_ManStop( p ); + return vResult; +} + +/**Function************************************************************* + + Synopsis [Computes functional support using one round of simulation.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Sim_ComputeSuppRound( Sim_Man_t * p, bool fUseTargets ) +{ + Vec_Int_t * vTargets; + Abc_Obj_t * pNode; + int i, Counter = 0; + int clk; + // perform one round of random simulation +clk = clock(); + Sim_UtilSimulate( p, 0 ); +p->timeSim += clock() - clk; + // iterate through the CIs and detect COs that depend on them + Abc_NtkForEachCi( p->pNtk, pNode, i ) + { + vTargets = p->vSuppTargs->pArray[i]; + if ( fUseTargets && vTargets->nSize == 0 ) + continue; + Counter += Sim_ComputeSuppRoundNode( p, i, fUseTargets ); + } + return Counter; +} + +/**Function************************************************************* + + Synopsis [Computes functional support for one node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Sim_ComputeSuppRoundNode( Sim_Man_t * p, int iNumCi, bool fUseTargets ) +{ + int fVerbose = 0; + Sim_Pat_t * pPat; + Vec_Int_t * vTargets; + Vec_Vec_t * vNodesByLevel; + Abc_Obj_t * pNodeCi, * pNode; + int i, k, v, Output, LuckyPat, fType0, fType1; + int Counter = 0; + int fFirst = 1; + int clk; + // collect nodes by level in the TFO of the CI + // (this procedure increments TravId of the collected nodes) +clk = clock(); + pNodeCi = Abc_NtkCi( p->pNtk, iNumCi ); + vNodesByLevel = Abc_DfsLevelized( pNodeCi, 0 ); +p->timeTrav += clock() - clk; + // complement the simulation info of the selected CI + Sim_UtilInfoFlip( p, pNodeCi ); + // simulate the levelized structure of nodes + Vec_VecForEachEntry( vNodesByLevel, pNode, i, k ) + { + fType0 = Abc_NodeIsTravIdCurrent( Abc_ObjFanin0(pNode) ); + fType1 = Abc_NodeIsTravIdCurrent( Abc_ObjFanin1(pNode) ); +clk = clock(); + Sim_UtilSimulateNode( p, pNode, 1, fType0, fType1 ); +p->timeSim += clock() - clk; + } + // set the simulation info of the affected COs + if ( fUseTargets ) + { + vTargets = p->vSuppTargs->pArray[iNumCi]; + for ( i = vTargets->nSize - 1; i >= 0; i-- ) + { + // get the target output + Output = vTargets->pArray[i]; + // get the target node + pNode = Abc_NtkCo( p->pNtk, Output ); + // the output should be in the cone + assert( Abc_NodeIsTravIdCurrent(pNode) ); + + // simulate the node + Sim_UtilSimulateNode( p, pNode, 1, 1, 1 ); + + // skip if the simulation info is equal + if ( Sim_UtilInfoCompare( p, pNode ) ) + continue; + + // otherwise, we solved a new target + Vec_IntRemove( vTargets, Output ); +if ( fVerbose ) + printf( "(%d,%d) ", iNumCi, Output ); + Counter++; + // make sure this variable is not yet detected + assert( !Sim_SuppFunHasVar(p->vSuppFun, Output, iNumCi) ); + // set this variable + Sim_SuppFunSetVar( p->vSuppFun, Output, iNumCi ); + + // detect the differences in the simulation info + Sim_UtilInfoDetectDiffs( p->vSim0->pArray[pNode->Id], p->vSim1->pArray[pNode->Id], p->nSimWords, p->vDiffs ); + // create new patterns + if ( !fFirst && p->vFifo->nSize > 1000 ) + continue; + + Vec_IntForEachEntry( p->vDiffs, LuckyPat, k ) + { + // set the new pattern + pPat = Sim_ManPatAlloc( p ); + pPat->Input = iNumCi; + pPat->Output = Output; + Abc_NtkForEachCi( p->pNtk, pNodeCi, v ) + if ( Sim_SimInfoHasVar( p->vSim0, pNodeCi, LuckyPat ) ) + Sim_SetBit( pPat->pData, v ); + Vec_PtrPush( p->vFifo, pPat ); + + fFirst = 0; + break; + } + } +if ( fVerbose && Counter ) +printf( "\n" ); + } + else + { + Abc_NtkForEachCo( p->pNtk, pNode, Output ) + { + if ( !Abc_NodeIsTravIdCurrent( pNode ) ) + continue; + Sim_UtilSimulateNode( p, pNode, 1, 1, 1 ); + if ( !Sim_UtilInfoCompare( p, pNode ) ) + { + if ( !Sim_SuppFunHasVar(p->vSuppFun, Output, iNumCi) ) + Counter++; + Sim_SuppFunSetVar( p->vSuppFun, Output, iNumCi ); + } + } + } + Vec_VecFree( vNodesByLevel ); + return Counter; +} + +/**Function************************************************************* + + Synopsis [Sets the simulation targets.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Sim_ComputeSuppSetTargets( Sim_Man_t * p ) +{ + Abc_Obj_t * pNode; + unsigned * pSuppStr, * pSuppFun; + int i, k, Num; + Abc_NtkForEachCo( p->pNtk, pNode, i ) + { + pSuppStr = p->vSuppStr->pArray[pNode->Id]; + pSuppFun = p->vSuppFun->pArray[i]; + // find vars in the structural support that are not in the functional support + Sim_UtilInfoDetectNews( pSuppFun, pSuppStr, p->nSuppWords, p->vDiffs ); + Vec_IntForEachEntry( p->vDiffs, Num, k ) + Vec_VecPush( p->vSuppTargs, Num, (void *)i ); + } +} + +/**Function************************************************************* + + Synopsis [Assigns random simulation info to the PIs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Sim_UtilAssignRandom( Sim_Man_t * p ) +{ + Abc_Obj_t * pNode; + unsigned * pSimInfo; + int i, k; + // assign the random/systematic simulation info to the PIs + Abc_NtkForEachCi( p->pNtk, pNode, i ) + { + pSimInfo = p->vSim0->pArray[pNode->Id]; + for ( k = 0; k < p->nSimWords; k++ ) + pSimInfo[k] = SIM_RANDOM_UNSIGNED; + } +} + +/**Function************************************************************* + + Synopsis [Sets the new patterns from fifo.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Sim_UtilAssignFromFifo( Sim_Man_t * p ) +{ + int fUseOneWord = 0; + Abc_Obj_t * pNode; + Sim_Pat_t * pPat; + unsigned * pSimInfo; + int iWord, iWordLim, i, w; + int iBeg, iEnd; + int Counter = 0; + // go through the patterns and fill in the dist-1 minterms for each + for ( iWord = 0; p->vFifo->nSize > 0; iWord = iWordLim ) + { + ++Counter; + // get the pattern + pPat = Vec_PtrPop( p->vFifo ); + if ( fUseOneWord ) + { + // get the first word of the next series + iWordLim = iWord + 1; + // set the pattern for all PIs from iBit to iWord + p->nInputs + iBeg = ABC_MAX( 0, pPat->Input - 16 ); + iEnd = ABC_MIN( iBeg + 32, p->nInputs ); +// for ( i = iBeg; i < iEnd; i++ ) + Abc_NtkForEachCi( p->pNtk, pNode, i ) + { + pNode = Abc_NtkCi(p->pNtk,i); + pSimInfo = p->vSim0->pArray[pNode->Id]; + if ( Sim_HasBit(pPat->pData, i) ) + pSimInfo[iWord] = SIM_MASK_FULL; + else + pSimInfo[iWord] = 0; + // flip one bit + if ( i >= iBeg && i < iEnd ) + Sim_XorBit( pSimInfo + iWord, i-iBeg ); + } + } + else + { + // get the first word of the next series + iWordLim = (iWord + p->nSuppWords < p->nSimWords)? iWord + p->nSuppWords : p->nSimWords; + // set the pattern for all PIs from iBit to iWord + p->nInputs + Abc_NtkForEachCi( p->pNtk, pNode, i ) + { + pSimInfo = p->vSim0->pArray[pNode->Id]; + if ( Sim_HasBit(pPat->pData, i) ) + { + for ( w = iWord; w < iWordLim; w++ ) + pSimInfo[w] = SIM_MASK_FULL; + } + else + { + for ( w = iWord; w < iWordLim; w++ ) + pSimInfo[w] = 0; + } + // flip one bit + Sim_XorBit( pSimInfo + iWord, i ); + } + } + Sim_ManPatFree( p, pPat ); + // stop if we ran out of room for patterns + if ( iWordLim == p->nSimWords ) + break; +// if ( Counter == 1 ) +// break; + } +} + +/**Function************************************************************* + + Synopsis [Get the given number of counter-examples using SAT.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Sim_SolveTargetsUsingSat( Sim_Man_t * p, int Limit ) +{ + Fraig_Params_t Params; + Fraig_Man_t * pMan; + Abc_Obj_t * pNodeCi; + Abc_Ntk_t * pMiter; + Sim_Pat_t * pPat; + void * pEntry; + int * pModel; + int RetValue, Output, Input, k, v; + int Counter = 0; + int clk; + + p->nSatRuns = 0; + // put targets into one array + Vec_VecForEachEntryReverse( p->vSuppTargs, pEntry, Input, k ) + { + p->nSatRuns++; + Output = (int)pEntry; + // set up the miter for the two cofactors of this output w.r.t. this input + pMiter = Abc_NtkMiterForCofactors( p->pNtk, Output, Input, -1 ); + + // transform the target into a fraig + Fraig_ParamsSetDefault( &Params ); + Params.fInternal = 1; +clk = clock(); + pMan = Abc_NtkToFraig( pMiter, &Params, 0 ); +p->timeFraig += clock() - clk; +clk = clock(); + Fraig_ManProveMiter( pMan ); +p->timeSat += clock() - clk; + + // analyze the result + RetValue = Fraig_ManCheckMiter( pMan ); + assert( RetValue >= 0 ); + if ( RetValue == 1 ) // unsat + { + p->nSatRunsUnsat++; + pModel = NULL; + Vec_PtrRemove( p->vSuppTargs->pArray[Input], pEntry ); + } + else // sat + { + p->nSatRunsSat++; + pModel = Fraig_ManReadModel( pMan ); + assert( pModel != NULL ); + assert( Sim_SolveSuppModelVerify( p->pNtk, pModel, Input, Output ) ); + +//printf( "Solved by SAT (%d,%d).\n", Input, Output ); + // set the new pattern + pPat = Sim_ManPatAlloc( p ); + pPat->Input = Input; + pPat->Output = Output; + Abc_NtkForEachCi( p->pNtk, pNodeCi, v ) + if ( pModel[v] ) + Sim_SetBit( pPat->pData, v ); + Vec_PtrPush( p->vFifo, pPat ); +/* + // set the new pattern + pPat = Sim_ManPatAlloc( p ); + pPat->Input = Input; + pPat->Output = Output; + Abc_NtkForEachCi( p->pNtk, pNodeCi, v ) + if ( pModel[v] ) + Sim_SetBit( pPat->pData, v ); + Sim_XorBit( pPat->pData, Input ); // flip the given bit + Vec_PtrPush( p->vFifo, pPat ); +*/ + Counter++; + } + // delete the fraig manager + Fraig_ManFree( pMan ); + // delete the target + Abc_NtkDelete( pMiter ); + + // stop when we found enough patterns +// if ( Counter == Limit ) + if ( Counter == 1 ) + return; + // switch to the next input if we found one model + if ( pModel ) + break; + } +} + + +/**Function************************************************************* + + Synopsis [Saves the counter example.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Sim_NtkSimTwoPats_rec( Abc_Obj_t * pNode ) +{ + int Value0, Value1; + if ( Abc_NodeIsTravIdCurrent( pNode ) ) + return (int)pNode->pCopy; + Abc_NodeSetTravIdCurrent( pNode ); + Value0 = Sim_NtkSimTwoPats_rec( Abc_ObjFanin0(pNode) ); + Value1 = Sim_NtkSimTwoPats_rec( Abc_ObjFanin1(pNode) ); + if ( Abc_ObjFaninC0(pNode) ) + Value0 = ~Value0; + if ( Abc_ObjFaninC1(pNode) ) + Value1 = ~Value1; + pNode->pCopy = (Abc_Obj_t *)(Value0 & Value1); + return Value0 & Value1; +} + +/**Function************************************************************* + + Synopsis [Verifies that pModel proves the presence of Input in the support of Output.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Sim_SolveSuppModelVerify( Abc_Ntk_t * pNtk, int * pModel, int Input, int Output ) +{ + Abc_Obj_t * pNode; + int RetValue, i; + // set the PI values + Abc_NtkIncrementTravId( pNtk ); + Abc_NtkForEachCi( pNtk, pNode, i ) + { + Abc_NodeSetTravIdCurrent( pNode ); + if ( pNode == Abc_NtkCi(pNtk,Input) ) + pNode->pCopy = (Abc_Obj_t *)1; + else if ( pModel[i] == 1 ) + pNode->pCopy = (Abc_Obj_t *)3; + else + pNode->pCopy = NULL; + } + // perform the traversal + RetValue = 3 & Sim_NtkSimTwoPats_rec( Abc_ObjFanin0( Abc_NtkCo(pNtk,Output) ) ); + if ( RetValue == 0 || RetValue == 3 ) + { + int x = 0; + } +// assert( RetValue == 1 || RetValue == 2 ); + return RetValue == 1 || RetValue == 2; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/opt/sim/simSwitch.c b/src/opt/sim/simSwitch.c new file mode 100644 index 00000000..06b730fc --- /dev/null +++ b/src/opt/sim/simSwitch.c @@ -0,0 +1,107 @@ +/**CFile**************************************************************** + + FileName [simSwitch.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Network and node package.] + + Synopsis [Computes switching activity of nodes in the ABC network.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: simSwitch.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abc.h" +#include "sim.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static void Sim_NodeSimulate( Abc_Obj_t * pNode, Vec_Ptr_t * vSimInfo, int nSimWords ); +static float Sim_ComputeSwitching( unsigned * pSimInfo, int nSimWords ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Computes switching activity using simulation.] + + Description [Computes switching activity, which is understood as the + probability of switching under random simulation. Assigns the + random simulation information at the CI and propagates it through + the internal nodes of the AIG.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Sim_NtkComputeSwitching( Abc_Ntk_t * pNtk, int nPatterns ) +{ + Vec_Int_t * vSwitching; + float * pSwitching; + Vec_Ptr_t * vNodes; + Vec_Ptr_t * vSimInfo; + Abc_Obj_t * pNode; + unsigned * pSimInfo; + int nSimWords, i; + + // allocate space for simulation info of all nodes + nSimWords = SIM_NUM_WORDS(nPatterns); + vSimInfo = Sim_UtilInfoAlloc( Abc_NtkObjNumMax(pNtk), nSimWords, 0 ); + // assign the random simulation to the CIs + vSwitching = Vec_IntStart( Abc_NtkObjNumMax(pNtk) ); + pSwitching = (float *)vSwitching->pArray; + Abc_NtkForEachCi( pNtk, pNode, i ) + { + pSimInfo = Vec_PtrEntry(vSimInfo, pNode->Id); + Sim_UtilGetRandom( pSimInfo, nSimWords ); + pSwitching[pNode->Id] = Sim_ComputeSwitching( pSimInfo, nSimWords ); + } + // simulate the internal nodes + vNodes = Abc_AigDfs( pNtk, 1, 0 ); + Vec_PtrForEachEntry( vNodes, pNode, i ) + { + Sim_UtilSimulateNodeOne( pNode, vSimInfo, nSimWords ); + pSimInfo = Vec_PtrEntry(vSimInfo, pNode->Id); + pSwitching[pNode->Id] = Sim_ComputeSwitching( pSimInfo, nSimWords ); + } + Vec_PtrFree( vNodes ); + Sim_UtilInfoFree( vSimInfo ); + return vSwitching; +} + +/**Function************************************************************* + + Synopsis [Computes switching activity of one node.] + + Description [Uses the formula: Switching = 2 * nOnes * nZeros / (nTotal ^ 2) ] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +float Sim_ComputeSwitching( unsigned * pSimInfo, int nSimWords ) +{ + int nOnes, nTotal; + nTotal = 32 * nSimWords; + nOnes = Sim_UtilCountOnes( pSimInfo, nSimWords ); + return (float)2.0 * nOnes * (nTotal - nOnes) / nTotal / nTotal; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/opt/sim/simSym.c b/src/opt/sim/simSym.c new file mode 100644 index 00000000..706b13dc --- /dev/null +++ b/src/opt/sim/simSym.c @@ -0,0 +1,93 @@ +/**CFile**************************************************************** + + FileName [simSym.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Network and node package.] + + Synopsis [Simulation to determine two-variable symmetries.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: simSym.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abc.h" +#include "sim.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Computes two variable symmetries.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Sim_ComputeTwoVarSymms( Abc_Ntk_t * pNtk ) +{ + Sym_Man_t * p; + Vec_Ptr_t * vResult; + int Result; + int i, clk = clock(); + +// srand( time(NULL) ); + srand( 0xABC ); + + // start the simulation manager + p = Sym_ManStart( pNtk ); + p->nPairsTotal = Sim_UtilCountAllPairs( p->vSuppFun, p->nSimWords, p->vPairsTotal ); + + // detect symmetries using circuit structure + Sim_SymmsStructCompute( pNtk, p->vMatrSymms ); + p->nPairsSymm = p->nPairsSymmStr = Sim_UtilCountPairs( p->vMatrSymms, p->vPairsSym ); + +printf( "Total = %6d. Sym = %6d. NonSym = %6d. Remaining = %6d.\n", + p->nPairsTotal, p->nPairsSymm, p->nPairsNonSymm, p->nPairsTotal-p->nPairsSymm-p->nPairsNonSymm ); + + // detect symmetries using simulation + for ( i = 1; i <= 1000; i++ ) + { + // generate random pattern + Sim_UtilGetRandom( p->uPatRand, p->nSimWords ); + // simulate this pattern + Sim_SymmsSimulate( p, p->uPatRand, p->vMatrNonSymms ); + if ( i % 100 != 0 ) + continue; + // count the number of pairs + p->nPairsSymm = Sim_UtilCountPairs( p->vMatrSymms, p->vPairsSym ); + p->nPairsNonSymm = Sim_UtilCountPairs( p->vMatrNonSymms, p->vPairsNonSym ); + +printf( "Total = %6d. Sym = %6d. NonSym = %6d. Remaining = %6d.\n", + p->nPairsTotal, p->nPairsSymm, p->nPairsNonSymm, p->nPairsTotal-p->nPairsSymm-p->nPairsNonSymm ); + } + + Result = p->nPairsSymm; + vResult = p->vMatrSymms; + // p->vMatrSymms = NULL; + Sym_ManStop( p ); + return Result; +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/opt/sim/simSymSat.c b/src/opt/sim/simSymSat.c new file mode 100644 index 00000000..88e33161 --- /dev/null +++ b/src/opt/sim/simSymSat.c @@ -0,0 +1,202 @@ +/**CFile**************************************************************** + + FileName [simSymSat.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Network and node package.] + + Synopsis [Satisfiability to determine two variable symmetries.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: simSymSat.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abc.h" +#include "sim.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static int Fraig_SymmsSatProveOne( Fraig_Man_t * p, int Var1, int Var2 ); +static int Fraig_SymmsIsCliqueMatrix( Fraig_Man_t * p, Extra_BitMat_t * pMat ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Performs the SAT based check.] + + Description [Given two bit matrices, with symm info and non-symm info, + checks the remaining pairs.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fraig_SymmsSatComputeOne( Fraig_Man_t * p, Extra_BitMat_t * pMatSym, Extra_BitMat_t * pMatNonSym ) +{ + int VarsU[512], VarsV[512]; + int nVarsU, nVarsV; + int v, u, i, k; + int Counter = 0; + int satCalled = 0; + int satProved = 0; + double Density; + int clk = clock(); + + extern int symsSat; + extern int Fraig_CountBits( Fraig_Man_t * pMan, Fraig_Node_t * pNode ); + + + // count undecided pairs + for ( v = 0; v < p->vInputs->nSize; v++ ) + for ( u = v+1; u < p->vInputs->nSize; u++ ) + { + if ( Extra_BitMatrixLookup1( pMatSym, v, u ) || Extra_BitMatrixLookup1( pMatNonSym, v, u ) ) + continue; + Counter++; + } + // compute the density of 1's in the input space of the functions + Density = (double)Fraig_CountBits(p, Fraig_Regular(p->vOutputs->pArray[0])) * 100.0 / FRAIG_SIM_ROUNDS / 32; + + printf( "Ins = %3d. Pairs to test = %4d. Dens = %5.2f %%. ", + p->vInputs->nSize, Counter, Density ); + + + // go through the remaining variable pairs + for ( v = 0; v < p->vInputs->nSize; v++ ) + for ( u = v+1; u < p->vInputs->nSize; u++ ) + { + if ( Extra_BitMatrixLookup1( pMatSym, v, u ) || Extra_BitMatrixLookup1( pMatNonSym, v, u ) ) + continue; + symsSat++; + satCalled++; + + // collect the variables that are symmetric with each + nVarsU = nVarsV = 0; + for ( i = 0; i < p->vInputs->nSize; i++ ) + { + if ( Extra_BitMatrixLookup1( pMatSym, u, i ) ) + VarsU[nVarsU++] = i; + if ( Extra_BitMatrixLookup1( pMatSym, v, i ) ) + VarsV[nVarsV++] = i; + } + + if ( Fraig_SymmsSatProveOne( p, v, u ) ) + { // update the symmetric variable info +//printf( "%d sym %d\n", v, u ); + for ( i = 0; i < nVarsU; i++ ) + for ( k = 0; k < nVarsV; k++ ) + { + Extra_BitMatrixInsert1( pMatSym, VarsU[i], VarsV[k] ); // Theorem 1 + Extra_BitMatrixInsert2( pMatSym, VarsU[i], VarsV[k] ); // Theorem 1 + Extra_BitMatrixOrTwo( pMatNonSym, VarsU[i], VarsV[k] ); // Theorem 2 + } + satProved++; + } + else + { // update the assymmetric variable info +//printf( "%d non-sym %d\n", v, u ); + for ( i = 0; i < nVarsU; i++ ) + for ( k = 0; k < nVarsV; k++ ) + { + Extra_BitMatrixInsert1( pMatNonSym, VarsU[i], VarsV[k] ); // Theorem 3 + Extra_BitMatrixInsert2( pMatNonSym, VarsU[i], VarsV[k] ); // Theorem 3 + } + } +//Extra_BitMatrixPrint( pMatSym ); +//Extra_BitMatrixPrint( pMatNonSym ); + } +printf( "SAT calls = %3d. Proved = %3d. ", satCalled, satProved ); +PRT( "Time", clock() - clk ); + + // make sure that the symmetry matrix contains only cliques + assert( Fraig_SymmsIsCliqueMatrix( p, pMatSym ) ); +} + +/**Function************************************************************* + + Synopsis [Returns 1 if the variables are symmetric; 0 otherwise.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Fraig_SymmsSatProveOne( Fraig_Man_t * p, int Var1, int Var2 ) +{ + Fraig_Node_t * pCof01, * pCof10, * pVar1, * pVar2; + int RetValue; + int nSatRuns = p->nSatCalls; + int nSatProof = p->nSatProof; + + p->nBTLimit = 10; // set the backtrack limit + + pVar1 = p->vInputs->pArray[Var1]; + pVar2 = p->vInputs->pArray[Var2]; + pCof01 = Fraig_CofactorTwo( p, p->vOutputs->pArray[0], pVar1, Fraig_Not(pVar2) ); + pCof10 = Fraig_CofactorTwo( p, p->vOutputs->pArray[0], Fraig_Not(pVar1), pVar2 ); + +//printf( "(%d,%d)", p->nSatCalls - nSatRuns, p->nSatProof - nSatProof ); + +// RetValue = (pCof01 == pCof10); +// RetValue = Fraig_NodesAreaEqual( p, pCof01, pCof10 ); + RetValue = Fraig_NodesAreEqual( p, pCof01, pCof10, -1 ); + return RetValue; +} + +/**Function************************************************************* + + Synopsis [A sanity check procedure.] + + Description [Makes sure that the symmetry information in the matrix + is closed w.r.t. the relationship of transitivity (that is the symmetry + graph is composed of cliques).] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Fraig_SymmsIsCliqueMatrix( Fraig_Man_t * p, Extra_BitMat_t * pMat ) +{ + int v, u, i; + for ( v = 0; v < p->vInputs->nSize; v++ ) + for ( u = v+1; u < p->vInputs->nSize; u++ ) + { + if ( !Extra_BitMatrixLookup1( pMat, v, u ) ) + continue; + // v and u are symmetric + for ( i = 0; i < p->vInputs->nSize; i++ ) + { + if ( i == v || i == u ) + continue; + // i is neither v nor u + // the symmetry status of i is the same w.r.t. to v and u + if ( Extra_BitMatrixLookup1( pMat, i, v ) != Extra_BitMatrixLookup1( pMat, i, u ) ) + return 0; + } + } + return 1; +} + + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/opt/sim/simSymSim.c b/src/opt/sim/simSymSim.c new file mode 100644 index 00000000..53fc4ac2 --- /dev/null +++ b/src/opt/sim/simSymSim.c @@ -0,0 +1,159 @@ +/**CFile**************************************************************** + + FileName [simSymSim.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Network and node package.] + + Synopsis [Simulation to determine two-variable symmetries.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: simSymSim.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abc.h" +#include "sim.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static void Sim_SymmsCreateSquare( Sym_Man_t * p, unsigned * pPat ); +static void Sim_SymmsDeriveInfo( Sym_Man_t * p, unsigned * pPat, Abc_Obj_t * pNode, Extra_BitMat_t * pMatrix, int Output ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Detects non-symmetric pairs using one pattern.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Sim_SymmsSimulate( Sym_Man_t * p, unsigned * pPat, Vec_Ptr_t * vMatrsNonSym ) +{ + Abc_Obj_t * pNode; + int i; + // create the simulation matrix + Sim_SymmsCreateSquare( p, pPat ); + // simulate each node in the DFS order + Vec_PtrForEachEntry( p->vNodes, pNode, i ) + { + if ( Abc_NodeIsConst(pNode) ) + continue; + Sim_UtilSimulateNodeOne( pNode, p->vSim, p->nSimWords ); + } + // collect info into the CO matrices + Abc_NtkForEachCo( p->pNtk, pNode, i ) + { + pNode = Abc_ObjFanin0(pNode); + if ( Abc_ObjIsCi(pNode) || Abc_NodeIsConst(pNode) ) + continue; + if ( Vec_IntEntry(p->vPairsTotal,i) == Vec_IntEntry(p->vPairsSym,i) + Vec_IntEntry(p->vPairsNonSym,i) ) + continue; + Sim_SymmsDeriveInfo( p, pPat, pNode, Vec_PtrEntry(vMatrsNonSym, i), i ); + } +} + +/**Function************************************************************* + + Synopsis [Creates the square matrix of simulation info.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Sim_SymmsCreateSquare( Sym_Man_t * p, unsigned * pPat ) +{ + unsigned * pSimInfo; + Abc_Obj_t * pNode; + int i, w; + // for each PI var copy the pattern + Abc_NtkForEachCi( p->pNtk, pNode, i ) + { + pSimInfo = Vec_PtrEntry( p->vSim, pNode->Id ); + if ( Sim_HasBit(pPat, i) ) + { + for ( w = 0; w < p->nSimWords; w++ ) + pSimInfo[w] = SIM_MASK_FULL; + } + else + { + for ( w = 0; w < p->nSimWords; w++ ) + pSimInfo[w] = 0; + } + // flip one bit + Sim_XorBit( pSimInfo, i ); + } +} + +/**Function************************************************************* + + Synopsis [Transfers the info to the POs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Sim_SymmsDeriveInfo( Sym_Man_t * p, unsigned * pPat, Abc_Obj_t * pNode, Extra_BitMat_t * pMat, int Output ) +{ + unsigned * pSuppInfo; + unsigned * pSimInfo; + int i, w; + // get the simuation info for the node + pSimInfo = Vec_PtrEntry( p->vSim, pNode->Id ); + pSuppInfo = Vec_PtrEntry( p->vSuppFun, Output ); + // generate vectors A1 and A2 + for ( w = 0; w < p->nSimWords; w++ ) + { + p->uPatCol[w] = pSuppInfo[w] & pPat[w] & pSimInfo[w]; + p->uPatRow[w] = pSuppInfo[w] & pPat[w] & ~pSimInfo[w]; + } + // add two dimensions + for ( i = 0; i < p->nInputs; i++ ) + if ( Sim_HasBit( p->uPatCol, i ) ) + Extra_BitMatrixOr( pMat, i, p->uPatRow ); + // add two dimensions + for ( i = 0; i < p->nInputs; i++ ) + if ( Sim_HasBit( p->uPatRow, i ) ) + Extra_BitMatrixOr( pMat, i, p->uPatCol ); + // generate vectors B1 and B2 + for ( w = 0; w < p->nSimWords; w++ ) + { + p->uPatCol[w] = pSuppInfo[w] & ~pPat[w] & pSimInfo[w]; + p->uPatRow[w] = pSuppInfo[w] & ~pPat[w] & ~pSimInfo[w]; + } + // add two dimensions + for ( i = 0; i < p->nInputs; i++ ) + if ( Sim_HasBit( p->uPatCol, i ) ) + Extra_BitMatrixOr( pMat, i, p->uPatRow ); + // add two dimensions + for ( i = 0; i < p->nInputs; i++ ) + if ( Sim_HasBit( p->uPatRow, i ) ) + Extra_BitMatrixOr( pMat, i, p->uPatCol ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/opt/sim/simSymStr.c b/src/opt/sim/simSymStr.c new file mode 100644 index 00000000..c3059d84 --- /dev/null +++ b/src/opt/sim/simSymStr.c @@ -0,0 +1,481 @@ +/**CFile**************************************************************** + + FileName [simSymStr.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Network and node package.] + + Synopsis [Structural detection of symmetries.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: simSymStr.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abc.h" +#include "sim.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +#define SIM_READ_SYMMS(pNode) ((Vec_Int_t *)pNode->pCopy) +#define SIM_SET_SYMMS(pNode,vVect) (pNode->pCopy = (Abc_Obj_t *)(vVect)) + +static void Sim_SymmsStructComputeOne( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode, int * pMap ); +static void Sim_SymmsBalanceCollect_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes ); +static void Sim_SymmsPartitionNodes( Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesPis0, Vec_Ptr_t * vNodesPis1, Vec_Ptr_t * vNodesOther ); +static void Sim_SymmsAppendFromGroup( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodesPi, Vec_Ptr_t * vNodesOther, Vec_Int_t * vSymms, int * pMap ); +static void Sim_SymmsAppendFromNode( Abc_Ntk_t * pNtk, Vec_Int_t * vSymms0, Vec_Ptr_t * vNodesOther, Vec_Ptr_t * vNodesPi0, Vec_Ptr_t * vNodesPi1, Vec_Int_t * vSymms, int * pMap ); +static int Sim_SymmsIsCompatibleWithNodes( Abc_Ntk_t * pNtk, unsigned uSymm, Vec_Ptr_t * vNodesOther, int * pMap ); +static int Sim_SymmsIsCompatibleWithGroup( unsigned uSymm, Vec_Ptr_t * vNodesPi, int * pMap ); +static void Sim_SymmsPrint( Vec_Int_t * vSymms ); +static void Sim_SymmsTrans( Vec_Int_t * vSymms ); +static void Sim_SymmsTransferToMatrix( Extra_BitMat_t * pMatSymm, Vec_Int_t * vSymms ); +static int * Sim_SymmsCreateMap( Abc_Ntk_t * pNtk ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Computes symmetries for a single output function.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Sim_SymmsStructCompute( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMatrs ) +{ + Vec_Ptr_t * vNodes; + Abc_Obj_t * pTemp; + int * pMap, i; + + assert( Abc_NtkCiNum(pNtk) + 10 < (1<<16) ); + + // get the structural support + pNtk->vSupps = Sim_ComputeStrSupp( pNtk ); + // set elementary info for the CIs + Abc_NtkForEachCi( pNtk, pTemp, i ) + SIM_SET_SYMMS( pTemp, Vec_IntAlloc(0) ); + // create the map of CI ids into their numbers + pMap = Sim_SymmsCreateMap( pNtk ); + // collect the nodes in the TFI cone of this output + vNodes = Abc_NtkDfs( pNtk, 0 ); + Vec_PtrForEachEntry( vNodes, pTemp, i ) + { + if ( Abc_NodeIsConst(pTemp) ) + continue; + Sim_SymmsStructComputeOne( pNtk, pTemp, pMap ); + } + // collect the results for the COs; + Abc_NtkForEachCo( pNtk, pTemp, i ) + { + pTemp = Abc_ObjFanin0(pTemp); + if ( Abc_ObjIsCi(pTemp) || Abc_NodeIsConst(pTemp) ) + continue; + Sim_SymmsTransferToMatrix( Vec_PtrEntry(vMatrs, i), SIM_READ_SYMMS(pTemp) ); + } + // clean the intermediate results + Sim_UtilInfoFree( pNtk->vSupps ); + pNtk->vSupps = NULL; + Abc_NtkForEachCi( pNtk, pTemp, i ) + Vec_IntFree( SIM_READ_SYMMS(pTemp) ); + Vec_PtrForEachEntry( vNodes, pTemp, i ) + Vec_IntFree( SIM_READ_SYMMS(pTemp) ); + Vec_PtrFree( vNodes ); + free( pMap ); +} + +/**Function************************************************************* + + Synopsis [Recursively computes symmetries. ] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Sim_SymmsStructComputeOne( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode, int * pMap ) +{ + Vec_Ptr_t * vNodes, * vNodesPi0, * vNodesPi1, * vNodesOther; + Vec_Int_t * vSymms; + Abc_Obj_t * pTemp; + int i; + + // allocate the temporary arrays + vNodes = Vec_PtrAlloc( 10 ); + vNodesPi0 = Vec_PtrAlloc( 10 ); + vNodesPi1 = Vec_PtrAlloc( 10 ); + vNodesOther = Vec_PtrAlloc( 10 ); + + // collect the fanins of the implication supergate + Sim_SymmsBalanceCollect_rec( pNode, vNodes ); + + // sort the nodes in the implication supergate + Sim_SymmsPartitionNodes( vNodes, vNodesPi0, vNodesPi1, vNodesOther ); + + // start the resulting set + vSymms = Vec_IntAlloc( 10 ); + // generate symmetries from the groups + Sim_SymmsAppendFromGroup( pNtk, vNodesPi0, vNodesOther, vSymms, pMap ); + Sim_SymmsAppendFromGroup( pNtk, vNodesPi1, vNodesOther, vSymms, pMap ); + // add symmetries from other inputs + for ( i = 0; i < vNodesOther->nSize; i++ ) + { + pTemp = Abc_ObjRegular(vNodesOther->pArray[i]); + Sim_SymmsAppendFromNode( pNtk, SIM_READ_SYMMS(pTemp), vNodesOther, vNodesPi0, vNodesPi1, vSymms, pMap ); + } + Vec_PtrFree( vNodes ); + Vec_PtrFree( vNodesPi0 ); + Vec_PtrFree( vNodesPi1 ); + Vec_PtrFree( vNodesOther ); + + // set the symmetry at the node + SIM_SET_SYMMS( pNode, vSymms ); +} + + +/**Function************************************************************* + + Synopsis [Returns the array of nodes to be combined into one multi-input AND-gate.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Sim_SymmsBalanceCollect_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes ) +{ + // if the new node is complemented, another gate begins + if ( Abc_ObjIsComplement(pNode) ) + { + Vec_PtrPushUnique( vNodes, pNode ); + return; + } + // if pNew is the PI node, return + if ( Abc_ObjIsCi(pNode) ) + { + Vec_PtrPushUnique( vNodes, pNode ); + return; + } + // go through the branches + Sim_SymmsBalanceCollect_rec( Abc_ObjChild0(pNode), vNodes ); + Sim_SymmsBalanceCollect_rec( Abc_ObjChild1(pNode), vNodes ); +} + +/**Function************************************************************* + + Synopsis [Divides PI variables into groups.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Sim_SymmsPartitionNodes( Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesPis0, + Vec_Ptr_t * vNodesPis1, Vec_Ptr_t * vNodesOther ) +{ + Abc_Obj_t * pNode; + int i; + Vec_PtrForEachEntry( vNodes, pNode, i ) + { + if ( !Abc_ObjIsCi(Abc_ObjRegular(pNode)) ) + Vec_PtrPush( vNodesOther, pNode ); + else if ( Abc_ObjIsComplement(pNode) ) + Vec_PtrPush( vNodesPis0, pNode ); + else + Vec_PtrPush( vNodesPis1, pNode ); + } +} + +/**Function************************************************************* + + Synopsis [Makes the product of two partitions.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Sim_SymmsAppendFromGroup( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodesPi, Vec_Ptr_t * vNodesOther, Vec_Int_t * vSymms, int * pMap ) +{ + Abc_Obj_t * pNode1, * pNode2; + unsigned uSymm; + int i, k; + + if ( vNodesPi->nSize == 0 ) + return; + + // go through the pairs + for ( i = 0; i < vNodesPi->nSize; i++ ) + for ( k = i+1; k < vNodesPi->nSize; k++ ) + { + // get the two PI nodes + pNode1 = Abc_ObjRegular(vNodesPi->pArray[i]); + pNode2 = Abc_ObjRegular(vNodesPi->pArray[k]); + assert( pMap[pNode1->Id] != pMap[pNode2->Id] ); + assert( pMap[pNode1->Id] >= 0 ); + assert( pMap[pNode2->Id] >= 0 ); + // generate symmetry + if ( pMap[pNode1->Id] < pMap[pNode2->Id] ) + uSymm = ((pMap[pNode1->Id] << 16) | pMap[pNode2->Id]); + else + uSymm = ((pMap[pNode2->Id] << 16) | pMap[pNode1->Id]); + // check if symmetry belongs + if ( Sim_SymmsIsCompatibleWithNodes( pNtk, uSymm, vNodesOther, pMap ) ) + Vec_IntPushUnique( vSymms, (int)uSymm ); + } +} + +/**Function************************************************************* + + Synopsis [Add the filters symmetries from the nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Sim_SymmsAppendFromNode( Abc_Ntk_t * pNtk, Vec_Int_t * vSymms0, Vec_Ptr_t * vNodesOther, + Vec_Ptr_t * vNodesPi0, Vec_Ptr_t * vNodesPi1, Vec_Int_t * vSymms, int * pMap ) +{ + unsigned uSymm; + int i; + + if ( vSymms0->nSize == 0 ) + return; + + // go through the pairs + for ( i = 0; i < vSymms0->nSize; i++ ) + { + uSymm = (unsigned)vSymms0->pArray[i]; + // check if symmetry belongs + if ( Sim_SymmsIsCompatibleWithNodes( pNtk, uSymm, vNodesOther, pMap ) && + Sim_SymmsIsCompatibleWithGroup( uSymm, vNodesPi0, pMap ) && + Sim_SymmsIsCompatibleWithGroup( uSymm, vNodesPi1, pMap ) ) + Vec_IntPushUnique( vSymms, (int)uSymm ); + } +} + +/**Function************************************************************* + + Synopsis [Returns 1 if symmetry is compatible with the group of nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Sim_SymmsIsCompatibleWithNodes( Abc_Ntk_t * pNtk, unsigned uSymm, Vec_Ptr_t * vNodesOther, int * pMap ) +{ + Vec_Int_t * vSymmsNode; + Abc_Obj_t * pNode; + int i, s, Ind1, Ind2, fIsVar1, fIsVar2; + + if ( vNodesOther->nSize == 0 ) + return 1; + + // get the indices of the PI variables + Ind1 = (uSymm & 0xffff); + Ind2 = (uSymm >> 16); + + // go through the nodes + // if they do not belong to a support, it is okay + // if one belongs, the other does not belong, quit + // if they belong, but are not part of symmetry, quit + for ( i = 0; i < vNodesOther->nSize; i++ ) + { + pNode = Abc_ObjRegular(vNodesOther->pArray[i]); + fIsVar1 = Sim_SuppStrHasVar( pNtk->vSupps, pNode, Ind1 ); + fIsVar2 = Sim_SuppStrHasVar( pNtk->vSupps, pNode, Ind2 ); + + if ( !fIsVar1 && !fIsVar2 ) + continue; + if ( fIsVar1 ^ fIsVar2 ) + return 0; + // both belong + // check if there is a symmetry + vSymmsNode = SIM_READ_SYMMS( pNode ); + for ( s = 0; s < vSymmsNode->nSize; s++ ) + if ( uSymm == (unsigned)vSymmsNode->pArray[s] ) + break; + if ( s == vSymmsNode->nSize ) + return 0; + } + return 1; +} + +/**Function************************************************************* + + Synopsis [Returns 1 if symmetry is compatible with the group of PIs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Sim_SymmsIsCompatibleWithGroup( unsigned uSymm, Vec_Ptr_t * vNodesPi, int * pMap ) +{ + Abc_Obj_t * pNode; + int i, Ind1, Ind2, fHasVar1, fHasVar2; + + if ( vNodesPi->nSize == 0 ) + return 1; + + // get the indices of the PI variables + Ind1 = (uSymm & 0xffff); + Ind2 = (uSymm >> 16); + + // go through the PI nodes + fHasVar1 = fHasVar2 = 0; + for ( i = 0; i < vNodesPi->nSize; i++ ) + { + pNode = Abc_ObjRegular(vNodesPi->pArray[i]); + if ( pMap[pNode->Id] == Ind1 ) + fHasVar1 = 1; + else if ( pMap[pNode->Id] == Ind2 ) + fHasVar2 = 1; + } + return fHasVar1 == fHasVar2; +} + + + +/**Function************************************************************* + + Synopsis [Improvements due to transitivity.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Sim_SymmsTrans( Vec_Int_t * vSymms ) +{ + unsigned uSymm, uSymma, uSymmr; + int i, Ind1, Ind2; + int k, Ind1a, Ind2a; + int j; + int nTrans = 0; + + for ( i = 0; i < vSymms->nSize; i++ ) + { + uSymm = (unsigned)vSymms->pArray[i]; + Ind1 = (uSymm & 0xffff); + Ind2 = (uSymm >> 16); + // find other symmetries that have Ind1 + for ( k = i+1; k < vSymms->nSize; k++ ) + { + uSymma = (unsigned)vSymms->pArray[k]; + if ( uSymma == uSymm ) + continue; + Ind1a = (uSymma & 0xffff); + Ind2a = (uSymma >> 16); + if ( Ind1a == Ind1 ) + { + // find the symmetry (Ind2,Ind2a) + if ( Ind2 < Ind2a ) + uSymmr = ((Ind2 << 16) | Ind2a); + else + uSymmr = ((Ind2a << 16) | Ind2); + for ( j = 0; j < vSymms->nSize; j++ ) + if ( uSymmr == (unsigned)vSymms->pArray[j] ) + break; + if ( j == vSymms->nSize ) + nTrans++; + } + } + + } + printf( "Trans = %d.\n", nTrans ); +} + + +/**Function************************************************************* + + Synopsis [Transfers from the vector to the matrix.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Sim_SymmsTransferToMatrix( Extra_BitMat_t * pMatSymm, Vec_Int_t * vSymms ) +{ + int i, Ind1, Ind2, nInputs; + unsigned uSymm; + // add diagonal elements + nInputs = Extra_BitMatrixReadSize( pMatSymm ); + for ( i = 0; i < nInputs; i++ ) + Extra_BitMatrixInsert1( pMatSymm, i, i ); + // add non-diagonal elements + for ( i = 0; i < vSymms->nSize; i++ ) + { + uSymm = (unsigned)vSymms->pArray[i]; + Ind1 = (uSymm & 0xffff); + Ind2 = (uSymm >> 16); + Extra_BitMatrixInsert1( pMatSymm, Ind1, Ind2 ); + Extra_BitMatrixInsert2( pMatSymm, Ind1, Ind2 ); + } +} + +/**Function************************************************************* + + Synopsis [Mapping of indices into numbers.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int * Sim_SymmsCreateMap( Abc_Ntk_t * pNtk ) +{ + int * pMap; + Abc_Obj_t * pNode; + int i; + pMap = ALLOC( int, Abc_NtkObjNumMax(pNtk) ); + for ( i = 0; i < Abc_NtkObjNumMax(pNtk); i++ ) + pMap[i] = -1; + Abc_NtkForEachCi( pNtk, pNode, i ) + pMap[pNode->Id] = i; + return pMap; +} + + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/opt/sim/simUtils.c b/src/opt/sim/simUtils.c new file mode 100644 index 00000000..5a57ca2d --- /dev/null +++ b/src/opt/sim/simUtils.c @@ -0,0 +1,457 @@ +/**CFile**************************************************************** + + FileName [simUtils.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Network and node package.] + + Synopsis [Various simulation utilities.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: simUtils.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abc.h" +#include "sim.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static int bit_count[256] = { + 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5, + 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, + 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, + 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, + 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, + 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, + 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, + 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8 +}; + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Allocates simulation information for all nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Sim_UtilInfoAlloc( int nSize, int nWords, bool fClean ) +{ + Vec_Ptr_t * vInfo; + int i; + assert( nSize > 0 && nWords > 0 ); + vInfo = Vec_PtrAlloc( nSize ); + vInfo->pArray[0] = ALLOC( unsigned, nSize * nWords ); + if ( fClean ) + memset( vInfo->pArray[0], 0, sizeof(unsigned) * nSize * nWords ); + for ( i = 1; i < nSize; i++ ) + vInfo->pArray[i] = ((unsigned *)vInfo->pArray[i-1]) + nWords; + vInfo->nSize = nSize; + return vInfo; +} + +/**Function************************************************************* + + Synopsis [Allocates simulation information for all nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Sim_UtilInfoFree( Vec_Ptr_t * p ) +{ + free( p->pArray[0] ); + Vec_PtrFree( p ); +} + +/**Function************************************************************* + + Synopsis [Adds the second supp-info the first.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Sim_UtilInfoAdd( unsigned * pInfo1, unsigned * pInfo2, int nWords ) +{ + int w; + for ( w = 0; w < nWords; w++ ) + pInfo1[w] |= pInfo2[w]; +} + +/**Function************************************************************* + + Synopsis [Returns the positions where pInfo2 is 1 while pInfo1 is 0.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Sim_UtilInfoDetectDiffs( unsigned * pInfo1, unsigned * pInfo2, int nWords, Vec_Int_t * vDiffs ) +{ + int w, b; + unsigned uMask; + vDiffs->nSize = 0; + for ( w = 0; w < nWords; w++ ) + if ( uMask = (pInfo2[w] ^ pInfo1[w]) ) + for ( b = 0; b < 32; b++ ) + if ( uMask & (1 << b) ) + Vec_IntPush( vDiffs, 32*w + b ); +} + +/**Function************************************************************* + + Synopsis [Returns the positions where pInfo2 is 1 while pInfo1 is 0.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Sim_UtilInfoDetectNews( unsigned * pInfo1, unsigned * pInfo2, int nWords, Vec_Int_t * vDiffs ) +{ + int w, b; + unsigned uMask; + vDiffs->nSize = 0; + for ( w = 0; w < nWords; w++ ) + if ( uMask = (pInfo2[w] & ~pInfo1[w]) ) + for ( b = 0; b < 32; b++ ) + if ( uMask & (1 << b) ) + Vec_IntPush( vDiffs, 32*w + b ); +} + +/**Function************************************************************* + + Synopsis [Flips the simulation info of the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Sim_UtilInfoFlip( Sim_Man_t * p, Abc_Obj_t * pNode ) +{ + unsigned * pSimInfo1, * pSimInfo2; + int k; + pSimInfo1 = p->vSim0->pArray[pNode->Id]; + pSimInfo2 = p->vSim1->pArray[pNode->Id]; + for ( k = 0; k < p->nSimWords; k++ ) + pSimInfo2[k] = ~pSimInfo1[k]; +} + +/**Function************************************************************* + + Synopsis [Returns 1 if the simulation infos are equal.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +bool Sim_UtilInfoCompare( Sim_Man_t * p, Abc_Obj_t * pNode ) +{ + unsigned * pSimInfo1, * pSimInfo2; + int k; + pSimInfo1 = p->vSim0->pArray[pNode->Id]; + pSimInfo2 = p->vSim1->pArray[pNode->Id]; + for ( k = 0; k < p->nSimWords; k++ ) + if ( pSimInfo2[k] != pSimInfo1[k] ) + return 0; + return 1; +} + +/**Function************************************************************* + + Synopsis [Simulates the internal nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Sim_UtilSimulate( Sim_Man_t * p, bool fType ) +{ + Abc_Obj_t * pNode; + int i; + // simulate the internal nodes + Abc_NtkForEachNode( p->pNtk, pNode, i ) + Sim_UtilSimulateNode( p, pNode, fType, fType, fType ); + // assign simulation info of the CO nodes + Abc_NtkForEachCo( p->pNtk, pNode, i ) + Sim_UtilSimulateNode( p, pNode, fType, fType, fType ); +} + +/**Function************************************************************* + + Synopsis [Simulates one node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Sim_UtilSimulateNode( Sim_Man_t * p, Abc_Obj_t * pNode, bool fType, bool fType1, bool fType2 ) +{ + unsigned * pSimmNode, * pSimmNode1, * pSimmNode2; + int k, fComp1, fComp2; + // simulate the internal nodes + if ( Abc_ObjIsNode(pNode) ) + { + if ( Abc_NodeIsConst(pNode) ) + return; + + if ( fType ) + pSimmNode = p->vSim1->pArray[ pNode->Id ]; + else + pSimmNode = p->vSim0->pArray[ pNode->Id ]; + + if ( fType1 ) + pSimmNode1 = p->vSim1->pArray[ Abc_ObjFaninId0(pNode) ]; + else + pSimmNode1 = p->vSim0->pArray[ Abc_ObjFaninId0(pNode) ]; + + if ( fType2 ) + pSimmNode2 = p->vSim1->pArray[ Abc_ObjFaninId1(pNode) ]; + else + pSimmNode2 = p->vSim0->pArray[ Abc_ObjFaninId1(pNode) ]; + + fComp1 = Abc_ObjFaninC0(pNode); + fComp2 = Abc_ObjFaninC1(pNode); + if ( fComp1 && fComp2 ) + for ( k = 0; k < p->nSimWords; k++ ) + pSimmNode[k] = ~pSimmNode1[k] & ~pSimmNode2[k]; + else if ( fComp1 && !fComp2 ) + for ( k = 0; k < p->nSimWords; k++ ) + pSimmNode[k] = ~pSimmNode1[k] & pSimmNode2[k]; + else if ( !fComp1 && fComp2 ) + for ( k = 0; k < p->nSimWords; k++ ) + pSimmNode[k] = pSimmNode1[k] & ~pSimmNode2[k]; + else // if ( fComp1 && fComp2 ) + for ( k = 0; k < p->nSimWords; k++ ) + pSimmNode[k] = pSimmNode1[k] & pSimmNode2[k]; + } + else + { + assert( Abc_ObjFaninNum(pNode) == 1 ); + if ( fType ) + pSimmNode = p->vSim1->pArray[ pNode->Id ]; + else + pSimmNode = p->vSim0->pArray[ pNode->Id ]; + + if ( fType1 ) + pSimmNode1 = p->vSim1->pArray[ Abc_ObjFaninId0(pNode) ]; + else + pSimmNode1 = p->vSim0->pArray[ Abc_ObjFaninId0(pNode) ]; + + fComp1 = Abc_ObjFaninC0(pNode); + if ( fComp1 ) + for ( k = 0; k < p->nSimWords; k++ ) + pSimmNode[k] = ~pSimmNode1[k]; + else + for ( k = 0; k < p->nSimWords; k++ ) + pSimmNode[k] = pSimmNode1[k]; + } +} + +/**Function************************************************************* + + Synopsis [Simulates one node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Sim_UtilSimulateNodeOne( Abc_Obj_t * pNode, Vec_Ptr_t * vSimInfo, int nSimWords ) +{ + unsigned * pSimmNode, * pSimmNode1, * pSimmNode2; + int k, fComp1, fComp2; + // simulate the internal nodes + assert( Abc_ObjIsNode(pNode) ); + if ( Abc_NodeIsConst(pNode) ) + return; + pSimmNode = Vec_PtrEntry(vSimInfo, pNode->Id); + pSimmNode1 = Vec_PtrEntry(vSimInfo, Abc_ObjFaninId0(pNode)); + pSimmNode2 = Vec_PtrEntry(vSimInfo, Abc_ObjFaninId1(pNode)); + fComp1 = Abc_ObjFaninC0(pNode); + fComp2 = Abc_ObjFaninC1(pNode); + if ( fComp1 && fComp2 ) + for ( k = 0; k < nSimWords; k++ ) + pSimmNode[k] = ~pSimmNode1[k] & ~pSimmNode2[k]; + else if ( fComp1 && !fComp2 ) + for ( k = 0; k < nSimWords; k++ ) + pSimmNode[k] = ~pSimmNode1[k] & pSimmNode2[k]; + else if ( !fComp1 && fComp2 ) + for ( k = 0; k < nSimWords; k++ ) + pSimmNode[k] = pSimmNode1[k] & ~pSimmNode2[k]; + else // if ( fComp1 && fComp2 ) + for ( k = 0; k < nSimWords; k++ ) + pSimmNode[k] = pSimmNode1[k] & pSimmNode2[k]; +} + +/**Function************************************************************* + + Synopsis [Returns 1 if the simulation infos are equal.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Sim_UtilCountSuppSizes( Sim_Man_t * p, int fStruct ) +{ + Abc_Obj_t * pNode, * pNodeCi; + int i, v, Counter; + Counter = 0; + if ( fStruct ) + { + Abc_NtkForEachCo( p->pNtk, pNode, i ) + Abc_NtkForEachCi( p->pNtk, pNodeCi, v ) + Counter += Sim_SuppStrHasVar( p->vSuppStr, pNode, v ); + } + else + { + Abc_NtkForEachCo( p->pNtk, pNode, i ) + Abc_NtkForEachCi( p->pNtk, pNodeCi, v ) + Counter += Sim_SuppFunHasVar( p->vSuppFun, i, v ); + } + return Counter; +} + +/**Function************************************************************* + + Synopsis [Counts the number of 1's in the bitstring.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Sim_UtilCountOnes( unsigned * pSimInfo, int nSimWords ) +{ + unsigned char * pBytes; + int nOnes, nBytes, i; + pBytes = (unsigned char *)pSimInfo; + nBytes = 4 * nSimWords; + nOnes = 0; + for ( i = 0; i < nBytes; i++ ) + nOnes += bit_count[ pBytes[i] ]; + return nOnes; +} + + +/**Function************************************************************* + + Synopsis [Returns the random pattern.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Sim_UtilGetRandom( unsigned * pPatRand, int nSimWords ) +{ + int k; + for ( k = 0; k < nSimWords; k++ ) + pPatRand[k] = SIM_RANDOM_UNSIGNED; +} + +/**Function************************************************************* + + Synopsis [Counts the total number of pairs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Sim_UtilCountAllPairs( Vec_Ptr_t * vSuppFun, int nSimWords, Vec_Int_t * vCounters ) +{ + unsigned * pSupp; + int Counter, nOnes, nPairs, i; + Counter = 0; + Vec_PtrForEachEntry( vSuppFun, pSupp, i ) + { + nOnes = Sim_UtilCountOnes( pSupp, nSimWords ); + nPairs = nOnes * (nOnes - 1) / 2; + Vec_IntWriteEntry( vCounters, i, nPairs ); + Counter += nPairs; + } + return Counter; +} + +/**Function************************************************************* + + Synopsis [Counts the number of entries in the array of matrices.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Sim_UtilCountPairs( Vec_Ptr_t * vMatrs, Vec_Int_t * vCounters ) +{ + Extra_BitMat_t * vMat; + int Counter, nPairs, i; + Counter = 0; + Vec_PtrForEachEntry( vMatrs, vMat, i ) + { + nPairs = Extra_BitMatrixCountOnesUpper( vMat ); + Vec_IntWriteEntry( vCounters, i, nPairs ); + Counter += nPairs; + } + return Counter; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/sat/fraig/fraig.h b/src/sat/fraig/fraig.h index 946ed56b..39c6fae8 100644 --- a/src/sat/fraig/fraig.h +++ b/src/sat/fraig/fraig.h @@ -50,6 +50,7 @@ struct Fraig_ParamsStruct_t_ int fTryProve; // tries to solve the final miter int fVerbose; // the verbosiness flag int fVerboseP; // the verbosiness flag (for proof reporting) + int fInternal; // is set to 1 for internal fraig calls }; //////////////////////////////////////////////////////////////////////// diff --git a/src/sat/fraig/fraigApi.c b/src/sat/fraig/fraigApi.c index 0194f3b4..c9e6960c 100644 --- a/src/sat/fraig/fraigApi.c +++ b/src/sat/fraig/fraigApi.c @@ -164,10 +164,9 @@ Fraig_Node_t * Fraig_ManReadIthVar( Fraig_Man_t * p, int i ) /**Function************************************************************* - Synopsis [Creates a new node.] + Synopsis [Creates a new PO node.] - Description [This procedure should be called to create the constant - node and the PI nodes first.] + Description [This procedure may take a complemented node.] SideEffects [] @@ -176,9 +175,8 @@ Fraig_Node_t * Fraig_ManReadIthVar( Fraig_Man_t * p, int i ) ***********************************************************************/ void Fraig_ManSetPo( Fraig_Man_t * p, Fraig_Node_t * pNode ) { -// assert( pNode->fNodePo == 0 ); // internal node may be a PO two times - pNode->fNodePo = 1; + Fraig_Regular(pNode)->fNodePo = 1; Fraig_NodeVecPush( p->vOutputs, pNode ); } diff --git a/src/sat/fraig/fraigFeed.c b/src/sat/fraig/fraigFeed.c index b46f6c41..73640387 100644 --- a/src/sat/fraig/fraigFeed.c +++ b/src/sat/fraig/fraigFeed.c @@ -768,7 +768,80 @@ void Fraig_ReallocateSimulationInfo( Fraig_Man_t * p ) /**Function************************************************************* - Synopsis [Doubles the size of simulation info.] + Synopsis [Generated trivial counter example.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int * Fraig_ManAllocCounterExample( Fraig_Man_t * p ) +{ + int * pModel; + pModel = ALLOC( int, p->vInputs->nSize ); + memset( pModel, 0, sizeof(int) * p->vInputs->nSize ); + return pModel; +} + + +/**Function************************************************************* + + Synopsis [Saves the counter example.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Fraig_ManSimulateBitNode_rec( Fraig_Man_t * p, Fraig_Node_t * pNode ) +{ + int Value0, Value1; + if ( Fraig_NodeIsTravIdCurrent( p, pNode ) ) + return pNode->fMark3; + Fraig_NodeSetTravIdCurrent( p, pNode ); + Value0 = Fraig_ManSimulateBitNode_rec( p, Fraig_Regular(pNode->p1) ); + Value1 = Fraig_ManSimulateBitNode_rec( p, Fraig_Regular(pNode->p2) ); + Value0 ^= Fraig_IsComplement(pNode->p1); + Value1 ^= Fraig_IsComplement(pNode->p2); + pNode->fMark3 = Value0 & Value1; + return pNode->fMark3; +} + +/**Function************************************************************* + + Synopsis [Simulates one bit.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Fraig_ManSimulateBitNode( Fraig_Man_t * p, Fraig_Node_t * pNode, int * pModel ) +{ + int fCompl, RetValue, i; + // set the PI values + Fraig_ManIncrementTravId( p ); + for ( i = 0; i < p->vInputs->nSize; i++ ) + { + Fraig_NodeSetTravIdCurrent( p, p->vInputs->pArray[i] ); + p->vInputs->pArray[i]->fMark3 = pModel[i]; + } + // perform the traversal + fCompl = Fraig_IsComplement(pNode); + RetValue = Fraig_ManSimulateBitNode_rec( p, Fraig_Regular(pNode) ); + return fCompl ^ RetValue; +} + + +/**Function************************************************************* + + Synopsis [Saves the counter example.] Description [] @@ -779,33 +852,52 @@ void Fraig_ReallocateSimulationInfo( Fraig_Man_t * p ) ***********************************************************************/ int * Fraig_ManSaveCounterExample( Fraig_Man_t * p, Fraig_Node_t * pNode ) { - int * pModel = NULL; + int * pModel; int iPattern; - int i; + int i, fCompl; - iPattern = Fraig_FindFirstDiff( p->pConst1, pNode, p->nWordsDyna, 0 ); + // the node can be complemented + fCompl = Fraig_IsComplement(pNode); + // because we compare with constant 0, p->pConst1 should also be complemented + fCompl = !fCompl; + + // derive the model + pModel = Fraig_ManAllocCounterExample( p ); + iPattern = Fraig_FindFirstDiff( p->pConst1, Fraig_Regular(pNode), fCompl, p->nWordsRand, 1 ); if ( iPattern >= 0 ) { - pModel = ALLOC( int, p->vInputs->nSize ); - memset( pModel, 0, sizeof(int) * p->vInputs->nSize ); for ( i = 0; i < p->vInputs->nSize; i++ ) - if ( Fraig_BitStringHasBit( p->vInputs->pArray[i]->puSimD, iPattern ) ) + if ( Fraig_BitStringHasBit( p->vInputs->pArray[i]->puSimR, iPattern ) ) pModel[i] = 1; +/* +printf( "SAT solver's pattern:\n" ); +for ( i = 0; i < p->vInputs->nSize; i++ ) + printf( "%d", pModel[i] ); +printf( "\n" ); +*/ + assert( Fraig_ManSimulateBitNode( p, pNode, pModel ) ); return pModel; } - iPattern = Fraig_FindFirstDiff( p->pConst1, pNode, p->nWordsRand, 1 ); + iPattern = Fraig_FindFirstDiff( p->pConst1, Fraig_Regular(pNode), fCompl, p->iWordStart, 0 ); if ( iPattern >= 0 ) { - pModel = ALLOC( int, p->vInputs->nSize ); - memset( pModel, 0, sizeof(int) * p->vInputs->nSize ); for ( i = 0; i < p->vInputs->nSize; i++ ) - if ( Fraig_BitStringHasBit( p->vInputs->pArray[i]->puSimR, iPattern ) ) + if ( Fraig_BitStringHasBit( p->vInputs->pArray[i]->puSimD, iPattern ) ) pModel[i] = 1; +/* +printf( "SAT solver's pattern:\n" ); +for ( i = 0; i < p->vInputs->nSize; i++ ) + printf( "%d", pModel[i] ); +printf( "\n" ); +*/ + assert( Fraig_ManSimulateBitNode( p, pNode, pModel ) ); return pModel; } - return pModel; + FREE( pModel ); + return NULL; } + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/sat/fraig/fraigInt.h b/src/sat/fraig/fraigInt.h index 5f8b3496..1c765c12 100644 --- a/src/sat/fraig/fraigInt.h +++ b/src/sat/fraig/fraigInt.h @@ -239,10 +239,11 @@ struct Fraig_NodeStruct_t_ unsigned fMark0 : 1; // the mark used for traversals unsigned fMark1 : 1; // the mark used for traversals unsigned fMark2 : 1; // the mark used for traversals + unsigned fMark3 : 1; // the mark used for traversals unsigned fFeedUse : 1; // the presence of the variable in the feedback unsigned fFeedVal : 1; // the value of the variable in the feedback unsigned nFanouts : 2; // the indicator of fanouts (none, one, or many) - unsigned nOnes : 22; // the number of 1's in the random sim info + unsigned nOnes : 21; // the number of 1's in the random sim info // the children of the node Fraig_Node_t * p1; // the first child @@ -379,6 +380,7 @@ extern void Fraig_FeedBackInit( Fraig_Man_t * p ); extern void Fraig_FeedBack( Fraig_Man_t * p, int * pModel, Msat_IntVec_t * vVars, Fraig_Node_t * pOld, Fraig_Node_t * pNew ); extern void Fraig_FeedBackTest( Fraig_Man_t * p ); extern int Fraig_FeedBackCompress( Fraig_Man_t * p ); +extern int * Fraig_ManAllocCounterExample( Fraig_Man_t * p ); extern int * Fraig_ManSaveCounterExample( Fraig_Man_t * p, Fraig_Node_t * pNode ); /*=== fraigMem.c =============================================================*/ extern Fraig_MemFixed_t * Fraig_MemFixedStart( int nEntrySize ); @@ -406,7 +408,7 @@ extern Fraig_Node_t * Fraig_HashTableLookupF0( Fraig_Man_t * pMan, Fraig_No extern void Fraig_HashTableInsertF0( Fraig_Man_t * pMan, Fraig_Node_t * pNode ); extern int Fraig_CompareSimInfo( Fraig_Node_t * pNode1, Fraig_Node_t * pNode2, int iWordLast, int fUseRand ); extern int Fraig_CompareSimInfoUnderMask( Fraig_Node_t * pNode1, Fraig_Node_t * pNode2, int iWordLast, int fUseRand, unsigned * puMask ); -extern int Fraig_FindFirstDiff( Fraig_Node_t * pNode1, Fraig_Node_t * pNode2, int iWordLast, int fUseRand ); +extern int Fraig_FindFirstDiff( Fraig_Node_t * pNode1, Fraig_Node_t * pNode2, int fCompl, int iWordLast, int fUseRand ); extern void Fraig_CollectXors( Fraig_Node_t * pNode1, Fraig_Node_t * pNode2, int iWordLast, int fUseRand, unsigned * puMask ); extern void Fraig_TablePrintStatsS( Fraig_Man_t * pMan ); extern void Fraig_TablePrintStatsF( Fraig_Man_t * pMan ); @@ -416,10 +418,6 @@ extern int Fraig_TableRehashF0( Fraig_Man_t * pMan, int fLinkEqu extern int Fraig_NodeCountPis( Msat_IntVec_t * vVars, int nVarsPi ); extern int Fraig_NodeCountSuppVars( Fraig_Man_t * p, Fraig_Node_t * pNode, int fSuppStr ); extern int Fraig_NodesCompareSupps( Fraig_Man_t * p, Fraig_Node_t * pOld, Fraig_Node_t * pNew ); -extern void Fraig_ManIncrementTravId( Fraig_Man_t * pMan ); -extern void Fraig_NodeSetTravIdCurrent( Fraig_Man_t * pMan, Fraig_Node_t * pNode ); -extern int Fraig_NodeIsTravIdCurrent( Fraig_Man_t * pMan, Fraig_Node_t * pNode ); -extern int Fraig_NodeIsTravIdPrevious( Fraig_Man_t * pMan, Fraig_Node_t * pNode ); extern int Fraig_NodeAndSimpleCase_rec( Fraig_Node_t * pOld, Fraig_Node_t * pNew ); extern int Fraig_NodeIsExorType( Fraig_Node_t * pNode ); extern void Fraig_ManSelectBestChoice( Fraig_Man_t * p ); @@ -435,6 +433,10 @@ extern int Fraig_NodeSimsContained( Fraig_Man_t * pMan, Fraig_No extern int Fraig_NodeIsInSupergate( Fraig_Node_t * pOld, Fraig_Node_t * pNew ); extern Fraig_NodeVec_t * Fraig_CollectSupergate( Fraig_Node_t * pNode, int fStopAtMux ); extern int Fraig_CountPis( Fraig_Man_t * p, Msat_IntVec_t * vVarNums ); +extern void Fraig_ManIncrementTravId( Fraig_Man_t * pMan ); +extern void Fraig_NodeSetTravIdCurrent( Fraig_Man_t * pMan, Fraig_Node_t * pNode ); +extern int Fraig_NodeIsTravIdCurrent( Fraig_Man_t * pMan, Fraig_Node_t * pNode ); +extern int Fraig_NodeIsTravIdPrevious( Fraig_Man_t * pMan, Fraig_Node_t * pNode ); /*=== fraigVec.c ===============================================================*/ extern void Fraig_NodeVecSortByRefCount( Fraig_NodeVec_t * p ); diff --git a/src/sat/fraig/fraigMan.c b/src/sat/fraig/fraigMan.c index 65716340..cfdba619 100644 --- a/src/sat/fraig/fraigMan.c +++ b/src/sat/fraig/fraigMan.c @@ -42,6 +42,7 @@ int timeAssign; ***********************************************************************/ void Fraig_ParamsSetDefault( Fraig_Params_t * pParams ) { + memset( pParams, 0, sizeof(Fraig_Params_t) ); pParams->nPatsRand = FRAIG_PATTERNS_RANDOM; // the number of words of random simulation info pParams->nPatsDyna = FRAIG_PATTERNS_DYNAMIC; // the number of words of dynamic simulation info pParams->nBTLimit = 99; // the max number of backtracks to perform diff --git a/src/sat/fraig/fraigSat.c b/src/sat/fraig/fraigSat.c index da9e8e2b..17201e58 100644 --- a/src/sat/fraig/fraigSat.c +++ b/src/sat/fraig/fraigSat.c @@ -122,11 +122,23 @@ void Fraig_ManProveMiter( Fraig_Man_t * p ) ***********************************************************************/ int Fraig_ManCheckMiter( Fraig_Man_t * p ) { - if ( p->vOutputs->pArray[0] == Fraig_Not(p->pConst1) ) + Fraig_Node_t * pNode; + FREE( p->pModel ); + // get the output node (it can be complemented!) + pNode = p->vOutputs->pArray[0]; + // if the miter is constant 0, the problem is UNSAT + if ( pNode == Fraig_Not(p->pConst1) ) return 1; + // consider the special case when the miter is constant 1 + if ( pNode == p->pConst1 ) + { + // in this case, any counter example will do to distinquish it from constant 0 + // here we pick the counter example composed of all zeros + p->pModel = Fraig_ManAllocCounterExample( p ); + return 0; + } // save the counter example - FREE( p->pModel ); - p->pModel = Fraig_ManSaveCounterExample( p, Fraig_Regular(p->vOutputs->pArray[0]) ); + p->pModel = Fraig_ManSaveCounterExample( p, pNode ); // if the model is not found, return undecided if ( p->pModel == NULL ) return -1; diff --git a/src/sat/fraig/fraigTable.c b/src/sat/fraig/fraigTable.c index 4dc6afdc..7a8af749 100644 --- a/src/sat/fraig/fraigTable.c +++ b/src/sat/fraig/fraigTable.c @@ -382,28 +382,52 @@ int Fraig_CompareSimInfo( Fraig_Node_t * pNode1, Fraig_Node_t * pNode2, int iWor SeeAlso [] ***********************************************************************/ -int Fraig_FindFirstDiff( Fraig_Node_t * pNode1, Fraig_Node_t * pNode2, int iWordLast, int fUseRand ) +int Fraig_FindFirstDiff( Fraig_Node_t * pNode1, Fraig_Node_t * pNode2, int fCompl, int iWordLast, int fUseRand ) { int i, v; assert( !Fraig_IsComplement(pNode1) ); assert( !Fraig_IsComplement(pNode2) ); - if ( fUseRand ) + // take into account possible internal complementation + fCompl ^= pNode1->fInv; + fCompl ^= pNode2->fInv; + // find the pattern + if ( fCompl ) { - // check the simulation info - for ( i = 0; i < iWordLast; i++ ) - if ( pNode1->puSimR[i] != pNode2->puSimR[i] ) - for ( v = 0; v < 32; v++ ) - if ( (pNode1->puSimR[i] ^ pNode2->puSimR[i]) & (1 << v) ) - return i * 32 + v; + if ( fUseRand ) + { + for ( i = 0; i < iWordLast; i++ ) + if ( pNode1->puSimR[i] != ~pNode2->puSimR[i] ) + for ( v = 0; v < 32; v++ ) + if ( (pNode1->puSimR[i] ^ ~pNode2->puSimR[i]) & (1 << v) ) + return i * 32 + v; + } + else + { + for ( i = 0; i < iWordLast; i++ ) + if ( pNode1->puSimD[i] != ~pNode2->puSimD[i] ) + for ( v = 0; v < 32; v++ ) + if ( (pNode1->puSimD[i] ^ ~pNode2->puSimD[i]) & (1 << v) ) + return i * 32 + v; + } } else { - // check the simulation info - for ( i = 0; i < iWordLast; i++ ) - if ( pNode1->puSimD[i] != pNode2->puSimD[i] ) - for ( v = 0; v < 32; v++ ) - if ( (pNode1->puSimD[i] ^ pNode2->puSimD[i]) & (1 << v) ) - return i * 32 + v; + if ( fUseRand ) + { + for ( i = 0; i < iWordLast; i++ ) + if ( pNode1->puSimR[i] != pNode2->puSimR[i] ) + for ( v = 0; v < 32; v++ ) + if ( (pNode1->puSimR[i] ^ pNode2->puSimR[i]) & (1 << v) ) + return i * 32 + v; + } + else + { + for ( i = 0; i < iWordLast; i++ ) + if ( pNode1->puSimD[i] != pNode2->puSimD[i] ) + for ( v = 0; v < 32; v++ ) + if ( (pNode1->puSimD[i] ^ pNode2->puSimD[i]) & (1 << v) ) + return i * 32 + v; + } } return -1; } diff --git a/src/sat/fraig/fraigUtil.c b/src/sat/fraig/fraigUtil.c index 6b7431f2..2155c4a3 100644 --- a/src/sat/fraig/fraigUtil.c +++ b/src/sat/fraig/fraigUtil.c @@ -962,6 +962,71 @@ Fraig_NodeVec_t * Fraig_CollectSupergate( Fraig_Node_t * pNode, int fStopAtMux ) return vSuper; } + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fraig_ManIncrementTravId( Fraig_Man_t * pMan ) +{ + pMan->nTravIds2++; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fraig_NodeSetTravIdCurrent( Fraig_Man_t * pMan, Fraig_Node_t * pNode ) +{ + pNode->TravId2 = pMan->nTravIds2; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Fraig_NodeIsTravIdCurrent( Fraig_Man_t * pMan, Fraig_Node_t * pNode ) +{ + return pNode->TravId2 == pMan->nTravIds2; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Fraig_NodeIsTravIdPrevious( Fraig_Man_t * pMan, Fraig_Node_t * pNode ) +{ + return pNode->TravId2 == pMan->nTravIds2 - 1; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/sat/sim/module.make b/src/sat/sim/module.make deleted file mode 100644 index ac887acf..00000000 --- a/src/sat/sim/module.make +++ /dev/null @@ -1,6 +0,0 @@ -SRC += src/sat/sim/simMan.c \ - src/sat/sim/simSat.c \ - src/sat/sim/simSupp.c \ - src/sat/sim/simSym.c \ - src/sat/sim/simUnate.c \ - src/sat/sim/simUtils.c diff --git a/src/sat/sim/sim.h b/src/sat/sim/sim.h deleted file mode 100644 index 7c4c50e3..00000000 --- a/src/sat/sim/sim.h +++ /dev/null @@ -1,136 +0,0 @@ -/**CFile**************************************************************** - - FileName [sim.h] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Simulation package.] - - Synopsis [External declarations.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: sim.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#ifndef __SIM_H__ -#define __SIM_H__ - -//////////////////////////////////////////////////////////////////////// -/// INCLUDES /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// PARAMETERS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// BASIC TYPES /// -//////////////////////////////////////////////////////////////////////// - -typedef struct Sim_Man_t_ Sim_Man_t; -struct Sim_Man_t_ -{ - // user specified parameters - Abc_Ntk_t * pNtk; - // internal simulation information - int nSimBits; // the number of bits in simulation info - int nSimWords; // the number of words in simulation info - Vec_Ptr_t * vSim0; // simulation info 1 - Vec_Ptr_t * vSim1; // simulation info 2 - // support information - int nSuppBits; // the number of bits in support info - int nSuppWords; // the number of words in support info - Vec_Ptr_t * vSuppStr; // structural supports - Vec_Ptr_t * vSuppFun; // functional supports - // unateness info - Vec_Ptr_t * vUnateVarsP; // unate variables - Vec_Ptr_t * vUnateVarsN; // unate variables - // symmtry info - Extra_BitMat_t * pMatSym; // symmetric pairs - Extra_BitMat_t * pMatNonSym; // non-symmetric pairs - // simulation targets - Vec_Ptr_t * vSuppTargs; // support targets - Vec_Ptr_t * vUnateTargs; // unateness targets - Vec_Ptr_t * vSymmTargs; // symmetry targets - // internal data structures - Extra_MmFixed_t * pMmPat; - Vec_Ptr_t * vFifo; - Vec_Int_t * vDiffs; - // runtime statistics - int time1; - int time2; - int time3; - int time4; -}; - -typedef struct Sim_Pat_t_ Sim_Pat_t; -struct Sim_Pat_t_ -{ - int Input; // the input which it has detected - int Output; // the output for which it was collected - unsigned * pData; // the simulation data -}; - -//////////////////////////////////////////////////////////////////////// -/// MACRO DEFITIONS /// -//////////////////////////////////////////////////////////////////////// - -#define SIM_NUM_WORDS(n) ((n)/32 + (((n)%32) > 0)) -#define SIM_LAST_BITS(n) ((((n)%32) > 0)? (n)%32 : 32) - -// generating random unsigned (#define RAND_MAX 0x7fff) -#define SIM_RANDOM_UNSIGNED ((((unsigned)rand()) << 24) ^ (((unsigned)rand()) << 12) ^ ((unsigned)rand())) - -// macros to get hold of bits in a bit string -#define Sim_SetBit(p,i) ((p)[(i)>>5] |= (1<<((i) & 31))) -#define Sim_XorBit(p,i) ((p)[(i)>>5] ^= (1<<((i) & 31))) -#define Sim_HasBit(p,i) (((p)[(i)>>5] & (1<<((i) & 31))) > 0) - -// macros to get hold of the support info -#define Sim_SuppStrSetVar(pMan,pNode,v) Sim_SetBit((unsigned*)pMan->vSuppStr->pArray[(pNode)->Id],(v)) -#define Sim_SuppStrHasVar(pMan,pNode,v) Sim_HasBit((unsigned*)pMan->vSuppStr->pArray[(pNode)->Id],(v)) -#define Sim_SuppFunSetVar(pMan,Output,v) Sim_SetBit((unsigned*)pMan->vSuppFun->pArray[Output],(v)) -#define Sim_SuppFunHasVar(pMan,Output,v) Sim_HasBit((unsigned*)pMan->vSuppFun->pArray[Output],(v)) -#define Sim_SimInfoSetVar(pMan,pNode,v) Sim_SetBit((unsigned*)pMan->vSim0->pArray[(pNode)->Id],(v)) -#define Sim_SimInfoHasVar(pMan,pNode,v) Sim_HasBit((unsigned*)pMan->vSim0->pArray[(pNode)->Id],(v)) - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -/*=== simMan.c ==========================================================*/ -extern Sim_Man_t * Sim_ManStart( Abc_Ntk_t * pNtk ); -extern void Sim_ManStop( Sim_Man_t * p ); -extern Sim_Pat_t * Sim_ManPatAlloc( Sim_Man_t * p ); -extern void Sim_ManPatFree( Sim_Man_t * p, Sim_Pat_t * pPat ); -extern void Sim_ManPrintStats( Sim_Man_t * p ); - -/*=== simSupp.c ==========================================================*/ -extern Sim_Man_t * Sim_ComputeSupp( Abc_Ntk_t * pNtk ); - -/*=== simUtil.c ==========================================================*/ -extern Vec_Ptr_t * Sim_UtilInfoAlloc( int nSize, int nWords, bool fClean ); -extern void Sim_UtilInfoFree( Vec_Ptr_t * p ); -extern void Sim_UtilInfoAdd( unsigned * pInfo1, unsigned * pInfo2, int nWords ); -extern void Sim_UtilInfoDetectDiffs( unsigned * pInfo1, unsigned * pInfo2, int nWords, Vec_Int_t * vDiffs ); -extern void Sim_UtilInfoDetectNews( unsigned * pInfo1, unsigned * pInfo2, int nWords, Vec_Int_t * vDiffs ); -extern void Sim_UtilComputeStrSupp( Sim_Man_t * p ); -extern void Sim_UtilAssignRandom( Sim_Man_t * p ); -extern void Sim_UtilFlipSimInfo( Sim_Man_t * p, Abc_Obj_t * pNode ); -extern bool Sim_UtilCompareSimInfo( Sim_Man_t * p, Abc_Obj_t * pNode ); -extern void Sim_UtilSimulate( Sim_Man_t * p, bool fFirst ); -extern void Sim_UtilSimulateNode( Sim_Man_t * p, Abc_Obj_t * pNode, bool fType, bool fType1, bool fType2 ); -extern int Sim_UtilCountSuppSizes( Sim_Man_t * p, int fStruct ); - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - -#endif - diff --git a/src/sat/sim/simMan.c b/src/sat/sim/simMan.c deleted file mode 100644 index 1dd4053c..00000000 --- a/src/sat/sim/simMan.c +++ /dev/null @@ -1,166 +0,0 @@ -/**CFile**************************************************************** - - FileName [simMan.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Network and node package.] - - Synopsis [Simulation manager.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: simMan.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" -#include "sim.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Starts the simulatin manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Sim_Man_t * Sim_ManStart( Abc_Ntk_t * pNtk ) -{ - Sim_Man_t * p; - int i; - // start the manager - p = ALLOC( Sim_Man_t, 1 ); - memset( p, 0, sizeof(Sim_Man_t) ); - p->pNtk = pNtk; - // internal simulation information - p->nSimBits = 2048; - p->nSimWords = SIM_NUM_WORDS(p->nSimBits); - p->vSim0 = Sim_UtilInfoAlloc( Abc_NtkObjNumMax(pNtk), p->nSimWords, 0 ); - p->vSim1 = Sim_UtilInfoAlloc( Abc_NtkObjNumMax(pNtk), p->nSimWords, 0 ); - // support information - p->nSuppBits = Abc_NtkCiNum(pNtk); - p->nSuppWords = SIM_NUM_WORDS(p->nSuppBits); - p->vSuppStr = Sim_UtilInfoAlloc( Abc_NtkObjNumMax(pNtk), p->nSuppWords, 1 ); - p->vSuppFun = Sim_UtilInfoAlloc( Abc_NtkCoNum(p->pNtk), p->nSuppWords, 1 ); - // other data - p->pMmPat = Extra_MmFixedStart( sizeof(Sim_Pat_t) + p->nSuppWords * sizeof(unsigned) ); - p->vFifo = Vec_PtrAlloc( 100 ); - p->vDiffs = Vec_IntAlloc( 100 ); - // allocate support targets - p->vSuppTargs = Vec_PtrAlloc( p->nSuppBits ); - p->vSuppTargs->nSize = p->nSuppBits; - for ( i = 0; i < p->nSuppBits; i++ ) - p->vSuppTargs->pArray[i] = Vec_IntAlloc( 8 ); - return p; -} - -/**Function************************************************************* - - Synopsis [Stops the simulatin manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Sim_ManStop( Sim_Man_t * p ) -{ - Sim_ManPrintStats( p ); - if ( p->vSim0 ) Sim_UtilInfoFree( p->vSim0 ); - if ( p->vSim1 ) Sim_UtilInfoFree( p->vSim1 ); - if ( p->vSuppStr ) Sim_UtilInfoFree( p->vSuppStr ); - if ( p->vSuppFun ) Sim_UtilInfoFree( p->vSuppFun ); - if ( p->vUnateVarsP ) Sim_UtilInfoFree( p->vUnateVarsP ); - if ( p->vUnateVarsN ) Sim_UtilInfoFree( p->vUnateVarsN ); - if ( p->pMatSym ) Extra_BitMatrixStop( p->pMatSym ); - if ( p->pMatNonSym ) Extra_BitMatrixStop( p->pMatNonSym ); - if ( p->vSuppTargs ) Vec_PtrFreeFree( p->vSuppTargs ); - if ( p->vUnateTargs ) Vec_PtrFree( p->vUnateTargs ); - if ( p->vSymmTargs ) Vec_PtrFree( p->vSymmTargs ); - if ( p->pMmPat ) Extra_MmFixedStop( p->pMmPat, 0 ); - if ( p->vFifo ) Vec_PtrFree( p->vFifo ); - if ( p->vDiffs ) Vec_IntFree( p->vDiffs ); - free( p ); -} - -/**Function************************************************************* - - Synopsis [Returns one simulation pattern.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Sim_Pat_t * Sim_ManPatAlloc( Sim_Man_t * p ) -{ - Sim_Pat_t * pPat; - pPat = (Sim_Pat_t *)Extra_MmFixedEntryFetch( p->pMmPat ); - pPat->Output = -1; - pPat->pData = (unsigned *)((char *)pPat + sizeof(Sim_Pat_t)); - memset( pPat->pData, 0, p->nSuppWords * sizeof(unsigned) ); - return pPat; -} - -/**Function************************************************************* - - Synopsis [Returns one simulation pattern.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Sim_ManPatFree( Sim_Man_t * p, Sim_Pat_t * pPat ) -{ - Extra_MmFixedEntryRecycle( p->pMmPat, (char *)pPat ); -} - -/**Function************************************************************* - - Synopsis [Prints the manager statisticis.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Sim_ManPrintStats( Sim_Man_t * p ) -{ - printf( "Inputs = %d. Outputs = %d. Sim words = %d.\n", - Abc_NtkCiNum(p->pNtk), Abc_NtkCoNum(p->pNtk), p->nSimWords ); - printf( "Total struct supps = %6d.\n", Sim_UtilCountSuppSizes(p, 1) ); - printf( "Total func supps = %6d.\n", Sim_UtilCountSuppSizes(p, 0) ); - printf( "Total targets = %6d.\n", Vec_PtrSizeSize(p->vSuppTargs) ); - printf( "Total sim patterns = %6d.\n", Vec_PtrSize(p->vFifo) ); -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/sat/sim/simSat.c b/src/sat/sim/simSat.c deleted file mode 100644 index b4e080fe..00000000 --- a/src/sat/sim/simSat.c +++ /dev/null @@ -1,48 +0,0 @@ -/**CFile**************************************************************** - - FileName [simSat.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Network and node package.] - - Synopsis [Simulation to determine functional support.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: simSat.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" -#include "sim.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/sat/sim/simSupp.c b/src/sat/sim/simSupp.c deleted file mode 100644 index 570e8dc6..00000000 --- a/src/sat/sim/simSupp.c +++ /dev/null @@ -1,273 +0,0 @@ -/**CFile**************************************************************** - - FileName [simSupp.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Network and node package.] - - Synopsis [Simulation to determine functional support.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: simSupp.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" -#include "sim.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static int Sim_ComputeSuppRound( Sim_Man_t * p, bool fUseTargets ); -static int Sim_ComputeSuppRoundNode( Sim_Man_t * p, int iNumCi, bool fUseTargets ); -static void Sim_ComputeSuppSetTargets( Sim_Man_t * p ); -static void Sim_UtilAssignFromFifo( Sim_Man_t * p ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Compute functional supports of the primary outputs.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Sim_Man_t * Sim_ComputeSupp( Abc_Ntk_t * pNtk ) -{ - Sim_Man_t * p; - int i, nSolved; - -// srand( time(NULL) ); - srand( 0xedfeedfe ); - - // start the simulation manager - p = Sim_ManStart( pNtk ); - Sim_UtilComputeStrSupp( p ); - - // compute functional support using one round of random simulation - Sim_UtilAssignRandom( p ); - Sim_ComputeSuppRound( p, 0 ); - - // set the support targets - Sim_ComputeSuppSetTargets( p ); -printf( "Initial targets = %5d.\n", Vec_PtrSizeSize(p->vSuppTargs) ); - if ( Vec_PtrSizeSize(p->vSuppTargs) == 0 ) - goto exit; - - // compute patterns using one round of random simulation - Sim_UtilAssignRandom( p ); - nSolved = Sim_ComputeSuppRound( p, 1 ); -printf( "First step targets = %5d. Solved = %5d.\n", Vec_PtrSizeSize(p->vSuppTargs), nSolved ); - if ( Vec_PtrSizeSize(p->vSuppTargs) == 0 ) - goto exit; - - // simulate until saturation - for ( i = 0; i < 10; i++ ) - { - // compute additional functional support -// Sim_UtilAssignFromFifo( p ); - Sim_UtilAssignRandom( p ); - nSolved = Sim_ComputeSuppRound( p, 1 ); -printf( "Next step targets = %5d. Solved = %5d.\n", Vec_PtrSizeSize(p->vSuppTargs), nSolved ); - if ( Vec_PtrSizeSize(p->vSuppTargs) == 0 ) - goto exit; - } - -exit: -// return p; - Sim_ManStop( p ); - return NULL; -} - -/**Function************************************************************* - - Synopsis [Computes functional support using one round of simulation.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Sim_ComputeSuppRound( Sim_Man_t * p, bool fUseTargets ) -{ - Vec_Int_t * vTargets; - Abc_Obj_t * pNode; - int i, Counter = 0; - // perform one round of random simulation - Sim_UtilSimulate( p, 0 ); - // iterate through the CIs and detect COs that depend on them - Abc_NtkForEachCi( p->pNtk, pNode, i ) - { - vTargets = p->vSuppTargs->pArray[i]; - if ( fUseTargets && vTargets->nSize == 0 ) - continue; - Counter += Sim_ComputeSuppRoundNode( p, i, fUseTargets ); - } - return Counter; -} - -/**Function************************************************************* - - Synopsis [Computes functional support for one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Sim_ComputeSuppRoundNode( Sim_Man_t * p, int iNumCi, bool fUseTargets ) -{ - Sim_Pat_t * pPat; - Vec_Int_t * vTargets; - Vec_Vec_t * vNodesByLevel; - Abc_Obj_t * pNodeCi, * pNode; - int i, k, v, Output, LuckyPat, fType0, fType1; - int Counter = 0; - // collect nodes by level in the TFO of the CI - // (this procedure increments TravId of the collected nodes) - pNodeCi = Abc_NtkCi( p->pNtk, iNumCi ); - vNodesByLevel = Abc_DfsLevelized( pNodeCi, 0 ); - // complement the simulation info of the selected CI - Sim_UtilFlipSimInfo( p, pNodeCi ); - // simulate the levelized structure of nodes - Vec_VecForEachEntry( vNodesByLevel, pNode, i, k ) - { - fType0 = Abc_NodeIsTravIdCurrent( Abc_ObjFanin0(pNode) ); - fType1 = Abc_NodeIsTravIdCurrent( Abc_ObjFanin1(pNode) ); - Sim_UtilSimulateNode( p, pNode, 1, fType0, fType1 ); - } - // set the simulation info of the affected COs - if ( fUseTargets ) - { - vTargets = p->vSuppTargs->pArray[iNumCi]; - for ( i = vTargets->nSize - 1; i >= 0; i-- ) - { - // get the target output - Output = vTargets->pArray[i]; - // get the target node - pNode = Abc_NtkCo( p->pNtk, Output ); - // the output should be in the cone - assert( Abc_NodeIsTravIdCurrent(pNode) ); - - // simulate the node - Sim_UtilSimulateNode( p, pNode, 1, 1, 1 ); - - // skip if the simulation info is equal - if ( Sim_UtilCompareSimInfo( p, pNode ) ) - continue; - - // otherwise, we solved a new target - Vec_IntRemove( vTargets, Output ); - Counter++; - // make sure this variable is not yet detected - assert( !Sim_SuppFunHasVar(p, Output, iNumCi) ); - // set this variable - Sim_SuppFunSetVar( p, Output, iNumCi ); - - // detect the differences in the simulation info - Sim_UtilInfoDetectDiffs( p->vSim0->pArray[pNode->Id], p->vSim1->pArray[pNode->Id], p->nSimWords, p->vDiffs ); - // create new patterns - Vec_IntForEachEntry( p->vDiffs, LuckyPat, k ) - { - // set the new pattern - pPat = Sim_ManPatAlloc( p ); - pPat->Input = iNumCi; - pPat->Output = Output; - Abc_NtkForEachCi( p->pNtk, pNodeCi, v ) - if ( Sim_SimInfoHasVar( p, pNodeCi, LuckyPat ) ) - Sim_SetBit( pPat->pData, v ); - Vec_PtrPush( p->vFifo, pPat ); - break; - } - } - } - else - { - Abc_NtkForEachCo( p->pNtk, pNode, Output ) - { - if ( !Abc_NodeIsTravIdCurrent( pNode ) ) - continue; - Sim_UtilSimulateNode( p, pNode, 1, 1, 1 ); - if ( !Sim_UtilCompareSimInfo( p, pNode ) ) - { - if ( !Sim_SuppFunHasVar(p, Output, iNumCi) ) - Counter++; - Sim_SuppFunSetVar( p, Output, iNumCi ); - } - } - } - Vec_VecFree( vNodesByLevel ); - return Counter; -} - -/**Function************************************************************* - - Synopsis [Sets the simulation targets.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Sim_ComputeSuppSetTargets( Sim_Man_t * p ) -{ - Abc_Obj_t * pNode; - unsigned * pSuppStr, * pSuppFun; - int i, k, Num; - Abc_NtkForEachCo( p->pNtk, pNode, i ) - { - pSuppStr = p->vSuppStr->pArray[pNode->Id]; - pSuppFun = p->vSuppFun->pArray[i]; - // find vars in the structural support that are not in the functional support - Sim_UtilInfoDetectNews( pSuppFun, pSuppStr, p->nSuppWords, p->vDiffs ); - Vec_IntForEachEntry( p->vDiffs, Num, k ) - Vec_IntPush( p->vSuppTargs->pArray[Num], i ); - } -} - -/**Function************************************************************* - - Synopsis [Sets the new patterns from fifo.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Sim_UtilAssignFromFifo( Sim_Man_t * p ) -{ - Sim_Pat_t * pPat; - int i; - for ( i = 0; i < p->nSimBits; i++ ) - { - pPat = Vec_PtrPop( p->vFifo ); - - } -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/sat/sim/simSym.c b/src/sat/sim/simSym.c deleted file mode 100644 index 6b8bdaa3..00000000 --- a/src/sat/sim/simSym.c +++ /dev/null @@ -1,48 +0,0 @@ -/**CFile**************************************************************** - - FileName [simSym.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Network and node package.] - - Synopsis [Simulation to determine two-variable symmetries.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: simSym.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" -#include "sim.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/sat/sim/simUnate.c b/src/sat/sim/simUnate.c deleted file mode 100644 index f7ad3557..00000000 --- a/src/sat/sim/simUnate.c +++ /dev/null @@ -1,48 +0,0 @@ -/**CFile**************************************************************** - - FileName [simUnate.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Network and node package.] - - Synopsis [Simulation to determine unateness of variables.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: simUnate.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" -#include "sim.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/sat/sim/simUtils.c b/src/sat/sim/simUtils.c deleted file mode 100644 index 5f5708f2..00000000 --- a/src/sat/sim/simUtils.c +++ /dev/null @@ -1,379 +0,0 @@ -/**CFile**************************************************************** - - FileName [simUtils.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Network and node package.] - - Synopsis [Various simulation utilities.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: simUtils.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" -#include "sim.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Allocates simulation information for all nodes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Ptr_t * Sim_UtilInfoAlloc( int nSize, int nWords, bool fClean ) -{ - Vec_Ptr_t * vInfo; - int i; - vInfo = Vec_PtrAlloc( nSize ); - vInfo->pArray[0] = ALLOC( unsigned, nSize * nWords ); - if ( fClean ) - memset( vInfo->pArray[0], 0, sizeof(unsigned) * nSize * nWords ); - for ( i = 1; i < nSize; i++ ) - vInfo->pArray[i] = ((unsigned *)vInfo->pArray[i-1]) + nWords; - vInfo->nSize = nSize; - return vInfo; -} - -/**Function************************************************************* - - Synopsis [Allocates simulation information for all nodes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Sim_UtilInfoFree( Vec_Ptr_t * p ) -{ - free( p->pArray[0] ); - Vec_PtrFree( p ); -} - -/**Function************************************************************* - - Synopsis [Adds the second supp-info the first.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Sim_UtilInfoAdd( unsigned * pInfo1, unsigned * pInfo2, int nWords ) -{ - int w; - for ( w = 0; w < nWords; w++ ) - pInfo1[w] |= pInfo2[w]; -} - -/**Function************************************************************* - - Synopsis [Returns the positions where pInfo2 is 1 while pInfo1 is 0.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Sim_UtilInfoDetectDiffs( unsigned * pInfo1, unsigned * pInfo2, int nWords, Vec_Int_t * vDiffs ) -{ - int w, b; - unsigned uMask; - vDiffs->nSize = 0; - for ( w = 0; w < nWords; w++ ) - if ( uMask = (pInfo2[w] ^ pInfo1[w]) ) - for ( b = 0; b < 32; b++ ) - if ( uMask & (1 << b) ) - Vec_IntPush( vDiffs, 32*w + b ); -} - -/**Function************************************************************* - - Synopsis [Returns the positions where pInfo2 is 1 while pInfo1 is 0.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Sim_UtilInfoDetectNews( unsigned * pInfo1, unsigned * pInfo2, int nWords, Vec_Int_t * vDiffs ) -{ - int w, b; - unsigned uMask; - vDiffs->nSize = 0; - for ( w = 0; w < nWords; w++ ) - if ( uMask = (pInfo2[w] & ~pInfo1[w]) ) - for ( b = 0; b < 32; b++ ) - if ( uMask & (1 << b) ) - Vec_IntPush( vDiffs, 32*w + b ); -} - -/**Function************************************************************* - - Synopsis [Computes structural supports.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Sim_UtilComputeStrSupp( Sim_Man_t * p ) -{ - Abc_Obj_t * pNode; - unsigned * pSimmNode, * pSimmNode1, * pSimmNode2; - int i, k; - // assign the structural support to the PIs - Abc_NtkForEachCi( p->pNtk, pNode, i ) - Sim_SuppStrSetVar( p, pNode, i ); - // derive the structural supports of the internal nodes - Abc_NtkForEachNode( p->pNtk, pNode, i ) - { - if ( Abc_NodeIsConst(pNode) ) - continue; - pSimmNode = p->vSuppStr->pArray[ pNode->Id ]; - pSimmNode1 = p->vSuppStr->pArray[ Abc_ObjFaninId0(pNode) ]; - pSimmNode2 = p->vSuppStr->pArray[ Abc_ObjFaninId1(pNode) ]; - for ( k = 0; k < p->nSuppWords; k++ ) - pSimmNode[k] = pSimmNode1[k] | pSimmNode2[k]; - } - // set the structural supports of the PO nodes - Abc_NtkForEachCo( p->pNtk, pNode, i ) - { - pSimmNode = p->vSuppStr->pArray[ pNode->Id ]; - pSimmNode1 = p->vSuppStr->pArray[ Abc_ObjFaninId0(pNode) ]; - for ( k = 0; k < p->nSuppWords; k++ ) - pSimmNode[k] = pSimmNode1[k]; - } -} - -/**Function************************************************************* - - Synopsis [Assigns random simulation info to the PIs.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Sim_UtilAssignRandom( Sim_Man_t * p ) -{ - Abc_Obj_t * pNode; - unsigned * pSimInfo; - int i, k; - // assign the random/systematic simulation info to the PIs - Abc_NtkForEachCi( p->pNtk, pNode, i ) - { - pSimInfo = p->vSim0->pArray[pNode->Id]; - for ( k = 0; k < p->nSimWords; k++ ) - pSimInfo[k] = SIM_RANDOM_UNSIGNED; - } -} - -/**Function************************************************************* - - Synopsis [Flips the simulation info of the node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Sim_UtilFlipSimInfo( Sim_Man_t * p, Abc_Obj_t * pNode ) -{ - unsigned * pSimInfo1, * pSimInfo2; - int k; - pSimInfo1 = p->vSim1->pArray[pNode->Id]; - pSimInfo2 = p->vSim0->pArray[pNode->Id]; - for ( k = 0; k < p->nSimWords; k++ ) - pSimInfo2[k] = ~pSimInfo1[k]; -} - -/**Function************************************************************* - - Synopsis [Returns 1 if the simulation infos are equal.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -bool Sim_UtilCompareSimInfo( Sim_Man_t * p, Abc_Obj_t * pNode ) -{ - unsigned * pSimInfo1, * pSimInfo2; - int k; - pSimInfo1 = p->vSim1->pArray[pNode->Id]; - pSimInfo2 = p->vSim0->pArray[pNode->Id]; - for ( k = 0; k < p->nSimWords; k++ ) - if ( pSimInfo2[k] != pSimInfo1[k] ) - return 0; - return 1; -} - -/**Function************************************************************* - - Synopsis [Simulates the internal nodes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Sim_UtilSimulate( Sim_Man_t * p, bool fType ) -{ - Abc_Obj_t * pNode; - int i; - // simulate the internal nodes - Abc_NtkForEachNode( p->pNtk, pNode, i ) - Sim_UtilSimulateNode( p, pNode, fType, fType, fType ); - // assign simulation info of the CO nodes - Abc_NtkForEachCo( p->pNtk, pNode, i ) - Sim_UtilSimulateNode( p, pNode, fType, fType, fType ); -} - -/**Function************************************************************* - - Synopsis [Simulates one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Sim_UtilSimulateNode( Sim_Man_t * p, Abc_Obj_t * pNode, bool fType, bool fType1, bool fType2 ) -{ - unsigned * pSimmNode, * pSimmNode1, * pSimmNode2; - int k, fComp1, fComp2; - // simulate the internal nodes - if ( Abc_ObjIsNode(pNode) ) - { - if ( Abc_NodeIsConst(pNode) ) - return; - - if ( fType ) - pSimmNode = p->vSim1->pArray[ pNode->Id ]; - else - pSimmNode = p->vSim0->pArray[ pNode->Id ]; - - if ( fType1 ) - pSimmNode1 = p->vSim1->pArray[ Abc_ObjFaninId0(pNode) ]; - else - pSimmNode1 = p->vSim0->pArray[ Abc_ObjFaninId0(pNode) ]; - - if ( fType2 ) - pSimmNode2 = p->vSim1->pArray[ Abc_ObjFaninId1(pNode) ]; - else - pSimmNode2 = p->vSim0->pArray[ Abc_ObjFaninId1(pNode) ]; - - fComp1 = Abc_ObjFaninC0(pNode); - fComp2 = Abc_ObjFaninC1(pNode); - if ( fComp1 && fComp2 ) - for ( k = 0; k < p->nSimWords; k++ ) - pSimmNode[k] = ~pSimmNode1[k] & ~pSimmNode2[k]; - else if ( fComp1 && !fComp2 ) - for ( k = 0; k < p->nSimWords; k++ ) - pSimmNode[k] = ~pSimmNode1[k] & pSimmNode2[k]; - else if ( !fComp1 && fComp2 ) - for ( k = 0; k < p->nSimWords; k++ ) - pSimmNode[k] = pSimmNode1[k] & ~pSimmNode2[k]; - else // if ( fComp1 && fComp2 ) - for ( k = 0; k < p->nSimWords; k++ ) - pSimmNode[k] = pSimmNode1[k] & pSimmNode2[k]; - } - else - { - assert( Abc_ObjFaninNum(pNode) == 1 ); - if ( fType ) - pSimmNode = p->vSim1->pArray[ pNode->Id ]; - else - pSimmNode = p->vSim0->pArray[ pNode->Id ]; - - if ( fType1 ) - pSimmNode1 = p->vSim1->pArray[ Abc_ObjFaninId0(pNode) ]; - else - pSimmNode1 = p->vSim0->pArray[ Abc_ObjFaninId0(pNode) ]; - - fComp1 = Abc_ObjFaninC0(pNode); - if ( fComp1 ) - for ( k = 0; k < p->nSimWords; k++ ) - pSimmNode[k] = ~pSimmNode1[k]; - else - for ( k = 0; k < p->nSimWords; k++ ) - pSimmNode[k] = pSimmNode1[k]; - } -} - -/**Function************************************************************* - - Synopsis [Returns 1 if the simulation infos are equal.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Sim_UtilCountSuppSizes( Sim_Man_t * p, int fStruct ) -{ - Abc_Obj_t * pNode, * pNodeCi; - int i, v, Counter; - Counter = 0; - if ( fStruct ) - { - Abc_NtkForEachCo( p->pNtk, pNode, i ) - Abc_NtkForEachCi( p->pNtk, pNodeCi, v ) - Counter += Sim_SuppStrHasVar( p, pNode, v ); - } - else - { - Abc_NtkForEachCo( p->pNtk, pNode, i ) - Abc_NtkForEachCi( p->pNtk, pNodeCi, v ) - Counter += Sim_SuppFunHasVar( p, i, v ); - } - return Counter; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/seq/module.make b/src/seq/module.make deleted file mode 100644 index d6d908e7..00000000 --- a/src/seq/module.make +++ /dev/null @@ -1 +0,0 @@ -SRC += diff --git a/src/sop/mvc/module.make b/src/sop/mvc/module.make deleted file mode 100644 index bdb5c5cf..00000000 --- a/src/sop/mvc/module.make +++ /dev/null @@ -1,16 +0,0 @@ -SRC += src/sop/mvc/mvc.c \ - src/sop/mvc/mvcApi.c \ - src/sop/mvc/mvcCompare.c \ - src/sop/mvc/mvcContain.c \ - src/sop/mvc/mvcCover.c \ - src/sop/mvc/mvcCube.c \ - src/sop/mvc/mvcDivide.c \ - src/sop/mvc/mvcDivisor.c \ - src/sop/mvc/mvcList.c \ - src/sop/mvc/mvcLits.c \ - src/sop/mvc/mvcMan.c \ - src/sop/mvc/mvcOpAlg.c \ - src/sop/mvc/mvcOpBool.c \ - src/sop/mvc/mvcPrint.c \ - src/sop/mvc/mvcSort.c \ - src/sop/mvc/mvcUtils.c diff --git a/src/sop/mvc/mvc.c b/src/sop/mvc/mvc.c deleted file mode 100644 index 9430276c..00000000 --- a/src/sop/mvc/mvc.c +++ /dev/null @@ -1,46 +0,0 @@ -/**CFile**************************************************************** - - FileName [mvc.c] - - PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] - - Synopsis [] - - Author [MVSIS Group] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - February 1, 2003.] - - Revision [$Id: mvc.c,v 1.3 2003/03/19 19:50:26 alanmi Exp $] - -***********************************************************************/ - -#include "mvc.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/sop/mvc/mvc.h b/src/sop/mvc/mvc.h deleted file mode 100644 index ee8c31be..00000000 --- a/src/sop/mvc/mvc.h +++ /dev/null @@ -1,733 +0,0 @@ -/**CFile**************************************************************** - - FileName [mvc.h] - - PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] - - Synopsis [Data structure for MV cube/cover manipulation.] - - Author [MVSIS Group] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - February 1, 2003.] - - Revision [$Id: mvc.h,v 1.10 2003/05/02 23:23:59 wjiang Exp $] - -***********************************************************************/ - -#ifndef __MVC_H__ -#define __MVC_H__ - -//////////////////////////////////////////////////////////////////////// -/// INCLUDES /// -//////////////////////////////////////////////////////////////////////// - -#include -#include "util.h" -#include "extra.h" -//#include "vm.h" - -//////////////////////////////////////////////////////////////////////// -/// PARAMETERS /// -//////////////////////////////////////////////////////////////////////// - -// this is the only part of Mvc package, which should be modified -// when compiling the package for other platforms - -// these parameters can be computed but setting them manually makes it faster -#define BITS_PER_WORD 32 // sizeof(Mvc_CubeWord_t) * 8 -#define BITS_PER_WORD_MINUS 31 // the same minus 1 -#define BITS_PER_WORD_LOG 5 // log2(sizeof(Mvc_CubeWord_t) * 8) -#define BITS_DISJOINT ((Mvc_CubeWord_t)0x55555555) // the mask of the type "01010101" -#define BITS_FULL ((Mvc_CubeWord_t)0xffffffff) // the mask of the type "11111111" - -// uncomment this macro to switch to standard memory management -//#define USE_SYSTEM_MEMORY_MANAGEMENT - -//////////////////////////////////////////////////////////////////////// -/// STRUCTURE DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -// cube/list/cover/data -typedef unsigned long Mvc_CubeWord_t; -typedef struct MvcCubeStruct Mvc_Cube_t; -typedef struct MvcListStruct Mvc_List_t; -typedef struct MvcCoverStruct Mvc_Cover_t; -typedef struct MvcDataStruct Mvc_Data_t; -typedef struct MvcManagerStruct Mvc_Manager_t; - -// the cube data structure -struct MvcCubeStruct -{ - Mvc_Cube_t * pNext; // the next cube in the linked list - unsigned iLast : 8; // the index of the last word - unsigned nUnused : 6; // the number of unused bits in the last word - unsigned fPrime : 1; // marks the prime cube - unsigned fEssen : 1; // marks the essential cube - unsigned nOnes : 16; // the number of 1's in the bit data - Mvc_CubeWord_t pData[1]; // the first Mvc_CubeWord_t filled with bit data -}; - -// the single-linked list of cubes in the cover -struct MvcListStruct -{ - Mvc_Cube_t * pHead; // the first cube in the list - Mvc_Cube_t * pTail; // the last cube in the list - int nItems; // the number of cubes in the list -}; - -// the cover data structure -struct MvcCoverStruct -{ - char nWords; // the number of machine words - char nUnused; // the number of unused bits in the last word - short nBits; // the number of used data bits in the cube - Mvc_List_t lCubes; // the single-linked list of cubes - Mvc_Cube_t ** pCubes; // the array of cubes (for sorting) - int nCubesAlloc; // the size of allocated storage - int * pLits; // the counter of lit occurrances in cubes - Mvc_Cube_t * pMask; // the multipurpose mask - Mvc_Manager_t * pMem; // the memory manager -}; - -// data structure to store information about MV variables -struct MvcDataStruct -{ - Mvc_Manager_t * pMan; // the memory manager -// Vm_VarMap_t * pVm; // the MV variable data - int nBinVars; // the number of binary variables - Mvc_Cube_t * pMaskBin; // the mask to select the binary bits only - Mvc_Cube_t ** ppMasks; // the mask to select each MV variable - Mvc_Cube_t * ppTemp[3]; // the temporary cubes -}; - -// the manager of covers and cubes (as of today, only managing memory) -struct MvcManagerStruct -{ - Extra_MmFixed_t * pManC; // the manager for covers - Extra_MmFixed_t * pMan1; // the manager for 1-word cubes - Extra_MmFixed_t * pMan2; // the manager for 2-word cubes - Extra_MmFixed_t * pMan4; // the manager for 3-word cubes -}; - -//////////////////////////////////////////////////////////////////////// -/// MACRO DEFITIONS /// -//////////////////////////////////////////////////////////////////////// - -// reading data from the header of the cube -#define Mvc_CubeReadNext(Cube) ((Cube)->pNext) -#define Mvc_CubeReadNextP(Cube) (&(Cube)->pNext) -#define Mvc_CubeReadLast(Cube) ((Cube)->iLast) -#define Mvc_CubeReadSize(Cube) ((Cube)->nOnes) -// setting data to the header of the cube -#define Mvc_CubeSetNext(Cube,Next) ((Cube)->pNext = (Next)) -#define Mvc_CubeSetLast(Cube,Last) ((Cube)->iLast = (Last)) -#define Mvc_CubeSetSize(Cube,Size) ((Cube)->nOnes = (Size)) -// checking the number of words - -#define Mvc_Cube1Words(Cube) ((Cube)->iLast == 0) -#define Mvc_Cube2Words(Cube) ((Cube)->iLast == 1) -#define Mvc_CubeNWords(Cube) ((Cube)->iLast > 1) -// getting one data bit -#define Mvc_CubeWhichWord(Bit) ((Bit) >> BITS_PER_WORD_LOG) -#define Mvc_CubeWhichBit(Bit) ((Bit) & BITS_PER_WORD_MINUS) -// accessing individual bits -#define Mvc_CubeBitValue(Cube, Bit) (((Cube)->pData[Mvc_CubeWhichWord(Bit)] & (((Mvc_CubeWord_t)1)<<(Mvc_CubeWhichBit(Bit)))) > 0) -#define Mvc_CubeBitInsert(Cube, Bit) ((Cube)->pData[Mvc_CubeWhichWord(Bit)] |= (((Mvc_CubeWord_t)1)<<(Mvc_CubeWhichBit(Bit)))) -#define Mvc_CubeBitRemove(Cube, Bit) ((Cube)->pData[Mvc_CubeWhichWord(Bit)] &= ~(((Mvc_CubeWord_t)1)<<(Mvc_CubeWhichBit(Bit)))) -// accessing values of the binary variables -#define Mvc_CubeVarValue(Cube, Var) (((Cube)->pData[Mvc_CubeWhichWord(2*(Var))] >> (Mvc_CubeWhichBit(2*(Var)))) & ((Mvc_CubeWord_t)3)) - -// various macros - -// cleaning the data bits of the cube -#define Mvc_Cube1BitClean( Cube )\ - ((Cube)->pData[0] = 0) -#define Mvc_Cube2BitClean( Cube )\ - (((Cube)->pData[0] = 0),\ - ((Cube)->pData[1] = 0)) -#define Mvc_CubeNBitClean( Cube )\ -{\ - int _i_;\ - for( _i_ = (Cube)->iLast; _i_ >= 0; _i_--)\ - (Cube)->pData[_i_] = 0;\ -} - -// cleaning the unused part of the lat word -#define Mvc_CubeBitCleanUnused( Cube )\ - ((Cube)->pData[(Cube)->iLast] &= (BITS_FULL >> (Cube)->nUnused)) - -// filling the used data bits with 1's -#define Mvc_Cube1BitFill( Cube )\ - (Cube)->pData[0] = (BITS_FULL >> (Cube)->nUnused); -#define Mvc_Cube2BitFill( Cube )\ - (((Cube)->pData[0] = BITS_FULL),\ - ((Cube)->pData[1] = (BITS_FULL >> (Cube)->nUnused))) -#define Mvc_CubeNBitFill( Cube )\ -{\ - int _i_;\ - (Cube)->pData[(Cube)->iLast] = (BITS_FULL >> (Cube)->nUnused);\ - for( _i_ = (Cube)->iLast - 1; _i_ >= 0; _i_-- )\ - (Cube)->pData[_i_] = BITS_FULL;\ -} - -// complementing the data bits -#define Mvc_Cube1BitNot( Cube )\ - ((Cube)->pData[0] ^= (BITS_FULL >> (Cube)->nUnused)) -#define Mvc_Cube2BitNot( Cube )\ - (((Cube)->pData[0] ^= BITS_FULL),\ - ((Cube)->pData[1] ^= (BITS_FULL >> (Cube)->nUnused))) -#define Mvc_CubeNBitNot( Cube )\ -{\ - int _i_;\ - (Cube)->pData[(Cube)->iLast] ^= (BITS_FULL >> (Cube)->nUnused);\ - for( _i_ = (Cube)->iLast - 1; _i_ >= 0; _i_-- )\ - (Cube)->pData[_i_] ^= BITS_FULL;\ -} - -#define Mvc_Cube1BitCopy( Cube1, Cube2 )\ - (((Cube1)->pData[0]) = ((Cube2)->pData[0])) -#define Mvc_Cube2BitCopy( Cube1, Cube2 )\ - ((((Cube1)->pData[0]) = ((Cube2)->pData[0])),\ - (((Cube1)->pData[1])= ((Cube2)->pData[1]))) -#define Mvc_CubeNBitCopy( Cube1, Cube2 )\ -{\ - int _i_;\ - for (_i_ = (Cube1)->iLast; _i_ >= 0; _i_--)\ - ((Cube1)->pData[_i_]) = ((Cube2)->pData[_i_]);\ -} - -#define Mvc_Cube1BitOr( CubeR, Cube1, Cube2 )\ - (((CubeR)->pData[0]) = ((Cube1)->pData[0] | (Cube2)->pData[0])) -#define Mvc_Cube2BitOr( CubeR, Cube1, Cube2 )\ - ((((CubeR)->pData[0]) = ((Cube1)->pData[0] | (Cube2)->pData[0])),\ - (((CubeR)->pData[1]) = ((Cube1)->pData[1] | (Cube2)->pData[1]))) -#define Mvc_CubeNBitOr( CubeR, Cube1, Cube2 )\ -{\ - int _i_;\ - for (_i_ = (Cube1)->iLast; _i_ >= 0; _i_--)\ - (((CubeR)->pData[_i_]) = ((Cube1)->pData[_i_] | (Cube2)->pData[_i_]));\ -} - -#define Mvc_Cube1BitExor( CubeR, Cube1, Cube2 )\ - (((CubeR)->pData[0]) = ((Cube1)->pData[0] ^ (Cube2)->pData[0])) -#define Mvc_Cube2BitExor( CubeR, Cube1, Cube2 )\ - ((((CubeR)->pData[0]) = ((Cube1)->pData[0] ^ (Cube2)->pData[0])),\ - (((CubeR)->pData[1]) = ((Cube1)->pData[1] ^ (Cube2)->pData[1]))) -#define Mvc_CubeNBitExor( CubeR, Cube1, Cube2 )\ -{\ - int _i_;\ - for (_i_ = (Cube1)->iLast; _i_ >= 0; _i_--)\ - (((CubeR)->pData[_i_]) = ((Cube1)->pData[_i_] ^ (Cube2)->pData[_i_]));\ -} - -#define Mvc_Cube1BitAnd( CubeR, Cube1, Cube2 )\ - (((CubeR)->pData[0]) = ((Cube1)->pData[0] & (Cube2)->pData[0])) -#define Mvc_Cube2BitAnd( CubeR, Cube1, Cube2 )\ - ((((CubeR)->pData[0]) = ((Cube1)->pData[0] & (Cube2)->pData[0])),\ - (((CubeR)->pData[1]) = ((Cube1)->pData[1] & (Cube2)->pData[1]))) -#define Mvc_CubeNBitAnd( CubeR, Cube1, Cube2 )\ -{\ - int _i_;\ - for (_i_ = (Cube1)->iLast; _i_ >= 0; _i_--)\ - (((CubeR)->pData[_i_]) = ((Cube1)->pData[_i_] & (Cube2)->pData[_i_]));\ -} - -#define Mvc_Cube1BitSharp( CubeR, Cube1, Cube2 )\ - (((CubeR)->pData[0]) = ((Cube1)->pData[0] & ~((Cube2)->pData[0]))) -#define Mvc_Cube2BitSharp( CubeR, Cube1, Cube2 )\ - ((((CubeR)->pData[0]) = ((Cube1)->pData[0] & ~((Cube2)->pData[0]))),\ - (((CubeR)->pData[1]) = ((Cube1)->pData[1] & ~((Cube2)->pData[1])))) -#define Mvc_CubeNBitSharp( CubeR, Cube1, Cube2 )\ -{\ - int _i_;\ - for (_i_ = (Cube1)->iLast; _i_ >= 0; _i_--)\ - (((CubeR)->pData[_i_]) = ((Cube1)->pData[_i_] & ~(Cube2)->pData[_i_]));\ -} - -#define Mvc_Cube1BitEmpty( Res, Cube )\ - (Res = ((Cube)->pData[0] == 0)) -#define Mvc_Cube2BitEmpty( Res, Cube )\ - (Res = ((Cube)->pData[0] == 0 && (Cube)->pData[1] == 0)) -#define Mvc_CubeNBitEmpty( Res, Cube )\ -{\ - int _i_; Res = 1;\ - for (_i_ = (Cube)->iLast; _i_ >= 0; _i_--)\ - if ( (Cube)->pData[_i_] )\ - { Res = 0; break; }\ -} - -#define Mvc_Cube1BitEqual( Res, Cube1, Cube2 )\ - (Res = (((Cube1)->pData[0]) == ((Cube2)->pData[0]))) -#define Mvc_Cube2BitEqual( Res, Cube1, Cube2 )\ - (Res = ((((Cube1)->pData[0]) == ((Cube2)->pData[0])) &&\ - (((Cube1)->pData[1]) == ((Cube2)->pData[1])))) -#define Mvc_CubeNBitEqual( Res, Cube1, Cube2 )\ -{\ - int _i_; Res = 1;\ - for (_i_ = (Cube1)->iLast; _i_ >= 0; _i_--)\ - if (((Cube1)->pData[_i_]) != ((Cube2)->pData[_i_]))\ - { Res = 0; break; }\ -} - -#define Mvc_Cube1BitLess( Res, Cube1, Cube2 )\ - (Res = (((Cube1)->pData[0]) < ((Cube2)->pData[0]))) -#define Mvc_Cube2BitLess( Res, Cube1, Cube2 )\ - (Res = ((((Cube1)->pData[0]) < ((Cube2)->pData[0])) ||\ - ((((Cube1)->pData[0]) == ((Cube2)->pData[0])) && (((Cube1)->pData[1]) < ((Cube2)->pData[1]))))) -#define Mvc_CubeNBitLess( Res, Cube1, Cube2 )\ -{\ - int _i_; Res = 1;\ - for (_i_ = (Cube1)->iLast; _i_ >= 0; _i_--)\ - if (((Cube1)->pData[_i_]) >= ((Cube2)->pData[_i_]))\ - { Res = 0; break; }\ -} - -#define Mvc_Cube1BitMore( Res, Cube1, Cube2 )\ - (Res = (((Cube1)->pData[0]) > ((Cube2)->pData[0]))) -#define Mvc_Cube2BitMore( Res, Cube1, Cube2 )\ - (Res = ((((Cube1)->pData[0]) > ((Cube2)->pData[0])) ||\ - ((((Cube1)->pData[0]) == ((Cube2)->pData[0])) && (((Cube1)->pData[1]) > ((Cube2)->pData[1]))))) -#define Mvc_CubeNBitMore( Res, Cube1, Cube2 )\ -{\ - int _i_; Res = 1;\ - for (_i_ = (Cube1)->iLast; _i_ >= 0; _i_--)\ - if (((Cube1)->pData[_i_]) <= ((Cube2)->pData[_i_]))\ - { Res = 0; break; }\ -} - -#define Mvc_Cube1BitNotImpl( Res, Cube1, Cube2 )\ - (Res = (((Cube1)->pData[0]) & ~((Cube2)->pData[0]))) -#define Mvc_Cube2BitNotImpl( Res, Cube1, Cube2 )\ - (Res = ((((Cube1)->pData[0]) & ~((Cube2)->pData[0])) ||\ - (((Cube1)->pData[1]) & ~((Cube2)->pData[1])))) -#define Mvc_CubeNBitNotImpl( Res, Cube1, Cube2 )\ -{\ - int _i_; Res = 0;\ - for (_i_ = (Cube1)->iLast; _i_ >= 0; _i_--)\ - if (((Cube1)->pData[_i_]) & ~((Cube2)->pData[_i_]))\ - { Res = 1; break; }\ -} - -#define Mvc_Cube1BitDisjoint( Res, Cube1, Cube2 )\ - (Res = ((((Cube1)->pData[0]) & ((Cube2)->pData[0])) == 0 )) -#define Mvc_Cube2BitDisjoint( Res, Cube1, Cube2 )\ - (Res = (((((Cube1)->pData[0]) & ((Cube2)->pData[0])) == 0 ) &&\ - ((((Cube1)->pData[1]) & ((Cube2)->pData[1])) == 0 ))) -#define Mvc_CubeNBitDisjoint( Res, Cube1, Cube2 )\ -{\ - int _i_; Res = 1;\ - for (_i_ = (Cube1)->iLast; _i_ >= 0; _i_--)\ - if (((Cube1)->pData[_i_]) & ((Cube2)->pData[_i_]))\ - { Res = 0; break; }\ -} - -#define Mvc_Cube1BitEqualUnderMask( Res, Cube1, Cube2, Mask )\ - (Res = ((((Cube1)->pData[0]) & ((Mask)->pData[0])) == (((Cube2)->pData[0]) & ((Mask)->pData[0])))) -#define Mvc_Cube2BitEqualUnderMask( Res, Cube1, Cube2, Mask )\ - (Res = (((((Cube1)->pData[0]) & ((Mask)->pData[0])) == (((Cube2)->pData[0]) & ((Mask)->pData[0]))) &&\ - ((((Cube1)->pData[1]) & ((Mask)->pData[1])) == (((Cube2)->pData[1]) & ((Mask)->pData[1]))))) -#define Mvc_CubeNBitEqualUnderMask( Res, Cube1, Cube2, Mask )\ -{\ - int _i_; Res = 1;\ - for (_i_ = (Cube1)->iLast; _i_ >= 0; _i_--)\ - if ((((Cube1)->pData[_i_]) & ((Mask)->pData[_i_])) != (((Cube2)->pData[_i_]) & ((Mask)->pData[_i_])))\ - { Res = 0; break; }\ -} - -#define Mvc_Cube1BitEqualOutsideMask( Res, Cube1, Cube2, Mask )\ - (Res = ((((Cube1)->pData[0]) | ((Mask)->pData[0])) == (((Cube2)->pData[0]) | ((Mask)->pData[0])))) -#define Mvc_Cube2BitEqualOutsideMask( Res, Cube1, Cube2, Mask )\ - (Res = (((((Cube1)->pData[0]) | ((Mask)->pData[0])) == (((Cube2)->pData[0]) | ((Mask)->pData[0]))) &&\ - ((((Cube1)->pData[1]) | ((Mask)->pData[1])) == (((Cube2)->pData[1]) | ((Mask)->pData[1]))))) -#define Mvc_CubeNBitEqualOutsideMask( Res, Cube1, Cube2, Mask )\ -{\ - int _i_; Res = 1;\ - for (_i_ = (Cube1)->iLast; _i_ >= 0; _i_--)\ - if ((((Cube1)->pData[_i_]) | ((Mask)->pData[_i_])) != (((Cube2)->pData[_i_]) | ((Mask)->pData[_i_])))\ - { Res = 0; break; }\ -} - -#define Mvc_Cube1BitIntersectUnderMask( Res, Cube1, Cube2, Mask)\ - (Res = ((((Cube1)->pData[0]) & ((Cube2)->pData[0]) & ((Mask)->pData[0])) > 0)) -#define Mvc_Cube2BitIntersectUnderMask( Res, Cube1, Cube2, Mask)\ - (Res = (((((Cube1)->pData[0]) & ((Cube2)->pData[0]) & ((Mask)->pData[0])) > 0) ||\ - ((((Cube1)->pData[1]) & ((Cube2)->pData[1]) & ((Mask)->pData[1])) > 0))) -#define Mvc_CubeNBitIntersectUnderMask( Res, Cube1, Cube2, Mask)\ -{\ - int _i_; Res = 0;\ - for (_i_ = (Cube1)->iLast; _i_ >= 0; _i_--)\ - if (((Cube1)->pData[_i_]) & ((Cube2)->pData[_i_]) & ((Mask)->pData[_i_]))\ - { Res = 1; break; }\ -} - -#define Mvc_Cube1BitNotImplUnderMask( Res, Cube1, Cube2, Mask )\ - (Res = (((Mask)->pData[0]) & ((Cube1)->pData[0]) & ~((Cube2)->pData[0]))) -#define Mvc_Cube2BitNotImplUnderMask( Res, Cube1, Cube2, Mask )\ - (Res = ((((Mask)->pData[0]) & ((Cube1)->pData[0]) & ~((Cube2)->pData[0])) ||\ - (((Mask)->pData[1]) & ((Cube1)->pData[1]) & ~((Cube2)->pData[1])))) -#define Mvc_CubeNBitNotImplUnderMask( Res, Cube1, Cube2, Mask )\ -{\ - int _i_; Res = 0;\ - for (_i_ = (Cube1)->iLast; _i_ >= 0; _i_--)\ - if (((Mask)->pData[_i_]) & ((Cube1)->pData[_i_]) & ~((Cube2)->pData[_i_]))\ - { Res = 1; break; }\ -} - -// the following macros make no assumption about the cube's bitset size -#define Mvc_CubeBitClean( Cube )\ - if ( Mvc_Cube1Words(Cube) ) { Mvc_Cube1BitClean( Cube ); }\ - else if ( Mvc_Cube2Words(Cube) ) { Mvc_Cube2BitClean( Cube ); }\ - else { Mvc_CubeNBitClean( Cube ); } -#define Mvc_CubeBitFill( Cube )\ - if ( Mvc_Cube1Words(Cube) ) { Mvc_Cube1BitFill( Cube ); }\ - else if ( Mvc_Cube2Words(Cube) ) { Mvc_Cube2BitFill( Cube ); }\ - else { Mvc_CubeNBitFill( Cube ); } -#define Mvc_CubeBitNot( Cube )\ - if ( Mvc_Cube1Words(Cube) ) { Mvc_Cube1BitNot( Cube ); }\ - else if ( Mvc_Cube2Words(Cube) ) { Mvc_Cube2BitNot( Cube ); }\ - else { Mvc_CubeNBitNot( Cube ); } -#define Mvc_CubeBitCopy( Cube1, Cube2 )\ - if ( Mvc_Cube1Words(Cube1) ) { Mvc_Cube1BitCopy( Cube1, Cube2 ); }\ - else if ( Mvc_Cube2Words(Cube1) ){ Mvc_Cube2BitCopy( Cube1, Cube2 ); }\ - else { Mvc_CubeNBitCopy( Cube1, Cube2 ); } -#define Mvc_CubeBitOr( CubeR, Cube1, Cube2 )\ - if ( Mvc_Cube1Words(Cube1) ) { Mvc_Cube1BitOr( CubeR, Cube1, Cube2 ); }\ - else if ( Mvc_Cube2Words(Cube1) ){ Mvc_Cube2BitOr( CubeR, Cube1, Cube2 ); }\ - else { Mvc_CubeNBitOr( CubeR, Cube1, Cube2 ); } -#define Mvc_CubeBitExor( CubeR, Cube1, Cube2 )\ - if ( Mvc_Cube1Words(Cube1) ) { Mvc_Cube1BitExor( CubeR, Cube1, Cube2 ); }\ - else if ( Mvc_Cube2Words(Cube1) ){ Mvc_Cube2BitExor( CubeR, Cube1, Cube2 ); }\ - else { Mvc_CubeNBitExor( CubeR, Cube1, Cube2 ); } -#define Mvc_CubeBitAnd( CubeR, Cube1, Cube2 )\ - if ( Mvc_Cube1Words(Cube1) ) { Mvc_Cube1BitAnd( CubeR, Cube1, Cube2 ); }\ - else if ( Mvc_Cube2Words(Cube1) ){ Mvc_Cube2BitAnd( CubeR, Cube1, Cube2 ); }\ - else { Mvc_CubeNBitAnd( CubeR, Cube1, Cube2 ); } -#define Mvc_CubeBitSharp( CubeR, Cube1, Cube2 )\ - if ( Mvc_Cube1Words(Cube1) ) { Mvc_Cube1BitSharp( CubeR, Cube1, Cube2 ); }\ - else if ( Mvc_Cube2Words(Cube1) ){ Mvc_Cube2BitSharp( CubeR, Cube1, Cube2 ); }\ - else { Mvc_CubeNBitSharp( CubeR, Cube1, Cube2 ); } -#define Mvc_CubeBitEmpty( Res, Cube )\ - if ( Mvc_Cube1Words(Cube) ) { Mvc_Cube1BitEmpty( Res, Cube ); }\ - else if ( Mvc_Cube2Words(Cube) ) { Mvc_Cube2BitEmpty( Res, Cube ); }\ - else { Mvc_CubeNBitEmpty( Res, Cube ); } -#define Mvc_CubeBitEqual( Res, Cube1, Cube2 )\ - if ( Mvc_Cube1Words(Cube1) ) { Mvc_Cube1BitEqual( Res, Cube1, Cube2 ); }\ - else if ( Mvc_Cube2Words(Cube1) ){ Mvc_Cube2BitEqual( Res, Cube1, Cube2 ); }\ - else { Mvc_CubeNBitEqual( Res, Cube1, Cube2 ); } -#define Mvc_CubeBitLess( Res, Cube1, Cube2 )\ - if ( Mvc_Cube1Words(Cube1) ) { Mvc_Cube1BitLess( Res, Cube1, Cube2 ); }\ - else if ( Mvc_Cube2Words(Cube1) ){ Mvc_Cube2BitLess( Res, Cube1, Cube2 ); }\ - else { Mvc_CubeNBitLess( Res, Cube1, Cube2 ); } -#define Mvc_CubeBitMore( Res, Cube1, Cube2 )\ - if ( Mvc_Cube1Words(Cube1) ) { Mvc_Cube1BitMore( Res, Cube1, Cube2 ); }\ - else if ( Mvc_Cube2Words(Cube1) ){ Mvc_Cube2BitMore( Res, Cube1, Cube2 ); }\ - else { Mvc_CubeNBitMore( Res, Cube1, Cube2 ); } -#define Mvc_CubeBitNotImpl( Res, Cube1, Cube2 )\ - if ( Mvc_Cube1Words(Cube1) ) { Mvc_Cube1BitNotImpl( Res, Cube1, Cube2 ); }\ - else if ( Mvc_Cube2Words(Cube1) ){ Mvc_Cube2BitNotImpl( Res, Cube1, Cube2 ); }\ - else { Mvc_CubeNBitNotImpl( Res, Cube1, Cube2 ); } -#define Mvc_CubeBitDisjoint( Res, Cube1, Cube2 )\ - if ( Mvc_Cube1Words(Cube1) ) { Mvc_Cube1BitDisjoint( Res, Cube1, Cube2 ); }\ - else if ( Mvc_Cube2Words(Cube1) ){ Mvc_Cube2BitDisjoint( Res, Cube1, Cube2 ); }\ - else { Mvc_CubeNBitDisjoint( Res, Cube1, Cube2 ); } -#define Mvc_CubeBitEqualUnderMask( Res, Cube1, Cube2, Mask )\ - if ( Mvc_Cube1Words(Cube1) ) { Mvc_Cube1BitEqualUnderMask( Res, Cube1, Cube2, Mask ); }\ - else if ( Mvc_Cube2Words(Cube1) ){ Mvc_Cube2BitEqualUnderMask( Res, Cube1, Cube2, Mask ); }\ - else { Mvc_CubeNBitEqualUnderMask( Res, Cube1, Cube2, Mask ); } -#define Mvc_CubeBitEqualOutsideMask( Res, Cube1, Cube2, Mask )\ - if ( Mvc_Cube1Words(Cube1) ) { Mvc_Cube1BitEqualOutsideMask( Res, Cube1, Cube2, Mask ); }\ - else if ( Mvc_Cube2Words(Cube1) ){ Mvc_Cube2BitEqualOutsideMask( Res, Cube1, Cube2, Mask ); }\ - else { Mvc_CubeNBitEqualOutsideMask( Res, Cube1, Cube2, Mask ); } -#define Mvc_CubeBitIntersectUnderMask( Res, Cube1, Cube2, Mask )\ - if ( Mvc_Cube1Words(Cube1) ) { Mvc_Cube1BitIntersectUnderMask( Res, Cube1, Cube2, Mask ); }\ - else if ( Mvc_Cube2Words(Cube1) ){ Mvc_Cube2BitIntersectUnderMask( Res, Cube1, Cube2, Mask ); }\ - else { Mvc_CubeNBitIntersectUnderMask( Res, Cube1, Cube2, Mask ); } -#define Mvc_CubeBitNotImplUnderMask( Res, Cube1, Cube2, Mask )\ - if ( Mvc_Cube1Words(Cube1) ) { Mvc_Cube1BitNotImplUnderMask( Res, Cube1, Cube2, Mask ); }\ - else if ( Mvc_Cube2Words(Cube1) ){ Mvc_Cube2BitNotImplUnderMask( Res, Cube1, Cube2, Mask ); }\ - else { Mvc_CubeNBitNotImplUnderMask( Res, Cube1, Cube2, Mask ); } - - -// managing linked lists -#define Mvc_ListAddCubeHead( pList, pCube )\ - {\ - if ( pList->pHead == NULL )\ - {\ - Mvc_CubeSetNext( pCube, NULL );\ - pList->pHead = pCube;\ - pList->pTail = pCube;\ - }\ - else\ - {\ - Mvc_CubeSetNext( pCube, pList->pHead );\ - pList->pHead = pCube;\ - }\ - pList->nItems++;\ - } -#define Mvc_ListAddCubeTail( pList, pCube )\ - {\ - if ( pList->pHead == NULL )\ - pList->pHead = pCube;\ - else\ - Mvc_CubeSetNext( pList->pTail, pCube );\ - pList->pTail = pCube;\ - Mvc_CubeSetNext( pCube, NULL );\ - pList->nItems++;\ - } -#define Mvc_ListDeleteCube( pList, pPrev, pCube )\ -{\ - if ( pPrev == NULL )\ - pList->pHead = pCube->pNext;\ - else\ - pPrev->pNext = pCube->pNext;\ - if ( pList->pTail == pCube )\ - {\ - assert( pCube->pNext == NULL );\ - pList->pTail = pPrev;\ - }\ - pList->nItems--;\ -} - -// managing linked lists inside the cover -#define Mvc_CoverAddCubeHead( pCover, pCube )\ -{\ - Mvc_List_t * pList = &pCover->lCubes;\ - Mvc_ListAddCubeHead( pList, pCube );\ -} -#define Mvc_CoverAddCubeTail( pCover, pCube )\ -{\ - Mvc_List_t * pList = &pCover->lCubes;\ - Mvc_ListAddCubeTail( pList, pCube );\ -} -#define Mvc_CoverDeleteCube( pCover, pPrev, pCube )\ -{\ - Mvc_List_t * pList = &pCover->lCubes;\ - Mvc_ListDeleteCube( pList, pPrev, pCube );\ -} - - - - - - -// iterator through the cubes in the cube list -#define Mvc_ListForEachCube( List, Cube )\ - for ( Cube = List->pHead;\ - Cube;\ - Cube = Cube->pNext ) -#define Mvc_ListForEachCubeSafe( List, Cube, Cube2 )\ - for ( Cube = List->pHead, Cube2 = (Cube? Cube->pNext: NULL);\ - Cube;\ - Cube = Cube2, Cube2 = (Cube? Cube->pNext: NULL) ) - -// iterator through cubes in the cover -#define Mvc_CoverForEachCube( Cover, Cube )\ - for ( Cube = (Cover)->lCubes.pHead;\ - Cube;\ - Cube = Cube->pNext ) -#define Mvc_CoverForEachCubeWithIndex( Cover, Cube, Index )\ - for ( Index = 0, Cube = (Cover)->lCubes.pHead;\ - Cube;\ - Index++, Cube = Cube->pNext ) -#define Mvc_CoverForEachCubeSafe( Cover, Cube, Cube2 )\ - for ( Cube = (Cover)->lCubes.pHead, Cube2 = (Cube? Cube->pNext: NULL);\ - Cube;\ - Cube = Cube2, Cube2 = (Cube? Cube->pNext: NULL) ) - -// iterator which starts from the given cube -#define Mvc_CoverForEachCubeStart( Start, Cube )\ - for ( Cube = Start;\ - Cube;\ - Cube = Cube->pNext ) -#define Mvc_CoverForEachCubeStartSafe( Start, Cube, Cube2 )\ - for ( Cube = Start, Cube2 = (Cube? Cube->pNext: NULL);\ - Cube;\ - Cube = Cube2, Cube2 = (Cube? Cube->pNext: NULL) ) - - -// iterator through literals of the cube -#define Mvc_CubeForEachBit( Cover, Cube, iBit, Value )\ - for ( iBit = 0;\ - iBit < Cover->nBits && ((Value = Mvc_CubeBitValue(Cube,iBit))>=0);\ - iBit++ ) -// iterator through values of binary variables -#define Mvc_CubeForEachVarValue( Cover, Cube, iVar, Value )\ - for ( iVar = 0;\ - iVar < Cover->nBits/2 && (Value = Mvc_CubeVarValue(Cube,iVar));\ - iVar++ ) - - -// macros which work 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) -#define MEM_ALLOC( Manager, Type, Size ) ((Type *)malloc( (Size) * sizeof(Type) )) -#define MEM_FREE( Manager, Type, Size, Pointer ) if ( Pointer ) { free(Pointer); Pointer = NULL; } - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// -//////////////////////////////////////////////////////////////////////// - -/*=== mvcApi.c ====================================================*/ -extern int Mvc_CoverReadWordNum( Mvc_Cover_t * pCover ); -extern int Mvc_CoverReadBitNum( Mvc_Cover_t * pCover ); -extern int Mvc_CoverReadCubeNum( Mvc_Cover_t * pCover ); -extern Mvc_Cube_t * Mvc_CoverReadCubeHead( Mvc_Cover_t * pCover ); -extern Mvc_Cube_t * Mvc_CoverReadCubeTail( Mvc_Cover_t * pCover ); -extern Mvc_List_t * Mvc_CoverReadCubeList( Mvc_Cover_t * pCover ); -extern int Mvc_ListReadCubeNum( Mvc_List_t * pList ); -extern Mvc_Cube_t * Mvc_ListReadCubeHead( Mvc_List_t * pList ); -extern Mvc_Cube_t * Mvc_ListReadCubeTail( Mvc_List_t * pList ); -extern void Mvc_CoverSetCubeNum( Mvc_Cover_t * pCover,int nItems ); -extern void Mvc_CoverSetCubeHead( Mvc_Cover_t * pCover, Mvc_Cube_t * pCube ); -extern void Mvc_CoverSetCubeTail( Mvc_Cover_t * pCover, Mvc_Cube_t * pCube ); -extern void Mvc_CoverSetCubeList( Mvc_Cover_t * pCover, Mvc_List_t * pList ); -extern int Mvc_CoverIsEmpty( Mvc_Cover_t * pCover ); -extern int Mvc_CoverIsTautology( Mvc_Cover_t * pCover ); -extern int Mvc_CoverIsBinaryBuffer( Mvc_Cover_t * pCover ); -extern void Mvc_CoverMakeEmpty( Mvc_Cover_t * pCover ); -extern void Mvc_CoverMakeTautology( Mvc_Cover_t * pCover ); -extern Mvc_Cover_t * Mvc_CoverCreateEmpty( Mvc_Cover_t * pCover ); -extern Mvc_Cover_t * Mvc_CoverCreateTautology( Mvc_Cover_t * pCover ); -/*=== mvcCover.c ====================================================*/ -extern Mvc_Cover_t * Mvc_CoverAlloc( Mvc_Manager_t * pMem, int nBits ); -extern Mvc_Cover_t * Mvc_CoverCreateConst( Mvc_Manager_t * pMem, int nBits, int Phase ); -extern Mvc_Cover_t * Mvc_CoverClone( Mvc_Cover_t * pCover ); -extern Mvc_Cover_t * Mvc_CoverDup( Mvc_Cover_t * pCover ); -extern void Mvc_CoverFree( Mvc_Cover_t * pCover ); -extern void Mvc_CoverAllocateMask( Mvc_Cover_t * pCover ); -extern void Mvc_CoverAllocateArrayLits( Mvc_Cover_t * pCover ); -extern void Mvc_CoverAllocateArrayCubes( Mvc_Cover_t * pCover ); -extern void Mvc_CoverDeallocateMask( Mvc_Cover_t * pCover ); -extern void Mvc_CoverDeallocateArrayLits( Mvc_Cover_t * pCover ); -/*=== mvcCube.c ====================================================*/ -extern Mvc_Cube_t * Mvc_CubeAlloc( Mvc_Cover_t * pCover ); -extern Mvc_Cube_t * Mvc_CubeDup( Mvc_Cover_t * pCover, Mvc_Cube_t * pCube ); -extern void Mvc_CubeFree( Mvc_Cover_t * pCover, Mvc_Cube_t * pCube ); -extern void Mvc_CubeBitRemoveDcs( Mvc_Cube_t * pCube ); -/*=== mvcCompare.c ====================================================*/ -extern int Mvc_CubeCompareInt( Mvc_Cube_t * pC1, Mvc_Cube_t * pC2, Mvc_Cube_t * pMask ); -extern int Mvc_CubeCompareSizeAndInt( Mvc_Cube_t * pC1, Mvc_Cube_t * pC2, Mvc_Cube_t * pMask ); -extern int Mvc_CubeCompareIntUnderMask( Mvc_Cube_t * pC1, Mvc_Cube_t * pC2, Mvc_Cube_t * pMask ); -extern int Mvc_CubeCompareIntOutsideMask( Mvc_Cube_t * pC1, Mvc_Cube_t * pC2, Mvc_Cube_t * pMask ); -extern int Mvc_CubeCompareIntOutsideAndUnderMask( Mvc_Cube_t * pC1, Mvc_Cube_t * pC2, Mvc_Cube_t * pMask ); -/*=== mvcDd.c ====================================================*/ -/* -extern DdNode * Mvc_CoverConvertToBdd( DdManager * dd, Mvc_Cover_t * pCover ); -extern DdNode * Mvc_CoverConvertToZdd( DdManager * dd, Mvc_Cover_t * pCover ); -extern DdNode * Mvc_CoverConvertToZdd2( DdManager * dd, Mvc_Cover_t * pCover ); -extern DdNode * Mvc_CubeConvertToBdd( DdManager * dd, Mvc_Cube_t * pCube ); -extern DdNode * Mvc_CubeConvertToZdd( DdManager * dd, Mvc_Cube_t * pCube ); -extern DdNode * Mvc_CubeConvertToZdd2( DdManager * dd, Mvc_Cube_t * pCube ); -*/ -/*=== mvcDivisor.c ====================================================*/ -extern Mvc_Cover_t * Mvc_CoverDivisor( Mvc_Cover_t * pCover ); -/*=== mvcDivide.c ====================================================*/ -extern void Mvc_CoverDivide( Mvc_Cover_t * pCover, Mvc_Cover_t * pDiv, Mvc_Cover_t ** ppQuo, Mvc_Cover_t ** ppRem ); -extern void Mvc_CoverDivideInternal( Mvc_Cover_t * pCover, Mvc_Cover_t * pDiv, Mvc_Cover_t ** ppQuo, Mvc_Cover_t ** ppRem ); -extern void Mvc_CoverDivideByLiteral( Mvc_Cover_t * pCover, Mvc_Cover_t * pDiv, Mvc_Cover_t ** ppQuo, Mvc_Cover_t ** ppRem ); -extern void Mvc_CoverDivideByCube( Mvc_Cover_t * pCover, Mvc_Cover_t * pDiv, Mvc_Cover_t ** ppQuo, Mvc_Cover_t ** ppRem ); -extern void Mvc_CoverDivideByLiteralQuo( Mvc_Cover_t * pCover, int iLit ); -/*=== mvcList.c ====================================================*/ -// these functions are available as macros -extern void Mvc_ListAddCubeHead_( Mvc_List_t * pList, Mvc_Cube_t * pCube ); -extern void Mvc_ListAddCubeTail_( Mvc_List_t * pList, Mvc_Cube_t * pCube ); -extern void Mvc_ListDeleteCube_( Mvc_List_t * pList, Mvc_Cube_t * pPrev, Mvc_Cube_t * pCube ); -extern void Mvc_CoverAddCubeHead_( Mvc_Cover_t * pCover, Mvc_Cube_t * pCube ); -extern void Mvc_CoverAddCubeTail_( Mvc_Cover_t * pCover, Mvc_Cube_t * pCube ); -extern void Mvc_CoverDeleteCube_( Mvc_Cover_t * pCover, Mvc_Cube_t * pPrev, Mvc_Cube_t * pCube ); -extern void Mvc_CoverAddDupCubeHead( Mvc_Cover_t * pCover, Mvc_Cube_t * pCube ); -extern void Mvc_CoverAddDupCubeTail( Mvc_Cover_t * pCover, Mvc_Cube_t * pCube ); -// other functions -extern void Mvc_CoverAddLiteralsOfCube( Mvc_Cover_t * pCover, Mvc_Cube_t * pCube ); -extern void Mvc_CoverDeleteLiteralsOfCube( Mvc_Cover_t * pCover, Mvc_Cube_t * pCube ); -extern void Mvc_CoverList2Array( Mvc_Cover_t * pCover ); -extern void Mvc_CoverArray2List( Mvc_Cover_t * pCover ); -extern Mvc_Cube_t * Mvc_ListGetTailFromHead( Mvc_Cube_t * pHead ); -/*=== mvcPrint.c ====================================================*/ -extern void Mvc_CoverPrint( Mvc_Cover_t * pCover ); -extern void Mvc_CubePrint( Mvc_Cover_t * pCover, Mvc_Cube_t * pCube ); -extern void Mvc_CoverPrintMv( Mvc_Data_t * pData, Mvc_Cover_t * pCover ); -extern void Mvc_CubePrintMv( Mvc_Data_t * pData, Mvc_Cover_t * pCover, Mvc_Cube_t * pCube ); -/*=== mvcSort.c ====================================================*/ -extern void Mvc_CoverSort( Mvc_Cover_t * pCover, Mvc_Cube_t * pMask, int (* pCompareFunc)(Mvc_Cube_t *, Mvc_Cube_t *, Mvc_Cube_t *) ); -/*=== mvcUtils.c ====================================================*/ -extern void Mvc_CoverSupport( Mvc_Cover_t * pCover, Mvc_Cube_t * pSupp ); -extern int Mvc_CoverSupportSizeBinary( Mvc_Cover_t * pCover ); -extern int Mvc_CoverSupportVarBelongs( Mvc_Cover_t * pCover, int iVar ); -extern void Mvc_CoverCommonCube( Mvc_Cover_t * pCover, Mvc_Cube_t * pComCube ); -extern int Mvc_CoverIsCubeFree( Mvc_Cover_t * pCover ); -extern void Mvc_CoverMakeCubeFree( Mvc_Cover_t * pCover ); -extern Mvc_Cover_t * Mvc_CoverCommonCubeCover( Mvc_Cover_t * pCover ); -extern int Mvc_CoverCheckSuppContainment( Mvc_Cover_t * pCover1, Mvc_Cover_t * pCover2 ); -extern int Mvc_CoverSetCubeSizes( Mvc_Cover_t * pCover ); -extern int Mvc_CoverGetCubeSize( Mvc_Cube_t * pCube ); -extern int Mvc_CoverCountCubePairDiffs( Mvc_Cover_t * pCover, unsigned char pDiffs[] ); -extern Mvc_Cover_t * Mvc_CoverRemap( Mvc_Cover_t * pCover, int * pVarsRem, int nVarsRem ); -extern void Mvc_CoverInverse( Mvc_Cover_t * pCover ); -extern Mvc_Cover_t * Mvc_CoverRemoveDontCareLits( Mvc_Cover_t * pCover ); -extern Mvc_Cover_t * Mvc_CoverCofactor( Mvc_Cover_t * pCover, int iValue, int iValueOther ); -extern Mvc_Cover_t * Mvc_CoverFlipVar( Mvc_Cover_t * pCover, int iValue0, int iValue1 ); -extern Mvc_Cover_t * Mvc_CoverUnivQuantify( Mvc_Cover_t * p, int iValueA0, int iValueA1, int iValueB0, int iValueB1 ); -extern Mvc_Cover_t ** Mvc_CoverCofactors( Mvc_Data_t * pData, Mvc_Cover_t * pCover, int iVar ); -extern int Mvr_CoverCountLitsWithValue( Mvc_Data_t * pData, Mvc_Cover_t * pCover, int iVar, int iValue ); -//extern Mvc_Cover_t * Mvc_CoverCreateExpanded( Mvc_Cover_t * pCover, Vm_VarMap_t * pVmNew ); -extern Mvc_Cover_t * Mvc_CoverTranspose( Mvc_Cover_t * pCover ); -extern int Mvc_UtilsCheckUnusedZeros( Mvc_Cover_t * pCover ); -/*=== mvcLits.c ====================================================*/ -extern int Mvc_CoverAnyLiteral( Mvc_Cover_t * pCover, Mvc_Cube_t * pMask ); -extern int Mvc_CoverBestLiteral( Mvc_Cover_t * pCover, Mvc_Cube_t * pMask ); -extern int Mvc_CoverWorstLiteral( Mvc_Cover_t * pCover, Mvc_Cube_t * pMask ); -extern Mvc_Cover_t * Mvc_CoverBestLiteralCover( Mvc_Cover_t * pCover, Mvc_Cover_t * pSimple ); -extern int Mvc_CoverFirstCubeFirstLit( Mvc_Cover_t * pCover ); -extern int Mvc_CoverCountLiterals( Mvc_Cover_t * pCover ); -extern int Mvc_CoverIsOneLiteral( Mvc_Cover_t * pCover ); -/*=== mvcOpAlg.c ====================================================*/ -extern Mvc_Cover_t * Mvc_CoverAlgebraicMultiply( Mvc_Cover_t * pCover1, Mvc_Cover_t * pCover2 ); -extern Mvc_Cover_t * Mvc_CoverAlgebraicSubtract( Mvc_Cover_t * pCover1, Mvc_Cover_t * pCover2 ); -extern int Mvc_CoverAlgebraicEqual( Mvc_Cover_t * pCover1, Mvc_Cover_t * pCover2 ); -/*=== mvcOpBool.c ====================================================*/ -extern Mvc_Cover_t * Mvc_CoverBooleanOr( Mvc_Cover_t * pCover1, Mvc_Cover_t * pCover2 ); -extern Mvc_Cover_t * Mvc_CoverBooleanAnd( Mvc_Data_t * p, Mvc_Cover_t * pCover1, Mvc_Cover_t * pCover2 ); -extern int Mvc_CoverBooleanEqual( Mvc_Data_t * p, Mvc_Cover_t * pCover1, Mvc_Cover_t * pCover2 ); - -/*=== mvcContain.c ====================================================*/ -extern int Mvc_CoverContain( Mvc_Cover_t * pCover ); -/*=== mvcTau.c ====================================================*/ -extern int Mvc_CoverTautology( Mvc_Data_t * p, Mvc_Cover_t * pCover ); -/*=== mvcCompl.c ====================================================*/ -extern Mvc_Cover_t * Mvc_CoverComplement( Mvc_Data_t * p, Mvc_Cover_t * pCover ); -/*=== mvcSharp.c ====================================================*/ -extern Mvc_Cover_t * Mvc_CoverSharp( Mvc_Data_t * p, Mvc_Cover_t * pA, Mvc_Cover_t * pB ); -extern int Mvc_CoverDist0Cubes( Mvc_Data_t * pData, Mvc_Cube_t * pA, Mvc_Cube_t * pB ); -extern void Mvc_CoverIntersectCubes( Mvc_Data_t * pData, Mvc_Cover_t * pC1, Mvc_Cover_t * pC2 ); -extern int Mvc_CoverIsIntersecting( Mvc_Data_t * pData, Mvc_Cover_t * pC1, Mvc_Cover_t * pC2 ); -extern void Mvc_CoverAppendCubes( Mvc_Cover_t * pC1, Mvc_Cover_t * pC2 ); -extern void Mvc_CoverCopyAndAppendCubes( Mvc_Cover_t * pC1, Mvc_Cover_t * pC2 ); -extern void Mvc_CoverRemoveCubes( Mvc_Cover_t * pC ); - -/*=== mvcReshape.c ====================================================*/ -extern void Mvc_CoverMinimizeByReshape( Mvc_Data_t * pData, Mvc_Cover_t * pCover ); - -/*=== mvcMerge.c ====================================================*/ -extern void Mvc_CoverDist1Merge( Mvc_Data_t * p, Mvc_Cover_t * pCover ); - -/*=== mvcData.c ====================================================*/ -//extern Mvc_Data_t * Mvc_CoverDataAlloc( Vm_VarMap_t * pVm, Mvc_Cover_t * pCover ); -//extern void Mvc_CoverDataFree( Mvc_Data_t * p, Mvc_Cover_t * pCover ); - -/*=== mvcMan.c ====================================================*/ -extern void Mvc_ManagerFree( Mvc_Manager_t * p ); -extern Mvc_Manager_t * Mvc_ManagerStart(); -extern Mvc_Manager_t * Mvc_ManagerAllocCover(); -extern Mvc_Manager_t * Mvc_ManagerAllocCube( int nWords ); -extern Mvc_Manager_t * Mvc_ManagerFreeCover( Mvc_Cover_t * pCover ); -extern Mvc_Manager_t * Mvc_ManagerFreeCube( Mvc_Cover_t * pCube, int nWords ); - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - -#endif - diff --git a/src/sop/mvc/mvcApi.c b/src/sop/mvc/mvcApi.c deleted file mode 100644 index 1f51a235..00000000 --- a/src/sop/mvc/mvcApi.c +++ /dev/null @@ -1,233 +0,0 @@ -/**CFile**************************************************************** - - FileName [mvcApi.c] - - PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] - - Synopsis [] - - Author [MVSIS Group] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - February 1, 2003.] - - Revision [$Id: mvcApi.c,v 1.4 2003/04/03 06:31:48 alanmi Exp $] - -***********************************************************************/ - -#include "mvc.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Mvc_CoverReadWordNum( Mvc_Cover_t * pCover ) { return pCover->nWords; } -int Mvc_CoverReadBitNum( Mvc_Cover_t * pCover ) { return pCover->nBits; } -int Mvc_CoverReadCubeNum( Mvc_Cover_t * pCover ) { return pCover->lCubes.nItems; } -Mvc_Cube_t * Mvc_CoverReadCubeHead( Mvc_Cover_t * pCover ) { return pCover->lCubes.pHead; } -Mvc_Cube_t * Mvc_CoverReadCubeTail( Mvc_Cover_t * pCover ) { return pCover->lCubes.pTail; } -Mvc_List_t * Mvc_CoverReadCubeList( Mvc_Cover_t * pCover ) { return &pCover->lCubes; } - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Mvc_ListReadCubeNum( Mvc_List_t * pList ) { return pList->nItems; } -Mvc_Cube_t * Mvc_ListReadCubeHead( Mvc_List_t * pList ) { return pList->pHead; } -Mvc_Cube_t * Mvc_ListReadCubeTail( Mvc_List_t * pList ) { return pList->pTail; } - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Mvc_CoverSetCubeNum( Mvc_Cover_t * pCover,int nItems ) { pCover->lCubes.nItems = nItems; } -void Mvc_CoverSetCubeHead( Mvc_Cover_t * pCover, Mvc_Cube_t * pCube ) { pCover->lCubes.pHead = pCube; } -void Mvc_CoverSetCubeTail( Mvc_Cover_t * pCover, Mvc_Cube_t * pCube ) { pCover->lCubes.pTail = pCube; } -void Mvc_CoverSetCubeList( Mvc_Cover_t * pCover, Mvc_List_t * pList ) { pCover->lCubes = *pList; } - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Mvc_CoverIsEmpty( Mvc_Cover_t * pCover ) -{ - return Mvc_CoverReadCubeNum(pCover) == 0; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Mvc_CoverIsTautology( Mvc_Cover_t * pCover ) -{ - Mvc_Cube_t * pCube; - int iBit, Value; - - if ( Mvc_CoverReadCubeNum(pCover) != 1 ) - return 0; - - pCube = Mvc_CoverReadCubeHead( pCover ); - Mvc_CubeForEachBit( pCover, pCube, iBit, Value ) - if ( Value == 0 ) - return 0; - return 1; -} - -/**Function************************************************************* - - Synopsis [Returns 1 if the cover is a binary buffer.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Mvc_CoverIsBinaryBuffer( Mvc_Cover_t * pCover ) -{ - Mvc_Cube_t * pCube; - if ( pCover->nBits != 2 ) - return 0; - if ( Mvc_CoverReadCubeNum(pCover) != 1 ) - return 0; - pCube = pCover->lCubes.pHead; - if ( Mvc_CubeBitValue(pCube, 0) == 0 && Mvc_CubeBitValue(pCube, 1) == 1 ) - return 1; - return 0; -} - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Mvc_CoverMakeEmpty( Mvc_Cover_t * pCover ) -{ - Mvc_Cube_t * pCube, * pCube2; - Mvc_CoverForEachCubeSafe( pCover, pCube, pCube2 ) - Mvc_CubeFree( pCover, pCube ); - pCover->lCubes.nItems = 0; - pCover->lCubes.pHead = NULL; - pCover->lCubes.pTail = NULL; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Mvc_CoverMakeTautology( Mvc_Cover_t * pCover ) -{ - Mvc_Cube_t * pCubeNew; - Mvc_CoverMakeEmpty( pCover ); - pCubeNew = Mvc_CubeAlloc( pCover ); - Mvc_CubeBitFill( pCubeNew ); - Mvc_CoverAddCubeTail( pCover, pCubeNew ); -} - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Mvc_Cover_t * Mvc_CoverCreateEmpty( Mvc_Cover_t * pCover ) -{ - Mvc_Cover_t * pCoverNew; - pCoverNew = Mvc_CoverAlloc( pCover->pMem, pCover->nBits ); - return pCoverNew; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Mvc_Cover_t * Mvc_CoverCreateTautology( Mvc_Cover_t * pCover ) -{ - Mvc_Cube_t * pCubeNew; - Mvc_Cover_t * pCoverNew; - pCoverNew = Mvc_CoverAlloc( pCover->pMem, pCover->nBits ); - pCubeNew = Mvc_CubeAlloc( pCoverNew ); - Mvc_CubeBitFill( pCubeNew ); - Mvc_CoverAddCubeTail( pCoverNew, pCubeNew ); - return pCoverNew; -} - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/sop/mvc/mvcCompare.c b/src/sop/mvc/mvcCompare.c deleted file mode 100644 index c7999d40..00000000 --- a/src/sop/mvc/mvcCompare.c +++ /dev/null @@ -1,369 +0,0 @@ -/**CFile**************************************************************** - - FileName [mvcCompare.c] - - PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] - - Synopsis [Various cube comparison functions.] - - Author [MVSIS Group] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - February 1, 2003.] - - Revision [$Id: mvcCompare.c,v 1.5 2003/04/03 23:25:41 alanmi Exp $] - -***********************************************************************/ - -#include "mvc.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Compares two cubes according to their integer value.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Mvc_CubeCompareInt( Mvc_Cube_t * pC1, Mvc_Cube_t * pC2, Mvc_Cube_t * pMask ) -{ - if ( Mvc_Cube1Words(pC1) ) - { - if ( pC1->pData[0] < pC2->pData[0] ) - return -1; - if ( pC1->pData[0] > pC2->pData[0] ) - return 1; - return 0; - } - else if ( Mvc_Cube2Words(pC1) ) - { - if ( pC1->pData[1] < pC2->pData[1] ) - return -1; - if ( pC1->pData[1] > pC2->pData[1] ) - return 1; - if ( pC1->pData[0] < pC2->pData[0] ) - return -1; - if ( pC1->pData[0] > pC2->pData[0] ) - return 1; - return 0; - } - else - { - int i = Mvc_CubeReadLast(pC1); - for(; i >= 0; i--) - { - if ( pC1->pData[i] < pC2->pData[i] ) - return -1; - if ( pC1->pData[i] > pC2->pData[i] ) - return 1; - } - return 0; - } -} - - -/**Function************************************************************* - - Synopsis [Compares the cubes (1) by size, (2) by integer value.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Mvc_CubeCompareSizeAndInt( Mvc_Cube_t * pC1, Mvc_Cube_t * pC2, Mvc_Cube_t * pMask ) -{ - // compare the cubes by size - if ( Mvc_CubeReadSize( pC1 ) < Mvc_CubeReadSize( pC2 ) ) - return 1; - if ( Mvc_CubeReadSize( pC1 ) > Mvc_CubeReadSize( pC2 ) ) - return -1; - // the cubes have the same size - - // compare the cubes as integers - if ( Mvc_Cube1Words( pC1 ) ) - { - if ( pC1->pData[0] < pC2->pData[0] ) - return -1; - if ( pC1->pData[0] > pC2->pData[0] ) - return 1; - return 0; - } - else if ( Mvc_Cube2Words( pC1 ) ) - { - if ( pC1->pData[1] < pC2->pData[1] ) - return -1; - if ( pC1->pData[1] > pC2->pData[1] ) - return 1; - if ( pC1->pData[0] < pC2->pData[0] ) - return -1; - if ( pC1->pData[0] > pC2->pData[0] ) - return 1; - return 0; - } - else - { - int i = Mvc_CubeReadLast( pC1 ); - for(; i >= 0; i--) - { - if ( pC1->pData[i] < pC2->pData[i] ) - return -1; - if ( pC1->pData[i] > pC2->pData[i] ) - return 1; - } - return 0; - } -} - -/**Function************************************************************* - - Synopsis [Compares two cubes under the mask.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Mvc_CubeCompareIntUnderMask( Mvc_Cube_t * pC1, Mvc_Cube_t * pC2, Mvc_Cube_t * pMask ) -{ - unsigned uBits1, uBits2; - - // compare the cubes under the mask - if ( Mvc_Cube1Words(pC1) ) - { - uBits1 = pC1->pData[0] & pMask->pData[0]; - uBits2 = pC2->pData[0] & pMask->pData[0]; - if ( uBits1 < uBits2 ) - return -1; - if ( uBits1 > uBits2 ) - return 1; - // cubes are equal - return 0; - } - else if ( Mvc_Cube2Words(pC1) ) - { - uBits1 = pC1->pData[1] & pMask->pData[1]; - uBits2 = pC2->pData[1] & pMask->pData[1]; - if ( uBits1 < uBits2 ) - return -1; - if ( uBits1 > uBits2 ) - return 1; - uBits1 = pC1->pData[0] & pMask->pData[0]; - uBits2 = pC2->pData[0] & pMask->pData[0]; - if ( uBits1 < uBits2 ) - return -1; - if ( uBits1 > uBits2 ) - return 1; - return 0; - } - else - { - int i = Mvc_CubeReadLast(pC1); - for(; i >= 0; i--) - { - uBits1 = pC1->pData[i] & pMask->pData[i]; - uBits2 = pC2->pData[i] & pMask->pData[i]; - if ( uBits1 < uBits2 ) - return -1; - if ( uBits1 > uBits2 ) - return 1; - } - return 0; - } -} - -/**Function************************************************************* - - Synopsis [Compares two cubes under the mask.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Mvc_CubeCompareIntOutsideMask( Mvc_Cube_t * pC1, Mvc_Cube_t * pC2, Mvc_Cube_t * pMask ) -{ - unsigned uBits1, uBits2; - - // compare the cubes under the mask - if ( Mvc_Cube1Words(pC1) ) - { - uBits1 = pC1->pData[0] | pMask->pData[0]; - uBits2 = pC2->pData[0] | pMask->pData[0]; - if ( uBits1 < uBits2 ) - return -1; - if ( uBits1 > uBits2 ) - return 1; - // cubes are equal - return 0; - } - else if ( Mvc_Cube2Words(pC1) ) - { - uBits1 = pC1->pData[1] | pMask->pData[1]; - uBits2 = pC2->pData[1] | pMask->pData[1]; - if ( uBits1 < uBits2 ) - return -1; - if ( uBits1 > uBits2 ) - return 1; - uBits1 = pC1->pData[0] | pMask->pData[0]; - uBits2 = pC2->pData[0] | pMask->pData[0]; - if ( uBits1 < uBits2 ) - return -1; - if ( uBits1 > uBits2 ) - return 1; - return 0; - } - else - { - int i = Mvc_CubeReadLast(pC1); - for(; i >= 0; i--) - { - uBits1 = pC1->pData[i] | pMask->pData[i]; - uBits2 = pC2->pData[i] | pMask->pData[i]; - if ( uBits1 < uBits2 ) - return -1; - if ( uBits1 > uBits2 ) - return 1; - } - return 0; - } -} - - -/**Function************************************************************* - - Synopsis [Compares the cubes (1) outside the mask, (2) under the mask.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Mvc_CubeCompareIntOutsideAndUnderMask( Mvc_Cube_t * pC1, Mvc_Cube_t * pC2, Mvc_Cube_t * pMask ) -{ - unsigned uBits1, uBits2; - - if ( Mvc_Cube1Words(pC1) ) - { - // compare the cubes outside the mask - uBits1 = pC1->pData[0] & ~(pMask->pData[0]); - uBits2 = pC2->pData[0] & ~(pMask->pData[0]); - if ( uBits1 < uBits2 ) - return -1; - if ( uBits1 > uBits2 ) - return 1; - - // compare the cubes under the mask - uBits1 = pC1->pData[0] & pMask->pData[0]; - uBits2 = pC2->pData[0] & pMask->pData[0]; - if ( uBits1 < uBits2 ) - return -1; - if ( uBits1 > uBits2 ) - return 1; - // cubes are equal - // should never happen - assert( 0 ); - return 0; - } - else if ( Mvc_Cube2Words(pC1) ) - { - // compare the cubes outside the mask - uBits1 = pC1->pData[1] & ~(pMask->pData[1]); - uBits2 = pC2->pData[1] & ~(pMask->pData[1]); - if ( uBits1 < uBits2 ) - return -1; - if ( uBits1 > uBits2 ) - return 1; - - uBits1 = pC1->pData[0] & ~(pMask->pData[0]); - uBits2 = pC2->pData[0] & ~(pMask->pData[0]); - if ( uBits1 < uBits2 ) - return -1; - if ( uBits1 > uBits2 ) - return 1; - - // compare the cubes under the mask - uBits1 = pC1->pData[1] & pMask->pData[1]; - uBits2 = pC2->pData[1] & pMask->pData[1]; - if ( uBits1 < uBits2 ) - return -1; - if ( uBits1 > uBits2 ) - return 1; - - uBits1 = pC1->pData[0] & pMask->pData[0]; - uBits2 = pC2->pData[0] & pMask->pData[0]; - if ( uBits1 < uBits2 ) - return -1; - if ( uBits1 > uBits2 ) - return 1; - - // cubes are equal - // should never happen - assert( 0 ); - return 0; - } - else - { - int i; - - // compare the cubes outside the mask - for( i = Mvc_CubeReadLast(pC1); i >= 0; i-- ) - { - uBits1 = pC1->pData[i] & ~(pMask->pData[i]); - uBits2 = pC2->pData[i] & ~(pMask->pData[i]); - if ( uBits1 < uBits2 ) - return -1; - if ( uBits1 > uBits2 ) - return 1; - } - // compare the cubes under the mask - for( i = Mvc_CubeReadLast(pC1); i >= 0; i-- ) - { - uBits1 = pC1->pData[i] & pMask->pData[i]; - uBits2 = pC2->pData[i] & pMask->pData[i]; - if ( uBits1 < uBits2 ) - return -1; - if ( uBits1 > uBits2 ) - return 1; - } -/* - { - Mvc_Cover_t * pCover; - pCover = Mvc_CoverAlloc( NULL, 96 ); - Mvc_CubePrint( pCover, pC1 ); - Mvc_CubePrint( pCover, pC2 ); - Mvc_CubePrint( pCover, pMask ); - } -*/ - // cubes are equal - // should never happen - assert( 0 ); - return 0; - } -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/sop/mvc/mvcContain.c b/src/sop/mvc/mvcContain.c deleted file mode 100644 index 37b933b8..00000000 --- a/src/sop/mvc/mvcContain.c +++ /dev/null @@ -1,173 +0,0 @@ -/**CFile**************************************************************** - - FileName [mvcContain.c] - - PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] - - Synopsis [Making the cover single-cube containment free.] - - Author [MVSIS Group] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - February 1, 2003.] - - Revision [$Id: mvcContain.c,v 1.4 2003/04/03 23:25:42 alanmi Exp $] - -***********************************************************************/ - -#include "mvc.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static void Mvc_CoverRemoveDuplicates( Mvc_Cover_t * pCover ); -static void Mvc_CoverRemoveContained( Mvc_Cover_t * pCover ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// -//////////////////////////////////////////////////////////////////////// - - -/**Function************************************************************* - - Synopsis [Removes the contained cubes.] - - Description [Returns 1 if the cover has been changed.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Mvc_CoverContain( Mvc_Cover_t * pCover ) -{ - int nCubes; - nCubes = Mvc_CoverReadCubeNum( pCover ); - if ( nCubes < 2 ) - return 0; - Mvc_CoverSetCubeSizes(pCover); - Mvc_CoverSort( pCover, NULL, Mvc_CubeCompareSizeAndInt ); - Mvc_CoverRemoveDuplicates( pCover ); - if ( nCubes > 1 ) - Mvc_CoverRemoveContained( pCover ); - return (nCubes != Mvc_CoverReadCubeNum(pCover)); -} - -/**Function************************************************************* - - Synopsis [Removes adjacent duplicated cubes from the cube list.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Mvc_CoverRemoveDuplicates( Mvc_Cover_t * pCover ) -{ - Mvc_Cube_t * pPrev, * pCube, * pCube2; - int fEqual; - - // set the first cube of the cover - pPrev = Mvc_CoverReadCubeHead(pCover); - // go through all the cubes after this one - Mvc_CoverForEachCubeStartSafe( Mvc_CubeReadNext(pPrev), pCube, pCube2 ) - { - // compare the current cube with the prev cube - Mvc_CubeBitEqual( fEqual, pPrev, pCube ); - if ( fEqual ) - { // they are equal - remove the current cube - Mvc_CoverDeleteCube( pCover, pPrev, pCube ); - Mvc_CubeFree( pCover, pCube ); - // don't change the previous cube cube - } - else - { // they are not equal - update the previous cube - pPrev = pCube; - } - } -} - -/**Function************************************************************* - - Synopsis [Removes contained cubes from the sorted cube list.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Mvc_CoverRemoveContained( Mvc_Cover_t * pCover ) -{ - Mvc_Cube_t * pCubeBeg, * pCubeEnd, * pCubeLarge; - Mvc_Cube_t * pCube, * pCube2, * pPrev; - unsigned sizeCur; - int Result; - - // since the cubes are sorted by size, it is sufficient - // to compare each cube with other cubes that have larger sizes - // if the given cube implies a larger cube, the larger cube is removed - pCubeBeg = Mvc_CoverReadCubeHead(pCover); - do - { - // get the current cube size - sizeCur = Mvc_CubeReadSize(pCubeBeg); - - // initialize the end of the given size group - pCubeEnd = pCubeBeg; - // find the beginning of the next size group - Mvc_CoverForEachCubeStart( Mvc_CubeReadNext(pCubeBeg), pCube ) - { - if ( sizeCur == Mvc_CubeReadSize(pCube) ) - pCubeEnd = pCube; - else // pCube is the first cube in the new size group - break; - } - // if we could not find the next size group - // the containment check is finished - if ( pCube == NULL ) - break; - // otherwise, pCubeBeg/pCubeEnd are the first/last cubes of the group - - // go through all the cubes between pCubeBeg and pCubeEnd, inclusive, - // and for each of them, try removing cubes after pCubeEnd - Mvc_CoverForEachCubeStart( pCubeBeg, pCubeLarge ) - { - pPrev = pCubeEnd; - Mvc_CoverForEachCubeStartSafe( Mvc_CubeReadNext(pCubeEnd), pCube, pCube2 ) - { - // check containment - Mvc_CubeBitNotImpl( Result, pCube, pCubeLarge ); - if ( !Result ) - { // pCubeLarge implies pCube - remove pCube - Mvc_CoverDeleteCube( pCover, pPrev, pCube ); - Mvc_CubeFree( pCover, pCube ); - // don't update the previous cube - } - else - { // update the previous cube - pPrev = pCube; - } - } - // quit, if the main cube was the last one of this size - if ( pCubeLarge == pCubeEnd ) - break; - } - - // set the beginning of the next group - pCubeBeg = Mvc_CubeReadNext(pCubeEnd); - } - while ( pCubeBeg ); -} - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/sop/mvc/mvcCover.c b/src/sop/mvc/mvcCover.c deleted file mode 100644 index bd9c4412..00000000 --- a/src/sop/mvc/mvcCover.c +++ /dev/null @@ -1,251 +0,0 @@ -/**CFile**************************************************************** - - FileName [mvcCover.c] - - PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] - - Synopsis [Basic procedures to manipulate unate cube covers.] - - Author [MVSIS Group] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - February 1, 2003.] - - Revision [$Id: mvcCover.c,v 1.5 2003/04/09 18:02:05 alanmi Exp $] - -***********************************************************************/ - -#include "mvc.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Mvc_Cover_t * Mvc_CoverAlloc( Mvc_Manager_t * pMem, int nBits ) -{ - Mvc_Cover_t * p; - int nBitsInUnsigned; - - nBitsInUnsigned = 8 * sizeof(Mvc_CubeWord_t); -#ifdef USE_SYSTEM_MEMORY_MANAGEMENT - p = (Mvc_Cover_t *)malloc( sizeof(Mvc_Cover_t) ); -#else - p = (Mvc_Cover_t *)Extra_MmFixedEntryFetch( pMem->pManC ); -#endif - p->pMem = pMem; - p->nBits = nBits; - p->nWords = nBits / nBitsInUnsigned + (int)(nBits % nBitsInUnsigned > 0); - p->nUnused = p->nWords * nBitsInUnsigned - p->nBits; - p->lCubes.nItems = 0; - p->lCubes.pHead = NULL; - p->lCubes.pTail = NULL; - p->nCubesAlloc = 0; - p->pCubes = NULL; - p->pMask = NULL; - p->pLits = NULL; - return p; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Mvc_Cover_t * Mvc_CoverClone( Mvc_Cover_t * p ) -{ - Mvc_Cover_t * pCover; -#ifdef USE_SYSTEM_MEMORY_MANAGEMENT - pCover = (Mvc_Cover_t *)malloc( sizeof(Mvc_Cover_t) ); -#else - pCover = (Mvc_Cover_t *)Extra_MmFixedEntryFetch( p->pMem->pManC ); -#endif - pCover->pMem = p->pMem; - pCover->nBits = p->nBits; - pCover->nWords = p->nWords; - pCover->nUnused = p->nUnused; - pCover->lCubes.nItems = 0; - pCover->lCubes.pHead = NULL; - pCover->lCubes.pTail = NULL; - pCover->nCubesAlloc = 0; - pCover->pCubes = NULL; - pCover->pMask = NULL; - pCover->pLits = NULL; - return pCover; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Mvc_Cover_t * Mvc_CoverDup( Mvc_Cover_t * p ) -{ - Mvc_Cover_t * pCover; - Mvc_Cube_t * pCube, * pCubeCopy; - // clone the cover - pCover = Mvc_CoverClone( p ); - // copy the cube list - Mvc_CoverForEachCube( p, pCube ) - { - pCubeCopy = Mvc_CubeDup( p, pCube ); - Mvc_CoverAddCubeTail( pCover, pCubeCopy ); - } - return pCover; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Mvc_CoverFree( Mvc_Cover_t * p ) -{ - Mvc_Cube_t * pCube, * pCube2; - // recycle cube list - Mvc_CoverForEachCubeSafe( p, pCube, pCube2 ) - Mvc_CubeFree( p, pCube ); - // recycle other pointers - Mvc_CubeFree( p, p->pMask ); - MEM_FREE( p->pMem, Mvc_Cube_t *, p->nCubesAlloc, p->pCubes ); - MEM_FREE( p->pMem, int, p->nBits, p->pLits ); - -#ifdef USE_SYSTEM_MEMORY_MANAGEMENT - free( p ); -#else - Extra_MmFixedEntryRecycle( p->pMem->pManC, (char *)p ); -#endif -} - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Mvc_CoverAllocateMask( Mvc_Cover_t * pCover ) -{ - if ( pCover->pMask == NULL ) - pCover->pMask = Mvc_CubeAlloc( pCover ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Mvc_CoverAllocateArrayLits( Mvc_Cover_t * pCover ) -{ - if ( pCover->pLits == NULL ) - pCover->pLits = MEM_ALLOC( pCover->pMem, int, pCover->nBits ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Mvc_CoverAllocateArrayCubes( Mvc_Cover_t * pCover ) -{ - if ( pCover->nCubesAlloc < pCover->lCubes.nItems ) - { - if ( pCover->nCubesAlloc > 0 ) - MEM_FREE( pCover->pMem, Mvc_Cube_t *, pCover->nCubesAlloc, pCover->pCubes ); - pCover->nCubesAlloc = pCover->lCubes.nItems; - pCover->pCubes = MEM_ALLOC( pCover->pMem, Mvc_Cube_t *, pCover->nCubesAlloc ); - } -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Mvc_CoverDeallocateMask( Mvc_Cover_t * pCover ) -{ - Mvc_CubeFree( pCover, pCover->pMask ); - pCover->pMask = NULL; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Mvc_CoverDeallocateArrayLits( Mvc_Cover_t * pCover ) -{ - if ( pCover->pLits ) - { - MEM_FREE( pCover->pMem, int, pCover->nBits, pCover->pLits ); - pCover->pLits = NULL; - } -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/sop/mvc/mvcCube.c b/src/sop/mvc/mvcCube.c deleted file mode 100644 index d02fa270..00000000 --- a/src/sop/mvc/mvcCube.c +++ /dev/null @@ -1,175 +0,0 @@ -/**CFile**************************************************************** - - FileName [mvcCube.c] - - PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] - - Synopsis [Manipulating unate cubes.] - - Author [MVSIS Group] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - February 1, 2003.] - - Revision [$Id: mvcCube.c,v 1.4 2003/04/03 06:31:49 alanmi Exp $] - -***********************************************************************/ - -#include "mvc.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Mvc_Cube_t * Mvc_CubeAlloc( Mvc_Cover_t * pCover ) -{ - Mvc_Cube_t * pCube; - - assert( pCover->nWords >= 0 ); - // allocate the cube -#ifdef USE_SYSTEM_MEMORY_MANAGEMENT - if ( pCover->nWords == 0 ) - pCube = (Mvc_Cube_t *)malloc( sizeof(Mvc_Cube_t) ); - else - pCube = (Mvc_Cube_t *)malloc( sizeof(Mvc_Cube_t) + sizeof(Mvc_CubeWord_t) * (pCover->nWords - 1) ); -#else - switch( pCover->nWords ) - { - case 0: - case 1: - pCube = (Mvc_Cube_t *)Extra_MmFixedEntryFetch( pCover->pMem->pMan1 ); - break; - case 2: - pCube = (Mvc_Cube_t *)Extra_MmFixedEntryFetch( pCover->pMem->pMan2 ); - break; - case 3: - case 4: - pCube = (Mvc_Cube_t *)Extra_MmFixedEntryFetch( pCover->pMem->pMan4 ); - break; - default: - pCube = (Mvc_Cube_t *)malloc( sizeof(Mvc_Cube_t) + sizeof(Mvc_CubeWord_t) * (pCover->nWords - 1) ); - break; - } -#endif - // set the parameters charactering this cube - if ( pCover->nWords == 0 ) - pCube->iLast = pCover->nWords; - else - pCube->iLast = pCover->nWords - 1; - pCube->nUnused = pCover->nUnused; - return pCube; -} - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Mvc_Cube_t * Mvc_CubeDup( Mvc_Cover_t * pCover, Mvc_Cube_t * pCube ) -{ - Mvc_Cube_t * pCubeCopy; - pCubeCopy = Mvc_CubeAlloc( pCover ); - Mvc_CubeBitCopy( pCubeCopy, pCube ); - return pCubeCopy; -} - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Mvc_CubeFree( Mvc_Cover_t * pCover, Mvc_Cube_t * pCube ) -{ - if ( pCube == NULL ) - return; - - // verify the parameters charactering this cube - assert( pCube->iLast == 0 || ((int)pCube->iLast) == pCover->nWords - 1 ); - assert( ((int)pCube->nUnused) == pCover->nUnused ); - - // deallocate the cube -#ifdef USE_SYSTEM_MEMORY_MANAGEMENT - free( pCube ); -#else - switch( pCover->nWords ) - { - case 0: - case 1: - Extra_MmFixedEntryRecycle( pCover->pMem->pMan1, (char *)pCube ); - break; - case 2: - Extra_MmFixedEntryRecycle( pCover->pMem->pMan2, (char *)pCube ); - break; - case 3: - case 4: - Extra_MmFixedEntryRecycle( pCover->pMem->pMan4, (char *)pCube ); - break; - default: - free( pCube ); - break; - } -#endif -} - - -/**Function************************************************************* - - Synopsis [Removes the don't-care variable from the cube.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Mvc_CubeBitRemoveDcs( Mvc_Cube_t * pCube ) -{ - unsigned Mask; - int i; - for ( i = Mvc_CubeReadLast(pCube); i >= 0; i-- ) - { - // detect those variables that are different (not DCs) - Mask = (pCube->pData[i] ^ (pCube->pData[i] >> 1)) & BITS_DISJOINT; - // create the mask of all that are different - Mask |= (Mask << 1); - // remove other bits from the set - pCube->pData[i] &= Mask; - } -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/sop/mvc/mvcDivide.c b/src/sop/mvc/mvcDivide.c deleted file mode 100644 index 6aa3d58d..00000000 --- a/src/sop/mvc/mvcDivide.c +++ /dev/null @@ -1,436 +0,0 @@ -/**CFile**************************************************************** - - FileName [mvcDivide.c] - - PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] - - Synopsis [Procedures for algebraic division.] - - Author [MVSIS Group] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - February 1, 2003.] - - Revision [$Id: mvcDivide.c,v 1.5 2003/04/26 20:41:36 alanmi Exp $] - -***********************************************************************/ - -#include "mvc.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static void Mvc_CoverVerifyDivision( Mvc_Cover_t * pCover, Mvc_Cover_t * pDiv, Mvc_Cover_t * pQuo, Mvc_Cover_t * pRem ); - -int s_fVerbose = 0; - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Mvc_CoverDivide( Mvc_Cover_t * pCover, Mvc_Cover_t * pDiv, Mvc_Cover_t ** ppQuo, Mvc_Cover_t ** ppRem ) -{ - // check the number of cubes - if ( Mvc_CoverReadCubeNum( pCover ) < Mvc_CoverReadCubeNum( pDiv ) ) - { - *ppQuo = NULL; - *ppRem = NULL; - return; - } - - // make sure that support of pCover contains that of pDiv - if ( !Mvc_CoverCheckSuppContainment( pCover, pDiv ) ) - { - *ppQuo = NULL; - *ppRem = NULL; - return; - } - - // perform the general division - Mvc_CoverDivideInternal( pCover, pDiv, ppQuo, ppRem ); -} - - -/**Function************************************************************* - - Synopsis [Merge the cubes inside the groups.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Mvc_CoverDivideInternal( Mvc_Cover_t * pCover, Mvc_Cover_t * pDiv, Mvc_Cover_t ** ppQuo, Mvc_Cover_t ** ppRem ) -{ - Mvc_Cover_t * pQuo, * pRem; - Mvc_Cube_t * pCubeC, * pCubeD, * pCubeCopy; - Mvc_Cube_t * pCube1, * pCube2; - int * pGroups, nGroups; // the cube groups - int nCubesC, nCubesD, nMerges, iCubeC, iCubeD, iMerge; - int fSkipG, GroupSize, g, c, RetValue; - int nCubes; - - // get cover sizes - nCubesD = Mvc_CoverReadCubeNum( pDiv ); - nCubesC = Mvc_CoverReadCubeNum( pCover ); - - // check trivial cases - if ( nCubesD == 1 ) - { - if ( Mvc_CoverIsOneLiteral( pDiv ) ) - Mvc_CoverDivideByLiteral( pCover, pDiv, ppQuo, ppRem ); - else - Mvc_CoverDivideByCube( pCover, pDiv, ppQuo, ppRem ); - return; - } - - // create the divisor and the remainder - pQuo = Mvc_CoverAlloc( pCover->pMem, pCover->nBits ); - pRem = Mvc_CoverAlloc( pCover->pMem, pCover->nBits ); - - // get the support of the divisor - Mvc_CoverAllocateMask( pDiv ); - Mvc_CoverSupport( pDiv, pDiv->pMask ); - - // sort the cubes of the divisor - Mvc_CoverSort( pDiv, NULL, Mvc_CubeCompareInt ); - // sort the cubes of the cover - Mvc_CoverSort( pCover, pDiv->pMask, Mvc_CubeCompareIntOutsideAndUnderMask ); - - // allocate storage for cube groups - pGroups = MEM_ALLOC( pCover->pMem, int, nCubesC + 1 ); - - // mask contains variables in the support of Div - // split the cubes into groups using the mask - Mvc_CoverList2Array( pCover ); - Mvc_CoverList2Array( pDiv ); - pGroups[0] = 0; - nGroups = 1; - for ( c = 1; c < nCubesC; c++ ) - { - // get the cubes - pCube1 = pCover->pCubes[c-1]; - pCube2 = pCover->pCubes[c ]; - // compare the cubes - Mvc_CubeBitEqualOutsideMask( RetValue, pCube1, pCube2, pDiv->pMask ); - if ( !RetValue ) - pGroups[nGroups++] = c; - } - // finish off the last group - pGroups[nGroups] = nCubesC; - - // consider each group separately and decide - // whether it can produce a quotient cube - nCubes = 0; - for ( g = 0; g < nGroups; g++ ) - { - // if the group has less than nCubesD cubes, - // there is no way it can produce the quotient cube - // copy the cubes to the remainder - GroupSize = pGroups[g+1] - pGroups[g]; - if ( GroupSize < nCubesD ) - { - for ( c = pGroups[g]; c < pGroups[g+1]; c++ ) - { - pCubeCopy = Mvc_CubeDup( pRem, pCover->pCubes[c] ); - Mvc_CoverAddCubeTail( pRem, pCubeCopy ); - nCubes++; - } - continue; - } - - // mark the cubes as those that should be added to the remainder - for ( c = pGroups[g]; c < pGroups[g+1]; c++ ) - Mvc_CubeSetSize( pCover->pCubes[c], 1 ); - - // go through the cubes in the group and at the same time - // go through the cubes in the divisor - iCubeD = 0; - iCubeC = 0; - pCubeD = pDiv->pCubes[iCubeD++]; - pCubeC = pCover->pCubes[pGroups[g]+iCubeC++]; - fSkipG = 0; - nMerges = 0; - - while ( 1 ) - { - // compare the topmost cubes in F and in D - RetValue = Mvc_CubeCompareIntUnderMask( pCubeC, pCubeD, pDiv->pMask ); - // cube are ordered in increasing order of their int value - if ( RetValue == -1 ) // pCubeC is above pCubeD - { // cube in C should be added to the remainder - // check that there is enough cubes in the group - if ( GroupSize - iCubeC < nCubesD - nMerges ) - { - fSkipG = 1; - break; - } - // get the next cube in the cover - pCubeC = pCover->pCubes[pGroups[g]+iCubeC++]; - continue; - } - if ( RetValue == 1 ) // pCubeD is above pCubeC - { // given cube in D does not have a corresponding cube in the cover - fSkipG = 1; - break; - } - // mark the cube as the one that should NOT be added to the remainder - Mvc_CubeSetSize( pCubeC, 0 ); - // remember this merged cube - iMerge = iCubeC-1; - nMerges++; - - // stop if we considered the last cube of the group - if ( iCubeD == nCubesD ) - break; - - // advance the cube of the divisor - assert( iCubeD < nCubesD ); - pCubeD = pDiv->pCubes[iCubeD++]; - - // advance the cube of the group - assert( pGroups[g]+iCubeC < nCubesC ); - pCubeC = pCover->pCubes[pGroups[g]+iCubeC++]; - } - - if ( fSkipG ) - { - // the group has failed, add all the cubes to the remainder - for ( c = pGroups[g]; c < pGroups[g+1]; c++ ) - { - pCubeCopy = Mvc_CubeDup( pRem, pCover->pCubes[c] ); - Mvc_CoverAddCubeTail( pRem, pCubeCopy ); - nCubes++; - } - continue; - } - - // the group has worked, add left-over cubes to the remainder - for ( c = pGroups[g]; c < pGroups[g+1]; c++ ) - { - pCubeC = pCover->pCubes[c]; - if ( Mvc_CubeReadSize(pCubeC) ) - { - pCubeCopy = Mvc_CubeDup( pRem, pCubeC ); - Mvc_CoverAddCubeTail( pRem, pCubeCopy ); - nCubes++; - } - } - - // create the quotient cube - pCube1 = Mvc_CubeAlloc( pQuo ); - Mvc_CubeBitSharp( pCube1, pCover->pCubes[pGroups[g]+iMerge], pDiv->pMask ); - // add the cube to the quotient - Mvc_CoverAddCubeTail( pQuo, pCube1 ); - nCubes += nCubesD; - } - assert( nCubes == nCubesC ); - - // deallocate the memory - MEM_FREE( pCover->pMem, int, nCubesC + 1, pGroups ); - - // return the results - *ppRem = pRem; - *ppQuo = pQuo; -// Mvc_CoverVerifyDivision( pCover, pDiv, pQuo, pRem ); -} - - -/**Function************************************************************* - - Synopsis [Divides the cover by a cube.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Mvc_CoverDivideByCube( Mvc_Cover_t * pCover, Mvc_Cover_t * pDiv, Mvc_Cover_t ** ppQuo, Mvc_Cover_t ** ppRem ) -{ - Mvc_Cover_t * pQuo, * pRem; - Mvc_Cube_t * pCubeC, * pCubeD, * pCubeCopy; - int CompResult; - - // get the only cube of D - assert( Mvc_CoverReadCubeNum(pDiv) == 1 ); - - // start the quotient and the remainder - pQuo = Mvc_CoverAlloc( pCover->pMem, pCover->nBits ); - pRem = Mvc_CoverAlloc( pCover->pMem, pCover->nBits ); - - // get the first and only cube of the divisor - pCubeD = Mvc_CoverReadCubeHead( pDiv ); - - // iterate through the cubes in the cover - Mvc_CoverForEachCube( pCover, pCubeC ) - { - // check the containment of literals from pCubeD in pCube - Mvc_Cube2BitNotImpl( CompResult, pCubeD, pCubeC ); - if ( !CompResult ) - { // this cube belongs to the quotient - // alloc the cube - pCubeCopy = Mvc_CubeAlloc( pQuo ); - // clean the support of D - Mvc_CubeBitSharp( pCubeCopy, pCubeC, pCubeD ); - // add the cube to the quotient - Mvc_CoverAddCubeTail( pQuo, pCubeCopy ); - } - else - { - // copy the cube - pCubeCopy = Mvc_CubeDup( pRem, pCubeC ); - // add the cube to the remainder - Mvc_CoverAddCubeTail( pRem, pCubeCopy ); - } - } - // return the results - *ppRem = pRem; - *ppQuo = pQuo; -} - -/**Function************************************************************* - - Synopsis [Divides the cover by a literal.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Mvc_CoverDivideByLiteral( Mvc_Cover_t * pCover, Mvc_Cover_t * pDiv, Mvc_Cover_t ** ppQuo, Mvc_Cover_t ** ppRem ) -{ - Mvc_Cover_t * pQuo, * pRem; - Mvc_Cube_t * pCubeC, * pCubeCopy; - int iLit; - - // get the only cube of D - assert( Mvc_CoverReadCubeNum(pDiv) == 1 ); - - // start the quotient and the remainder - pQuo = Mvc_CoverAlloc( pCover->pMem, pCover->nBits ); - pRem = Mvc_CoverAlloc( pCover->pMem, pCover->nBits ); - - // get the first and only literal in the divisor cube - iLit = Mvc_CoverFirstCubeFirstLit( pDiv ); - - // iterate through the cubes in the cover - Mvc_CoverForEachCube( pCover, pCubeC ) - { - // copy the cube - pCubeCopy = Mvc_CubeDup( pCover, pCubeC ); - // add the cube to the quotient or to the remainder depending on the literal - if ( Mvc_CubeBitValue( pCubeCopy, iLit ) ) - { // remove the literal - Mvc_CubeBitRemove( pCubeCopy, iLit ); - // add the cube ot the quotient - Mvc_CoverAddCubeTail( pQuo, pCubeCopy ); - } - else - { // add the cube ot the remainder - Mvc_CoverAddCubeTail( pRem, pCubeCopy ); - } - } - // return the results - *ppRem = pRem; - *ppQuo = pQuo; -} - - -/**Function************************************************************* - - Synopsis [Derives the quotient of division by literal.] - - Description [Reduces the cover to be the equal to the result of - division of the given cover by the literal.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Mvc_CoverDivideByLiteralQuo( Mvc_Cover_t * pCover, int iLit ) -{ - Mvc_Cube_t * pCube, * pCube2, * pPrev; - // delete those cubes that do not have this literal - // remove this literal from other cubes - pPrev = NULL; - Mvc_CoverForEachCubeSafe( pCover, pCube, pCube2 ) - { - if ( Mvc_CubeBitValue( pCube, iLit ) == 0 ) - { // delete the cube from the cover - Mvc_CoverDeleteCube( pCover, pPrev, pCube ); - Mvc_CubeFree( pCover, pCube ); - // don't update the previous cube - } - else - { // delete this literal from the cube - Mvc_CubeBitRemove( pCube, iLit ); - // update the previous cube - pPrev = pCube; - } - } -} - - -/**Function************************************************************* - - Synopsis [Verifies that the result of algebraic division is correct.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Mvc_CoverVerifyDivision( Mvc_Cover_t * pCover, Mvc_Cover_t * pDiv, Mvc_Cover_t * pQuo, Mvc_Cover_t * pRem ) -{ - Mvc_Cover_t * pProd; - Mvc_Cover_t * pDiff; - - pProd = Mvc_CoverAlgebraicMultiply( pDiv, pQuo ); - pDiff = Mvc_CoverAlgebraicSubtract( pCover, pProd ); - - if ( Mvc_CoverAlgebraicEqual( pDiff, pRem ) ) - printf( "Verification OKAY!\n" ); - else - { - printf( "Verification FAILED!\n" ); - printf( "pCover:\n" ); - Mvc_CoverPrint( pCover ); - printf( "pDiv:\n" ); - Mvc_CoverPrint( pDiv ); - printf( "pRem:\n" ); - Mvc_CoverPrint( pRem ); - printf( "pQuo:\n" ); - Mvc_CoverPrint( pQuo ); - } - - Mvc_CoverFree( pProd ); - Mvc_CoverFree( pDiff ); -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/sop/mvc/mvcDivisor.c b/src/sop/mvc/mvcDivisor.c deleted file mode 100644 index e92c3a65..00000000 --- a/src/sop/mvc/mvcDivisor.c +++ /dev/null @@ -1,90 +0,0 @@ -/**CFile**************************************************************** - - FileName [mvcDivisor.c] - - PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] - - Synopsis [Procedures for compute the quick divisor.] - - Author [MVSIS Group] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - February 1, 2003.] - - Revision [$Id: mvcDivisor.c,v 1.1 2003/04/03 15:34:08 alanmi Exp $] - -***********************************************************************/ - -#include "mvc.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static void Mvc_CoverDivisorZeroKernel( Mvc_Cover_t * pCover ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Returns the quick divisor of the cover.] - - Description [Returns NULL, if there is not divisor other than - trivial.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Mvc_Cover_t * Mvc_CoverDivisor( Mvc_Cover_t * pCover ) -{ - Mvc_Cover_t * pKernel; - if ( Mvc_CoverReadCubeNum(pCover) <= 1 ) - return NULL; - // allocate the literal array and count literals - if ( Mvc_CoverAnyLiteral( pCover, NULL ) == -1 ) - return NULL; - // duplicate the cover - pKernel = Mvc_CoverDup(pCover); - // perform the kerneling - Mvc_CoverDivisorZeroKernel( pKernel ); - assert( Mvc_CoverReadCubeNum(pKernel) ); - return pKernel; -} - -/**Function************************************************************* - - Synopsis [Computes a level-zero kernel.] - - Description [Modifies the cover to contain one level-zero kernel.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Mvc_CoverDivisorZeroKernel( Mvc_Cover_t * pCover ) -{ - int iLit; - // find any literal that occurs at least two times -// iLit = Mvc_CoverAnyLiteral( pCover, NULL ); - iLit = Mvc_CoverWorstLiteral( pCover, NULL ); -// iLit = Mvc_CoverBestLiteral( pCover, NULL ); - if ( iLit == -1 ) - return; - // derive the cube-free quotient - Mvc_CoverDivideByLiteralQuo( pCover, iLit ); // the same cover - Mvc_CoverMakeCubeFree( pCover ); // the same cover - // call recursively - Mvc_CoverDivisorZeroKernel( pCover ); // the same cover -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/sop/mvc/mvcList.c b/src/sop/mvc/mvcList.c deleted file mode 100644 index 678ae9fd..00000000 --- a/src/sop/mvc/mvcList.c +++ /dev/null @@ -1,362 +0,0 @@ -/**CFile**************************************************************** - - FileName [mvcList.c] - - PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] - - Synopsis [Manipulating list of cubes in the cover.] - - Author [MVSIS Group] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - February 1, 2003.] - - Revision [$Id: mvcList.c,v 1.4 2003/04/03 06:31:50 alanmi Exp $] - -***********************************************************************/ - -#include "mvc.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Mvc_ListAddCubeHead_( Mvc_List_t * pList, Mvc_Cube_t * pCube ) -{ - if ( pList->pHead == NULL ) - { - Mvc_CubeSetNext( pCube, NULL ); - pList->pHead = pCube; - pList->pTail = pCube; - } - else - { - Mvc_CubeSetNext( pCube, pList->pHead ); - pList->pHead = pCube; - } - pList->nItems++; -} - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Mvc_ListAddCubeTail_( Mvc_List_t * pList, Mvc_Cube_t * pCube ) -{ - if ( pList->pHead == NULL ) - pList->pHead = pCube; - else - Mvc_CubeSetNext( pList->pTail, pCube ); - pList->pTail = pCube; - Mvc_CubeSetNext( pCube, NULL ); - pList->nItems++; -} - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Mvc_ListDeleteCube_( Mvc_List_t * pList, Mvc_Cube_t * pPrev, Mvc_Cube_t * pCube ) -{ - if ( pPrev == NULL ) // deleting the head cube - pList->pHead = Mvc_CubeReadNext(pCube); - else - pPrev->pNext = pCube->pNext; - if ( pList->pTail == pCube ) // deleting the tail cube - { - assert( Mvc_CubeReadNext(pCube) == NULL ); - pList->pTail = pPrev; - } - pList->nItems--; -} - - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Mvc_CoverAddCubeHead_( Mvc_Cover_t * pCover, Mvc_Cube_t * pCube ) -{ - Mvc_List_t * pList = &pCover->lCubes; - if ( pList->pHead == NULL ) - { - Mvc_CubeSetNext( pCube, NULL ); - pList->pHead = pCube; - pList->pTail = pCube; - } - else - { - Mvc_CubeSetNext( pCube, pList->pHead ); - pList->pHead = pCube; - } - pList->nItems++; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Mvc_CoverAddCubeTail_( Mvc_Cover_t * pCover, Mvc_Cube_t * pCube ) -{ - Mvc_List_t * pList = &pCover->lCubes; - - if ( pList->pHead == NULL ) - pList->pHead = pCube; - else - Mvc_CubeSetNext( pList->pTail, pCube ); - pList->pTail = pCube; - Mvc_CubeSetNext( pCube, NULL ); - pList->nItems++; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Mvc_CoverDeleteCube_( Mvc_Cover_t * pCover, Mvc_Cube_t * pPrev, Mvc_Cube_t * pCube ) -{ - Mvc_List_t * pList = &pCover->lCubes; - - if ( pPrev == NULL ) // deleting the head cube - pList->pHead = Mvc_CubeReadNext(pCube); - else - pPrev->pNext = pCube->pNext; - if ( pList->pTail == pCube ) // deleting the tail cube - { - assert( Mvc_CubeReadNext(pCube) == NULL ); - pList->pTail = pPrev; - } - pList->nItems--; -} - - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Mvc_CoverAddDupCubeHead( Mvc_Cover_t * pCover, Mvc_Cube_t * pCube ) -{ - Mvc_Cube_t * pCubeNew; - pCubeNew = Mvc_CubeAlloc( pCover ); - Mvc_CubeBitCopy( pCubeNew, pCube ); - Mvc_CoverAddCubeHead( pCover, pCubeNew ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Mvc_CoverAddDupCubeTail( Mvc_Cover_t * pCover, Mvc_Cube_t * pCube ) -{ - Mvc_Cube_t * pCubeNew; - // copy the cube as part of this cover - pCubeNew = Mvc_CubeAlloc( pCover ); - Mvc_CubeBitCopy( pCubeNew, pCube ); - // clean the last bits of the new cube -// pCubeNew->pData[pCubeNew->iLast] &= (BITS_FULL >> pCubeNew->nUnused); - // add the cube at the end - Mvc_CoverAddCubeTail( pCover, pCubeNew ); -} - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Mvc_CoverAddLiteralsOfCube( Mvc_Cover_t * pCover, Mvc_Cube_t * pCube ) -{ -// int iBit, Value; -// assert( pCover->pLits ); -// Mvc_CubeForEachBit( pCover, pCube, iBit, Value ) -// if ( Value ) -// pCover->pLits[iBit] += Value; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Mvc_CoverDeleteLiteralsOfCube( Mvc_Cover_t * pCover, Mvc_Cube_t * pCube ) -{ -// int iBit, Value; -// assert( pCover->pLits ); -// Mvc_CubeForEachBit( pCover, pCube, iBit, Value ) -// if ( Value ) -// pCover->pLits[iBit] -= Value; -} - - -/**Function************************************************************* - - Synopsis [Transfers the cubes from the list into the array.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Mvc_CoverList2Array( Mvc_Cover_t * pCover ) -{ - Mvc_Cube_t * pCube; - int Counter; - // resize storage if necessary - Mvc_CoverAllocateArrayCubes( pCover ); - // iterate through the cubes - Counter = 0; - Mvc_CoverForEachCube( pCover, pCube ) - pCover->pCubes[ Counter++ ] = pCube; - assert( Counter == Mvc_CoverReadCubeNum(pCover) ); -} - -/**Function************************************************************* - - Synopsis [Transfers the cubes from the array into list.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Mvc_CoverArray2List( Mvc_Cover_t * pCover ) -{ - Mvc_Cube_t * pCube; - int nCubes, i; - - assert( pCover->pCubes ); - - nCubes = Mvc_CoverReadCubeNum(pCover); - if ( nCubes == 0 ) - return; - if ( nCubes == 1 ) - { - pCube = pCover->pCubes[0]; - pCube->pNext = NULL; - pCover->lCubes.pHead = pCover->lCubes.pTail = pCube; - return; - } - // set up the first cube - pCube = pCover->pCubes[0]; - pCover->lCubes.pHead = pCube; - // set up the last cube - pCube = pCover->pCubes[nCubes-1]; - pCube->pNext = NULL; - pCover->lCubes.pTail = pCube; - - // link all cubes starting from the first one - for ( i = 0; i < nCubes - 1; i++ ) - pCover->pCubes[i]->pNext = pCover->pCubes[i+1]; -} - -/**Function************************************************************* - - Synopsis [Returns the tail of the linked list given by the head.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Mvc_Cube_t * Mvc_ListGetTailFromHead( Mvc_Cube_t * pHead ) -{ - Mvc_Cube_t * pCube, * pTail; - for ( pTail = pCube = pHead; - pCube; - pTail = pCube, pCube = Mvc_CubeReadNext(pCube) ); - return pTail; -} - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/sop/mvc/mvcLits.c b/src/sop/mvc/mvcLits.c deleted file mode 100644 index 98211719..00000000 --- a/src/sop/mvc/mvcLits.c +++ /dev/null @@ -1,345 +0,0 @@ -/**CFile**************************************************************** - - FileName [mvcLits.c] - - PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] - - Synopsis [Literal counting/updating procedures.] - - Author [MVSIS Group] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - February 1, 2003.] - - Revision [$Id: mvcLits.c,v 1.4 2003/04/03 06:31:50 alanmi Exp $] - -***********************************************************************/ - -#include "mvc.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Find the any literal that occurs more than once.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Mvc_CoverAnyLiteral( Mvc_Cover_t * pCover, Mvc_Cube_t * pMask ) -{ - Mvc_Cube_t * pCube; - int nWord, nBit, i; - int nLitsCur; - int fUseFirst = 0; - - // go through each literal - if ( fUseFirst ) - { - for ( i = 0; i < pCover->nBits; i++ ) - if ( !pMask || Mvc_CubeBitValue(pMask,i) ) - { - // get the word and bit of this literal - nWord = Mvc_CubeWhichWord(i); - nBit = Mvc_CubeWhichBit(i); - // go through all the cubes - nLitsCur = 0; - Mvc_CoverForEachCube( pCover, pCube ) - if ( pCube->pData[nWord] & (1< 1 ) - return i; - } - } - } - else - { - for ( i = pCover->nBits - 1; i >=0; i-- ) - if ( !pMask || Mvc_CubeBitValue(pMask,i) ) - { - // get the word and bit of this literal - nWord = Mvc_CubeWhichWord(i); - nBit = Mvc_CubeWhichBit(i); - // go through all the cubes - nLitsCur = 0; - Mvc_CoverForEachCube( pCover, pCube ) - if ( pCube->pData[nWord] & (1< 1 ) - return i; - } - } - } - return -1; -} - -/**Function************************************************************* - - Synopsis [Find the most often occurring literal.] - - Description [Find the most often occurring literal among those - that occur more than once.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Mvc_CoverBestLiteral( Mvc_Cover_t * pCover, Mvc_Cube_t * pMask ) -{ - Mvc_Cube_t * pCube; - int nWord, nBit; - int i, iMax, nLitsMax, nLitsCur; - int fUseFirst = 1; - - // go through each literal - iMax = -1; - nLitsMax = -1; - for ( i = 0; i < pCover->nBits; i++ ) - if ( !pMask || Mvc_CubeBitValue(pMask,i) ) - { - // get the word and bit of this literal - nWord = Mvc_CubeWhichWord(i); - nBit = Mvc_CubeWhichBit(i); - // go through all the cubes - nLitsCur = 0; - Mvc_CoverForEachCube( pCover, pCube ) - if ( pCube->pData[nWord] & (1< 1 ) - return iMax; - return -1; -} - -/**Function************************************************************* - - Synopsis [Find the most often occurring literal.] - - Description [Find the most often occurring literal among those - that occur more than once.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Mvc_CoverWorstLiteral( Mvc_Cover_t * pCover, Mvc_Cube_t * pMask ) -{ - Mvc_Cube_t * pCube; - int nWord, nBit; - int i, iMin, nLitsMin, nLitsCur; - int fUseFirst = 1; - - // go through each literal - iMin = -1; - nLitsMin = 1000000; - for ( i = 0; i < pCover->nBits; i++ ) - if ( !pMask || Mvc_CubeBitValue(pMask,i) ) - { - // get the word and bit of this literal - nWord = Mvc_CubeWhichWord(i); - nBit = Mvc_CubeWhichBit(i); - // go through all the cubes - nLitsCur = 0; - Mvc_CoverForEachCube( pCover, pCube ) - if ( pCube->pData[nWord] & (1< nLitsCur ) - { - nLitsMin = nLitsCur; - iMin = i; - } - } - else - { - if ( nLitsMin >= nLitsCur ) - { - nLitsMin = nLitsCur; - iMin = i; - } - } - } - - if ( nLitsMin < 1000000 ) - return iMin; - return -1; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Mvc_Cover_t * Mvc_CoverBestLiteralCover( Mvc_Cover_t * pCover, Mvc_Cover_t * pSimple ) -{ - Mvc_Cover_t * pCoverNew; - Mvc_Cube_t * pCubeNew; - Mvc_Cube_t * pCubeS; - int iLitBest; - - // create the new cover - pCoverNew = Mvc_CoverClone( pCover ); - // get the new cube - pCubeNew = Mvc_CubeAlloc( pCoverNew ); - // clean the cube - Mvc_CubeBitClean( pCubeNew ); - - // get the first cube of pSimple - assert( Mvc_CoverReadCubeNum(pSimple) == 1 ); - pCubeS = Mvc_CoverReadCubeHead( pSimple ); - // find the best literal among those of pCubeS - iLitBest = Mvc_CoverBestLiteral( pCover, pCubeS ); - - // insert this literal into the cube - Mvc_CubeBitInsert( pCubeNew, iLitBest ); - // add the cube to the cover - Mvc_CoverAddCubeTail( pCoverNew, pCubeNew ); - return pCoverNew; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Mvc_CoverFirstCubeFirstLit( Mvc_Cover_t * pCover ) -{ - Mvc_Cube_t * pCube; - int iBit, Value; - - // get the first cube - pCube = Mvc_CoverReadCubeHead( pCover ); - // get the first literal - Mvc_CubeForEachBit( pCover, pCube, iBit, Value ) - if ( Value ) - return iBit; - return -1; -} - -/**Function************************************************************* - - Synopsis [Returns the number of literals in the cover.] - - Description [Allocates storage for literal counters and fills it up - using the current information.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Mvc_CoverCountLiterals( Mvc_Cover_t * pCover ) -{ - Mvc_Cube_t * pCube; - int nWord, nBit; - int i, CounterTot, CounterCur; - - // allocate/clean the storage for literals -// Mvc_CoverAllocateArrayLits( pCover ); -// memset( pCover->pLits, 0, pCover->nBits * sizeof(int) ); - // go through each literal - CounterTot = 0; - for ( i = 0; i < pCover->nBits; i++ ) - { - // get the word and bit of this literal - nWord = Mvc_CubeWhichWord(i); - nBit = Mvc_CubeWhichBit(i); - // go through all the cubes - CounterCur = 0; - Mvc_CoverForEachCube( pCover, pCube ) - if ( pCube->pData[nWord] & (1< -#include "mvc.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Mvc_Manager_t * Mvc_ManagerStart() -{ - Mvc_Manager_t * p; - p = ALLOC( Mvc_Manager_t, 1 ); - memset( p, 0, sizeof(Mvc_Manager_t) ); - p->pMan1 = Extra_MmFixedStart( sizeof(Mvc_Cube_t) ); - p->pMan2 = Extra_MmFixedStart( sizeof(Mvc_Cube_t) + sizeof(Mvc_CubeWord_t) ); - p->pMan4 = Extra_MmFixedStart( sizeof(Mvc_Cube_t) + 3 * sizeof(Mvc_CubeWord_t) ); - p->pManC = Extra_MmFixedStart( sizeof(Mvc_Cover_t) ); - return p; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Mvc_ManagerFree( Mvc_Manager_t * p ) -{ - Extra_MmFixedStop( p->pMan1, 0 ); - Extra_MmFixedStop( p->pMan2, 0 ); - Extra_MmFixedStop( p->pMan4, 0 ); - Extra_MmFixedStop( p->pManC, 0 ); - free( p ); -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/sop/mvc/mvcOpAlg.c b/src/sop/mvc/mvcOpAlg.c deleted file mode 100644 index befccb70..00000000 --- a/src/sop/mvc/mvcOpAlg.c +++ /dev/null @@ -1,163 +0,0 @@ -/**CFile**************************************************************** - - FileName [mvcOperAlg.c] - - PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] - - Synopsis [Miscellaneous operations on covers.] - - Author [MVSIS Group] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - February 1, 2003.] - - Revision [$Id: mvcOpAlg.c,v 1.4 2003/04/26 20:41:36 alanmi Exp $] - -***********************************************************************/ - -#include "mvc.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Multiplies two disjoint-support covers.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Mvc_Cover_t * Mvc_CoverAlgebraicMultiply( Mvc_Cover_t * pCover1, Mvc_Cover_t * pCover2 ) -{ - Mvc_Cover_t * pCover; - Mvc_Cube_t * pCube1, * pCube2, * pCube; - int CompResult; - - // covers should be the same base - assert( pCover1->nBits == pCover2->nBits ); - // make sure that supports do not overlap - Mvc_CoverAllocateMask( pCover1 ); - Mvc_CoverAllocateMask( pCover2 ); - Mvc_CoverSupport( pCover1, pCover1->pMask ); - Mvc_CoverSupport( pCover2, pCover2->pMask ); - // check if the cubes are bit-wise disjoint - Mvc_CubeBitDisjoint( CompResult, pCover1->pMask, pCover2->pMask ); - if ( !CompResult ) - printf( "Mvc_CoverMultiply(): Cover supports are not disjoint!\n" ); - - // iterate through the cubes - pCover = Mvc_CoverClone( pCover1 ); - Mvc_CoverForEachCube( pCover1, pCube1 ) - Mvc_CoverForEachCube( pCover2, pCube2 ) - { - // create the product cube - pCube = Mvc_CubeAlloc( pCover ); - // set the product cube equal to the product of the two cubes - Mvc_CubeBitOr( pCube, pCube1, pCube2 ); - // add the cube to the cover - Mvc_CoverAddCubeTail( pCover, pCube ); - } - return pCover; -} - - -/**Function************************************************************* - - Synopsis [Subtracts the second cover from the first.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Mvc_Cover_t * Mvc_CoverAlgebraicSubtract( Mvc_Cover_t * pCover1, Mvc_Cover_t * pCover2 ) -{ - Mvc_Cover_t * pCover; - Mvc_Cube_t * pCube1, * pCube2, * pCube; - int fFound; - int CompResult; - - // covers should be the same base - assert( pCover1->nBits == pCover2->nBits ); - - // iterate through the cubes - pCover = Mvc_CoverClone( pCover1 ); - Mvc_CoverForEachCube( pCover1, pCube1 ) - { - fFound = 0; - Mvc_CoverForEachCube( pCover2, pCube2 ) - { - Mvc_CubeBitEqual( CompResult, pCube1, pCube2 ); - if ( CompResult ) - { - fFound = 1; - break; - } - } - if ( !fFound ) - { - // create the copy of the cube - pCube = Mvc_CubeDup( pCover, pCube1 ); - // add the cube copy to the cover - Mvc_CoverAddCubeTail( pCover, pCube ); - } - } - return pCover; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Mvc_CoverAlgebraicEqual( Mvc_Cover_t * pCover1, Mvc_Cover_t * pCover2 ) -{ - Mvc_Cube_t * pCube1, * pCube2; - int fFound; - int CompResult; - - // covers should be the same base - assert( pCover1->nBits == pCover2->nBits ); - // iterate through the cubes - Mvc_CoverForEachCube( pCover1, pCube1 ) - { - fFound = 0; - Mvc_CoverForEachCube( pCover2, pCube2 ) - { - Mvc_CubeBitEqual( CompResult, pCube1, pCube2 ); - if ( CompResult ) - { - fFound = 1; - break; - } - } - if ( !fFound ) - return 0; - } - return 1; -} - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/sop/mvc/mvcOpBool.c b/src/sop/mvc/mvcOpBool.c deleted file mode 100644 index 57b1a968..00000000 --- a/src/sop/mvc/mvcOpBool.c +++ /dev/null @@ -1,151 +0,0 @@ -/**CFile**************************************************************** - - FileName [mvcProc.c] - - PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] - - Synopsis [Various boolean procedures working with covers.] - - Author [MVSIS Group] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - February 1, 2003.] - - Revision [$Id: mvcOpBool.c,v 1.4 2003/04/16 01:55:37 alanmi Exp $] - -***********************************************************************/ - -#include "mvc.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Mvc_Cover_t * Mvc_CoverBooleanOr( Mvc_Cover_t * pCover1, Mvc_Cover_t * pCover2 ) -{ - Mvc_Cover_t * pCover; - Mvc_Cube_t * pCube, * pCubeCopy; - // make sure the covers are compatible - assert( pCover1->nBits == pCover2->nBits ); - // clone the cover - pCover = Mvc_CoverClone( pCover1 ); - // create the cubes by making pair-wise products - // of cubes in pCover1 and pCover2 - Mvc_CoverForEachCube( pCover1, pCube ) - { - pCubeCopy = Mvc_CubeDup( pCover, pCube ); - Mvc_CoverAddCubeTail( pCover, pCubeCopy ); - } - Mvc_CoverForEachCube( pCover2, pCube ) - { - pCubeCopy = Mvc_CubeDup( pCover, pCube ); - Mvc_CoverAddCubeTail( pCover, pCubeCopy ); - } - return pCover; -} - -#if 0 - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Mvc_Cover_t * Mvc_CoverBooleanAnd( Mvc_Data_t * p, Mvc_Cover_t * pCover1, Mvc_Cover_t * pCover2 ) -{ - Mvc_Cover_t * pCover; - Mvc_Cube_t * pCube1, * pCube2, * pCubeCopy; - // make sure the covers are compatible - assert( pCover1->nBits == pCover2->nBits ); - // clone the cover - pCover = Mvc_CoverClone( pCover1 ); - // create the cubes by making pair-wise products - // of cubes in pCover1 and pCover2 - Mvc_CoverForEachCube( pCover1, pCube1 ) - { - Mvc_CoverForEachCube( pCover2, pCube2 ) - { - if ( Mvc_CoverDist0Cubes( p, pCube1, pCube2 ) ) - { - pCubeCopy = Mvc_CubeAlloc( pCover ); - Mvc_CubeBitAnd( pCubeCopy, pCube1, pCube2 ); - Mvc_CoverAddCubeTail( pCover, pCubeCopy ); - } - } - // if the number of cubes in the new cover is too large - // try compressing them - if ( Mvc_CoverReadCubeNum( pCover ) > 500 ) - Mvc_CoverContain( pCover ); - } - return pCover; -} - -/**Function************************************************************* - - Synopsis [Returns 1 if the two covers are equal.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Mvc_CoverBooleanEqual( Mvc_Data_t * p, Mvc_Cover_t * pCover1, Mvc_Cover_t * pCover2 ) -{ - Mvc_Cover_t * pSharp; - - pSharp = Mvc_CoverSharp( p, pCover1, pCover2 ); - if ( Mvc_CoverReadCubeNum( pSharp ) ) - { -Mvc_CoverContain( pSharp ); -printf( "Sharp \n" ); -Mvc_CoverPrint( pSharp ); - Mvc_CoverFree( pSharp ); - return 0; - } - Mvc_CoverFree( pSharp ); - - pSharp = Mvc_CoverSharp( p, pCover2, pCover1 ); - if ( Mvc_CoverReadCubeNum( pSharp ) ) - { -Mvc_CoverContain( pSharp ); -printf( "Sharp \n" ); -Mvc_CoverPrint( pSharp ); - Mvc_CoverFree( pSharp ); - return 0; - } - Mvc_CoverFree( pSharp ); - - return 1; -} - -#endif - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/sop/mvc/mvcPrint.c b/src/sop/mvc/mvcPrint.c deleted file mode 100644 index 3a31235b..00000000 --- a/src/sop/mvc/mvcPrint.c +++ /dev/null @@ -1,220 +0,0 @@ -/**CFile**************************************************************** - - FileName [mvcPrint.c] - - PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] - - Synopsis [Printing cubes and covers.] - - Author [MVSIS Group] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - February 1, 2003.] - - Revision [$Id: mvcPrint.c,v 1.6 2003/04/09 18:02:06 alanmi Exp $] - -***********************************************************************/ - -#include "mvc.h" -//#include "vm.h" -//#include "vmInt.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static void Mvc_CubePrintBinary( Mvc_Cover_t * pCover, Mvc_Cube_t * pCube ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Mvc_CoverPrint( Mvc_Cover_t * pCover ) -{ - Mvc_Cube_t * pCube; - int i; - // print general statistics - printf( "The cover contains %d cubes (%d bits and %d words)\n", - pCover->lCubes.nItems, pCover->nBits, pCover->nWords ); - // iterate through the cubes - Mvc_CoverForEachCube( pCover, pCube ) - Mvc_CubePrint( pCover, pCube ); - - if ( pCover->pLits ) - { - for ( i = 0; i < pCover->nBits; i++ ) - printf( " %d", pCover->pLits[i] ); - printf( "\n" ); - } - printf( "End of cover printout\n" ); -} - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Mvc_CubePrint( Mvc_Cover_t * pCover, Mvc_Cube_t * pCube ) -{ - int iBit, Value; - // iterate through the literals -// printf( "Size = %2d ", Mvc_CubeReadSize(pCube) ); - Mvc_CubeForEachBit( pCover, pCube, iBit, Value ) - printf( "%c", '0' + Value ); - printf( "\n" ); -} - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Mvc_CoverPrintBinary( Mvc_Cover_t * pCover ) -{ - Mvc_Cube_t * pCube; - int i; - // print general statistics - printf( "The cover contains %d cubes (%d bits and %d words)\n", - pCover->lCubes.nItems, pCover->nBits, pCover->nWords ); - // iterate through the cubes - Mvc_CoverForEachCube( pCover, pCube ) - Mvc_CubePrintBinary( pCover, pCube ); - - if ( pCover->pLits ) - { - for ( i = 0; i < pCover->nBits; i++ ) - printf( " %d", pCover->pLits[i] ); - printf( "\n" ); - } - printf( "End of cover printout\n" ); -} - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Mvc_CubePrintBinary( Mvc_Cover_t * pCover, Mvc_Cube_t * pCube ) -{ - int iVar, Value; - // iterate through the literals -// printf( "Size = %2d ", Mvc_CubeReadSize(pCube) ); - Mvc_CubeForEachVarValue( pCover, pCube, iVar, Value ) - { - assert( Value != 0 ); - if ( Value == 3 ) - printf( "-" ); - else if ( Value == 1 ) - printf( "0" ); - else - printf( "1" ); - } - printf( "\n" ); -} - -#if 0 - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Mvc_CoverPrintMv( Mvc_Data_t * pData, Mvc_Cover_t * pCover ) -{ - Mvc_Cube_t * pCube; - int i; - // print general statistics - printf( "The cover contains %d cubes (%d bits and %d words)\n", - pCover->lCubes.nItems, pCover->nBits, pCover->nWords ); - // iterate through the cubes - Mvc_CoverForEachCube( pCover, pCube ) - Mvc_CubePrintMv( pData, pCover, pCube ); - - if ( pCover->pLits ) - { - for ( i = 0; i < pCover->nBits; i++ ) - printf( " %d", pCover->pLits[i] ); - printf( "\n" ); - } - printf( "End of cover printout\n" ); -} - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Mvc_CubePrintMv( Mvc_Data_t * pData, Mvc_Cover_t * pCover, Mvc_Cube_t * pCube ) -{ - int iLit, iVar; - // iterate through the literals - printf( "Size = %2d ", Mvc_CubeReadSize(pCube) ); - iVar = 0; - for ( iLit = 0; iLit < pData->pVm->nValuesIn; iLit++ ) - { - if ( iLit == pData->pVm->pValuesFirst[iVar+1] ) - { - printf( " " ); - iVar++; - } - if ( Mvc_CubeBitValue( pCube, iLit ) ) - printf( "%c", '0' + iLit - pData->pVm->pValuesFirst[iVar] ); - else - printf( "-" ); - } - printf( "\n" ); -} - -#endif - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/sop/mvc/mvcSort.c b/src/sop/mvc/mvcSort.c deleted file mode 100644 index 1126b22a..00000000 --- a/src/sop/mvc/mvcSort.c +++ /dev/null @@ -1,141 +0,0 @@ -/**CFile**************************************************************** - - FileName [mvcSort.c] - - PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] - - Synopsis [Sorting cubes in the cover with the mask.] - - Author [MVSIS Group] - - Affiliation [uC Berkeley] - - Date [Ver. 1.0. Started - February 1, 2003.] - - Revision [$Id: mvcSort.c,v 1.5 2003/04/27 01:03:45 wjiang Exp $] - -***********************************************************************/ - -#include "mvc.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - - -Mvc_Cube_t * Mvc_CoverSort_rec( Mvc_Cube_t * pList, int nItems, Mvc_Cube_t * pMask, int (* pCompareFunc)(Mvc_Cube_t *, Mvc_Cube_t *, Mvc_Cube_t *) ); -Mvc_Cube_t * Mvc_CoverSortMerge( Mvc_Cube_t * pList1, Mvc_Cube_t * pList2, Mvc_Cube_t * pMask, int (* pCompareFunc)(Mvc_Cube_t *, Mvc_Cube_t *, Mvc_Cube_t *) ); - -//////////////////////////////////////////////////////////////////////// -/// FuNCTION DEFITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Sorts cubes using the given cost function.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Mvc_CoverSort( Mvc_Cover_t * pCover, Mvc_Cube_t * pMask, int (* pCompareFunc)(Mvc_Cube_t *, Mvc_Cube_t *, Mvc_Cube_t *) ) -{ - Mvc_Cube_t * pHead; - int nCubes; - // one cube does not need sorting - nCubes = Mvc_CoverReadCubeNum(pCover); - if ( nCubes <= 1 ) - return; - // sort the cubes - pHead = Mvc_CoverSort_rec( Mvc_CoverReadCubeHead(pCover), nCubes, pMask, pCompareFunc ); - // insert the sorted list into the cover - Mvc_CoverSetCubeHead( pCover, pHead ); - Mvc_CoverSetCubeTail( pCover, Mvc_ListGetTailFromHead(pHead) ); - // make sure that the list is sorted in the increasing order - assert( pCompareFunc( Mvc_CoverReadCubeHead(pCover), Mvc_CoverReadCubeTail(pCover), pMask ) <= 0 ); -} - -/**Function************************************************************* - - Synopsis [Recursive part of Mvc_CoverSort()] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Mvc_Cube_t * Mvc_CoverSort_rec( Mvc_Cube_t * pList, int nItems, Mvc_Cube_t * pMask, int (* pCompareFunc)(Mvc_Cube_t *, Mvc_Cube_t *, Mvc_Cube_t *) ) -{ - Mvc_Cube_t * pList1, * pList2; - int nItems1, nItems2, i; - - // trivial case - if ( nItems == 1 ) - { - Mvc_CubeSetNext( pList, NULL ); - return pList; - } - - // select the new sizes - nItems1 = nItems/2; - nItems2 = nItems - nItems1; - - // set the new beginnings - pList1 = pList2 = pList; - for ( i = 0; i < nItems1; i++ ) - pList2 = Mvc_CubeReadNext( pList2 ); - - // solve recursively - pList1 = Mvc_CoverSort_rec( pList1, nItems1, pMask, pCompareFunc ); - pList2 = Mvc_CoverSort_rec( pList2, nItems2, pMask, pCompareFunc ); - - // merge - return Mvc_CoverSortMerge( pList1, pList2, pMask, pCompareFunc ); -} - - -/**Function************************************************************* - - Synopsis [Merges two NULL-terminated linked lists.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Mvc_Cube_t * Mvc_CoverSortMerge( Mvc_Cube_t * pList1, Mvc_Cube_t * pList2, Mvc_Cube_t * pMask, int (* pCompareFunc)(Mvc_Cube_t *, Mvc_Cube_t *, Mvc_Cube_t *) ) -{ - Mvc_Cube_t * pList = NULL, ** ppTail = &pList; - Mvc_Cube_t * pCube; - while ( pList1 && pList2 ) - { - if ( pCompareFunc( pList1, pList2, pMask ) < 0 ) - { - pCube = pList1; - pList1 = Mvc_CubeReadNext(pList1); - } - else - { - pCube = pList2; - pList2 = Mvc_CubeReadNext(pList2); - } - *ppTail = pCube; - ppTail = Mvc_CubeReadNextP(pCube); - } - *ppTail = pList1? pList1: pList2; - return pList; -} - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/sop/mvc/mvcUtils.c b/src/sop/mvc/mvcUtils.c deleted file mode 100644 index 3fb57276..00000000 --- a/src/sop/mvc/mvcUtils.c +++ /dev/null @@ -1,868 +0,0 @@ -/**CFile**************************************************************** - - FileName [mvcUtils.c] - - PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] - - Synopsis [Various cover handling utilities.] - - Author [MVSIS Group] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - February 1, 2003.] - - Revision [$Id: mvcUtils.c,v 1.7 2003/04/26 20:41:36 alanmi Exp $] - -***********************************************************************/ - -#include "mvc.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static int bit_count[256] = { - 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5, - 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, - 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, - 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, - 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, - 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, - 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, - 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8 -}; - - -static void Mvc_CoverCopyColumn( Mvc_Cover_t * pCoverOld, Mvc_Cover_t * pCoverNew, int iColOld, int iColNew ); - - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Mvc_CoverSupport( Mvc_Cover_t * pCover, Mvc_Cube_t * pSupp ) -{ - Mvc_Cube_t * pCube; - // clean the support - Mvc_CubeBitClean( pSupp ); - // collect the support - Mvc_CoverForEachCube( pCover, pCube ) - Mvc_CubeBitOr( pSupp, pSupp, pCube ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Mvc_CoverSupportAnd( Mvc_Cover_t * pCover, Mvc_Cube_t * pSupp ) -{ - Mvc_Cube_t * pCube; - // clean the support - Mvc_CubeBitFill( pSupp ); - // collect the support - Mvc_CoverForEachCube( pCover, pCube ) - Mvc_CubeBitAnd( pSupp, pSupp, pCube ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Mvc_CoverSupportSizeBinary( Mvc_Cover_t * pCover ) -{ - Mvc_Cube_t * pSupp; - int Counter, i, v0, v1; - // compute the support - pSupp = Mvc_CubeAlloc( pCover ); - Mvc_CoverSupportAnd( pCover, pSupp ); - Counter = pCover->nBits/2; - for ( i = 0; i < pCover->nBits/2; i++ ) - { - v0 = Mvc_CubeBitValue( pSupp, 2*i ); - v1 = Mvc_CubeBitValue( pSupp, 2*i+1 ); - if ( v0 && v1 ) - Counter--; - } - Mvc_CubeFree( pCover, pSupp ); - return Counter; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Mvc_CoverSupportVarBelongs( Mvc_Cover_t * pCover, int iVar ) -{ - Mvc_Cube_t * pSupp; - int RetValue, v0, v1; - // compute the support - pSupp = Mvc_CubeAlloc( pCover ); - Mvc_CoverSupportAnd( pCover, pSupp ); - v0 = Mvc_CubeBitValue( pSupp, 2*iVar ); - v1 = Mvc_CubeBitValue( pSupp, 2*iVar+1 ); - RetValue = (int)( !v0 || !v1 ); - Mvc_CubeFree( pCover, pSupp ); - return RetValue; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Mvc_CoverCommonCube( Mvc_Cover_t * pCover, Mvc_Cube_t * pComCube ) -{ - Mvc_Cube_t * pCube; - // clean the support - Mvc_CubeBitFill( pComCube ); - // collect the support - Mvc_CoverForEachCube( pCover, pCube ) - Mvc_CubeBitAnd( pComCube, pComCube, pCube ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Mvc_CoverIsCubeFree( Mvc_Cover_t * pCover ) -{ - int Result; - // get the common cube - Mvc_CoverAllocateMask( pCover ); - Mvc_CoverCommonCube( pCover, pCover->pMask ); - // check whether the common cube is empty - Mvc_CubeBitEmpty( Result, pCover->pMask ); - return Result; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Mvc_CoverMakeCubeFree( Mvc_Cover_t * pCover ) -{ - Mvc_Cube_t * pCube; - // get the common cube - Mvc_CoverAllocateMask( pCover ); - Mvc_CoverCommonCube( pCover, pCover->pMask ); - // remove this cube from the cubes in the cover - Mvc_CoverForEachCube( pCover, pCube ) - Mvc_CubeBitSharp( pCube, pCube, pCover->pMask ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Mvc_Cover_t * Mvc_CoverCommonCubeCover( Mvc_Cover_t * pCover ) -{ - Mvc_Cover_t * pRes; - Mvc_Cube_t * pCube; - // create the new cover - pRes = Mvc_CoverClone( pCover ); - // get the new cube - pCube = Mvc_CubeAlloc( pRes ); - // get the common cube - Mvc_CoverCommonCube( pCover, pCube ); - // add the cube to the cover - Mvc_CoverAddCubeTail( pRes, pCube ); - return pRes; -} - - -/**Function************************************************************* - - Synopsis [Returns 1 if the support of cover2 is contained in the support of cover1.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Mvc_CoverCheckSuppContainment( Mvc_Cover_t * pCover1, Mvc_Cover_t * pCover2 ) -{ - int Result; - assert( pCover1->nBits == pCover2->nBits ); - // set the supports - Mvc_CoverAllocateMask( pCover1 ); - Mvc_CoverSupport( pCover1, pCover1->pMask ); - Mvc_CoverAllocateMask( pCover2 ); - Mvc_CoverSupport( pCover2, pCover2->pMask ); - // check the containment - Mvc_CubeBitNotImpl( Result, pCover2->pMask, pCover1->pMask ); - return !Result; -} - -/**Function************************************************************* - - Synopsis [Counts the cube sizes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Mvc_CoverSetCubeSizes( Mvc_Cover_t * pCover ) -{ - Mvc_Cube_t * pCube; - unsigned char * pByte, * pByteStart, * pByteStop; - int nBytes, nOnes; - - // get the number of unsigned chars in the cube's bit strings - nBytes = pCover->nBits / (8 * sizeof(unsigned char)) + (int)(pCover->nBits % (8 * sizeof(unsigned char)) > 0); - // iterate through the cubes - Mvc_CoverForEachCube( pCover, pCube ) - { - // clean the counter of ones - nOnes = 0; - // set the starting and stopping positions - pByteStart = (unsigned char *)pCube->pData; - pByteStop = pByteStart + nBytes; - // iterate through the positions - for ( pByte = pByteStart; pByte < pByteStop; pByte++ ) - nOnes += bit_count[*pByte]; - // set the nOnes - Mvc_CubeSetSize( pCube, nOnes ); - } - return 1; -} - -/**Function************************************************************* - - Synopsis [Counts the cube sizes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Mvc_CoverGetCubeSize( Mvc_Cube_t * pCube ) -{ - unsigned char * pByte, * pByteStart, * pByteStop; - int nOnes, nBytes, nBits; - // get the number of unsigned chars in the cube's bit strings - nBits = (pCube->iLast + 1) * sizeof(Mvc_CubeWord_t) * 8 - pCube->nUnused; - nBytes = nBits / (8 * sizeof(unsigned char)) + (int)(nBits % (8 * sizeof(unsigned char)) > 0); - // clean the counter of ones - nOnes = 0; - // set the starting and stopping positions - pByteStart = (unsigned char *)pCube->pData; - pByteStop = pByteStart + nBytes; - // iterate through the positions - for ( pByte = pByteStart; pByte < pByteStop; pByte++ ) - nOnes += bit_count[*pByte]; - return nOnes; -} - -/**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 Mvc_CoverCountCubePairDiffs( Mvc_Cover_t * pCover, unsigned char pDiffs[] ) -{ - Mvc_Cube_t * pCube1; - Mvc_Cube_t * pCube2; - Mvc_Cube_t * pMask; - unsigned char * pByte, * pByteStart, * pByteStop; - int nBytes, nOnes; - int nCubePairs; - - // allocate a temporary mask - pMask = Mvc_CubeAlloc( pCover ); - // get the number of unsigned chars in the cube's bit strings - nBytes = pCover->nBits / (8 * sizeof(unsigned char)) + (int)(pCover->nBits % (8 * sizeof(unsigned char)) > 0); - // iterate through the cubes - nCubePairs = 0; - Mvc_CoverForEachCube( pCover, pCube1 ) - { - Mvc_CoverForEachCubeStart( Mvc_CubeReadNext(pCube1), pCube2 ) - { - // find the bit-wise exor of cubes - Mvc_CubeBitExor( pMask, pCube1, pCube2 ); - // set the starting and stopping positions - pByteStart = (unsigned char *)pMask->pData; - pByteStop = pByteStart + nBytes; - // clean the counter of ones - nOnes = 0; - // iterate through the positions - for ( pByte = pByteStart; pByte < pByteStop; pByte++ ) - nOnes += bit_count[*pByte]; - // set the nOnes - pDiffs[nCubePairs++] = nOnes; - } - } - // deallocate the mask - Mvc_CubeFree( pCover, pMask ); - return 1; -} - - -/**Function************************************************************* - - Synopsis [Creates a new cover containing some literals of the old cover.] - - Description [Creates the new cover containing the given number (nVarsRem) - literals of the old cover. All the bits of the new cover are initialized - to "1". The selected bits from the old cover are copied on top. The numbers - of the selected bits to copy are given in the array pVarsRem. The i-set - entry in this array is the index of the bit in the old cover which goes - to the i-th place in the new cover. If the i-th entry in pVarsRem is -1, - it means that the i-th bit does not change (remains composed of all 1's). - This is a useful feature to speed up remapping covers, which are known - to depend only on a subset of input variables.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Mvc_Cover_t * Mvc_CoverRemap( Mvc_Cover_t * p, int * pVarsRem, int nVarsRem ) -{ - Mvc_Cover_t * pCover; - Mvc_Cube_t * pCube, * pCubeCopy; - int i; - // clone the cover - pCover = Mvc_CoverAlloc( p->pMem, nVarsRem ); - // copy the cube list - Mvc_CoverForEachCube( p, pCube ) - { - pCubeCopy = Mvc_CubeAlloc( pCover ); - //Mvc_CubeBitClean( pCubeCopy ); //changed by wjiang - Mvc_CubeBitFill( pCubeCopy ); //changed by wjiang - Mvc_CoverAddCubeTail( pCover, pCubeCopy ); - } - // copy the corresponding columns - for ( i = 0; i < nVarsRem; i++ ) - { - if (pVarsRem[i] < 0) - continue; //added by wjiang - assert( pVarsRem[i] >= 0 && pVarsRem[i] < p->nBits ); - Mvc_CoverCopyColumn( p, pCover, pVarsRem[i], i ); - } - return pCover; -} - -/**Function************************************************************* - - Synopsis [Copies a column from the old cover to the new cover.] - - Description [Copies the column (iColOld) of the old cover (pCoverOld) - into the column (iColNew) of the new cover (pCoverNew). Assumes that - the number of cubes is the same in both covers. Makes no assuptions - about the current contents of the column in the new cover.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Mvc_CoverCopyColumn( Mvc_Cover_t * pCoverOld, Mvc_Cover_t * pCoverNew, - int iColOld, int iColNew ) -{ - Mvc_Cube_t * pCubeOld, * pCubeNew; - int iWordOld, iWordNew, iBitOld, iBitNew; - - assert( Mvc_CoverReadCubeNum(pCoverOld) == Mvc_CoverReadCubeNum(pCoverNew) ); - - // get the place of the old and new columns - iWordOld = Mvc_CubeWhichWord(iColOld); - iBitOld = Mvc_CubeWhichBit(iColOld); - iWordNew = Mvc_CubeWhichWord(iColNew); - iBitNew = Mvc_CubeWhichBit(iColNew); - - // go through the cubes of both covers - pCubeNew = Mvc_CoverReadCubeHead(pCoverNew); - Mvc_CoverForEachCube( pCoverOld, pCubeOld ) - { - if ( pCubeOld->pData[iWordOld] & (1<pData[iWordNew] |= (1<pData[iWordNew] &= ~(1<pVm, iVar); - nValues = Vm_VarMapReadValues(pData->pVm, iVar); - ppCofs = ALLOC( Mvc_Cover_t *, nValues + 1 ); - for ( i = 0; i <= nValues; i++ ) - ppCofs[i] = Mvc_CoverClone( pCover ); - - // go through the cubes - Mvc_CoverForEachCube( pCover, pCube ) - { - // if the literal if a full literal, add it to last "cofactor" - Mvc_CubeBitEqualUnderMask( Res, pCube, pData->ppMasks[iVar], pData->ppMasks[iVar] ); - if ( Res ) - { - pCubeNew = Mvc_CubeDup(pCover, pCube); - Mvc_CoverAddCubeTail( ppCofs[nValues], pCubeNew ); - continue; - } - - // otherwise, add it to separate values - for ( i = 0; i < nValues; i++ ) - if ( Mvc_CubeBitValue( pCube, iValueFirst + i ) ) - { - pCubeNew = Mvc_CubeDup(pCover, pCube); - Mvc_CubeBitOr( pCubeNew, pCubeNew, pData->ppMasks[iVar] ); - Mvc_CoverAddCubeTail( ppCofs[i], pCubeNew ); - } - } - return ppCofs; -} - -/**Function************************************************************* - - Synopsis [Count the cubes with non-trivial literals with the given value.] - - Description [The data and the cover are given (pData, pCover). Also given - are the variable number and the number of a value of this variable. - This procedure returns the number of cubes having a non-trivial literal - of this variable that have the given value present.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Mvr_CoverCountLitsWithValue( Mvc_Data_t * pData, Mvc_Cover_t * pCover, int iVar, int iValue ) -{ - Mvc_Cube_t * pCube; - int iValueFirst, Res, Counter; - - Counter = 0; - iValueFirst = Vm_VarMapReadValuesFirst( pData->pVm, iVar ); - Mvc_CoverForEachCube( pCover, pCube ) - { - // check if the given literal is the full literal - Mvc_CubeBitEqualUnderMask( Res, pCube, pData->ppMasks[iVar], pData->ppMasks[iVar] ); - if ( Res ) - continue; - // this literal is not a full literal; check if it has this value - Counter += Mvc_CubeBitValue( pCube, iValueFirst + iValue ); - } - return Counter; -} - -/**Function************************************************************* - - Synopsis [Creates the expanded cover.] - - Description [The original cover is expanded by adding some variables. - These variables are the additional variables in pVmNew, compared to - pCvr->pVm. The resulting cover is the same as the original one, except - that it contains the additional variables present as full literals - in every cube.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Mvc_Cover_t * Mvc_CoverCreateExpanded( Mvc_Cover_t * pCover, Vm_VarMap_t * pVmNew ) -{ - Mvc_Cover_t * pCoverNew; - Mvc_Cube_t * pCube, * pCubeNew; - int i, iLast, iLastNew; - - // create the new cover - pCoverNew = Mvc_CoverAlloc( pCover->pMem, Vm_VarMapReadValuesInNum(pVmNew) ); - - // get the cube composed of extra bits - Mvc_CoverAllocateMask( pCoverNew ); - Mvc_CubeBitClean( pCoverNew->pMask ); - for ( i = pCover->nBits; i < pCoverNew->nBits; i++ ) - Mvc_CubeBitInsert( pCoverNew->pMask, i ); - - // get the indexes of the last words in both covers - iLast = pCover->nWords? pCover->nWords - 1: 0; - iLastNew = pCoverNew->nWords? pCoverNew->nWords - 1: 0; - - // create the cubes of the new cover - Mvc_CoverForEachCube( pCover, pCube ) - { - pCubeNew = Mvc_CubeAlloc( pCoverNew ); - Mvc_CubeBitClean( pCubeNew ); - // copy the bits (cannot immediately use Mvc_CubeBitCopy, - // because covers have different numbers of bits) - Mvc_CubeSetLast( pCubeNew, iLast ); - Mvc_CubeBitCopy( pCubeNew, pCube ); - Mvc_CubeSetLast( pCubeNew, iLastNew ); - // add the extra bits - Mvc_CubeBitOr( pCubeNew, pCubeNew, pCoverNew->pMask ); - // add the cube to the new cover - Mvc_CoverAddCubeTail( pCoverNew, pCubeNew ); - } - return pCoverNew; -} - -#endif - -/**Function************************************************************* - - Synopsis [Transposes the cube cover.] - - Description [Returns the cube cover that looks like a transposed - matrix, compared to the matrix derived from the original cover.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Mvc_Cover_t * Mvc_CoverTranspose( Mvc_Cover_t * pCover ) -{ - Mvc_Cover_t * pRes; - Mvc_Cube_t * pCubeRes, * pCube; - int nWord, nBit, i, iCube; - - pRes = Mvc_CoverAlloc( pCover->pMem, Mvc_CoverReadCubeNum(pCover) ); - for ( i = 0; i < pCover->nBits; i++ ) - { - // get the word and bit of this literal - nWord = Mvc_CubeWhichWord(i); - nBit = Mvc_CubeWhichBit(i); - // get the transposed cube - pCubeRes = Mvc_CubeAlloc( pRes ); - Mvc_CubeBitClean( pCubeRes ); - iCube = 0; - Mvc_CoverForEachCube( pCover, pCube ) - { - if ( pCube->pData[nWord] & (1<nUnused == 0 ) - continue; - - Unsigned = ( pCube->pData[pCube->iLast] & - (BITS_FULL << (32-pCube->nUnused)) ); - if( Unsigned ) - { - printf( "Cube %2d out of %2d contains dirty bits.\n", nCubes, - Mvc_CoverReadCubeNum(pCover) ); - } - nCubes++; - } - return 1; -} - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - -- cgit v1.2.3