mirror of https://github.com/YosysHQ/abc.git
Version abc90118
This commit is contained in:
parent
c9ad5880cc
commit
f936cc0680
7
Makefile
7
Makefile
|
|
@ -12,12 +12,12 @@ MODULES := \
|
|||
src/bdd/cudd src/bdd/dsd src/bdd/epd src/bdd/mtr \
|
||||
src/bdd/parse src/bdd/reo src/bdd/cas \
|
||||
src/map/fpga src/map/mapper src/map/mio src/map/super \
|
||||
src/map/if \
|
||||
src/map/if src/map/amap \
|
||||
src/misc/extra src/misc/mvc src/misc/st src/misc/util \
|
||||
src/misc/nm src/misc/vec src/misc/hash \
|
||||
src/misc/bzlib src/misc/zlib \
|
||||
src/opt/cut src/opt/dec src/opt/fxu src/opt/rwr src/opt/mfs \
|
||||
src/opt/sim src/opt/ret src/opt/res src/opt/lpk src/opt/fret \
|
||||
src/opt/sim src/opt/ret src/opt/res src/opt/lpk \
|
||||
src/sat/bsat src/sat/csat src/sat/msat src/sat/fraig \
|
||||
src/sat/psat \
|
||||
src/aig/ivy src/aig/hop src/aig/rwt src/aig/deco \
|
||||
|
|
@ -25,7 +25,8 @@ MODULES := \
|
|||
src/aig/csw src/aig/ioa src/aig/aig src/aig/kit \
|
||||
src/aig/bdc src/aig/bar src/aig/ntl src/aig/nwk \
|
||||
src/aig/mfx src/aig/tim src/aig/saig src/aig/bbr \
|
||||
src/aig/int src/aig/dch src/aig/ssw src/aig/cgt
|
||||
src/aig/int src/aig/dch src/aig/ssw src/aig/cgt \
|
||||
src/aig/cec src/aig/fsim
|
||||
|
||||
default: $(PROG)
|
||||
|
||||
|
|
|
|||
276
abc.dsp
276
abc.dsp
|
|
@ -42,7 +42,7 @@ RSC=rc.exe
|
|||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /W3 /GX /O2 /I "src/base/abc" /I "src/base/abci" /I "src/base/cmd" /I "src/base/io" /I "src/base/main" /I "src/base/ver" /I "src/bdd/cudd" /I "src/bdd/dsd" /I "src/bdd/epd" /I "src/bdd/mtr" /I "src/bdd/parse" /I "src/bdd/reo" /I "src/bdd/cas" /I "src/map/fpga" /I "src/map/mapper" /I "src/map/mio" /I "src/map/super" /I "src/map/if" /I "src/map/pcm" /I "src/map/ply" /I "src/misc/extra" /I "src/misc/mvc" /I "src/misc/st" /I "src/misc/util" /I "src/misc/espresso" /I "src/misc/nm" /I "src/misc/vec" /I "src/misc/hash" /I "src/misc/bzlib" /I "src/misc/zlib" /I "src/opt/cut" /I "src/opt/dec" /I "src/opt/fxu" /I "src/opt/rwr" /I "src/opt/sim" /I "src/opt/ret" /I "src/opt/res" /I "src/opt/lpk" /I "src/sat/bsat" /I "src/sat/csat" /I "src/sat/msat" /I "src/sat/fraig" /I "src/sat/nsat" /I "src/sat/psat" /I "src/aig/ivy" /I "src/aig/hop" /I "src/aig/rwt" /I "src/aig/deco" /I "src/aig/mem" /I "src/aig/dar" /I "src/aig/fra" /I "src/aig/cnf" /I "src/aig/csw" /I "src/aig/ioa" /I "src/aig/aig" /I "src/aig/kit" /I "src/aig/bdc" /I "src/aig/bar" /I "src/aig/ntl" /I "src/aig/nwk" /I "src/aig/tim" /I "src/opt/mfs" /I "src/aig/mfx" /I "src/aig/saig" /I "src/aig/bbr" /I "src/aig/int" /I "src/aig/dch" /I "src/aig/ssw" /I "src/sat/lsat" /I "src/aig/cec" /I "src/aig/cgt" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /D ABC_DLL=DLLEXPORT /D "_CRT_SECURE_NO_DEPRECATE" /D "ABC_USE_LIBRARIES" /FR /YX /FD /c
|
||||
# ADD CPP /nologo /W3 /GX /O2 /I "src/base/abc" /I "src/base/abci" /I "src/base/cmd" /I "src/base/io" /I "src/base/main" /I "src/base/ver" /I "src/bdd/cudd" /I "src/bdd/dsd" /I "src/bdd/epd" /I "src/bdd/mtr" /I "src/bdd/parse" /I "src/bdd/reo" /I "src/bdd/cas" /I "src/map/fpga" /I "src/map/mapper" /I "src/map/mio" /I "src/map/super" /I "src/map/if" /I "src/map/pcm" /I "src/map/ply" /I "src/misc/extra" /I "src/misc/mvc" /I "src/misc/st" /I "src/misc/util" /I "src/misc/espresso" /I "src/misc/nm" /I "src/misc/vec" /I "src/misc/hash" /I "src/misc/bzlib" /I "src/misc/zlib" /I "src/opt/cut" /I "src/opt/dec" /I "src/opt/fxu" /I "src/opt/rwr" /I "src/opt/sim" /I "src/opt/ret" /I "src/opt/res" /I "src/opt/lpk" /I "src/sat/bsat" /I "src/sat/csat" /I "src/sat/msat" /I "src/sat/fraig" /I "src/sat/nsat" /I "src/sat/psat" /I "src/aig/ivy" /I "src/aig/hop" /I "src/aig/rwt" /I "src/aig/deco" /I "src/aig/mem" /I "src/aig/dar" /I "src/aig/fra" /I "src/aig/cnf" /I "src/aig/csw" /I "src/aig/ioa" /I "src/aig/aig" /I "src/aig/kit" /I "src/aig/bdc" /I "src/aig/bar" /I "src/aig/ntl" /I "src/aig/nwk" /I "src/aig/tim" /I "src/opt/mfs" /I "src/aig/mfx" /I "src/aig/saig" /I "src/aig/bbr" /I "src/aig/int" /I "src/aig/dch" /I "src/aig/ssw" /I "src/sat/lsat" /I "src/aig/cec" /I "src/aig/cgt" /I "src/aig/sec" /I "src/map/amap" /I "src/aig/fsim" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /D ABC_DLL=ABC_DLLEXPORT /D "_CRT_SECURE_NO_DEPRECATE" /FR /YX /FD /c
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
|
|
@ -50,7 +50,7 @@ BSC32=bscmake.exe
|
|||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 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 /machine:I386
|
||||
# ADD LINK32 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 m114pr.lib /nologo /subsystem:console /profile /machine:I386 /out:"_TEST/abc.exe" /libpath:"lib"
|
||||
# ADD LINK32 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 m114pr.lib /nologo /subsystem:console /profile /machine:I386 /nodefaultlib:"libcp.lib libc.lib" /out:"_TEST/abc.exe" /libpath:"lib"
|
||||
|
||||
!ELSEIF "$(CFG)" == "abc - Win32 Debug"
|
||||
|
||||
|
|
@ -66,7 +66,7 @@ LINK32=link.exe
|
|||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "src/base/abc" /I "src/base/abci" /I "src/base/cmd" /I "src/base/io" /I "src/base/main" /I "src/base/ver" /I "src/bdd/cudd" /I "src/bdd/dsd" /I "src/bdd/epd" /I "src/bdd/mtr" /I "src/bdd/parse" /I "src/bdd/reo" /I "src/bdd/cas" /I "src/map/fpga" /I "src/map/mapper" /I "src/map/mio" /I "src/map/super" /I "src/map/if" /I "src/map/pcm" /I "src/map/ply" /I "src/misc/extra" /I "src/misc/mvc" /I "src/misc/st" /I "src/misc/util" /I "src/misc/espresso" /I "src/misc/nm" /I "src/misc/vec" /I "src/misc/hash" /I "src/misc/bzlib" /I "src/misc/zlib" /I "src/opt/cut" /I "src/opt/dec" /I "src/opt/fxu" /I "src/opt/rwr" /I "src/opt/sim" /I "src/opt/ret" /I "src/opt/res" /I "src/opt/lpk" /I "src/sat/bsat" /I "src/sat/csat" /I "src/sat/msat" /I "src/sat/fraig" /I "src/sat/nsat" /I "src/sat/psat" /I "src/aig/ivy" /I "src/aig/hop" /I "src/aig/rwt" /I "src/aig/deco" /I "src/aig/mem" /I "src/aig/dar" /I "src/aig/fra" /I "src/aig/cnf" /I "src/aig/csw" /I "src/aig/ioa" /I "src/aig/aig" /I "src/aig/kit" /I "src/aig/bdc" /I "src/aig/bar" /I "src/aig/ntl" /I "src/aig/nwk" /I "src/aig/tim" /I "src/opt/mfs" /I "src/aig/mfx" /I "src/aig/saig" /I "src/aig/bbr" /I "src/aig/int" /I "src/aig/dch" /I "src/aig/ssw" /I "src/sat/lsat" /I "src/aig/cec" /I "src/aig/cgt" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /D ABC_DLL=DLLEXPORT /D "_CRT_SECURE_NO_DEPRECATE" /D "ABC_USE_LIBRARIES" /FR /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "src/base/abc" /I "src/base/abci" /I "src/base/cmd" /I "src/base/io" /I "src/base/main" /I "src/base/ver" /I "src/bdd/cudd" /I "src/bdd/dsd" /I "src/bdd/epd" /I "src/bdd/mtr" /I "src/bdd/parse" /I "src/bdd/reo" /I "src/bdd/cas" /I "src/map/fpga" /I "src/map/mapper" /I "src/map/mio" /I "src/map/super" /I "src/map/if" /I "src/map/pcm" /I "src/map/ply" /I "src/misc/extra" /I "src/misc/mvc" /I "src/misc/st" /I "src/misc/util" /I "src/misc/espresso" /I "src/misc/nm" /I "src/misc/vec" /I "src/misc/hash" /I "src/misc/bzlib" /I "src/misc/zlib" /I "src/opt/cut" /I "src/opt/dec" /I "src/opt/fxu" /I "src/opt/rwr" /I "src/opt/sim" /I "src/opt/ret" /I "src/opt/res" /I "src/opt/lpk" /I "src/sat/bsat" /I "src/sat/csat" /I "src/sat/msat" /I "src/sat/fraig" /I "src/sat/nsat" /I "src/sat/psat" /I "src/aig/ivy" /I "src/aig/hop" /I "src/aig/rwt" /I "src/aig/deco" /I "src/aig/mem" /I "src/aig/dar" /I "src/aig/fra" /I "src/aig/cnf" /I "src/aig/csw" /I "src/aig/ioa" /I "src/aig/aig" /I "src/aig/kit" /I "src/aig/bdc" /I "src/aig/bar" /I "src/aig/ntl" /I "src/aig/nwk" /I "src/aig/tim" /I "src/opt/mfs" /I "src/aig/mfx" /I "src/aig/saig" /I "src/aig/bbr" /I "src/aig/int" /I "src/aig/dch" /I "src/aig/ssw" /I "src/sat/lsat" /I "src/aig/cec" /I "src/aig/cgt" /I "src/aig/sec" /I "src/map/amap" /I "src/aig/fsim" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /D ABC_DLL=ABC_DLLEXPORT /D "_CRT_SECURE_NO_DEPRECATE" /FR /YX /FD /GZ /c
|
||||
# SUBTRACT CPP /X
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
|
|
@ -75,7 +75,7 @@ BSC32=bscmake.exe
|
|||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 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 /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 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 m114pd.lib /nologo /subsystem:console /debug /machine:I386 /out:"_TEST/abc.exe" /pdbtype:sept /libpath:"lib"
|
||||
# ADD LINK32 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 m114pd.lib /nologo /subsystem:console /debug /machine:I386 /nodefaultlib:"libcpd.lib libcd.lib" /out:"_TEST/abc.exe" /pdbtype:sept /libpath:"lib"
|
||||
|
||||
!ENDIF
|
||||
|
||||
|
|
@ -290,6 +290,10 @@ SOURCE=.\src\base\abci\abcMeasure.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\base\abci\abcMerge.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\base\abci\abcMini.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
@ -538,6 +542,10 @@ SOURCE=.\src\base\io\ioWriteBlifMv.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\base\io\ioWriteBook.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\base\io\ioWriteCnf.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
@ -1640,26 +1648,6 @@ SOURCE=.\src\opt\lpk\lpkSets.c
|
|||
# Begin Group "fret"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\opt\fret\fretFlow.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\opt\fret\fretime.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\opt\fret\fretInit.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\opt\fret\fretMain.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\opt\fret\fretTime.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "mfs"
|
||||
|
||||
|
|
@ -1961,96 +1949,72 @@ SOURCE=.\src\map\if\ifTruth.c
|
|||
SOURCE=.\src\map\if\ifUtil.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "pcm"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\map\pcm\pcmCore.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\map\pcm\pcmCut.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\map\pcm\pcmInt.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\map\pcm\pcmMan.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\map\pcm\pcmMap.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\map\pcm\pcmReduce.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\map\pcm\pcmTime.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\map\pcm\pcmTruth.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\map\pcm\pcmUtil.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "ply"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# End Group
|
||||
# Begin Group "pcm"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# End Group
|
||||
# Begin Group "amap"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\map\ply\ply.h
|
||||
SOURCE=.\src\map\amap\amap.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\map\ply\plyAbc.c
|
||||
SOURCE=.\src\map\amap\amapCore.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\map\ply\plyAig.c
|
||||
SOURCE=.\src\map\amap\amapGraph.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\map\ply\plyFake.c
|
||||
SOURCE=.\src\map\amap\amapInt.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\map\ply\plyInt.h
|
||||
SOURCE=.\src\map\amap\amapLib.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\map\ply\plyIter.c
|
||||
SOURCE=.\src\map\amap\amapMan.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\map\ply\plyLib.c
|
||||
SOURCE=.\src\map\amap\amapMatch.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\map\ply\plyMan.c
|
||||
SOURCE=.\src\map\amap\amapMerge.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\map\ply\plyMap.c
|
||||
SOURCE=.\src\map\amap\amapOutput.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\map\ply\plyNtk.c
|
||||
SOURCE=.\src\map\amap\amapParse.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\map\ply\plyPair.c
|
||||
SOURCE=.\src\map\amap\amapPerm.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\map\ply\plyPar.c
|
||||
SOURCE=.\src\map\amap\amapRead.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\map\amap\amapRule.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\map\amap\amapUniq.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Group
|
||||
|
|
@ -2934,6 +2898,10 @@ SOURCE=.\src\aig\aig\aig.h
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\aig\aigCanon.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\aig\aigCheck.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
@ -3310,10 +3278,6 @@ SOURCE=.\src\aig\saig\saigIoa.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\saig\saigLoc.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\saig\saigMiter.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
@ -3338,12 +3302,40 @@ SOURCE=.\src\aig\saig\saigScl.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\saig\saigSimExt.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\saig\saigSimFast.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\saig\saigSimMv.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\saig\saigSimSeq.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\saig\saigStrSim.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\saig\saigSwitch.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\saig\saigSynch.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\saig\saigTrans.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\saig\saigWnd.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "int"
|
||||
|
||||
|
|
@ -3532,6 +3524,46 @@ SOURCE=.\src\aig\ssw\sswUnique.c
|
|||
# Begin Group "cec"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\cec\cec.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\cec\cecAig.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\cec\cecClass.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\cec\cecCnf.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\cec\cecCore.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\cec\cecInt.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\cec\cecMan.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\cec\cecSat.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\cec\cecSim.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\cec\cecStatus.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "cgt"
|
||||
|
||||
|
|
@ -3565,6 +3597,90 @@ SOURCE=.\src\aig\cgt\cgtMan.c
|
|||
SOURCE=.\src\aig\cgt\cgtSat.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "sec"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# End Group
|
||||
# Begin Group "nal"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\nal\nal.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\nal\nalCore.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\nal\nalFlop.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\nal\nalFunc.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\nal\nalInt.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\nal\nalMan.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\nal\nalModels.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\nal\nalRead.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\nal\nalUtil.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\nal\nalWrite.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "fsim"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\fsim\fsim.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\fsim\fsimCore.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\fsim\fsimFront.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\fsim\fsimInt.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\fsim\fsimMan.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\fsim\fsimSim.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\fsim\fsimSwitch.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\fsim\fsimTsim.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Group
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
|
|
|||
6
abc.rc
6
abc.rc
|
|
@ -22,10 +22,10 @@ set gnuplotunix gnuplot
|
|||
|
||||
# standard aliases
|
||||
alias b balance
|
||||
alias cg clockgate
|
||||
alias cl cleanup
|
||||
alias clp collapse
|
||||
alias cs care_set
|
||||
alias dc2 dcompress2
|
||||
alias esd ext_seq_dcs
|
||||
alias f fraig
|
||||
alias fs fraig_sweep
|
||||
|
|
@ -40,6 +40,7 @@ alias pd print_dsd
|
|||
alias pex print_exdc -d
|
||||
alias pf print_factor
|
||||
alias pfan print_fanio
|
||||
alias pg print_gates
|
||||
alias pl print_level
|
||||
alias plat print_latch
|
||||
alias pio print_io
|
||||
|
|
@ -139,3 +140,6 @@ alias t2 "r i/intel_001.aig; ps; indcut -v"
|
|||
alias t "r c\s\0\000.aig; int"
|
||||
#alias t "r test/interpol.blif; st; int"
|
||||
|
||||
#read_library at\syn\brdcm.genlib
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -144,6 +144,7 @@ struct Aig_Man_t_
|
|||
void * pImpData; // implication checking data
|
||||
void * pManTime; // the timing manager
|
||||
void * pManCuts;
|
||||
int * pFastSim;
|
||||
Vec_Ptr_t * vMapped;
|
||||
Vec_Int_t * vFlopNums;
|
||||
Vec_Int_t * vFlopReprs;
|
||||
|
|
@ -154,6 +155,7 @@ struct Aig_Man_t_
|
|||
int fCreatePios;
|
||||
Vec_Int_t * vEquPairs;
|
||||
Vec_Vec_t * vClockDoms;
|
||||
Vec_Int_t * vProbs; // probability of node being 1
|
||||
// timing statistics
|
||||
int time1;
|
||||
int time2;
|
||||
|
|
@ -195,14 +197,14 @@ struct Aig_ManCut_t_
|
|||
};
|
||||
|
||||
#ifdef WIN32
|
||||
#define DLLEXPORT __declspec(dllexport)
|
||||
#define DLLIMPORT __declspec(dllimport)
|
||||
#define ABC_DLLEXPORT __declspec(dllexport)
|
||||
#define ABC_DLLIMPORT __declspec(dllimport)
|
||||
#else /* defined(WIN32) */
|
||||
#define DLLIMPORT
|
||||
#define ABC_DLLIMPORT
|
||||
#endif /* defined(WIN32) */
|
||||
|
||||
#ifndef ABC_DLL
|
||||
#define ABC_DLL DLLIMPORT
|
||||
#define ABC_DLL ABC_DLLIMPORT
|
||||
#endif
|
||||
|
||||
static inline Aig_Cut_t * Aig_ObjCuts( Aig_ManCut_t * p, Aig_Obj_t * pObj ) { return p->pCuts[pObj->Id]; }
|
||||
|
|
@ -338,6 +340,7 @@ static inline int Aig_ObjSetLevel( Aig_Obj_t * pObj, int i ) { assert(
|
|||
static inline void Aig_ObjClean( Aig_Obj_t * pObj ) { memset( pObj, 0, sizeof(Aig_Obj_t) ); }
|
||||
static inline Aig_Obj_t * Aig_ObjFanout0( Aig_Man_t * p, Aig_Obj_t * pObj ) { assert(p->pFanData && pObj->Id < p->nFansAlloc); return Aig_ManObj(p, p->pFanData[5*pObj->Id] >> 1); }
|
||||
static inline Aig_Obj_t * Aig_ObjEquiv( Aig_Man_t * p, Aig_Obj_t * pObj ) { return p->pEquivs? p->pEquivs[pObj->Id] : NULL; }
|
||||
static inline void Aig_ObjSetEquiv( Aig_Man_t * p, Aig_Obj_t * pObj, Aig_Obj_t * pEqu ) { assert(p->pEquivs); p->pEquivs[pObj->Id] = pEqu; }
|
||||
static inline Aig_Obj_t * Aig_ObjRepr( Aig_Man_t * p, Aig_Obj_t * pObj ) { return p->pReprs? p->pReprs[pObj->Id] : NULL; }
|
||||
static inline void Aig_ObjSetRepr( Aig_Man_t * p, Aig_Obj_t * pObj, Aig_Obj_t * pRepr ) { assert(p->pReprs); p->pReprs[pObj->Id] = pRepr; }
|
||||
static inline Aig_Obj_t * Aig_ObjHaig( Aig_Obj_t * pObj ) { assert( Aig_Regular(pObj)->pHaig ); return Aig_NotCond( Aig_Regular(pObj)->pHaig, Aig_IsComplement(pObj) ); }
|
||||
|
|
@ -529,9 +532,9 @@ extern void Aig_ManStartMemory( Aig_Man_t * p );
|
|||
extern void Aig_ManStopMemory( Aig_Man_t * p );
|
||||
/*=== aigMffc.c ==========================================================*/
|
||||
extern int Aig_NodeRef_rec( Aig_Obj_t * pNode, unsigned LevelMin );
|
||||
extern int Aig_NodeDeref_rec( Aig_Obj_t * pNode, unsigned LevelMin );
|
||||
extern int Aig_NodeDeref_rec( Aig_Obj_t * pNode, unsigned LevelMin, float * pPower, float * pProbs );
|
||||
extern int Aig_NodeMffsSupp( Aig_Man_t * p, Aig_Obj_t * pNode, int LevelMin, Vec_Ptr_t * vSupp );
|
||||
extern int Aig_NodeMffsLabel( Aig_Man_t * p, Aig_Obj_t * pNode );
|
||||
extern int Aig_NodeMffsLabel( Aig_Man_t * p, Aig_Obj_t * pNode, float * pPower );
|
||||
extern int Aig_NodeMffsLabelCut( Aig_Man_t * p, Aig_Obj_t * pNode, Vec_Ptr_t * vLeaves );
|
||||
extern int Aig_NodeMffsExtendCut( Aig_Man_t * p, Aig_Obj_t * pNode, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vResult );
|
||||
/*=== aigObj.c ==========================================================*/
|
||||
|
|
|
|||
|
|
@ -0,0 +1,694 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [aigCanon.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [AIG package.]
|
||||
|
||||
Synopsis [Processing the library of semi-canonical AIGs.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - April 28, 2007.]
|
||||
|
||||
Revision [$Id: aigCanon.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "aig.h"
|
||||
#include "kit.h"
|
||||
#include "bdc.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define RMAN_MAXVARS 12
|
||||
#define RMAX_MAXWORD (RMAN_MAXVARS <= 5 ? 1 : (1 << (RMAN_MAXVARS - 5)))
|
||||
|
||||
typedef struct Aig_VSig_t_ Aig_VSig_t;
|
||||
struct Aig_VSig_t_
|
||||
{
|
||||
int nOnes;
|
||||
short nCofOnes[RMAN_MAXVARS];
|
||||
};
|
||||
|
||||
typedef struct Aig_Tru_t_ Aig_Tru_t;
|
||||
struct Aig_Tru_t_
|
||||
{
|
||||
Aig_Tru_t * pNext;
|
||||
int Id;
|
||||
unsigned nVisits : 27;
|
||||
unsigned nVars : 5;
|
||||
unsigned pTruth[0];
|
||||
};
|
||||
|
||||
typedef struct Aig_RMan_t_ Aig_RMan_t;
|
||||
struct Aig_RMan_t_
|
||||
{
|
||||
int nVars; // the largest variable number
|
||||
Aig_Man_t * pAig; // recorded subgraphs
|
||||
// hash table
|
||||
int nBins;
|
||||
Aig_Tru_t ** pBins;
|
||||
int nEntries;
|
||||
Aig_MmFlex_t* pMemTrus;
|
||||
// bidecomposion
|
||||
Bdc_Man_t * pBidec;
|
||||
// temporaries
|
||||
unsigned pTruthInit[RMAX_MAXWORD]; // canonical truth table
|
||||
unsigned pTruth[RMAX_MAXWORD]; // current truth table
|
||||
unsigned pTruthC[RMAX_MAXWORD]; // canonical truth table
|
||||
unsigned pTruthTemp[RMAX_MAXWORD]; // temporary truth table
|
||||
Aig_VSig_t pMints[2*RMAN_MAXVARS]; // minterm count
|
||||
char pPerm[RMAN_MAXVARS]; // permutation
|
||||
char pPermR[RMAN_MAXVARS]; // reverse permutation
|
||||
// statistics
|
||||
int nVarFuncs[RMAN_MAXVARS+1];
|
||||
int nTotal;
|
||||
int nTtDsd;
|
||||
int nTtDsdPart;
|
||||
int nTtDsdNot;
|
||||
int nUniqueVars;
|
||||
};
|
||||
|
||||
static Aig_RMan_t * s_pRMan = NULL;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Allocates recording manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_RMan_t * Aig_RManStart()
|
||||
{
|
||||
static Bdc_Par_t Pars = {0}, * pPars = &Pars;
|
||||
Aig_RMan_t * p;
|
||||
p = ALLOC( Aig_RMan_t, 1 );
|
||||
memset( p, 0, sizeof(Aig_RMan_t) );
|
||||
p->nVars = RMAN_MAXVARS;
|
||||
p->pAig = Aig_ManStart( 1000000 );
|
||||
Aig_IthVar( p->pAig, p->nVars-1 );
|
||||
// create hash table
|
||||
p->nBins = Aig_PrimeCudd(5000);
|
||||
p->pBins = CALLOC( Aig_Tru_t *, p->nBins );
|
||||
p->pMemTrus = Aig_MmFlexStart();
|
||||
// bi-decomposition manager
|
||||
pPars->nVarsMax = p->nVars;
|
||||
pPars->fVerbose = 0;
|
||||
p->pBidec = Bdc_ManAlloc( pPars );
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the hash key.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Aig_RManTableHash( unsigned * pTruth, int nVars, int nBins, int * pPrimes )
|
||||
{
|
||||
int i, nWords = Kit_TruthWordNum( nVars );
|
||||
unsigned uHash = 0;
|
||||
for ( i = 0; i < nWords; i++ )
|
||||
uHash ^= pTruth[i] * pPrimes[i & 0xf];
|
||||
return (int)(uHash % nBins);
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the given record.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Tru_t ** Aig_RManTableLookup( Aig_RMan_t * p, unsigned * pTruth, int nVars )
|
||||
{
|
||||
static int s_Primes[16] = {
|
||||
1291, 1699, 1999, 2357, 2953, 3313, 3907, 4177,
|
||||
4831, 5147, 5647, 6343, 6899, 7103, 7873, 8147 };
|
||||
Aig_Tru_t ** ppSpot, * pEntry;
|
||||
ppSpot = p->pBins + Aig_RManTableHash( pTruth, nVars, p->nBins, s_Primes );
|
||||
for ( pEntry = *ppSpot; pEntry; ppSpot = &pEntry->pNext, pEntry = pEntry->pNext )
|
||||
if ( Kit_TruthIsEqual( pEntry->pTruth, pTruth, nVars ) )
|
||||
return ppSpot;
|
||||
return ppSpot;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Find or add new entry.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Aig_RManTableResize( Aig_RMan_t * p )
|
||||
{
|
||||
Aig_Tru_t * pEntry, * pNext;
|
||||
Aig_Tru_t ** pBinsOld, ** ppPlace;
|
||||
int nBinsOld, Counter, i, clk;
|
||||
assert( p->pBins != NULL );
|
||||
clk = clock();
|
||||
// save the old Bins
|
||||
pBinsOld = p->pBins;
|
||||
nBinsOld = p->nBins;
|
||||
// get the new Bins
|
||||
p->nBins = Aig_PrimeCudd( 3 * nBinsOld );
|
||||
p->pBins = CALLOC( Aig_Tru_t *, p->nBins );
|
||||
// rehash the entries from the old table
|
||||
Counter = 0;
|
||||
for ( i = 0; i < nBinsOld; i++ )
|
||||
for ( pEntry = pBinsOld[i], pNext = pEntry? pEntry->pNext : NULL;
|
||||
pEntry; pEntry = pNext, pNext = pEntry? pEntry->pNext : NULL )
|
||||
{
|
||||
// get the place where this entry goes in the Bins
|
||||
ppPlace = Aig_RManTableLookup( p, pEntry->pTruth, pEntry->nVars );
|
||||
assert( *ppPlace == NULL ); // should not be there
|
||||
// add the entry to the list
|
||||
*ppPlace = pEntry;
|
||||
pEntry->pNext = NULL;
|
||||
Counter++;
|
||||
}
|
||||
assert( Counter == p->nEntries );
|
||||
// PRT( "Time", clock() - clk );
|
||||
free( pBinsOld );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Find or add new entry.]
|
||||
|
||||
Description [Returns 1 if this is a new entry.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Aig_RManTableFindOrAdd( Aig_RMan_t * p, unsigned * pTruth, int nVars )
|
||||
{
|
||||
Aig_Tru_t ** ppSpot, * pEntry;
|
||||
int nBytes;
|
||||
ppSpot = Aig_RManTableLookup( p, pTruth, nVars );
|
||||
if ( *ppSpot )
|
||||
{
|
||||
(*ppSpot)->nVisits++;
|
||||
return 0;
|
||||
}
|
||||
nBytes = sizeof(Aig_Tru_t) + sizeof(unsigned) * Kit_TruthWordNum(nVars);
|
||||
if ( p->nEntries == 3*p->nBins )
|
||||
Aig_RManTableResize( p );
|
||||
pEntry = (Aig_Tru_t *)Aig_MmFlexEntryFetch( p->pMemTrus, nBytes );
|
||||
pEntry->Id = p->nEntries++;
|
||||
pEntry->nVars = nVars;
|
||||
pEntry->nVisits = 1;
|
||||
pEntry->pNext = NULL;
|
||||
memcpy( pEntry->pTruth, pTruth, sizeof(unsigned) * Kit_TruthWordNum(nVars) );
|
||||
*ppSpot = pEntry;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Deallocates recording manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Aig_RManStop( Aig_RMan_t * p )
|
||||
{
|
||||
int i;
|
||||
printf( "Total funcs = %10d\n", p->nTotal );
|
||||
printf( "Full DSD funcs = %10d\n", p->nTtDsd );
|
||||
printf( "Part DSD funcs = %10d\n", p->nTtDsdPart );
|
||||
printf( "Non- DSD funcs = %10d\n", p->nTtDsdNot );
|
||||
printf( "Uniq-var funcs = %10d\n", p->nUniqueVars );
|
||||
printf( "Unique funcs = %10d\n", p->nEntries );
|
||||
printf( "Distribution of functions:\n" );
|
||||
for ( i = 5; i <= p->nVars; i++ )
|
||||
printf( "%2d = %8d\n", i, p->nVarFuncs[i] );
|
||||
Aig_MmFlexStop( p->pMemTrus, 0 );
|
||||
Aig_ManStop( p->pAig );
|
||||
Bdc_ManFree( p->pBidec );
|
||||
free( p->pBins );
|
||||
free( p );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Stops recording.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Aig_RManQuit()
|
||||
{
|
||||
extern void Ioa_WriteAiger( Aig_Man_t * pMan, char * pFileName, int fWriteSymbols, int fCompact );
|
||||
char Buffer[20];
|
||||
if ( s_pRMan == NULL )
|
||||
return;
|
||||
// dump the library file
|
||||
sprintf( Buffer, "aiglib%02d.aig", s_pRMan->nVars );
|
||||
Ioa_WriteAiger( s_pRMan->pAig, Buffer, 0, 1 );
|
||||
// quit the manager
|
||||
Aig_RManStop( s_pRMan );
|
||||
s_pRMan = NULL;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns 1 if all variables are unique.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Aig_RManPrintVarProfile( unsigned * pTruth, int nVars, unsigned * pTruthAux )
|
||||
{
|
||||
short pStore2[32];
|
||||
int i;
|
||||
Kit_TruthCountOnesInCofsSlow( pTruth, nVars, pStore2, pTruthAux );
|
||||
for ( i = 0; i < nVars; i++ )
|
||||
printf( "%2d/%2d ", pStore2[2*i], pStore2[2*i+1] );
|
||||
printf( "\n" );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Sorts numbers in the increasing order.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Aig_RManSortNums( short * pArray, int nVars )
|
||||
{
|
||||
int i, j, best_i, tmp;
|
||||
for ( i = 0; i < nVars-1; i++ )
|
||||
{
|
||||
best_i = i;
|
||||
for ( j = i+1; j < nVars; j++ )
|
||||
if ( pArray[j] > pArray[best_i] )
|
||||
best_i = j;
|
||||
tmp = pArray[i]; pArray[i] = pArray[best_i]; pArray[best_i] = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Prints signatures for all variables.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Aig_RManPrintSigs( Aig_VSig_t * pSigs, int nVars )
|
||||
{
|
||||
int v, i, k;
|
||||
for ( v = 0; v < nVars; v++ )
|
||||
{
|
||||
printf( "%2d : ", v );
|
||||
for ( k = 0; k < 2; k++ )
|
||||
{
|
||||
printf( "%5d ", pSigs[2*v+k].nOnes );
|
||||
printf( "(" );
|
||||
for ( i = 0; i < nVars; i++ )
|
||||
printf( "%4d ", pSigs[2*v+k].nCofOnes[i] );
|
||||
printf( ") " );
|
||||
}
|
||||
printf( "\n" );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes signatures for all variables.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Aig_RManComputeVSigs( unsigned * pTruth, int nVars, Aig_VSig_t * pSigs, unsigned * pAux )
|
||||
{
|
||||
int v;
|
||||
for ( v = 0; v < nVars; v++ )
|
||||
{
|
||||
Kit_TruthCofactor0New( pAux, pTruth, nVars, v );
|
||||
pSigs[2*v+0].nOnes = Kit_TruthCountOnes( pAux, nVars );
|
||||
Kit_TruthCountOnesInCofs0( pAux, nVars, pSigs[2*v+0].nCofOnes );
|
||||
Aig_RManSortNums( pSigs[2*v+0].nCofOnes, nVars );
|
||||
|
||||
Kit_TruthCofactor1New( pAux, pTruth, nVars, v );
|
||||
pSigs[2*v+1].nOnes = Kit_TruthCountOnes( pAux, nVars );
|
||||
Kit_TruthCountOnesInCofs0( pAux, nVars, pSigs[2*v+1].nCofOnes );
|
||||
Aig_RManSortNums( pSigs[2*v+1].nCofOnes, nVars );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computs signatures for all variables.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Aig_RManCompareSigs( Aig_VSig_t * p0, Aig_VSig_t * p1, int nVars )
|
||||
{
|
||||
// return memcmp( p0, p1, sizeof(int) + sizeof(short) * nVars );
|
||||
return memcmp( p0, p1, sizeof(int) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns 1 if all variables are unique.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Aig_RManVarsAreUnique( Aig_VSig_t * pMints, int nVars )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < nVars - 1; i++ )
|
||||
if ( Aig_RManCompareSigs( &pMints[2*i], &pMints[2*(i+1)], nVars ) == 0 )
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns 1 if all variables are unique.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Aig_RManPrintUniqueVars( Aig_VSig_t * pMints, int nVars )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < nVars; i++ )
|
||||
if ( Aig_RManCompareSigs( &pMints[2*i], &pMints[2*i+1], nVars ) == 0 )
|
||||
printf( "=" );
|
||||
else
|
||||
printf( "x" );
|
||||
printf( "\n" );
|
||||
|
||||
printf( "0" );
|
||||
for ( i = 1; i < nVars; i++ )
|
||||
if ( Aig_RManCompareSigs( &pMints[2*(i-1)], &pMints[2*i], nVars ) == 0 )
|
||||
printf( "-" );
|
||||
else if ( i < 10 )
|
||||
printf( "%c", '0' + i );
|
||||
else
|
||||
printf( "%c", 'A' + i-10 );
|
||||
printf( "\n" );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Canonicize the truth table.]
|
||||
|
||||
Description [Returns the phase. ]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
unsigned Aig_RManSemiCanonicize( unsigned * pOut, unsigned * pIn, int nVars, char * pCanonPerm, Aig_VSig_t * pSigs, int fReturnIn )
|
||||
{
|
||||
Aig_VSig_t TempSig;
|
||||
int i, Temp, fChange, Counter;
|
||||
unsigned * pTemp, uCanonPhase = 0;
|
||||
// collect signatures
|
||||
Aig_RManComputeVSigs( pIn, nVars, pSigs, pOut );
|
||||
// canonicize phase
|
||||
for ( i = 0; i < nVars; i++ )
|
||||
{
|
||||
// if ( pStore[2*i+0] <= pStore[2*i+1] )
|
||||
if ( Aig_RManCompareSigs( &pSigs[2*i+0], &pSigs[2*i+1], nVars ) <= 0 )
|
||||
continue;
|
||||
uCanonPhase |= (1 << i);
|
||||
TempSig = pSigs[2*i+0];
|
||||
pSigs[2*i+0] = pSigs[2*i+1];
|
||||
pSigs[2*i+1] = TempSig;
|
||||
Kit_TruthChangePhase( pIn, nVars, i );
|
||||
}
|
||||
// permute
|
||||
Counter = 0;
|
||||
do {
|
||||
fChange = 0;
|
||||
for ( i = 0; i < nVars-1; i++ )
|
||||
{
|
||||
// if ( pStore[2*i] <= pStore[2*(i+1)] )
|
||||
if ( Aig_RManCompareSigs( &pSigs[2*i], &pSigs[2*(i+1)], nVars ) <= 0 )
|
||||
continue;
|
||||
Counter++;
|
||||
fChange = 1;
|
||||
|
||||
Temp = pCanonPerm[i];
|
||||
pCanonPerm[i] = pCanonPerm[i+1];
|
||||
pCanonPerm[i+1] = Temp;
|
||||
|
||||
TempSig = pSigs[2*i];
|
||||
pSigs[2*i] = pSigs[2*(i+1)];
|
||||
pSigs[2*(i+1)] = TempSig;
|
||||
|
||||
TempSig = pSigs[2*i+1];
|
||||
pSigs[2*i+1] = pSigs[2*(i+1)+1];
|
||||
pSigs[2*(i+1)+1] = TempSig;
|
||||
|
||||
Kit_TruthSwapAdjacentVars( pOut, pIn, nVars, i );
|
||||
pTemp = pIn; pIn = pOut; pOut = pTemp;
|
||||
}
|
||||
} while ( fChange );
|
||||
|
||||
// swap if it was moved an even number of times
|
||||
if ( fReturnIn ^ !(Counter & 1) )
|
||||
Kit_TruthCopy( pOut, pIn, nVars );
|
||||
return uCanonPhase;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Aig_Obj_t * Bdc_FunCopyHop( Bdc_Fun_t * pObj )
|
||||
{ return Aig_NotCond( Bdc_FuncCopy(Bdc_Regular(pObj)), Bdc_IsComplement(pObj) ); }
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Records one function.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Aig_RManSaveOne( Aig_RMan_t * p, unsigned * pTruth, int nVars )
|
||||
{
|
||||
int i, nNodes, RetValue;
|
||||
Bdc_Fun_t * pFunc;
|
||||
Aig_Obj_t * pTerm;
|
||||
// perform decomposition
|
||||
RetValue = Bdc_ManDecompose( p->pBidec, pTruth, NULL, nVars, NULL, 1000 );
|
||||
if ( RetValue < 0 )
|
||||
{
|
||||
printf( "Decomposition failed.\n" );
|
||||
return;
|
||||
}
|
||||
// convert back into HOP
|
||||
Bdc_FuncSetCopy( Bdc_ManFunc( p->pBidec, 0 ), Aig_ManConst1(p->pAig) );
|
||||
for ( i = 0; i < nVars; i++ )
|
||||
Bdc_FuncSetCopy( Bdc_ManFunc( p->pBidec, i+1 ), Aig_IthVar(p->pAig, i) );
|
||||
nNodes = Bdc_ManNodeNum(p->pBidec);
|
||||
for ( i = nVars + 1; i < nNodes; i++ )
|
||||
{
|
||||
pFunc = Bdc_ManFunc( p->pBidec, i );
|
||||
Bdc_FuncSetCopy( pFunc, Aig_And( p->pAig,
|
||||
Bdc_FunCopyHop(Bdc_FuncFanin0(pFunc)),
|
||||
Bdc_FunCopyHop(Bdc_FuncFanin1(pFunc)) ) );
|
||||
}
|
||||
pTerm = Bdc_FunCopyHop( Bdc_ManRoot(p->pBidec) );
|
||||
pTerm = Aig_ObjCreatePo( p->pAig, pTerm );
|
||||
// assert( pTerm->fPhase == 0 );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Records one function.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Aig_RManRecord( unsigned * pTruth, int nVarsInit )
|
||||
{
|
||||
int fVerify = 1;
|
||||
Kit_DsdNtk_t * pNtk;
|
||||
Kit_DsdObj_t * pObj;
|
||||
unsigned uPhaseC;
|
||||
int i, nVars, nWords;
|
||||
int fUniqueVars;
|
||||
|
||||
if ( nVarsInit > RMAN_MAXVARS )
|
||||
{
|
||||
printf( "The number of variables in too large.\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( s_pRMan == NULL )
|
||||
s_pRMan = Aig_RManStart();
|
||||
s_pRMan->nTotal++;
|
||||
// canonicize the function
|
||||
pNtk = Kit_DsdDecompose( pTruth, nVarsInit );
|
||||
pObj = Kit_DsdNonDsdPrimeMax( pNtk );
|
||||
if ( pObj == NULL || pObj->nFans == 3 )
|
||||
{
|
||||
s_pRMan->nTtDsd++;
|
||||
Kit_DsdNtkFree( pNtk );
|
||||
return;
|
||||
}
|
||||
nVars = pObj->nFans;
|
||||
s_pRMan->nVarFuncs[nVars]++;
|
||||
if ( nVars < nVarsInit )
|
||||
s_pRMan->nTtDsdPart++;
|
||||
else
|
||||
s_pRMan->nTtDsdNot++;
|
||||
// compute the number of words
|
||||
nWords = Aig_TruthWordNum( nVars );
|
||||
// copy the function
|
||||
memcpy( s_pRMan->pTruthInit, Kit_DsdObjTruth(pObj), 4*nWords );
|
||||
Kit_DsdNtkFree( pNtk );
|
||||
// canonicize the output
|
||||
if ( s_pRMan->pTruthInit[0] & 1 )
|
||||
Kit_TruthNot( s_pRMan->pTruthInit, s_pRMan->pTruthInit, nVars );
|
||||
memcpy( s_pRMan->pTruth, s_pRMan->pTruthInit, 4*nWords );
|
||||
|
||||
// canonize the function
|
||||
for ( i = 0; i < nVars; i++ )
|
||||
s_pRMan->pPerm[i] = i;
|
||||
uPhaseC = Aig_RManSemiCanonicize( s_pRMan->pTruthTemp, s_pRMan->pTruth, nVars, s_pRMan->pPerm, s_pRMan->pMints, 1 );
|
||||
// check unique variables
|
||||
fUniqueVars = Aig_RManVarsAreUnique( s_pRMan->pMints, nVars );
|
||||
s_pRMan->nUniqueVars += fUniqueVars;
|
||||
|
||||
/*
|
||||
printf( "%4d : ", s_pRMan->nTotal );
|
||||
printf( "%2d %2d ", nVarsInit, nVars );
|
||||
Extra_PrintBinary( stdout, &uPhaseC, nVars );
|
||||
printf( " " );
|
||||
for ( i = 0; i < nVars; i++ )
|
||||
printf( "%2d/%2d ", s_pRMan->pMints[2*i], s_pRMan->pMints[2*i+1] );
|
||||
printf( "\n" );
|
||||
Aig_RManPrintUniqueVars( s_pRMan->pMints, nVars );
|
||||
Extra_PrintBinary( stdout, s_pRMan->pTruth, 1<<nVars ); printf( "\n\n" );
|
||||
*/
|
||||
/*
|
||||
printf( "\n" );
|
||||
printf( "%4d : ", s_pRMan->nTotal );
|
||||
printf( "%2d %2d ", nVarsInit, nVars );
|
||||
printf( " " );
|
||||
printf( "\n" );
|
||||
Aig_RManPrintUniqueVars( s_pRMan->pMints, nVars );
|
||||
// Aig_RManPrintSigs( s_pRMan->pMints, nVars );
|
||||
*/
|
||||
|
||||
//Extra_PrintBinary( stdout, s_pRMan->pTruth, 1<<nVars ); printf( "\n\n" );
|
||||
|
||||
if ( Aig_RManTableFindOrAdd( s_pRMan, s_pRMan->pTruth, nVars ) )
|
||||
Aig_RManSaveOne( s_pRMan, s_pRMan->pTruth, nVars );
|
||||
|
||||
if ( fVerify )
|
||||
{
|
||||
// derive reverse permutation
|
||||
for ( i = 0; i < nVars; i++ )
|
||||
s_pRMan->pPermR[i] = s_pRMan->pPerm[i];
|
||||
// implement permutation
|
||||
Kit_TruthPermute( s_pRMan->pTruthTemp, s_pRMan->pTruth, nVars, s_pRMan->pPermR, 1 );
|
||||
// implement polarity
|
||||
for ( i = 0; i < nVars; i++ )
|
||||
if ( uPhaseC & (1 << i) )
|
||||
Kit_TruthChangePhase( s_pRMan->pTruth, nVars, i );
|
||||
|
||||
// perform verification
|
||||
if ( fUniqueVars && !Kit_TruthIsEqual( s_pRMan->pTruth, s_pRMan->pTruthInit, nVars ) )
|
||||
printf( "Verification failed.\n" );
|
||||
}
|
||||
//Aig_RManPrintVarProfile( s_pRMan->pTruth, nVars, s_pRMan->pTruthTemp );
|
||||
//Extra_PrintBinary( stdout, s_pRMan->pTruth, 1<<nVars ); printf( "\n" );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -978,6 +978,7 @@ Aig_Man_t * Aig_ManDupOneOutput( Aig_Man_t * p, int iPoNum, int fAddRegs )
|
|||
return pNew;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -199,17 +199,19 @@ void Aig_ManStop( Aig_Man_t * p )
|
|||
assert( !pObj->fMarkA && !pObj->fMarkB );
|
||||
// Aig_TableProfile( p );
|
||||
Aig_MmFixedStop( p->pMemObjs, 0 );
|
||||
if ( p->vPis ) Vec_PtrFree( p->vPis );
|
||||
if ( p->vPos ) Vec_PtrFree( p->vPos );
|
||||
if ( p->vObjs ) Vec_PtrFree( p->vObjs );
|
||||
if ( p->vBufs ) Vec_PtrFree( p->vBufs );
|
||||
if ( p->vLevelR ) Vec_IntFree( p->vLevelR );
|
||||
if ( p->vLevels ) Vec_VecFree( p->vLevels );
|
||||
if ( p->vFlopNums) Vec_IntFree( p->vFlopNums );
|
||||
if ( p->vFlopReprs)Vec_IntFree( p->vFlopReprs );
|
||||
if ( p->pManExdc ) Aig_ManStop( p->pManExdc );
|
||||
if ( p->vOnehots ) Vec_VecFree( (Vec_Vec_t *)p->vOnehots );
|
||||
if ( p->vClockDoms)Vec_VecFree( p->vClockDoms );
|
||||
if ( p->vPis ) Vec_PtrFree( p->vPis );
|
||||
if ( p->vPos ) Vec_PtrFree( p->vPos );
|
||||
if ( p->vObjs ) Vec_PtrFree( p->vObjs );
|
||||
if ( p->vBufs ) Vec_PtrFree( p->vBufs );
|
||||
if ( p->vLevelR ) Vec_IntFree( p->vLevelR );
|
||||
if ( p->vLevels ) Vec_VecFree( p->vLevels );
|
||||
if ( p->vFlopNums) Vec_IntFree( p->vFlopNums );
|
||||
if ( p->vFlopReprs) Vec_IntFree( p->vFlopReprs );
|
||||
if ( p->pManExdc ) Aig_ManStop( p->pManExdc );
|
||||
if ( p->vOnehots ) Vec_VecFree( (Vec_Vec_t *)p->vOnehots );
|
||||
if ( p->vClockDoms) Vec_VecFree( p->vClockDoms );
|
||||
if ( p->vProbs ) Vec_IntFree( p->vProbs );
|
||||
FREE( p->pFastSim );
|
||||
FREE( p->pData );
|
||||
FREE( p->pSeqModel );
|
||||
FREE( p->pName );
|
||||
|
|
|
|||
|
|
@ -39,17 +39,22 @@
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Aig_NodeDeref_rec( Aig_Obj_t * pNode, unsigned LevelMin )
|
||||
int Aig_NodeDeref_rec( Aig_Obj_t * pNode, unsigned LevelMin, float * pPower, float * pProbs )
|
||||
{
|
||||
float Power0 = 0.0, Power1 = 0.0;
|
||||
Aig_Obj_t * pFanin;
|
||||
int Counter = 0;
|
||||
if ( pProbs )
|
||||
*pPower = 0.0;
|
||||
if ( Aig_ObjIsPi(pNode) )
|
||||
return 0;
|
||||
// consider the first fanin
|
||||
pFanin = Aig_ObjFanin0(pNode);
|
||||
assert( pFanin->nRefs > 0 );
|
||||
if ( --pFanin->nRefs == 0 && (!LevelMin || pFanin->Level > LevelMin) )
|
||||
Counter += Aig_NodeDeref_rec( pFanin, LevelMin );
|
||||
Counter += Aig_NodeDeref_rec( pFanin, LevelMin, &Power0, pProbs );
|
||||
if ( pProbs )
|
||||
*pPower += Power0 + 2.0 * pProbs[pFanin->Id] * (1.0 - pProbs[pFanin->Id]);
|
||||
// skip the buffer
|
||||
if ( Aig_ObjIsBuf(pNode) )
|
||||
return Counter;
|
||||
|
|
@ -58,7 +63,9 @@ int Aig_NodeDeref_rec( Aig_Obj_t * pNode, unsigned LevelMin )
|
|||
pFanin = Aig_ObjFanin1(pNode);
|
||||
assert( pFanin->nRefs > 0 );
|
||||
if ( --pFanin->nRefs == 0 && (!LevelMin || pFanin->Level > LevelMin) )
|
||||
Counter += Aig_NodeDeref_rec( pFanin, LevelMin );
|
||||
Counter += Aig_NodeDeref_rec( pFanin, LevelMin, &Power1, pProbs );
|
||||
if ( pProbs )
|
||||
*pPower += Power1 + 2.0 * pProbs[pFanin->Id] * (1.0 - pProbs[pFanin->Id]);
|
||||
return Counter + 1;
|
||||
}
|
||||
|
||||
|
|
@ -173,7 +180,7 @@ int Aig_NodeMffsSupp( Aig_Man_t * p, Aig_Obj_t * pNode, int LevelMin, Vec_Ptr_t
|
|||
assert( Aig_ObjIsNode(pNode) );
|
||||
if ( vSupp ) Vec_PtrClear( vSupp );
|
||||
Aig_ManIncrementTravId( p );
|
||||
ConeSize1 = Aig_NodeDeref_rec( pNode, LevelMin );
|
||||
ConeSize1 = Aig_NodeDeref_rec( pNode, LevelMin, NULL, NULL );
|
||||
Aig_NodeMffsSupp_rec( p, pNode, LevelMin, vSupp, 1, NULL );
|
||||
ConeSize2 = Aig_NodeRef_rec( pNode, LevelMin );
|
||||
assert( ConeSize1 == ConeSize2 );
|
||||
|
|
@ -192,13 +199,14 @@ int Aig_NodeMffsSupp( Aig_Man_t * p, Aig_Obj_t * pNode, int LevelMin, Vec_Ptr_t
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Aig_NodeMffsLabel( Aig_Man_t * p, Aig_Obj_t * pNode )
|
||||
int Aig_NodeMffsLabel( Aig_Man_t * p, Aig_Obj_t * pNode, float * pPower )
|
||||
{
|
||||
int ConeSize1, ConeSize2;
|
||||
assert( (pPower != NULL) == (p->vProbs != NULL) );
|
||||
assert( !Aig_IsComplement(pNode) );
|
||||
assert( Aig_ObjIsNode(pNode) );
|
||||
Aig_ManIncrementTravId( p );
|
||||
ConeSize1 = Aig_NodeDeref_rec( pNode, 0 );
|
||||
ConeSize1 = Aig_NodeDeref_rec( pNode, 0, pPower, p->vProbs? (float *)p->vProbs->pArray : NULL );
|
||||
ConeSize2 = Aig_NodeRefLabel_rec( p, pNode, 0 );
|
||||
assert( ConeSize1 == ConeSize2 );
|
||||
assert( ConeSize1 > 0 );
|
||||
|
|
@ -225,7 +233,7 @@ int Aig_NodeMffsLabelCut( Aig_Man_t * p, Aig_Obj_t * pNode, Vec_Ptr_t * vLeaves
|
|||
Aig_ManIncrementTravId( p );
|
||||
Vec_PtrForEachEntry( vLeaves, pObj, i )
|
||||
pObj->nRefs++;
|
||||
ConeSize1 = Aig_NodeDeref_rec( pNode, 0 );
|
||||
ConeSize1 = Aig_NodeDeref_rec( pNode, 0, NULL, NULL );
|
||||
ConeSize2 = Aig_NodeRefLabel_rec( p, pNode, 0 );
|
||||
Vec_PtrForEachEntry( vLeaves, pObj, i )
|
||||
pObj->nRefs--;
|
||||
|
|
@ -256,7 +264,7 @@ int Aig_NodeMffsExtendCut( Aig_Man_t * p, Aig_Obj_t * pNode, Vec_Ptr_t * vLeaves
|
|||
if ( LevelMax == 0 )
|
||||
return 0;
|
||||
// dereference the cut
|
||||
ConeSize1 = Aig_NodeDeref_rec( pNode, 0 );
|
||||
ConeSize1 = Aig_NodeDeref_rec( pNode, 0, NULL, NULL );
|
||||
// try expanding each node in the boundary
|
||||
ConeBest = AIG_INFINITY;
|
||||
pLeafBest = NULL;
|
||||
|
|
@ -264,7 +272,7 @@ int Aig_NodeMffsExtendCut( Aig_Man_t * p, Aig_Obj_t * pNode, Vec_Ptr_t * vLeaves
|
|||
{
|
||||
if ( (int)pObj->Level != LevelMax )
|
||||
continue;
|
||||
ConeCur1 = Aig_NodeDeref_rec( pObj, 0 );
|
||||
ConeCur1 = Aig_NodeDeref_rec( pObj, 0, NULL, NULL );
|
||||
if ( ConeBest > ConeCur1 )
|
||||
{
|
||||
ConeBest = ConeCur1;
|
||||
|
|
@ -276,7 +284,7 @@ int Aig_NodeMffsExtendCut( Aig_Man_t * p, Aig_Obj_t * pNode, Vec_Ptr_t * vLeaves
|
|||
assert( pLeafBest != NULL );
|
||||
assert( Aig_ObjIsNode(pLeafBest) );
|
||||
// deref the best leaf
|
||||
ConeCur1 = Aig_NodeDeref_rec( pLeafBest, 0 );
|
||||
ConeCur1 = Aig_NodeDeref_rec( pLeafBest, 0, NULL, NULL );
|
||||
// collect the cut nodes
|
||||
Vec_PtrClear( vResult );
|
||||
Aig_ManIncrementTravId( p );
|
||||
|
|
|
|||
|
|
@ -116,6 +116,15 @@ Aig_Obj_t * Aig_ObjCreate( Aig_Man_t * p, Aig_Obj_t * pGhost )
|
|||
assert( !Aig_IsComplement(pObj->pHaig) );
|
||||
// printf( "Creating HAIG node %d equivalent to node %d.\n", pObj->pHaig->Id, pObj->Id );
|
||||
}
|
||||
// create the power counter
|
||||
if ( p->vProbs )
|
||||
{
|
||||
float Prob0 = Aig_Int2Float( Vec_IntEntry( p->vProbs, Aig_ObjFaninId0(pObj) ) );
|
||||
float Prob1 = Aig_Int2Float( Vec_IntEntry( p->vProbs, Aig_ObjFaninId1(pObj) ) );
|
||||
Prob0 = Aig_ObjFaninC0(pObj)? 1.0 - Prob0 : Prob0;
|
||||
Prob1 = Aig_ObjFaninC1(pObj)? 1.0 - Prob1 : Prob1;
|
||||
Vec_IntSetEntry( p->vProbs, pObj->Id, Aig_Float2Int(Prob0 * Prob1) );
|
||||
}
|
||||
return pObj;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -232,6 +232,7 @@ int Aig_ManSeqCleanup( Aig_Man_t * p )
|
|||
Vec_PtrFree( vNodes );
|
||||
p->nTruePis = Aig_ManPiNum(p) - Aig_ManRegNum(p);
|
||||
p->nTruePos = Aig_ManPoNum(p) - Aig_ManRegNum(p);
|
||||
Aig_ManSetPioNumbers( p );
|
||||
// remove dangling nodes
|
||||
return Aig_ManCleanup( p );
|
||||
}
|
||||
|
|
@ -577,6 +578,58 @@ void Aig_ManComputeSccs( Aig_Man_t * p )
|
|||
Vec_VecFree( (Vec_Vec_t *)vSupports );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs partitioned register sweep.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Man_t * Aig_ManSclPart( Aig_Man_t * pAig, int fLatchConst, int fLatchEqual, int fVerbose )
|
||||
{
|
||||
Vec_Ptr_t * vResult;
|
||||
Vec_Int_t * vPart;
|
||||
int i, nCountPis, nCountRegs;
|
||||
int * pMapBack;
|
||||
Aig_Man_t * pTemp, * pNew;
|
||||
int nClasses;
|
||||
|
||||
if ( pAig->vClockDoms )
|
||||
{
|
||||
vResult = Vec_PtrAlloc( 100 );
|
||||
Vec_PtrForEachEntry( (Vec_Ptr_t *)pAig->vClockDoms, vPart, i )
|
||||
Vec_PtrPush( vResult, Vec_IntDup(vPart) );
|
||||
}
|
||||
else
|
||||
vResult = Aig_ManRegPartitionSimple( pAig, 0, 0 );
|
||||
|
||||
Aig_ManReprStart( pAig, Aig_ManObjNumMax(pAig) );
|
||||
Vec_PtrForEachEntry( vResult, vPart, i )
|
||||
{
|
||||
pTemp = Aig_ManRegCreatePart( pAig, vPart, &nCountPis, &nCountRegs, &pMapBack );
|
||||
Aig_ManSetRegNum( pTemp, pTemp->nRegs );
|
||||
if (nCountPis>0)
|
||||
{
|
||||
pNew = Aig_ManScl( pTemp, fLatchConst, fLatchEqual, fVerbose );
|
||||
nClasses = Aig_TransferMappedClasses( pAig, pTemp, pMapBack );
|
||||
if ( fVerbose )
|
||||
printf( "%3d : Reg = %4d. PI = %4d. (True = %4d. Regs = %4d.) And = %5d. It = %3d. Cl = %5d\n",
|
||||
i, Vec_IntSize(vPart), Aig_ManPiNum(pTemp)-Vec_IntSize(vPart), nCountPis, nCountRegs, Aig_ManNodeNum(pTemp), 0, nClasses );
|
||||
Aig_ManStop( pNew );
|
||||
}
|
||||
Aig_ManStop( pTemp );
|
||||
free( pMapBack );
|
||||
}
|
||||
pNew = Aig_ManDupRepr( pAig, 0 );
|
||||
Aig_ManSeqCleanup( pNew );
|
||||
Vec_VecFree( (Vec_Vec_t*)vResult );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Gives the current ABC network to AIG manager for processing.]
|
||||
|
|
@ -596,6 +649,10 @@ Aig_Man_t * Aig_ManScl( Aig_Man_t * pAig, int fLatchConst, int fLatchEqual, int
|
|||
Aig_Man_t * pAigInit, * pAigNew;
|
||||
Aig_Obj_t * pFlop1, * pFlop2;
|
||||
int i, Entry1, Entry2, nTruePis;//, nRegs;
|
||||
|
||||
if ( pAig->vClockDoms && Vec_VecSize(pAig->vClockDoms) > 0 )
|
||||
return Aig_ManSclPart( pAig, fLatchConst, fLatchEqual, fVerbose);
|
||||
|
||||
// store the original AIG
|
||||
assert( pAig->vFlopNums == NULL );
|
||||
pAigInit = pAig;
|
||||
|
|
|
|||
|
|
@ -44,10 +44,10 @@ static inline int Aig_XsimInv( int Value )
|
|||
}
|
||||
static inline int Aig_XsimAnd( int Value0, int Value1 )
|
||||
{
|
||||
if ( Value0 == AIG_XVS0 || Value1 == AIG_XVS0 )
|
||||
return AIG_XVS0;
|
||||
if ( Value0 == AIG_XVSX || Value1 == AIG_XVSX )
|
||||
return AIG_XVSX;
|
||||
if ( Value0 == AIG_XVS0 || Value1 == AIG_XVS0 )
|
||||
return AIG_XVS0;
|
||||
assert( Value0 == AIG_XVS1 && Value1 == AIG_XVS1 );
|
||||
return AIG_XVS1;
|
||||
}
|
||||
|
|
@ -371,7 +371,7 @@ Vec_Ptr_t * Aig_ManTernarySimulate( Aig_Man_t * p, int fVerbose )
|
|||
}
|
||||
|
||||
// printf( "%d ", Aig_TsiStateCount(pTsi, pState) );
|
||||
// Aig_TsiStatePrint( pTsi, pState );
|
||||
//Aig_TsiStatePrint( pTsi, pState );
|
||||
// check if this state exists
|
||||
if ( Aig_TsiStateLookup( pTsi, pState, pTsi->nWords ) )
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
SRC += src/aig/aig/aigCheck.c \
|
||||
src/aig/aig/aigCanon.c \
|
||||
src/aig/aig/aigCuts.c \
|
||||
src/aig/aig/aigDfs.c \
|
||||
src/aig/aig/aigDup.c \
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
***********************************************************************/
|
||||
|
||||
#include "bbr.h"
|
||||
#include "mtr.h"
|
||||
#include "mtr.h"
|
||||
|
||||
/*
|
||||
The ideas implemented in this file are inspired by the paper:
|
||||
|
|
@ -721,7 +721,7 @@ int Bbr_BuildTreeNode( DdManager * dd,
|
|||
Bbr_ImageNode_t * pNode1, * pNode2;
|
||||
Bbr_ImageVar_t * pVar;
|
||||
Bbr_ImageNode_t * pNode;
|
||||
DdNode * bCube, * bTemp, * bSuppTemp, * bParts;
|
||||
DdNode * bCube, * bTemp, * bSuppTemp;//, * bParts;
|
||||
int iNode1, iNode2;
|
||||
int iVarBest, nSupp, v;
|
||||
|
||||
|
|
@ -773,7 +773,7 @@ int Bbr_BuildTreeNode( DdManager * dd,
|
|||
Bbr_FindBestPartitions( dd, pVar->bParts, nNodes, pNodes, &iNode1, &iNode2 );
|
||||
pNode1 = pNodes[iNode1];
|
||||
pNode2 = pNodes[iNode2];
|
||||
|
||||
/*
|
||||
// it is not possible that a var appears only in these two
|
||||
// otherwise, it would have a different cost
|
||||
bParts = Cudd_bddAnd( dd, dd->vars[iNode1], dd->vars[iNode2] ); Cudd_Ref( bParts );
|
||||
|
|
@ -781,7 +781,7 @@ int Bbr_BuildTreeNode( DdManager * dd,
|
|||
if ( pVars[v] && pVars[v]->bParts == bParts )
|
||||
assert( 0 );
|
||||
Cudd_RecursiveDeref( dd, bParts );
|
||||
|
||||
*/
|
||||
// combines two nodes
|
||||
pNode = Bbr_CombineTwoNodes( dd, b1, pNode1, pNode2 );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,7 +72,8 @@ Bdc_Man_t * Bdc_ManAlloc( Bdc_Par_t * pPars )
|
|||
p->nNodesAlloc = 512;
|
||||
p->pNodes = ALLOC( Bdc_Fun_t, p->nNodesAlloc );
|
||||
// memory
|
||||
p->vMemory = Vec_IntStart( 4 * p->nWords * p->nNodesAlloc );
|
||||
p->vMemory = Vec_IntStart( 8 * p->nWords * p->nNodesAlloc );
|
||||
Vec_IntClear(p->vMemory);
|
||||
// set up hash table
|
||||
p->nTableSize = (1 << p->pPars->nVarsMax);
|
||||
p->pTable = ALLOC( Bdc_Fun_t *, p->nTableSize );
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@ struct Bdc_Man_t_
|
|||
static inline Bdc_Fun_t * Bdc_FunNew( Bdc_Man_t * p ) { Bdc_Fun_t * pRes; if ( p->nNodes >= p->nNodesAlloc || p->nNodesNew >= p->nNodesMax ) return NULL; pRes = p->pNodes + p->nNodes++; p->nNodesNew++; memset( pRes, 0, sizeof(Bdc_Fun_t) ); return pRes; }
|
||||
static inline Bdc_Fun_t * Bdc_FunWithId( Bdc_Man_t * p, int Id ) { assert( Id < p->nNodes ); return p->pNodes + Id; }
|
||||
static inline int Bdc_FunId( Bdc_Man_t * p, Bdc_Fun_t * pFun ) { return pFun - p->pNodes; }
|
||||
static inline void Bdc_IsfStart( Bdc_Man_t * p, Bdc_Isf_t * pF ) { pF->uSupp = 0; pF->uUniq = 0; pF->puOn = Vec_IntFetch( p->vMemory, p->nWords ); pF->puOff = Vec_IntFetch( p->vMemory, p->nWords ); }
|
||||
static inline void Bdc_IsfStart( Bdc_Man_t * p, Bdc_Isf_t * pF ) { pF->uSupp = 0; pF->uUniq = 0; pF->puOn = Vec_IntFetch( p->vMemory, p->nWords ); pF->puOff = Vec_IntFetch( p->vMemory, p->nWords ); assert( pF->puOff && pF->puOn ); }
|
||||
static inline void Bdc_IsfClean( Bdc_Isf_t * p ) { p->uSupp = 0; p->uUniq = 0; }
|
||||
static inline void Bdc_IsfCopy( Bdc_Isf_t * p, Bdc_Isf_t * q ) { Bdc_Isf_t T = *p; *p = *q; *q = T; }
|
||||
static inline void Bdc_IsfNot( Bdc_Isf_t * p ) { unsigned * puT = p->puOn; p->puOn = p->puOff; p->puOff = puT; }
|
||||
|
|
|
|||
|
|
@ -0,0 +1,100 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [cec.h]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Combinatinoal equivalence checking.]
|
||||
|
||||
Synopsis [External declarations.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: cec.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef __CEC_H__
|
||||
#define __CEC_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// INCLUDES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// PARAMETERS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// BASIC TYPES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// dynamic SAT parameters
|
||||
typedef struct Cec_ParSat_t_ Cec_ParSat_t;
|
||||
struct Cec_ParSat_t_
|
||||
{
|
||||
int nBTLimit; // conflict limit at a node
|
||||
int nSatVarMax; // the max number of SAT variables
|
||||
int nCallsRecycle; // calls to perform before recycling SAT solver
|
||||
int fFirstStop; // stop on the first sat output
|
||||
int fPolarFlip; // uses polarity adjustment
|
||||
int fVerbose; // verbose stats
|
||||
};
|
||||
|
||||
// combinational SAT sweeping parameters
|
||||
typedef struct Cec_ParCsw_t_ Cec_ParCsw_t;
|
||||
struct Cec_ParCsw_t_
|
||||
{
|
||||
int nWords; // the number of simulation words
|
||||
int nRounds; // the number of simulation rounds
|
||||
int nBTlimit; // conflict limit at a node
|
||||
int fRewriting; // enables AIG rewriting
|
||||
int fVerbose; // verbose stats
|
||||
};
|
||||
|
||||
// combinational equivalence checking parameters
|
||||
typedef struct Cec_ParCec_t_ Cec_ParCec_t;
|
||||
struct Cec_ParCec_t_
|
||||
{
|
||||
int nIters; // iterations of SAT solving/sweeping
|
||||
int nBTLimitBeg; // starting backtrack limit
|
||||
int nBTlimitMulti; // multiple of backtrack limit
|
||||
int fUseSmartCnf; // use smart CNF computation
|
||||
int fRewriting; // enables AIG rewriting
|
||||
int fSatSweeping; // enables SAT sweeping
|
||||
int fFirstStop; // stop on the first sat output
|
||||
int fVerbose; // verbose stats
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// MACRO DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*=== cecCore.c ==========================================================*/
|
||||
extern void Cec_ManSatSetDefaultParams( Cec_ParSat_t * p );
|
||||
extern void Cec_ManCswSetDefaultParams( Cec_ParCsw_t * p );
|
||||
extern void Cec_ManCecSetDefaultParams( Cec_ParCec_t * p );
|
||||
extern int Cec_Solve( Aig_Man_t * pAig0, Aig_Man_t * pAig1, Cec_ParCec_t * p );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -0,0 +1,151 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [cecAig.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Combinatinoal equivalence checking.]
|
||||
|
||||
Synopsis [AIG manipulation.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: cecAig.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "cecInt.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Derives combinational miter of the two AIGs.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Obj_t * Cec_DeriveMiter_rec( Aig_Man_t * pNew, Aig_Obj_t * pObj )
|
||||
{
|
||||
if ( pObj->pData )
|
||||
return pObj->pData;
|
||||
Cec_DeriveMiter_rec( pNew, Aig_ObjFanin0(pObj) );
|
||||
if ( Aig_ObjIsBuf(pObj) )
|
||||
return pObj->pData = Aig_ObjChild0Copy(pObj);
|
||||
Cec_DeriveMiter_rec( pNew, Aig_ObjFanin1(pObj) );
|
||||
pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
|
||||
Aig_Regular(pObj->pData)->pHaig = pObj->pHaig;
|
||||
return pObj->pData;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Derives combinational miter of the two AIGs.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Man_t * Cec_DeriveMiter( Aig_Man_t * p0, Aig_Man_t * p1 )
|
||||
{
|
||||
Bar_Progress_t * pProgress = NULL;
|
||||
Aig_Man_t * pNew;
|
||||
Aig_Obj_t * pObj0, * pObj1, * pObjNew;
|
||||
int i;
|
||||
assert( Aig_ManPiNum(p0) == Aig_ManPiNum(p1) );
|
||||
assert( Aig_ManPoNum(p0) == Aig_ManPoNum(p1) );
|
||||
// create the new manager
|
||||
pNew = Aig_ManStart( Aig_ManNodeNum(p0) + Aig_ManNodeNum(p1) );
|
||||
pNew->pName = Aig_UtilStrsav( p0->pName );
|
||||
// create the PIs
|
||||
Aig_ManCleanData( p0 );
|
||||
Aig_ManCleanData( p1 );
|
||||
Aig_ManConst1(p0)->pData = Aig_ManConst1(pNew);
|
||||
Aig_ManConst1(p1)->pData = Aig_ManConst1(pNew);
|
||||
Aig_ManForEachPi( p0, pObj0, i )
|
||||
{
|
||||
pObjNew = Aig_ObjCreatePi( pNew );
|
||||
pObj0->pData = pObjNew;
|
||||
Aig_ManPi(p1, i)->pData = pObjNew;
|
||||
}
|
||||
// add logic for the POs
|
||||
pProgress = Bar_ProgressStart( stdout, Aig_ManPoNum(p0) );
|
||||
Aig_ManForEachPo( p0, pObj0, i )
|
||||
{
|
||||
Bar_ProgressUpdate( pProgress, i, "Miter..." );
|
||||
pObj1 = Aig_ManPo( p1, i );
|
||||
Cec_DeriveMiter_rec( pNew, Aig_ObjFanin0(pObj0) );
|
||||
Cec_DeriveMiter_rec( pNew, Aig_ObjFanin0(pObj1) );
|
||||
pObjNew = Aig_Exor( pNew, Aig_ObjChild0Copy(pObj0), Aig_ObjChild0Copy(pObj1) );
|
||||
Aig_ObjCreatePo( pNew, pObjNew );
|
||||
}
|
||||
Bar_ProgressStop( pProgress );
|
||||
Aig_ManCleanup( pNew );
|
||||
Aig_ManSetRegNum( pNew, 0 );
|
||||
// check the resulting network
|
||||
// if ( !Aig_ManCheck(pNew) )
|
||||
// printf( "Cec_DeriveMiter(): The check has failed.\n" );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Duplicates AIG in the DFS order.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Man_t * Cec_Duplicate( Aig_Man_t * p )
|
||||
{
|
||||
Aig_Man_t * pNew;
|
||||
Aig_Obj_t * pObj;
|
||||
int i;
|
||||
// create the new manager
|
||||
pNew = Aig_ManStart( Aig_ManNodeNum(p) );
|
||||
pNew->pName = Aig_UtilStrsav( p->pName );
|
||||
// create the PIs
|
||||
Aig_ManCleanData( p );
|
||||
Aig_ManConst1(p)->pData = Aig_ManConst1(pNew);
|
||||
Aig_ManForEachPi( p, pObj, i )
|
||||
pObj->pData = Aig_ObjCreatePi( pNew );
|
||||
// add logic for the POs
|
||||
Aig_ManForEachPo( p, pObj, i )
|
||||
{
|
||||
Cec_DeriveMiter_rec( pNew, Aig_ObjFanin0(pObj) );
|
||||
Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) );
|
||||
}
|
||||
Aig_ManCleanup( pNew );
|
||||
Aig_ManSetRegNum( pNew, 0 );
|
||||
assert( Aig_ManBufNum(p) != 0 || Aig_ManNodeNum(p) == Aig_ManNodeNum(pNew) );
|
||||
// check the resulting network
|
||||
// if ( !Aig_ManCheck(pNew) )
|
||||
// printf( "Cec_DeriveMiter(): The check has failed.\n" );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,569 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [cecClass.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Combinatinoal equivalence checking.]
|
||||
|
||||
Synopsis [Equivalence class representation.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: cecClass.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "cecInt.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Man_t * Caig_ManSpecReduce( Caig_Man_t * p )
|
||||
{
|
||||
Aig_Man_t * pAig;
|
||||
Aig_Obj_t ** pCopy;
|
||||
Aig_Obj_t * pMiter, * pRes0, * pRes1, * pRepr;
|
||||
int i;
|
||||
pCopy = ALLOC( Aig_Obj_t *, p->nObjs );
|
||||
pCopy[0] = NULL;
|
||||
pAig = Aig_ManStart( p->nNodes );
|
||||
for ( i = 1; i < p->nObjs; i++ )
|
||||
{
|
||||
if ( p->pFans0[i] == 0 ) // pi always has zero first fanin
|
||||
{
|
||||
pCopy[i] = Aig_ObjCreatePi( pAig );
|
||||
continue;
|
||||
}
|
||||
if ( p->pFans1[i] == 0 ) // po always has non-zero 1st fanin and zero 2nd fanin
|
||||
continue;
|
||||
pRes0 = pCopy[ Cec_Lit2Var(p->pFans0[i]) ];
|
||||
pRes0 = Aig_NotCond( pRes0, Cec_LitIsCompl(p->pFans0[i]) );
|
||||
pRes1 = pCopy[ Cec_Lit2Var(p->pFans1[i]) ];
|
||||
pRes1 = Aig_NotCond( pRes1, Cec_LitIsCompl(p->pFans1[i]) );
|
||||
pCopy[i] = Aig_And( pAig, pRes0, pRes1 );
|
||||
if ( p->pReprs[i] < 0 )
|
||||
continue;
|
||||
assert( p->pReprs[i] < i );
|
||||
pRepr = p->pReprs[i]? pCopy[ p->pReprs[i] ] : Aig_ManConst1(pAig);
|
||||
if ( Aig_Regular(pCopy[i]) == Aig_Regular(pRepr) )
|
||||
continue;
|
||||
pMiter = Aig_Exor( pAig, pCopy[i], pRepr );
|
||||
Aig_ObjCreatePo( pAig, Aig_NotCond(pMiter, Aig_ObjPhaseReal(pMiter)) );
|
||||
}
|
||||
free( pCopy );
|
||||
Aig_ManSetRegNum( pAig, 0 );
|
||||
Aig_ManCleanup( pAig );
|
||||
return pAig;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Caig_ManCountOne( Caig_Man_t * p, int i )
|
||||
{
|
||||
int Ent, nLits = 0;
|
||||
assert( p->pReprs[i] < 0 && p->pNexts[i] > 0 );
|
||||
for ( Ent = p->pNexts[i]; Ent; Ent = p->pNexts[Ent] )
|
||||
{
|
||||
assert( p->pReprs[Ent] == i );
|
||||
nLits++;
|
||||
}
|
||||
return 1 + nLits;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Caig_ManCountLiterals( Caig_Man_t * p )
|
||||
{
|
||||
int i, nLits = 0;
|
||||
for ( i = 1; i < p->nObjs; i++ )
|
||||
if ( p->pReprs[i] < 0 && p->pNexts[i] > 0 )
|
||||
nLits += Caig_ManCountOne(p, i) - 1;
|
||||
return nLits;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Caig_ManPrintOne( Caig_Man_t * p, int i, int Counter )
|
||||
{
|
||||
int Ent;
|
||||
printf( "Class %4d : Num = %2d {", Counter, Caig_ManCountOne(p, i) );
|
||||
for ( Ent = i; Ent; Ent = p->pNexts[Ent] )
|
||||
printf(" %d", Ent );
|
||||
printf( " }\n" );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Caig_ManPrintClasses( Caig_Man_t * p, int fVerbose )
|
||||
{
|
||||
int i, Counter = 0, Counter1 = 0, CounterX = 0, nLits;
|
||||
for ( i = 1; i < p->nObjs; i++ )
|
||||
{
|
||||
if ( p->pReprs[i] < 0 && p->pNexts[i] > 0 )
|
||||
Counter++;
|
||||
if ( p->pReprs[i] == 0 )
|
||||
Counter1++;
|
||||
if ( p->pReprs[i] < 0 && p->pNexts[i] == 0 )
|
||||
CounterX++;
|
||||
}
|
||||
nLits = Caig_ManCountLiterals( p );
|
||||
printf( "Class = %6d. Const1 = %6d. Other = %6d. Lits = %7d. Total = %7d.\n",
|
||||
Counter, Counter1, CounterX, nLits, nLits+Counter1 );
|
||||
if ( fVerbose )
|
||||
for ( i = 1; i < p->nObjs; i++ )
|
||||
if ( p->pReprs[i] < 0 && p->pNexts[i] > 0 )
|
||||
Caig_ManPrintOne( p, i, ++Counter );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Caig_ManCollectSimsSimple( Caig_Man_t * p, int i )
|
||||
{
|
||||
int Ent;
|
||||
Vec_PtrClear( p->vSims );
|
||||
for ( Ent = i; Ent; Ent = p->pNexts[Ent] )
|
||||
Vec_PtrPush( p->vSims, p->pSims + Ent );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Caig_ManCollectSimsNormal( Caig_Man_t * p, int i )
|
||||
{
|
||||
unsigned * pSim;
|
||||
int Ent;
|
||||
Vec_PtrClear( p->vSims );
|
||||
for ( Ent = i; Ent; Ent = p->pNexts[Ent] )
|
||||
{
|
||||
pSim = Caig_ManSimDeref( p, Ent );
|
||||
Vec_PtrPush( p->vSims, pSim + 1 );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Caig_ManCompareEqual( unsigned * p0, unsigned * p1, int nWords )
|
||||
{
|
||||
int w;
|
||||
if ( (p0[0] & 1) == (p1[0] & 1) )
|
||||
{
|
||||
for ( w = 0; w < nWords; w++ )
|
||||
if ( p0[w] != p1[w] )
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( w = 0; w < nWords; w++ )
|
||||
if ( p0[w] != ~p1[w] )
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Caig_ManCompareConst( unsigned * p, int nWords )
|
||||
{
|
||||
int w;
|
||||
if ( p[0] & 1 )
|
||||
{
|
||||
for ( w = 0; w < nWords; w++ )
|
||||
if ( p[w] != ~0 )
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( w = 0; w < nWords; w++ )
|
||||
if ( p[w] != 0 )
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Caig_ManClassCreate( Caig_Man_t * p, Vec_Int_t * vClass )
|
||||
{
|
||||
int * pNext, Repr, Ent, i;
|
||||
assert( Vec_IntSize(vClass) > 0 );
|
||||
Vec_IntForEachEntry( vClass, Ent, i )
|
||||
{
|
||||
if ( i == 0 )
|
||||
{
|
||||
Repr = Ent;
|
||||
p->pReprs[Ent] = -1;
|
||||
pNext = p->pNexts + Ent;
|
||||
}
|
||||
else
|
||||
{
|
||||
p->pReprs[Ent] = Repr;
|
||||
*pNext = Ent;
|
||||
pNext = p->pNexts + Ent;
|
||||
}
|
||||
}
|
||||
*pNext = 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Caig_ManClassRefineOne( Caig_Man_t * p, int i, Vec_Ptr_t * vSims )
|
||||
{
|
||||
unsigned * pSim0, * pSim1;
|
||||
int Ent, c = 0, d = 0;
|
||||
Vec_IntClear( p->vClassOld );
|
||||
Vec_IntClear( p->vClassNew );
|
||||
pSim0 = Vec_PtrEntry( vSims, c++ );
|
||||
Vec_IntPush( p->vClassOld, i );
|
||||
for ( Ent = p->pNexts[i]; Ent; Ent = p->pNexts[Ent] )
|
||||
{
|
||||
pSim1 = Vec_PtrEntry( vSims, c++ );
|
||||
if ( Caig_ManCompareEqual( pSim0, pSim1, p->nWords ) )
|
||||
Vec_IntPush( p->vClassOld, Ent );
|
||||
else
|
||||
{
|
||||
Vec_IntPush( p->vClassNew, Ent );
|
||||
Vec_PtrWriteEntry( vSims, d++, pSim1 );
|
||||
}
|
||||
}
|
||||
Vec_PtrShrink( vSims, d );
|
||||
if ( Vec_IntSize(p->vClassNew) == 0 )
|
||||
return 0;
|
||||
Caig_ManClassCreate( p, p->vClassOld );
|
||||
Caig_ManClassCreate( p, p->vClassNew );
|
||||
if ( Vec_IntSize(p->vClassNew) > 1 )
|
||||
return 1 + Caig_ManClassRefineOne( p, Vec_IntEntry(p->vClassNew,0), vSims );
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Caig_ManHashKey( unsigned * pSim, int nWords, int nTableSize )
|
||||
{
|
||||
static int s_Primes[16] = {
|
||||
1291, 1699, 1999, 2357, 2953, 3313, 3907, 4177,
|
||||
4831, 5147, 5647, 6343, 6899, 7103, 7873, 8147 };
|
||||
unsigned uHash = 0;
|
||||
int i;
|
||||
if ( pSim[0] & 1 )
|
||||
for ( i = 0; i < nWords; i++ )
|
||||
uHash ^= ~pSim[i] * s_Primes[i & 0xf];
|
||||
else
|
||||
for ( i = 0; i < nWords; i++ )
|
||||
uHash ^= pSim[i] * s_Primes[i & 0xf];
|
||||
return (int)(uHash % nTableSize);
|
||||
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Caig_ManClassesCreate( Caig_Man_t * p )
|
||||
{
|
||||
int * pTable, nTableSize, i, Key;
|
||||
nTableSize = Aig_PrimeCudd( 100 + p->nObjs / 10 );
|
||||
pTable = CALLOC( int, nTableSize );
|
||||
p->pReprs = ALLOC( int, p->nObjs );
|
||||
p->pNexts = CALLOC( int, p->nObjs );
|
||||
for ( i = 1; i < p->nObjs; i++ )
|
||||
{
|
||||
if ( Caig_ManCompareConst( p->pSims + i, 1 ) )
|
||||
{
|
||||
p->pReprs[i] = 0;
|
||||
continue;
|
||||
}
|
||||
Key = Caig_ManHashKey( p->pSims + i, 1, nTableSize );
|
||||
if ( pTable[Key] == 0 )
|
||||
p->pReprs[i] = -1;
|
||||
else
|
||||
{
|
||||
p->pNexts[ pTable[Key] ] = i;
|
||||
p->pReprs[i] = p->pReprs[ pTable[Key] ];
|
||||
if ( p->pReprs[i] == -1 )
|
||||
p->pReprs[i] = pTable[Key];
|
||||
}
|
||||
pTable[Key] = i;
|
||||
}
|
||||
FREE( pTable );
|
||||
Caig_ManPrintClasses( p, 0 );
|
||||
// refine classes
|
||||
p->vSims = Vec_PtrAlloc( 100 );
|
||||
p->vClassOld = Vec_IntAlloc( 100 );
|
||||
p->vClassNew = Vec_IntAlloc( 100 );
|
||||
for ( i = 1; i < p->nObjs; i++ )
|
||||
if ( p->pReprs[i] < 0 && p->pNexts[i] > 0 )
|
||||
{
|
||||
Caig_ManCollectSimsSimple( p, i );
|
||||
Caig_ManClassRefineOne( p, i, p->vSims );
|
||||
}
|
||||
// clean memory
|
||||
memset( p->pSims, 0, sizeof(unsigned) * p->nObjs );
|
||||
Caig_ManPrintClasses( p, 0 );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Caig_ManSimulateSimple( Caig_Man_t * p )
|
||||
{
|
||||
unsigned Res0, Res1;
|
||||
int i;
|
||||
for ( i = 1; i < p->nObjs; i++ )
|
||||
{
|
||||
if ( p->pFans0[i] == 0 ) // pi
|
||||
{
|
||||
p->pSims[i] = Aig_ManRandom( 0 );
|
||||
continue;
|
||||
}
|
||||
Res0 = p->pSims[Cec_Lit2Var(p->pFans0[i])];
|
||||
Res1 = p->pSims[Cec_Lit2Var(p->pFans1[i])];
|
||||
p->pSims[i] = (Cec_LitIsCompl(p->pFans0[i]) ? ~Res0: Res0) &
|
||||
(Cec_LitIsCompl(p->pFans1[i]) ? ~Res1: Res1);
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Caig_ManProcessClass( Caig_Man_t * p, int i )
|
||||
{
|
||||
Caig_ManCollectSimsNormal( p, i );
|
||||
Caig_ManClassRefineOne( p, i, p->vSims );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Caig_ManProcessRefined( Caig_Man_t * p, Vec_Int_t * vRefined )
|
||||
{
|
||||
Vec_Int_t * vClasses;
|
||||
int * pTable, nTableSize, i, Key, iNode;
|
||||
unsigned * pSim;
|
||||
if ( Vec_IntSize(vRefined) == 0 )
|
||||
return;
|
||||
nTableSize = Aig_PrimeCudd( 100 + Vec_IntSize(vRefined) / 5 );
|
||||
pTable = CALLOC( int, nTableSize );
|
||||
vClasses = Vec_IntAlloc( 100 );
|
||||
Vec_IntForEachEntry( vRefined, iNode, i )
|
||||
{
|
||||
pSim = Caig_ManSimRead( p, iNode );
|
||||
assert( !Caig_ManCompareConst( pSim + 1, p->nWords ) );
|
||||
Key = Caig_ManHashKey( pSim + 1, p->nWords, nTableSize );
|
||||
if ( pTable[Key] == 0 )
|
||||
{
|
||||
assert( p->pReprs[iNode] == 0 );
|
||||
assert( p->pNexts[iNode] == 0 );
|
||||
p->pReprs[iNode] = -1;
|
||||
Vec_IntPush( vClasses, iNode );
|
||||
}
|
||||
else
|
||||
{
|
||||
p->pNexts[ pTable[Key] ] = iNode;
|
||||
p->pReprs[iNode] = p->pReprs[ pTable[Key] ];
|
||||
if ( p->pReprs[iNode] == -1 )
|
||||
p->pReprs[iNode] = pTable[Key];
|
||||
assert( p->pReprs[iNode] > 0 );
|
||||
}
|
||||
pTable[Key] = iNode;
|
||||
}
|
||||
FREE( pTable );
|
||||
// refine classes
|
||||
Vec_IntForEachEntry( vClasses, iNode, i )
|
||||
{
|
||||
if ( p->pNexts[iNode] == 0 )
|
||||
{
|
||||
Caig_ManSimDeref( p, iNode );
|
||||
continue;
|
||||
}
|
||||
Caig_ManCollectSimsNormal( p, iNode );
|
||||
Caig_ManClassRefineOne( p, iNode, p->vSims );
|
||||
}
|
||||
Vec_IntFree( vClasses );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Caig_Man_t * Caig_ManClassesPrepare( Aig_Man_t * pAig, int nWords, int nIters )
|
||||
{
|
||||
Caig_Man_t * p;
|
||||
int i;
|
||||
Aig_ManRandom( 1 );
|
||||
p = Caig_ManCreate( pAig );
|
||||
p->nWords = 1;
|
||||
Caig_ManSimulateSimple( p );
|
||||
Caig_ManClassesCreate( p );
|
||||
p->nWords = nWords;
|
||||
for ( i = 0; i < nIters; i++ )
|
||||
{
|
||||
Caig_ManSimulateRound( p, 0 );
|
||||
Caig_ManPrintClasses( p, 0 );
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,328 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [cecCnf.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Combinatinoal equivalence checking.]
|
||||
|
||||
Synopsis [CNF computation.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: cecCnf.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "cecInt.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Addes clauses to the solver.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Cec_AddClausesMux( Cec_ManSat_t * p, Aig_Obj_t * pNode )
|
||||
{
|
||||
Aig_Obj_t * pNodeI, * pNodeT, * pNodeE;
|
||||
int pLits[4], RetValue, VarF, VarI, VarT, VarE, fCompT, fCompE;
|
||||
|
||||
assert( !Aig_IsComplement( pNode ) );
|
||||
assert( Aig_ObjIsMuxType( pNode ) );
|
||||
// get nodes (I = if, T = then, E = else)
|
||||
pNodeI = Aig_ObjRecognizeMux( pNode, &pNodeT, &pNodeE );
|
||||
// get the variable numbers
|
||||
VarF = Cec_ObjSatNum(p,pNode);
|
||||
VarI = Cec_ObjSatNum(p,pNodeI);
|
||||
VarT = Cec_ObjSatNum(p,Aig_Regular(pNodeT));
|
||||
VarE = Cec_ObjSatNum(p,Aig_Regular(pNodeE));
|
||||
// get the complementation flags
|
||||
fCompT = Aig_IsComplement(pNodeT);
|
||||
fCompE = Aig_IsComplement(pNodeE);
|
||||
|
||||
// f = ITE(i, t, e)
|
||||
|
||||
// i' + t' + f
|
||||
// i' + t + f'
|
||||
// i + e' + f
|
||||
// i + e + f'
|
||||
|
||||
// create four clauses
|
||||
pLits[0] = toLitCond(VarI, 1);
|
||||
pLits[1] = toLitCond(VarT, 1^fCompT);
|
||||
pLits[2] = toLitCond(VarF, 0);
|
||||
if ( p->pPars->fPolarFlip )
|
||||
{
|
||||
if ( pNodeI->fPhase ) pLits[0] = lit_neg( pLits[0] );
|
||||
if ( Aig_Regular(pNodeT)->fPhase ) pLits[1] = lit_neg( pLits[1] );
|
||||
if ( pNode->fPhase ) pLits[2] = lit_neg( pLits[2] );
|
||||
}
|
||||
RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 );
|
||||
assert( RetValue );
|
||||
pLits[0] = toLitCond(VarI, 1);
|
||||
pLits[1] = toLitCond(VarT, 0^fCompT);
|
||||
pLits[2] = toLitCond(VarF, 1);
|
||||
if ( p->pPars->fPolarFlip )
|
||||
{
|
||||
if ( pNodeI->fPhase ) pLits[0] = lit_neg( pLits[0] );
|
||||
if ( Aig_Regular(pNodeT)->fPhase ) pLits[1] = lit_neg( pLits[1] );
|
||||
if ( pNode->fPhase ) pLits[2] = lit_neg( pLits[2] );
|
||||
}
|
||||
RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 );
|
||||
assert( RetValue );
|
||||
pLits[0] = toLitCond(VarI, 0);
|
||||
pLits[1] = toLitCond(VarE, 1^fCompE);
|
||||
pLits[2] = toLitCond(VarF, 0);
|
||||
if ( p->pPars->fPolarFlip )
|
||||
{
|
||||
if ( pNodeI->fPhase ) pLits[0] = lit_neg( pLits[0] );
|
||||
if ( Aig_Regular(pNodeE)->fPhase ) pLits[1] = lit_neg( pLits[1] );
|
||||
if ( pNode->fPhase ) pLits[2] = lit_neg( pLits[2] );
|
||||
}
|
||||
RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 );
|
||||
assert( RetValue );
|
||||
pLits[0] = toLitCond(VarI, 0);
|
||||
pLits[1] = toLitCond(VarE, 0^fCompE);
|
||||
pLits[2] = toLitCond(VarF, 1);
|
||||
if ( p->pPars->fPolarFlip )
|
||||
{
|
||||
if ( pNodeI->fPhase ) pLits[0] = lit_neg( pLits[0] );
|
||||
if ( Aig_Regular(pNodeE)->fPhase ) pLits[1] = lit_neg( pLits[1] );
|
||||
if ( pNode->fPhase ) pLits[2] = lit_neg( pLits[2] );
|
||||
}
|
||||
RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 );
|
||||
assert( RetValue );
|
||||
|
||||
// two additional clauses
|
||||
// t' & e' -> f'
|
||||
// t & e -> f
|
||||
|
||||
// t + e + f'
|
||||
// t' + e' + f
|
||||
|
||||
if ( VarT == VarE )
|
||||
{
|
||||
// assert( fCompT == !fCompE );
|
||||
return;
|
||||
}
|
||||
|
||||
pLits[0] = toLitCond(VarT, 0^fCompT);
|
||||
pLits[1] = toLitCond(VarE, 0^fCompE);
|
||||
pLits[2] = toLitCond(VarF, 1);
|
||||
if ( p->pPars->fPolarFlip )
|
||||
{
|
||||
if ( Aig_Regular(pNodeT)->fPhase ) pLits[0] = lit_neg( pLits[0] );
|
||||
if ( Aig_Regular(pNodeE)->fPhase ) pLits[1] = lit_neg( pLits[1] );
|
||||
if ( pNode->fPhase ) pLits[2] = lit_neg( pLits[2] );
|
||||
}
|
||||
RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 );
|
||||
assert( RetValue );
|
||||
pLits[0] = toLitCond(VarT, 1^fCompT);
|
||||
pLits[1] = toLitCond(VarE, 1^fCompE);
|
||||
pLits[2] = toLitCond(VarF, 0);
|
||||
if ( p->pPars->fPolarFlip )
|
||||
{
|
||||
if ( Aig_Regular(pNodeT)->fPhase ) pLits[0] = lit_neg( pLits[0] );
|
||||
if ( Aig_Regular(pNodeE)->fPhase ) pLits[1] = lit_neg( pLits[1] );
|
||||
if ( pNode->fPhase ) pLits[2] = lit_neg( pLits[2] );
|
||||
}
|
||||
RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 );
|
||||
assert( RetValue );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Addes clauses to the solver.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Cec_AddClausesSuper( Cec_ManSat_t * p, Aig_Obj_t * pNode, Vec_Ptr_t * vSuper )
|
||||
{
|
||||
Aig_Obj_t * pFanin;
|
||||
int * pLits, nLits, RetValue, i;
|
||||
assert( !Aig_IsComplement(pNode) );
|
||||
assert( Aig_ObjIsNode( pNode ) );
|
||||
// create storage for literals
|
||||
nLits = Vec_PtrSize(vSuper) + 1;
|
||||
pLits = ALLOC( int, nLits );
|
||||
// suppose AND-gate is A & B = C
|
||||
// add !A => !C or A + !C
|
||||
Vec_PtrForEachEntry( vSuper, pFanin, i )
|
||||
{
|
||||
pLits[0] = toLitCond(Cec_ObjSatNum(p,Aig_Regular(pFanin)), Aig_IsComplement(pFanin));
|
||||
pLits[1] = toLitCond(Cec_ObjSatNum(p,pNode), 1);
|
||||
if ( p->pPars->fPolarFlip )
|
||||
{
|
||||
if ( Aig_Regular(pFanin)->fPhase ) pLits[0] = lit_neg( pLits[0] );
|
||||
if ( pNode->fPhase ) pLits[1] = lit_neg( pLits[1] );
|
||||
}
|
||||
RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 2 );
|
||||
assert( RetValue );
|
||||
}
|
||||
// add A & B => C or !A + !B + C
|
||||
Vec_PtrForEachEntry( vSuper, pFanin, i )
|
||||
{
|
||||
pLits[i] = toLitCond(Cec_ObjSatNum(p,Aig_Regular(pFanin)), !Aig_IsComplement(pFanin));
|
||||
if ( p->pPars->fPolarFlip )
|
||||
{
|
||||
if ( Aig_Regular(pFanin)->fPhase ) pLits[i] = lit_neg( pLits[i] );
|
||||
}
|
||||
}
|
||||
pLits[nLits-1] = toLitCond(Cec_ObjSatNum(p,pNode), 0);
|
||||
if ( p->pPars->fPolarFlip )
|
||||
{
|
||||
if ( pNode->fPhase ) pLits[nLits-1] = lit_neg( pLits[nLits-1] );
|
||||
}
|
||||
RetValue = sat_solver_addclause( p->pSat, pLits, pLits + nLits );
|
||||
assert( RetValue );
|
||||
free( pLits );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Collects the supergate.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Cec_CollectSuper_rec( Aig_Obj_t * pObj, Vec_Ptr_t * vSuper, int fFirst, int fUseMuxes )
|
||||
{
|
||||
// if the new node is complemented or a PI, another gate begins
|
||||
if ( Aig_IsComplement(pObj) || Aig_ObjIsPi(pObj) ||
|
||||
(!fFirst && Aig_ObjRefs(pObj) > 1) ||
|
||||
(fUseMuxes && Aig_ObjIsMuxType(pObj)) )
|
||||
{
|
||||
Vec_PtrPushUnique( vSuper, pObj );
|
||||
return;
|
||||
}
|
||||
// go through the branches
|
||||
Cec_CollectSuper_rec( Aig_ObjChild0(pObj), vSuper, 0, fUseMuxes );
|
||||
Cec_CollectSuper_rec( Aig_ObjChild1(pObj), vSuper, 0, fUseMuxes );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Collects the supergate.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Cec_CollectSuper( Aig_Obj_t * pObj, int fUseMuxes, Vec_Ptr_t * vSuper )
|
||||
{
|
||||
assert( !Aig_IsComplement(pObj) );
|
||||
assert( !Aig_ObjIsPi(pObj) );
|
||||
Vec_PtrClear( vSuper );
|
||||
Cec_CollectSuper_rec( pObj, vSuper, 1, fUseMuxes );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Updates the solver clause database.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Cec_ObjAddToFrontier( Cec_ManSat_t * p, Aig_Obj_t * pObj, Vec_Ptr_t * vFrontier )
|
||||
{
|
||||
assert( !Aig_IsComplement(pObj) );
|
||||
if ( Cec_ObjSatNum(p,pObj) )
|
||||
return;
|
||||
assert( Cec_ObjSatNum(p,pObj) == 0 );
|
||||
if ( Aig_ObjIsConst1(pObj) )
|
||||
return;
|
||||
Vec_PtrPush( p->vUsedNodes, pObj );
|
||||
Cec_ObjSetSatNum( p, pObj, p->nSatVars++ );
|
||||
if ( Aig_ObjIsNode(pObj) )
|
||||
Vec_PtrPush( vFrontier, pObj );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Updates the solver clause database.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Cec_CnfNodeAddToSolver( Cec_ManSat_t * p, Aig_Obj_t * pObj )
|
||||
{
|
||||
Vec_Ptr_t * vFrontier;
|
||||
Aig_Obj_t * pNode, * pFanin;
|
||||
int i, k, fUseMuxes = 1;
|
||||
// quit if CNF is ready
|
||||
if ( Cec_ObjSatNum(p,pObj) )
|
||||
return;
|
||||
// start the frontier
|
||||
vFrontier = Vec_PtrAlloc( 100 );
|
||||
Cec_ObjAddToFrontier( p, pObj, vFrontier );
|
||||
// explore nodes in the frontier
|
||||
Vec_PtrForEachEntry( vFrontier, pNode, i )
|
||||
{
|
||||
// create the supergate
|
||||
assert( Cec_ObjSatNum(p,pNode) );
|
||||
if ( fUseMuxes && Aig_ObjIsMuxType(pNode) )
|
||||
{
|
||||
Vec_PtrClear( p->vFanins );
|
||||
Vec_PtrPushUnique( p->vFanins, Aig_ObjFanin0( Aig_ObjFanin0(pNode) ) );
|
||||
Vec_PtrPushUnique( p->vFanins, Aig_ObjFanin0( Aig_ObjFanin1(pNode) ) );
|
||||
Vec_PtrPushUnique( p->vFanins, Aig_ObjFanin1( Aig_ObjFanin0(pNode) ) );
|
||||
Vec_PtrPushUnique( p->vFanins, Aig_ObjFanin1( Aig_ObjFanin1(pNode) ) );
|
||||
Vec_PtrForEachEntry( p->vFanins, pFanin, k )
|
||||
Cec_ObjAddToFrontier( p, Aig_Regular(pFanin), vFrontier );
|
||||
Cec_AddClausesMux( p, pNode );
|
||||
}
|
||||
else
|
||||
{
|
||||
Cec_CollectSuper( pNode, fUseMuxes, p->vFanins );
|
||||
Vec_PtrForEachEntry( p->vFanins, pFanin, k )
|
||||
Cec_ObjAddToFrontier( p, Aig_Regular(pFanin), vFrontier );
|
||||
Cec_AddClausesSuper( p, pNode, p->vFanins );
|
||||
}
|
||||
assert( Vec_PtrSize(p->vFanins) > 1 );
|
||||
}
|
||||
Vec_PtrFree( vFrontier );
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,233 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [cecCore.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Combinatinoal equivalence checking.]
|
||||
|
||||
Synopsis [Core procedures.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: cecCore.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "cecInt.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [This procedure sets default parameters.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Cec_ManSatSetDefaultParams( Cec_ParSat_t * p )
|
||||
{
|
||||
memset( p, 0, sizeof(Cec_ParSat_t) );
|
||||
p->nBTLimit = 100; // conflict limit at a node
|
||||
p->nSatVarMax = 2000; // the max number of SAT variables
|
||||
p->nCallsRecycle = 10; // calls to perform before recycling SAT solver
|
||||
p->fFirstStop = 0; // stop on the first sat output
|
||||
p->fPolarFlip = 0; // uses polarity adjustment
|
||||
p->fVerbose = 0; // verbose stats
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [This procedure sets default parameters.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Cec_ManCswSetDefaultParams( Cec_ParCsw_t * p )
|
||||
{
|
||||
memset( p, 0, sizeof(Cec_ParCsw_t) );
|
||||
p->nWords = 15; // the number of simulation words
|
||||
p->nRounds = 10; // the number of simulation rounds
|
||||
p->nBTlimit = 10; // conflict limit at a node
|
||||
p->fRewriting = 0; // enables AIG rewriting
|
||||
p->fVerbose = 1; // verbose stats
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [This procedure sets default parameters.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Cec_ManCecSetDefaultParams( Cec_ParCec_t * p )
|
||||
{
|
||||
memset( p, 0, sizeof(Cec_ParCec_t) );
|
||||
p->nIters = 5; // iterations of SAT solving/sweeping
|
||||
p->nBTLimitBeg = 2; // starting backtrack limit
|
||||
p->nBTlimitMulti = 8; // multiple of backtrack limiter
|
||||
p->fUseSmartCnf = 0; // use smart CNF computation
|
||||
p->fRewriting = 0; // enables AIG rewriting
|
||||
p->fSatSweeping = 0; // enables SAT sweeping
|
||||
p->fFirstStop = 0; // stop on the first sat output
|
||||
p->fVerbose = 1; // verbose stats
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs equivalence checking.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Cec_Sweep( Aig_Man_t * pAig, int nBTLimit )
|
||||
{
|
||||
Cec_MtrStatus_t Status;
|
||||
Cec_ParCsw_t ParsCsw, * pParsCsw = &ParsCsw;
|
||||
Cec_ParSat_t ParsSat, * pParsSat = &ParsSat;
|
||||
Caig_Man_t * pCaig;
|
||||
Aig_Man_t * pSRAig;
|
||||
int clk;
|
||||
|
||||
Cec_ManCswSetDefaultParams( pParsCsw );
|
||||
pParsCsw->nBTlimit = nBTLimit;
|
||||
pCaig = Caig_ManClassesPrepare( pAig, pParsCsw->nWords, pParsCsw->nRounds );
|
||||
|
||||
pSRAig = Caig_ManSpecReduce( pCaig );
|
||||
Aig_ManPrintStats( pSRAig );
|
||||
|
||||
Cec_ManSatSetDefaultParams( pParsSat );
|
||||
pParsSat->fFirstStop = 0;
|
||||
pParsSat->nBTLimit = pParsCsw->nBTlimit;
|
||||
clk = clock();
|
||||
Status = Cec_SatSolveOutputs( pSRAig, pParsSat );
|
||||
Cec_MiterStatusPrint( Status, "SRM ", clock() - clk );
|
||||
|
||||
Aig_ManStop( pSRAig );
|
||||
|
||||
Caig_ManDelete( pCaig );
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs equivalence checking.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Cec_Solve( Aig_Man_t * pAig0, Aig_Man_t * pAig1, Cec_ParCec_t * pPars )
|
||||
{
|
||||
Cec_ParSat_t ParsSat, * pParsSat = &ParsSat;
|
||||
Cec_MtrStatus_t Status;
|
||||
Aig_Man_t * pMiter;
|
||||
int i, clk = clock();
|
||||
if ( pPars->fVerbose )
|
||||
{
|
||||
Status = Cec_MiterStatusTrivial( pAig0 );
|
||||
Status.nNodes += pAig1? Aig_ManNodeNum( pAig1 ) : 0;
|
||||
Cec_MiterStatusPrint( Status, "Init ", 0 );
|
||||
}
|
||||
// create combinational miter
|
||||
if ( pAig1 == NULL )
|
||||
{
|
||||
Status = Cec_MiterStatus( pAig0 );
|
||||
if ( Status.nSat > 0 && pPars->fFirstStop )
|
||||
{
|
||||
if ( pPars->fVerbose )
|
||||
printf( "Output %d is trivially SAT.\n", Status.iOut );
|
||||
return 0;
|
||||
}
|
||||
if ( Status.nUndec == 0 )
|
||||
{
|
||||
if ( pPars->fVerbose )
|
||||
printf( "The miter has no undecided outputs.\n" );
|
||||
return 1;
|
||||
}
|
||||
pMiter = Cec_Duplicate( pAig0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
pMiter = Cec_DeriveMiter( pAig0, pAig1 );
|
||||
Status = Cec_MiterStatus( pMiter );
|
||||
if ( Status.nSat > 0 && pPars->fFirstStop )
|
||||
{
|
||||
if ( pPars->fVerbose )
|
||||
printf( "Output %d is trivially SAT.\n", Status.iOut );
|
||||
Aig_ManStop( pMiter );
|
||||
return 0;
|
||||
}
|
||||
if ( Status.nUndec == 0 )
|
||||
{
|
||||
if ( pPars->fVerbose )
|
||||
printf( "The problem is solved by structrual hashing.\n" );
|
||||
Aig_ManStop( pMiter );
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if ( pPars->fVerbose )
|
||||
Cec_MiterStatusPrint( Status, "Strash", clock() - clk );
|
||||
// start parameter structures
|
||||
Cec_ManSatSetDefaultParams( pParsSat );
|
||||
pParsSat->fFirstStop = pPars->fFirstStop;
|
||||
pParsSat->nBTLimit = pPars->nBTLimitBeg;
|
||||
for ( i = 0; i < pPars->nIters; i++ )
|
||||
{
|
||||
// try SAT solving
|
||||
clk = clock();
|
||||
pParsSat->nBTLimit *= pPars->nBTlimitMulti;
|
||||
Status = Cec_SatSolveOutputs( pMiter, pParsSat );
|
||||
if ( pPars->fVerbose )
|
||||
Cec_MiterStatusPrint( Status, "SAT ", clock() - clk );
|
||||
if ( Status.nSat && pParsSat->fFirstStop )
|
||||
break;
|
||||
if ( Status.nUndec == 0 )
|
||||
break;
|
||||
|
||||
// try rewriting
|
||||
|
||||
// try SAT sweeping
|
||||
Cec_Sweep( pMiter, 10 );
|
||||
i = i;
|
||||
}
|
||||
Aig_ManStop( pMiter );
|
||||
return 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,220 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [cecInt.h]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Combinatinoal equivalence checking.]
|
||||
|
||||
Synopsis [External declarations.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: cecInt.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef __CEC_INT_H__
|
||||
#define __CEC_INT_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// INCLUDES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "aig.h"
|
||||
#include "satSolver.h"
|
||||
#include "bar.h"
|
||||
#include "cec.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// PARAMETERS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// BASIC TYPES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct Cec_ManSat_t_ Cec_ManSat_t;
|
||||
struct Cec_ManSat_t_
|
||||
{
|
||||
// parameters
|
||||
Cec_ParSat_t * pPars;
|
||||
// AIGs used in the package
|
||||
Aig_Man_t * pAig; // the AIG whose outputs are considered
|
||||
Vec_Int_t * vStatus; // status for each output
|
||||
// SAT solving
|
||||
sat_solver * pSat; // recyclable SAT solver
|
||||
int nSatVars; // the counter of SAT variables
|
||||
int * pSatVars; // mapping of each node into its SAT var
|
||||
Vec_Ptr_t * vUsedNodes; // nodes whose SAT vars are assigned
|
||||
int nRecycles; // the number of times SAT solver was recycled
|
||||
int nCallsSince; // the number of calls since the last recycle
|
||||
Vec_Ptr_t * vFanins; // fanins of the CNF node
|
||||
// SAT calls statistics
|
||||
int nSatUnsat; // the number of proofs
|
||||
int nSatSat; // the number of failure
|
||||
int nSatUndec; // the number of timeouts
|
||||
// runtime stats
|
||||
int timeSatUnsat; // unsat
|
||||
int timeSatSat; // sat
|
||||
int timeSatUndec; // undecided
|
||||
int timeTotal; // total runtime
|
||||
};
|
||||
|
||||
typedef struct Cec_ManCla_t_ Cec_ManCla_t;
|
||||
|
||||
typedef struct Cec_ManCsw_t_ Cec_ManCsw_t;
|
||||
struct Cec_ManCsw_t_
|
||||
{
|
||||
// parameters
|
||||
Cec_ParCsw_t * pPars;
|
||||
// AIGs used in the package
|
||||
Aig_Man_t * pAig; // the AIG for SAT sweeping
|
||||
Aig_Man_t * pFraig; // the AIG after SAT sweeping
|
||||
// equivalence classes
|
||||
Cec_ManCla_t * ppClasses; // equivalence classes of nodes
|
||||
// choice node statistics
|
||||
int nLits; // the number of lits in the cand equiv classes
|
||||
int nReprs; // the number of proved equivalent pairs
|
||||
int nEquivs; // the number of final equivalences
|
||||
int nChoices; // the number of final choice nodes
|
||||
};
|
||||
|
||||
typedef struct Cec_ManCec_t_ Cec_ManCec_t;
|
||||
struct Cec_ManCec_t_
|
||||
{
|
||||
// parameters
|
||||
Cec_ParCec_t * pPars;
|
||||
// AIGs used in the package
|
||||
Aig_Man_t * pAig; // the miter for equivalence checking
|
||||
// mapping of PI/PO nodes
|
||||
|
||||
// counter-example
|
||||
int * pCex; // counter-example
|
||||
int iOutput; // the output for this counter-example
|
||||
|
||||
// statistics
|
||||
|
||||
};
|
||||
|
||||
typedef struct Cec_MtrStatus_t_ Cec_MtrStatus_t;
|
||||
struct Cec_MtrStatus_t_
|
||||
{
|
||||
int nInputs; // the total number of inputs
|
||||
int nNodes; // the total number of nodes
|
||||
int nOutputs; // the total number of outputs
|
||||
int nUnsat; // the number of UNSAT outputs
|
||||
int nSat; // the number of SAT outputs
|
||||
int nUndec; // the number of undecided outputs
|
||||
int iOut; // the satisfied output
|
||||
};
|
||||
|
||||
// combinational simulation manager
|
||||
typedef struct Caig_Man_t_ Caig_Man_t;
|
||||
struct Caig_Man_t_
|
||||
{
|
||||
// parameters
|
||||
Aig_Man_t * pAig; // the AIG to be used for simulation
|
||||
int nWords; // the number of words to simulate
|
||||
// AIG representation
|
||||
int nPis; // the number of primary inputs
|
||||
int nPos; // the number of primary outputs
|
||||
int nNodes; // the number of internal nodes
|
||||
int nObjs; // nPis + nNodes + nPos + 1
|
||||
int * pFans0; // fanin0 for all objects
|
||||
int * pFans1; // fanin1 for all objects
|
||||
// simulation info
|
||||
unsigned short* pRefs; // reference counter for each node
|
||||
unsigned * pSims; // simlulation information for each node
|
||||
// recycable memory
|
||||
unsigned * pMems; // allocated simulaton memory
|
||||
int nWordsAlloc; // the number of allocated entries
|
||||
int nMems; // the number of used entries
|
||||
int nMemsMax; // the max number of used entries
|
||||
int MemFree; // next free entry
|
||||
// equivalence class representation
|
||||
int * pReprs; // representatives of each node
|
||||
int * pNexts; // nexts for each node
|
||||
// temporaries
|
||||
Vec_Ptr_t * vSims; // pointers to sim info
|
||||
Vec_Int_t * vClassOld; // old class numbers
|
||||
Vec_Int_t * vClassNew; // new class numbers
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// MACRO DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static inline int Cec_Var2Lit( int Var, int fCompl ) { return Var + Var + fCompl; }
|
||||
static inline int Cec_Lit2Var( int Lit ) { return Lit >> 1; }
|
||||
static inline int Cec_LitIsCompl( int Lit ) { return Lit & 1; }
|
||||
static inline int Cec_LitNot( int Lit ) { return Lit ^ 1; }
|
||||
static inline int Cec_LitNotCond( int Lit, int c ) { return Lit ^ (int)(c > 0); }
|
||||
static inline int Cec_LitRegular( int Lit ) { return Lit & ~01; }
|
||||
|
||||
static inline int Cec_ObjSatNum( Cec_ManSat_t * p, Aig_Obj_t * pObj ) { return p->pSatVars[pObj->Id]; }
|
||||
static inline void Cec_ObjSetSatNum( Cec_ManSat_t * p, Aig_Obj_t * pObj, int Num ) { p->pSatVars[pObj->Id] = Num; }
|
||||
|
||||
static inline Aig_Obj_t * Cec_ObjFraig( Aig_Obj_t * pObj ) { return pObj->pData; }
|
||||
static inline void Cec_ObjSetFraig( Aig_Obj_t * pObj, Aig_Obj_t * pNode ) { pObj->pData = pNode; }
|
||||
|
||||
static inline int Cec_ObjIsConst1Cand( Aig_Man_t * pAig, Aig_Obj_t * pObj )
|
||||
{
|
||||
return Aig_ObjRepr(pAig, pObj) == Aig_ManConst1(pAig);
|
||||
}
|
||||
static inline void Cec_ObjSetConst1Cand( Aig_Man_t * pAig, Aig_Obj_t * pObj )
|
||||
{
|
||||
assert( !Cec_ObjIsConst1Cand( pAig, pObj ) );
|
||||
Aig_ObjSetRepr( pAig, pObj, Aig_ManConst1(pAig) );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*=== cecAig.c ==========================================================*/
|
||||
extern Aig_Man_t * Cec_Duplicate( Aig_Man_t * p );
|
||||
extern Aig_Man_t * Cec_DeriveMiter( Aig_Man_t * p0, Aig_Man_t * p1 );
|
||||
/*=== cecClass.c ==========================================================*/
|
||||
extern Aig_Man_t * Caig_ManSpecReduce( Caig_Man_t * p );
|
||||
extern int Caig_ManCompareEqual( unsigned * p0, unsigned * p1, int nWords );
|
||||
extern int Caig_ManCompareConst( unsigned * p, int nWords );
|
||||
extern void Caig_ManProcessClass( Caig_Man_t * p, int i );
|
||||
extern void Caig_ManProcessRefined( Caig_Man_t * p, Vec_Int_t * vRefined );
|
||||
extern Caig_Man_t * Caig_ManClassesPrepare( Aig_Man_t * pAig, int nWords, int nIters );
|
||||
/*=== cecCnf.c ==========================================================*/
|
||||
extern void Cec_CnfNodeAddToSolver( Cec_ManSat_t * p, Aig_Obj_t * pObj );
|
||||
/*=== cecSat.c ==========================================================*/
|
||||
extern Cec_MtrStatus_t Cec_SatSolveOutputs( Aig_Man_t * pAig, Cec_ParSat_t * pPars );
|
||||
/*=== cecSim.c ==========================================================*/
|
||||
extern Caig_Man_t * Caig_ManCreate( Aig_Man_t * pAig );
|
||||
extern void Caig_ManDelete( Caig_Man_t * p );
|
||||
extern unsigned * Caig_ManSimRead( Caig_Man_t * p, int i );
|
||||
extern unsigned * Caig_ManSimRef( Caig_Man_t * p, int i );
|
||||
extern unsigned * Caig_ManSimDeref( Caig_Man_t * p, int i );
|
||||
extern int Caig_ManSimulateRound( Caig_Man_t * p, int fMiter );
|
||||
extern int Cec_ManSimulate( Aig_Man_t * pAig, int nWords, int nIters, int TimeLimit, int fMiter, int fVerbose );
|
||||
/*=== cecStatus.c ==========================================================*/
|
||||
extern int Cec_OutputStatus( Aig_Man_t * p, Aig_Obj_t * pObj );
|
||||
extern Cec_MtrStatus_t Cec_MiterStatus( Aig_Man_t * p );
|
||||
extern Cec_MtrStatus_t Cec_MiterStatusTrivial( Aig_Man_t * p );
|
||||
extern void Cec_MiterStatusPrint( Cec_MtrStatus_t S, char * pString, int Time );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [saigLoc.c]
|
||||
FileName [cecMan.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Sequential AIG package.]
|
||||
PackageName [Combinatinoal equivalence checking.]
|
||||
|
||||
Synopsis [Localization.]
|
||||
Synopsis [Manager pcocures.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
|
|
@ -14,11 +14,11 @@
|
|||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: saigLoc.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
Revision [$Id: cecMan.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "saig.h"
|
||||
#include "cecInt.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
|
|
@ -40,6 +40,17 @@
|
|||
|
||||
***********************************************************************/
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
|
|
@ -4,23 +4,21 @@
|
|||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Combinational equivalence checking.]
|
||||
PackageName [Combinatinoal equivalence checking.]
|
||||
|
||||
Synopsis [Backend calling the SAT solver.]
|
||||
Synopsis [SAT solver calls.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 30, 2007.]
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: cecSat.c,v 1.00 2007/06/30 00:00:00 alanmi Exp $]
|
||||
Revision [$Id: cecSat.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "aig.h"
|
||||
#include "cnf.h"
|
||||
#include "solver.h"
|
||||
#include "cecInt.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
|
|
@ -32,7 +30,7 @@
|
|||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Writes CNF into a file.]
|
||||
Synopsis [Creates the manager.]
|
||||
|
||||
Description []
|
||||
|
||||
|
|
@ -41,33 +39,25 @@
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
solver * Cnf_WriteIntoSolverNew( Cnf_Dat_t * p )
|
||||
Cec_ManSat_t * Cec_ManCreate( Aig_Man_t * pAig, Cec_ParSat_t * pPars )
|
||||
{
|
||||
solver * pSat;
|
||||
int i, status;
|
||||
pSat = solver_new();
|
||||
for ( i = 0; i < p->nVars; i++ )
|
||||
solver_newVar( pSat );
|
||||
for ( i = 0; i < p->nClauses; i++ )
|
||||
{
|
||||
if ( !solver_addClause( pSat, p->pClauses[i+1]-p->pClauses[i], p->pClauses[i] ) )
|
||||
{
|
||||
solver_delete( pSat );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
status = solver_simplify(pSat);
|
||||
if ( status == 0 )
|
||||
{
|
||||
solver_delete( pSat );
|
||||
return NULL;
|
||||
}
|
||||
return pSat;
|
||||
Cec_ManSat_t * p;
|
||||
// create interpolation manager
|
||||
p = ALLOC( Cec_ManSat_t, 1 );
|
||||
memset( p, 0, sizeof(Cec_ManSat_t) );
|
||||
p->pPars = pPars;
|
||||
p->pAig = pAig;
|
||||
// SAT solving
|
||||
p->nSatVars = 1;
|
||||
p->pSatVars = CALLOC( int, Aig_ManObjNumMax(pAig) );
|
||||
p->vUsedNodes = Vec_PtrAlloc( 1000 );
|
||||
p->vFanins = Vec_PtrAlloc( 100 );
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Adds the OR-clause.]
|
||||
Synopsis [Frees the manager.]
|
||||
|
||||
Description []
|
||||
|
||||
|
|
@ -76,25 +66,19 @@ solver * Cnf_WriteIntoSolverNew( Cnf_Dat_t * p )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Cnf_DataWriteAndClausesNew( void * p, Cnf_Dat_t * pCnf )
|
||||
void Cec_ManStop( Cec_ManSat_t * p )
|
||||
{
|
||||
/*
|
||||
sat_solver * pSat = p;
|
||||
Aig_Obj_t * pObj;
|
||||
int i, Lit;
|
||||
Aig_ManForEachPo( pCnf->pMan, pObj, i )
|
||||
{
|
||||
Lit = toLitCond( pCnf->pVarNums[pObj->Id], 0 );
|
||||
if ( !sat_solver_addclause( pSat, &Lit, &Lit+1 ) )
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
return 1;
|
||||
if ( p->pSat )
|
||||
sat_solver_delete( p->pSat );
|
||||
Vec_PtrFree( p->vUsedNodes );
|
||||
Vec_PtrFree( p->vFanins );
|
||||
FREE( p->pSatVars );
|
||||
free( p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Adds the OR-clause.]
|
||||
Synopsis [Recycles the SAT solver.]
|
||||
|
||||
Description []
|
||||
|
||||
|
|
@ -103,63 +87,106 @@ int Cnf_DataWriteAndClausesNew( void * p, Cnf_Dat_t * pCnf )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Cnf_DataWriteOrClauseNew( solver * pSat, Cnf_Dat_t * pCnf )
|
||||
void Cec_ManSatSolverRecycle( Cec_ManSat_t * p )
|
||||
{
|
||||
Aig_Obj_t * pObj;
|
||||
int i, * pLits;
|
||||
pLits = ALLOC( int, Aig_ManPoNum(pCnf->pMan) );
|
||||
Aig_ManForEachPo( pCnf->pMan, pObj, i )
|
||||
pLits[i] = solver_mkLit_args( pCnf->pVarNums[pObj->Id], 0 );
|
||||
if ( !solver_addClause( pSat, Aig_ManPoNum(pCnf->pMan), pLits ) )
|
||||
int Lit;
|
||||
if ( p->pSat )
|
||||
{
|
||||
free( pLits );
|
||||
Aig_Obj_t * pObj;
|
||||
int i;
|
||||
Vec_PtrForEachEntry( p->vUsedNodes, pObj, i )
|
||||
Cec_ObjSetSatNum( p, pObj, 0 );
|
||||
Vec_PtrClear( p->vUsedNodes );
|
||||
// memset( p->pSatVars, 0, sizeof(int) * Aig_ManObjNumMax(p->pAigTotal) );
|
||||
sat_solver_delete( p->pSat );
|
||||
}
|
||||
p->pSat = sat_solver_new();
|
||||
sat_solver_setnvars( p->pSat, 1000 );
|
||||
// var 0 is not used
|
||||
// var 1 is reserved for const1 node - add the clause
|
||||
p->nSatVars = 1;
|
||||
// p->nSatVars = 0;
|
||||
Lit = toLit( p->nSatVars );
|
||||
if ( p->pPars->fPolarFlip )
|
||||
Lit = lit_neg( Lit );
|
||||
sat_solver_addclause( p->pSat, &Lit, &Lit + 1 );
|
||||
Cec_ObjSetSatNum( p, Aig_ManConst1(p->pAig), p->nSatVars++ );
|
||||
|
||||
p->nRecycles++;
|
||||
p->nCallsSince = 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Runs equivalence test for the two nodes.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Cec_ManSatCheckNode( Cec_ManSat_t * p, Aig_Obj_t * pNode )
|
||||
{
|
||||
int nBTLimit = p->pPars->nBTLimit;
|
||||
int Lit, RetValue, status, clk;
|
||||
|
||||
// sanity checks
|
||||
assert( !Aig_IsComplement(pNode) );
|
||||
|
||||
p->nCallsSince++; // experiment with this!!!
|
||||
|
||||
// check if SAT solver needs recycling
|
||||
if ( p->pSat == NULL ||
|
||||
(p->pPars->nSatVarMax &&
|
||||
p->nSatVars > p->pPars->nSatVarMax &&
|
||||
p->nCallsSince > p->pPars->nCallsRecycle) )
|
||||
Cec_ManSatSolverRecycle( p );
|
||||
|
||||
// if the nodes do not have SAT variables, allocate them
|
||||
Cec_CnfNodeAddToSolver( p, pNode );
|
||||
|
||||
// propage unit clauses
|
||||
if ( p->pSat->qtail != p->pSat->qhead )
|
||||
{
|
||||
status = sat_solver_simplify(p->pSat);
|
||||
assert( status != 0 );
|
||||
assert( p->pSat->qtail == p->pSat->qhead );
|
||||
}
|
||||
|
||||
// solve under assumptions
|
||||
// A = 1; B = 0 OR A = 1; B = 1
|
||||
Lit = toLitCond( Cec_ObjSatNum(p,pNode), pNode->fPhase );
|
||||
if ( p->pPars->fPolarFlip )
|
||||
{
|
||||
if ( pNode->fPhase ) Lit = lit_neg( Lit );
|
||||
}
|
||||
//Sat_SolverWriteDimacs( p->pSat, "temp.cnf", pLits, pLits + 2, 1 );
|
||||
clk = clock();
|
||||
RetValue = sat_solver_solve( p->pSat, &Lit, &Lit + 1,
|
||||
(sint64)nBTLimit, (sint64)0, (sint64)0, (sint64)0 );
|
||||
if ( RetValue == l_False )
|
||||
{
|
||||
p->timeSatUnsat += clock() - clk;
|
||||
Lit = lit_neg( Lit );
|
||||
RetValue = sat_solver_addclause( p->pSat, &Lit, &Lit + 1 );
|
||||
assert( RetValue );
|
||||
p->timeSatUnsat++;
|
||||
return 1;
|
||||
}
|
||||
else if ( RetValue == l_True )
|
||||
{
|
||||
p->timeSatSat += clock() - clk;
|
||||
p->timeSatSat++;
|
||||
return 0;
|
||||
}
|
||||
free( pLits );
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Writes the given clause in a file in DIMACS format.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Sat_SolverPrintStatsNew( FILE * pFile, solver * pSat )
|
||||
{
|
||||
// printf( "starts : %8d\n", solver_num_assigns(pSat) );
|
||||
printf( "vars : %8d\n", solver_num_vars(pSat) );
|
||||
printf( "clauses : %8d\n", solver_num_clauses(pSat) );
|
||||
printf( "conflicts : %8d\n", solver_num_learnts(pSat) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns a counter-example.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int * Sat_SolverGetModelNew( solver * pSat, int * pVars, int nVars )
|
||||
{
|
||||
int * pModel;
|
||||
int i;
|
||||
pModel = ALLOC( int, nVars+1 );
|
||||
for ( i = 0; i < nVars; i++ )
|
||||
else // if ( RetValue == l_Undef )
|
||||
{
|
||||
assert( pVars[i] >= 0 && pVars[i] < solver_num_vars(pSat) );
|
||||
pModel[i] = (int)(solver_modelValue_Var( pSat, pVars[i] ) == solver_l_True);
|
||||
p->timeSatUndec += clock() - clk;
|
||||
p->timeSatUndec++;
|
||||
return -1;
|
||||
}
|
||||
return pModel;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
@ -173,112 +200,51 @@ int * Sat_SolverGetModelNew( solver * pSat, int * pVars, int nVars )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Cec_RunSat( Aig_Man_t * pMan, sint64 nConfLimit, sint64 nInsLimit, int fFlipBits, int fAndOuts, int fVerbose )
|
||||
Cec_MtrStatus_t Cec_SatSolveOutputs( Aig_Man_t * pAig, Cec_ParSat_t * pPars )
|
||||
{
|
||||
solver * pSat;
|
||||
Cnf_Dat_t * pCnf;
|
||||
int status, RetValue, clk = clock();
|
||||
Vec_Int_t * vCiIds;
|
||||
|
||||
assert( Aig_ManRegNum(pMan) == 0 );
|
||||
pMan->pData = NULL;
|
||||
|
||||
// derive CNF
|
||||
pCnf = Cnf_Derive( pMan, Aig_ManPoNum(pMan) );
|
||||
// pCnf = Cnf_DeriveSimple( pMan, Aig_ManPoNum(pMan) );
|
||||
|
||||
// convert into SAT solver
|
||||
pSat = Cnf_WriteIntoSolverNew( pCnf );
|
||||
if ( pSat == NULL )
|
||||
Bar_Progress_t * pProgress = NULL;
|
||||
Cec_MtrStatus_t Status;
|
||||
Cec_ManSat_t * p;
|
||||
Aig_Obj_t * pObj;
|
||||
int i, status;
|
||||
Status = Cec_MiterStatus( pAig );
|
||||
p = Cec_ManCreate( pAig, pPars );
|
||||
pProgress = Bar_ProgressStart( stdout, Aig_ManPoNum(pAig) );
|
||||
Aig_ManForEachPo( pAig, pObj, i )
|
||||
{
|
||||
Cnf_DataFree( pCnf );
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
if ( fAndOuts )
|
||||
{
|
||||
assert( 0 );
|
||||
// assert each output independently
|
||||
if ( !Cnf_DataWriteAndClausesNew( pSat, pCnf ) )
|
||||
Bar_ProgressUpdate( pProgress, i, "SAT..." );
|
||||
if ( Cec_OutputStatus(pAig, pObj) )
|
||||
continue;
|
||||
status = Cec_ManSatCheckNode( p, Aig_ObjFanin0(pObj) );
|
||||
if ( status == 1 )
|
||||
{
|
||||
solver_delete( pSat );
|
||||
Cnf_DataFree( pCnf );
|
||||
return 1;
|
||||
Status.nUndec--, Status.nUnsat++;
|
||||
Aig_ObjPatchFanin0( pAig, pObj, Aig_ManConst0(pAig) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// add the OR clause for the outputs
|
||||
if ( !Cnf_DataWriteOrClauseNew( pSat, pCnf ) )
|
||||
if ( status == 0 )
|
||||
{
|
||||
solver_delete( pSat );
|
||||
Cnf_DataFree( pCnf );
|
||||
return 1;
|
||||
Status.nUndec--, Status.nSat++;
|
||||
Aig_ObjPatchFanin0( pAig, pObj, Aig_ManConst1(pAig) );
|
||||
}
|
||||
if ( status == -1 )
|
||||
continue;
|
||||
// save the pattern (if it is first)
|
||||
if ( Status.iOut == -1 )
|
||||
{
|
||||
}
|
||||
// quit if at least one of them is solved
|
||||
if ( status == 0 && pPars->fFirstStop )
|
||||
break;
|
||||
}
|
||||
vCiIds = Cnf_DataCollectPiSatNums( pCnf, pMan );
|
||||
Cnf_DataFree( pCnf );
|
||||
|
||||
|
||||
// printf( "Created SAT problem with %d variable and %d clauses. ", sat_solver_nvars(pSat), sat_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. ", sat_solver_nvars(pSat), sat_solver_nclauses(pSat) );
|
||||
// PRT( "Time", clock() - clk );
|
||||
if ( status == 0 )
|
||||
{
|
||||
Vec_IntFree( vCiIds );
|
||||
solver_delete( pSat );
|
||||
// printf( "The problem is UNSATISFIABLE after simplification.\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
// solve the miter
|
||||
clk = clock();
|
||||
if ( fVerbose )
|
||||
solver_set_verbosity( pSat, 1 );
|
||||
status = solver_solve( pSat, 0, NULL );
|
||||
if ( status == solver_l_Undef )
|
||||
{
|
||||
// printf( "The problem timed out.\n" );
|
||||
RetValue = -1;
|
||||
}
|
||||
else if ( status == solver_l_True )
|
||||
{
|
||||
// printf( "The problem is SATISFIABLE.\n" );
|
||||
RetValue = 0;
|
||||
}
|
||||
else if ( status == solver_l_False )
|
||||
{
|
||||
// printf( "The problem is UNSATISFIABLE.\n" );
|
||||
RetValue = 1;
|
||||
}
|
||||
else
|
||||
assert( 0 );
|
||||
// PRT( "SAT sat_solver time", clock() - clk );
|
||||
// printf( "The number of conflicts = %d.\n", (int)pSat->sat_solver_stats.conflicts );
|
||||
|
||||
// if the problem is SAT, get the counterexample
|
||||
if ( status == solver_l_True )
|
||||
{
|
||||
pMan->pData = Sat_SolverGetModelNew( pSat, vCiIds->pArray, vCiIds->nSize );
|
||||
}
|
||||
// free the sat_solver
|
||||
if ( fVerbose )
|
||||
Sat_SolverPrintStatsNew( stdout, pSat );
|
||||
//sat_solver_store_write( pSat, "trace.cnf" );
|
||||
//sat_solver_store_free( pSat );
|
||||
solver_delete( pSat );
|
||||
Vec_IntFree( vCiIds );
|
||||
return RetValue;
|
||||
Aig_ManCleanup( pAig );
|
||||
Bar_ProgressStop( pProgress );
|
||||
printf( " Confs = %8d. Recycles = %6d.\n", p->pPars->nBTLimit, p->nRecycles );
|
||||
Cec_ManStop( p );
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,459 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [cecSim.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Combinatinoal equivalence checking.]
|
||||
|
||||
Synopsis [AIG simulation.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: cecSim.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "cecInt.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Count PIs with fanout.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Caig_ManCountRelevantPis( Aig_Man_t * pAig )
|
||||
{
|
||||
Aig_Obj_t * pObj;
|
||||
int i, Counter = 0;
|
||||
Aig_ManForEachPi( pAig, pObj, i )
|
||||
if ( Aig_ObjRefs(pObj) )
|
||||
Counter++;
|
||||
else
|
||||
pObj->iData = -1;
|
||||
return Counter;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Count PIs with fanout.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Caig_ManCountRelevantPos( Aig_Man_t * pAig )
|
||||
{
|
||||
Aig_Obj_t * pObj;
|
||||
int i, Counter = 0;
|
||||
Aig_ManForEachPo( pAig, pObj, i )
|
||||
if ( !Aig_ObjIsConst1(Aig_ObjFanin0(pObj)) )
|
||||
Counter++;
|
||||
else
|
||||
pObj->iData = -1;
|
||||
return Counter;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Find the PO corresponding to the PO driver.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Caig_ManFindPo( Aig_Man_t * pAig, int iNode )
|
||||
{
|
||||
Aig_Obj_t * pObj;
|
||||
int i;
|
||||
Aig_ManForEachPo( pAig, pObj, i )
|
||||
if ( pObj->iData == iNode )
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates fast simulation manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Caig_ManCreate_rec( Caig_Man_t * p, Aig_Obj_t * pObj )
|
||||
{
|
||||
int iFan0, iFan1;
|
||||
assert( !Aig_IsComplement(pObj) );
|
||||
assert( !Aig_ObjIsConst1(pObj) );
|
||||
if ( pObj->iData )
|
||||
return pObj->iData;
|
||||
if ( Aig_ObjIsNode(pObj) )
|
||||
{
|
||||
iFan0 = Caig_ManCreate_rec( p, Aig_ObjFanin0(pObj) );
|
||||
iFan0 = (iFan0 << 1) | Aig_ObjFaninC0(pObj);
|
||||
iFan1 = Caig_ManCreate_rec( p, Aig_ObjFanin1(pObj) );
|
||||
iFan1 = (iFan1 << 1) | Aig_ObjFaninC1(pObj);
|
||||
}
|
||||
else if ( Aig_ObjIsPo(pObj) )
|
||||
{
|
||||
iFan0 = Caig_ManCreate_rec( p, Aig_ObjFanin0(pObj) );
|
||||
iFan0 = (iFan0 << 1) | Aig_ObjFaninC0(pObj);
|
||||
iFan1 = 0;
|
||||
}
|
||||
else
|
||||
iFan0 = iFan1 = 0;
|
||||
assert( Aig_ObjRefs(pObj) < (1<<16) );
|
||||
p->pFans0[p->nObjs] = iFan0;
|
||||
p->pFans1[p->nObjs] = iFan1;
|
||||
p->pRefs[p->nObjs] = (unsigned short)Aig_ObjRefs(pObj);
|
||||
return pObj->iData = p->nObjs++;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates fast simulation manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Caig_Man_t * Caig_ManCreate( Aig_Man_t * pAig )
|
||||
{
|
||||
Caig_Man_t * p;
|
||||
Aig_Obj_t * pObj;
|
||||
int i, nObjs;
|
||||
Aig_ManCleanData( pAig );
|
||||
p = (Caig_Man_t *)ALLOC( Caig_Man_t, 1 );
|
||||
memset( p, 0, sizeof(Caig_Man_t) );
|
||||
p->pAig = pAig;
|
||||
p->nPis = Caig_ManCountRelevantPis(pAig);
|
||||
p->nPos = Caig_ManCountRelevantPos(pAig);
|
||||
p->nNodes = Aig_ManNodeNum(pAig);
|
||||
nObjs = p->nPis + p->nPos + p->nNodes + 1;
|
||||
p->pFans0 = ALLOC( int, nObjs );
|
||||
p->pFans1 = ALLOC( int, nObjs );
|
||||
p->pRefs = ALLOC( unsigned short, nObjs );
|
||||
p->pSims = CALLOC( unsigned, nObjs );
|
||||
// add objects
|
||||
p->nObjs = 1;
|
||||
Aig_ManForEachPo( pAig, pObj, i )
|
||||
if ( !Aig_ObjIsConst1(Aig_ObjFanin0(pObj)) )
|
||||
Caig_ManCreate_rec( p, pObj );
|
||||
assert( p->nObjs == nObjs );
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates fast simulation manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Caig_ManDelete( Caig_Man_t * p )
|
||||
{
|
||||
if ( p->vSims ) Vec_PtrFree( p->vSims );
|
||||
if ( p->vClassOld ) Vec_IntFree( p->vClassOld );
|
||||
if ( p->vClassNew ) Vec_IntFree( p->vClassNew );
|
||||
FREE( p->pFans0 );
|
||||
FREE( p->pFans1 );
|
||||
FREE( p->pRefs );
|
||||
FREE( p->pSims );
|
||||
FREE( p->pMems );
|
||||
FREE( p->pReprs );
|
||||
FREE( p->pNexts );
|
||||
FREE( p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [References simulation info.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
unsigned * Caig_ManSimRead( Caig_Man_t * p, int i )
|
||||
{
|
||||
assert( i && p->pSims[i] > 0 );
|
||||
return p->pMems + p->pSims[i];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [References simulation info.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
unsigned * Caig_ManSimRef( Caig_Man_t * p, int i )
|
||||
{
|
||||
unsigned * pSim;
|
||||
assert( i );
|
||||
assert( p->pSims[i] == 0 );
|
||||
if ( p->MemFree == 0 )
|
||||
{
|
||||
int * pPlace, Ent;
|
||||
if ( p->nWordsAlloc == 0 )
|
||||
{
|
||||
assert( p->pMems == NULL );
|
||||
p->nWordsAlloc = (1<<17); // -> 1Mb
|
||||
p->nMems = 1;
|
||||
}
|
||||
p->nWordsAlloc *= 2;
|
||||
p->pMems = REALLOC( unsigned, p->pMems, p->nWordsAlloc );
|
||||
pPlace = &p->MemFree;
|
||||
for ( Ent = p->nMems * (p->nWords + 1);
|
||||
Ent + p->nWords + 1 < p->nWordsAlloc;
|
||||
Ent += p->nWords + 1 )
|
||||
{
|
||||
*pPlace = Ent;
|
||||
pPlace = p->pMems + Ent;
|
||||
}
|
||||
*pPlace = 0;
|
||||
}
|
||||
p->pSims[i] = p->MemFree;
|
||||
pSim = p->pMems + p->MemFree;
|
||||
p->MemFree = pSim[0];
|
||||
pSim[0] = p->pRefs[i];
|
||||
p->nMems++;
|
||||
if ( p->nMemsMax < p->nMems )
|
||||
p->nMemsMax = p->nMems;
|
||||
return pSim;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Dereference simulaton info.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
unsigned * Caig_ManSimDeref( Caig_Man_t * p, int i )
|
||||
{
|
||||
unsigned * pSim;
|
||||
assert( i );
|
||||
assert( p->pSims[i] > 0 );
|
||||
pSim = p->pMems + p->pSims[i];
|
||||
if ( --pSim[0] == 0 )
|
||||
{
|
||||
pSim[0] = p->MemFree;
|
||||
p->MemFree = p->pSims[i];
|
||||
p->pSims[i] = 0;
|
||||
p->nMems--;
|
||||
}
|
||||
return pSim;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Simulates one round.]
|
||||
|
||||
Description [Returns the number of PO entry if failed; 0 otherwise.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Caig_ManSimulateRound( Caig_Man_t * p, int fMiter )
|
||||
{
|
||||
Vec_Int_t * vRefined = NULL;
|
||||
unsigned * pRes0, * pRes1, * pRes;
|
||||
int i, w, iFan0, iFan1;
|
||||
if ( p->pReprs )
|
||||
vRefined = Vec_IntAlloc( 1000 );
|
||||
for ( i = 1; i < p->nObjs; i++ )
|
||||
{
|
||||
if ( p->pFans0[i] == 0 ) // pi always has zero first fanin
|
||||
{
|
||||
pRes = Caig_ManSimRef( p, i );
|
||||
for ( w = 1; w <= p->nWords; w++ )
|
||||
pRes[w] = Aig_ManRandom( 0 );
|
||||
goto references;
|
||||
}
|
||||
if ( p->pFans1[i] == 0 ) // po always has non-zero 1st fanin and zero 2nd fanin
|
||||
{
|
||||
if ( fMiter )
|
||||
{
|
||||
unsigned Const = Cec_LitIsCompl(p->pFans0[i])? ~0 : 0;
|
||||
pRes0 = Caig_ManSimDeref( p, Cec_Lit2Var(p->pFans0[i]) );
|
||||
for ( w = 1; w <= p->nWords; w++ )
|
||||
if ( pRes0[w] != Const )
|
||||
return i;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
pRes = Caig_ManSimRef( p, i );
|
||||
iFan0 = p->pFans0[i];
|
||||
iFan1 = p->pFans1[i];
|
||||
pRes0 = Caig_ManSimDeref( p, Cec_Lit2Var(p->pFans0[i]) );
|
||||
pRes1 = Caig_ManSimDeref( p, Cec_Lit2Var(p->pFans1[i]) );
|
||||
if ( Cec_LitIsCompl(iFan0) && Cec_LitIsCompl(iFan1) )
|
||||
for ( w = 1; w <= p->nWords; w++ )
|
||||
pRes[w] = ~(pRes0[w] | pRes1[w]);
|
||||
else if ( Cec_LitIsCompl(iFan0) && !Cec_LitIsCompl(iFan1) )
|
||||
for ( w = 1; w <= p->nWords; w++ )
|
||||
pRes[w] = ~pRes0[w] & pRes1[w];
|
||||
else if ( !Cec_LitIsCompl(iFan0) && Cec_LitIsCompl(iFan1) )
|
||||
for ( w = 1; w <= p->nWords; w++ )
|
||||
pRes[w] = pRes0[w] & ~pRes1[w];
|
||||
else if ( !Cec_LitIsCompl(iFan0) && !Cec_LitIsCompl(iFan1) )
|
||||
for ( w = 1; w <= p->nWords; w++ )
|
||||
pRes[w] = pRes0[w] & pRes1[w];
|
||||
references:
|
||||
if ( p->pReprs == NULL )
|
||||
continue;
|
||||
// if this node is candidate constant, collect it
|
||||
if ( p->pReprs[i] == 0 && !Caig_ManCompareConst(pRes + 1, p->nWords) )
|
||||
{
|
||||
pRes[0]++;
|
||||
Vec_IntPush( vRefined, i );
|
||||
}
|
||||
// if the node belongs to a class, save it
|
||||
if ( p->pReprs[i] > 0 || p->pNexts[i] > 0 )
|
||||
pRes[0]++;
|
||||
// if this is the last node of the class, process it
|
||||
if ( p->pReprs[i] > 0 && p->pNexts[i] == 0 )
|
||||
Caig_ManProcessClass( p, p->pReprs[i] );
|
||||
}
|
||||
if ( p->pReprs )
|
||||
Caig_ManProcessRefined( p, vRefined );
|
||||
if ( p->pReprs )
|
||||
Vec_IntFree( vRefined );
|
||||
assert( p->nMems == 1 );
|
||||
/*
|
||||
if ( p->nMems > 1 )
|
||||
{
|
||||
for ( i = 1; i < p->nObjs; i++ )
|
||||
if ( p->pSims[i] )
|
||||
{
|
||||
int x = 0;
|
||||
}
|
||||
}
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns 1 if the bug is detected, 0 otherwise.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Cec_ManSimulate( Aig_Man_t * pAig, int nWords, int nIters, int TimeLimit, int fMiter, int fVerbose )
|
||||
{
|
||||
Caig_Man_t * p;
|
||||
Cec_MtrStatus_t Status;
|
||||
int i, RetValue = 0, clk, clkTotal = clock();
|
||||
/*
|
||||
p = Caig_ManClassesPrepare( pAig, nWords, nIters );
|
||||
// if ( fVerbose )
|
||||
printf( "Maxcut = %6d. AIG mem = %8.3f Mb. Sim mem = %8.3f Mb.\n",
|
||||
p->nMemsMax,
|
||||
1.0*(p->nObjs * 14)/(1<<20),
|
||||
1.0*(p->nMemsMax * (nWords+1))/(1<<20) );
|
||||
Caig_ManDelete( p );
|
||||
return 0;
|
||||
*/
|
||||
Status = Cec_MiterStatus( pAig );
|
||||
if ( Status.nSat > 0 )
|
||||
{
|
||||
printf( "Miter is trivially satisfiable (output %d).\n", Status.iOut );
|
||||
return 1;
|
||||
}
|
||||
if ( Status.nUndec == 0 )
|
||||
{
|
||||
printf( "Miter is trivially unsatisfiable.\n" );
|
||||
return 0;
|
||||
}
|
||||
Aig_ManRandom( 1 );
|
||||
p = Caig_ManCreate( pAig );
|
||||
p->nWords = nWords;
|
||||
for ( i = 0; i < nIters; i++ )
|
||||
{
|
||||
clk = clock();
|
||||
RetValue = Caig_ManSimulateRound( p, fMiter );
|
||||
if ( fVerbose )
|
||||
{
|
||||
printf( "Iter %3d out of %3d and timeout %3d sec. ", i+1, nIters, TimeLimit );
|
||||
printf("Time = %7.2f sec\r", (1.0*clock()-clkTotal)/CLOCKS_PER_SEC);
|
||||
}
|
||||
if ( RetValue > 0 )
|
||||
{
|
||||
int iOut = Caig_ManFindPo(p->pAig, RetValue);
|
||||
if ( fVerbose )
|
||||
printf( "Miter is satisfiable after simulation (output %d).\n", iOut );
|
||||
break;
|
||||
}
|
||||
if ( (clock() - clk)/CLOCKS_PER_SEC >= TimeLimit )
|
||||
{
|
||||
printf( "No bug detected after %d rounds with time limit %d seconds.\n", i+1, TimeLimit );
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( fVerbose )
|
||||
printf( "Maxcut = %6d. AIG mem = %8.3f Mb. Sim mem = %8.3f Mb.\n",
|
||||
p->nMemsMax,
|
||||
1.0*(p->nObjs * 14)/(1<<20),
|
||||
1.0*(p->nMemsMax * 4 * (nWords+1))/(1<<20) );
|
||||
Caig_ManDelete( p );
|
||||
return RetValue > 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,187 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [cecStatus.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Combinatinoal equivalence checking.]
|
||||
|
||||
Synopsis [Miter status.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: cecStatus.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "cecInt.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns 1 if the output is known.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Cec_OutputStatus( Aig_Man_t * p, Aig_Obj_t * pObj )
|
||||
{
|
||||
Aig_Obj_t * pChild;
|
||||
assert( Aig_ObjIsPo(pObj) );
|
||||
pChild = Aig_ObjChild0(pObj);
|
||||
// check if the output is constant 0
|
||||
if ( pChild == Aig_ManConst0(p) )
|
||||
return 1;
|
||||
// check if the output is constant 1
|
||||
if ( pChild == Aig_ManConst1(p) )
|
||||
return 1;
|
||||
// check if the output is a primary input
|
||||
if ( Aig_ObjIsPi(Aig_Regular(pChild)) )
|
||||
return 1;
|
||||
// check if the output is 1 for the 0000 pattern
|
||||
if ( Aig_Regular(pChild)->fPhase != (unsigned)Aig_IsComplement(pChild) )
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns number of used inputs.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Cec_CountInputs( Aig_Man_t * p )
|
||||
{
|
||||
Aig_Obj_t * pObj;
|
||||
int i, Counter = 0;
|
||||
Aig_ManForEachPi( p, pObj, i )
|
||||
Counter += (int)(pObj->nRefs > 0);
|
||||
return Counter;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Checks the status of the miter.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Cec_MtrStatus_t Cec_MiterStatus( Aig_Man_t * p )
|
||||
{
|
||||
Cec_MtrStatus_t Status;
|
||||
Aig_Obj_t * pObj, * pChild;
|
||||
int i;
|
||||
assert( p->nRegs == 0 );
|
||||
memset( &Status, 0, sizeof(Cec_MtrStatus_t) );
|
||||
Status.iOut = -1;
|
||||
Status.nInputs = Cec_CountInputs( p );
|
||||
Status.nNodes = Aig_ManNodeNum( p );
|
||||
Status.nOutputs = Aig_ManPoNum(p);
|
||||
Aig_ManForEachPo( p, pObj, i )
|
||||
{
|
||||
pChild = Aig_ObjChild0(pObj);
|
||||
// check if the output is constant 0
|
||||
if ( pChild == Aig_ManConst0(p) )
|
||||
Status.nUnsat++;
|
||||
// check if the output is constant 1
|
||||
else if ( pChild == Aig_ManConst1(p) )
|
||||
{
|
||||
Status.nSat++;
|
||||
if ( Status.iOut == -1 )
|
||||
Status.iOut = i;
|
||||
}
|
||||
// check if the output is a primary input
|
||||
else if ( Aig_ObjIsPi(Aig_Regular(pChild)) )
|
||||
{
|
||||
Status.nSat++;
|
||||
if ( Status.iOut == -1 )
|
||||
Status.iOut = i;
|
||||
}
|
||||
// check if the output is 1 for the 0000 pattern
|
||||
else if ( Aig_Regular(pChild)->fPhase != (unsigned)Aig_IsComplement(pChild) )
|
||||
{
|
||||
Status.nSat++;
|
||||
if ( Status.iOut == -1 )
|
||||
Status.iOut = i;
|
||||
}
|
||||
else
|
||||
Status.nUndec++;
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Checks the status of the miter.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Cec_MtrStatus_t Cec_MiterStatusTrivial( Aig_Man_t * p )
|
||||
{
|
||||
Cec_MtrStatus_t Status;
|
||||
memset( &Status, 0, sizeof(Cec_MtrStatus_t) );
|
||||
Status.iOut = -1;
|
||||
Status.nInputs = Aig_ManPiNum(p);
|
||||
Status.nNodes = Aig_ManNodeNum( p );
|
||||
Status.nOutputs = Aig_ManPoNum(p);
|
||||
Status.nUndec = Aig_ManPoNum(p);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Prints the status of the miter.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Cec_MiterStatusPrint( Cec_MtrStatus_t S, char * pString, int Time )
|
||||
{
|
||||
printf( "%s:", pString );
|
||||
printf( " I =%6d", S.nInputs );
|
||||
printf( " N =%7d", S.nNodes );
|
||||
printf( " " );
|
||||
printf( " ? =%6d", S.nUndec );
|
||||
printf( " U =%6d", S.nUnsat );
|
||||
printf( " S =%6d", S.nSat );
|
||||
printf(" %7.2f sec\n", (float)(Time)/(float)(CLOCKS_PER_SEC));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
SRC += src/aig/cec/cecAig.c \
|
||||
src/aig/cec/cecClass.c \
|
||||
src/aig/cec/cecCnf.c \
|
||||
src/aig/cec/cecCore.c \
|
||||
src/aig/cec/cecMan.c \
|
||||
src/aig/cec/cecSat.c \
|
||||
src/aig/cec/cecSim.c \
|
||||
src/aig/cec/cecStatus.c
|
||||
|
|
@ -52,8 +52,9 @@ struct Cgt_Par_t_
|
|||
int nConfMax; // the max number of conflicts at a node
|
||||
int nVarsMin; // the min number of variables to recycle the SAT solver
|
||||
int nFlopsMin; // the min number of flops needed to recycle the SAT solver
|
||||
int fAreaOnly; // derive clock gating to minimize area
|
||||
int fVerbose; // verbosity flag
|
||||
|
||||
int fVeryVerbose; // verbosity flag
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ void Cgt_ManDetectCandidates_rec( Aig_Man_t * pAig, Aig_Obj_t * pObj, int nLevel
|
|||
void Cgt_ManDetectCandidates( Aig_Man_t * pAig, Aig_Obj_t * pObj, int nLevelMax, Vec_Ptr_t * vCands )
|
||||
{
|
||||
Vec_PtrClear( vCands );
|
||||
if ( !Aig_ObjIsNode(Aig_ObjFanin0(pObj)) )
|
||||
if ( !Aig_ObjIsNode(pObj) )
|
||||
return;
|
||||
Aig_ManIncrementTravId( pAig );
|
||||
Cgt_ManDetectCandidates_rec( pAig, pObj, nLevelMax, vCands );
|
||||
|
|
@ -134,6 +134,67 @@ void Cgt_ManDetectFanout( Aig_Man_t * pAig, Aig_Obj_t * pObj, int nOdcMax, Vec_P
|
|||
assert( Vec_PtrSize(vFanout) > 0 );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes visited nodes in the topological order.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Cgt_ManCollectVisited_rec( Aig_Man_t * pAig, Aig_Obj_t * pObj, Vec_Ptr_t * vVisited )
|
||||
{
|
||||
if ( Aig_ObjIsPi(pObj) )
|
||||
return;
|
||||
if ( Aig_ObjIsTravIdCurrent(pAig, pObj) )
|
||||
return;
|
||||
Aig_ObjSetTravIdCurrent(pAig, pObj);
|
||||
assert( Aig_ObjIsNode(pObj) );
|
||||
Cgt_ManCollectVisited_rec( pAig, Aig_ObjFanin0(pObj), vVisited );
|
||||
Cgt_ManCollectVisited_rec( pAig, Aig_ObjFanin1(pObj), vVisited );
|
||||
Vec_PtrPush( vVisited, pObj );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes visited nodes in the topological order.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Cgt_ManCollectVisited( Aig_Man_t * pAig, Vec_Ptr_t * vFanout, Vec_Ptr_t * vVisited )
|
||||
{
|
||||
Aig_Obj_t * pObj;
|
||||
int i;
|
||||
Vec_PtrClear( vVisited );
|
||||
Aig_ManIncrementTravId( pAig );
|
||||
Vec_PtrForEachEntry( vFanout, pObj, i )
|
||||
Cgt_ManCollectVisited_rec( pAig, pObj, vVisited );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Aig_Obj_t * Aig_ObjChild0CopyVec( Vec_Ptr_t * vCopy, Aig_Obj_t * pObj )
|
||||
{ return Aig_NotCond((Aig_Obj_t *)Vec_PtrEntry(vCopy, Aig_ObjFaninId0(pObj)), Aig_ObjFaninC0(pObj)); }
|
||||
static inline Aig_Obj_t * Aig_ObjChild1CopyVec( Vec_Ptr_t * vCopy, Aig_Obj_t * pObj )
|
||||
{ return Aig_NotCond((Aig_Obj_t *)Vec_PtrEntry(vCopy, Aig_ObjFaninId1(pObj)), Aig_ObjFaninC1(pObj)); }
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Derives miter for clock-gating.]
|
||||
|
|
@ -145,15 +206,46 @@ void Cgt_ManDetectFanout( Aig_Man_t * pAig, Aig_Obj_t * pObj, int nOdcMax, Vec_P
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Obj_t * Cgt_ManConstructMiter( Cgt_Man_t * p, Aig_Man_t * pNew, Aig_Obj_t * pObjLo )
|
||||
Aig_Obj_t * Cgt_ManConstructCareCondition( Cgt_Man_t * p, Aig_Man_t * pNew, Aig_Obj_t * pObjLo, Vec_Ptr_t * vCopy0, Vec_Ptr_t * vCopy1 )
|
||||
{
|
||||
Aig_Obj_t * pMiter, * pRoot;
|
||||
Aig_Obj_t * pMiter, * pObj, * pTemp;
|
||||
int i;
|
||||
assert( Aig_ObjIsPi(pObjLo) );
|
||||
pMiter = Aig_ManConst0( pNew );
|
||||
// detect nodes and their cone
|
||||
Cgt_ManDetectFanout( p->pAig, pObjLo, p->pPars->nOdcMax, p->vFanout );
|
||||
Vec_PtrForEachEntry( p->vFanout, pRoot, i )
|
||||
pMiter = Aig_Or( pNew, pMiter, Aig_Exor(pNew, pRoot->pData, pRoot->pNext) );
|
||||
Cgt_ManCollectVisited( p->pAig, p->vFanout, p->vVisited );
|
||||
// add new variables if the observability condition depends on PI variables
|
||||
Vec_PtrForEachEntry( p->vVisited, pObj, i )
|
||||
{
|
||||
assert( Aig_ObjIsNode(pObj) );
|
||||
if ( Saig_ObjIsPi(p->pAig, Aig_ObjFanin0(pObj)) && Vec_PtrEntry(vCopy0, Aig_ObjFaninId0(pObj)) == NULL )
|
||||
{
|
||||
pTemp = Aig_ObjCreatePi( pNew );
|
||||
Vec_PtrWriteEntry( vCopy0, Aig_ObjFaninId0(pObj), pTemp );
|
||||
Vec_PtrWriteEntry( vCopy1, Aig_ObjFaninId0(pObj), pTemp );
|
||||
}
|
||||
if ( Saig_ObjIsPi(p->pAig, Aig_ObjFanin1(pObj)) && Vec_PtrEntry(vCopy0, Aig_ObjFaninId1(pObj)) == NULL )
|
||||
{
|
||||
pTemp = Aig_ObjCreatePi( pNew );
|
||||
Vec_PtrWriteEntry( vCopy0, Aig_ObjFaninId1(pObj), pTemp );
|
||||
Vec_PtrWriteEntry( vCopy1, Aig_ObjFaninId1(pObj), pTemp );
|
||||
}
|
||||
}
|
||||
// construct AIGs for the nodes
|
||||
Vec_PtrForEachEntry( p->vVisited, pObj, i )
|
||||
{
|
||||
pTemp = Aig_And( pNew, Aig_ObjChild0CopyVec(vCopy0, pObj), Aig_ObjChild1CopyVec(vCopy0, pObj) );
|
||||
Vec_PtrWriteEntry( vCopy0, Aig_ObjId(pObj), pTemp );
|
||||
pTemp = Aig_And( pNew, Aig_ObjChild0CopyVec(vCopy1, pObj), Aig_ObjChild1CopyVec(vCopy1, pObj) );
|
||||
Vec_PtrWriteEntry( vCopy1, Aig_ObjId(pObj), pTemp );
|
||||
}
|
||||
// construct the care miter
|
||||
pMiter = Aig_ManConst0( pNew );
|
||||
Vec_PtrForEachEntry( p->vFanout, pObj, i )
|
||||
{
|
||||
pTemp = Aig_Exor( pNew, Vec_PtrEntry(vCopy0, Aig_ObjId(pObj)), Vec_PtrEntry(vCopy1, Aig_ObjId(pObj)) );
|
||||
pMiter = Aig_Or( pNew, pMiter, pTemp );
|
||||
}
|
||||
return pMiter;
|
||||
}
|
||||
|
||||
|
|
@ -171,11 +263,12 @@ Aig_Obj_t * Cgt_ManConstructMiter( Cgt_Man_t * p, Aig_Man_t * pNew, Aig_Obj_t *
|
|||
Aig_Man_t * Cgt_ManDeriveAigForGating( Cgt_Man_t * p )
|
||||
{
|
||||
Aig_Man_t * pNew;
|
||||
Aig_Obj_t * pObj, * pObjLi, * pObjLo;
|
||||
Aig_Obj_t * pObj, * pObjLi, * pObjLo, * pCare, * pMiter;
|
||||
Vec_Ptr_t * vCopy0, * vCopy1;
|
||||
int i;
|
||||
assert( Aig_ManRegNum(p->pAig) );
|
||||
Aig_ManCleanNext( p->pAig );
|
||||
pNew = Aig_ManStart( Aig_ManObjNumMax(p->pAig) );
|
||||
pNew->pName = Aig_UtilStrsav( "CG_miter" );
|
||||
// build the first frame
|
||||
Aig_ManConst1(p->pAig)->pData = Aig_ManConst1(pNew);
|
||||
Aig_ManForEachPi( p->pAig, pObj, i )
|
||||
|
|
@ -184,24 +277,126 @@ Aig_Man_t * Cgt_ManDeriveAigForGating( Cgt_Man_t * p )
|
|||
pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
|
||||
// Saig_ManForEachPo( p->pAig, pObj, i )
|
||||
// pObj->pData = Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) );
|
||||
// build the second frame
|
||||
Aig_ManConst1(p->pAig)->pNext = Aig_ManConst1(pNew);
|
||||
Saig_ManForEachPi( p->pAig, pObj, i )
|
||||
pObj->pNext = Aig_ObjCreatePi( pNew );
|
||||
Saig_ManForEachLiLo( p->pAig, pObjLi, pObjLo, i )
|
||||
pObjLo->pNext = Aig_ObjChild0Copy(pObjLi);
|
||||
Aig_ManForEachNode( p->pAig, pObj, i )
|
||||
if ( Aig_ObjLevel(pObj) <= p->pPars->nOdcMax )
|
||||
pObj->pNext = Aig_And( pNew, Aig_ObjChild0Next(pObj), Aig_ObjChild1Next(pObj) );
|
||||
// construct clock-gating miters for each register input
|
||||
Saig_ManForEachLiLo( p->pAig, pObjLi, pObjLo, i )
|
||||
pObjLi->pData = Aig_ObjCreatePo( pNew, Cgt_ManConstructMiter(p, pNew, pObjLo) );
|
||||
Aig_ManCleanNext( p->pAig );
|
||||
Aig_ManSetPioNumbers( p->pAig );
|
||||
if ( p->pPars->nOdcMax > 0 )
|
||||
{
|
||||
// create storage for observability conditions
|
||||
vCopy0 = Vec_PtrStart( Aig_ManObjNumMax(p->pAig) );
|
||||
vCopy1 = Vec_PtrStart( Aig_ManObjNumMax(p->pAig) );
|
||||
// initialize register outputs
|
||||
Saig_ManForEachLiLo( p->pAig, pObjLi, pObjLo, i )
|
||||
{
|
||||
Vec_PtrWriteEntry( vCopy0, Aig_ObjId(pObjLo), Aig_ObjChild0Copy(pObjLi) );
|
||||
Vec_PtrWriteEntry( vCopy1, Aig_ObjId(pObjLo), Aig_ObjChild0Copy(pObjLi) );
|
||||
}
|
||||
// compute observability condition for each latch output
|
||||
Saig_ManForEachLiLo( p->pAig, pObjLi, pObjLo, i )
|
||||
{
|
||||
// set the constants
|
||||
Vec_PtrWriteEntry( vCopy0, Aig_ObjId(pObjLo), Aig_ManConst0(pNew) );
|
||||
Vec_PtrWriteEntry( vCopy1, Aig_ObjId(pObjLo), Aig_ManConst1(pNew) );
|
||||
// compute condition
|
||||
pCare = Cgt_ManConstructCareCondition( p, pNew, pObjLo, vCopy0, vCopy1 );
|
||||
// restore the values
|
||||
Vec_PtrWriteEntry( vCopy0, Aig_ObjId(pObjLo), Aig_ObjChild0Copy(pObjLi) );
|
||||
Vec_PtrWriteEntry( vCopy1, Aig_ObjId(pObjLo), Aig_ObjChild0Copy(pObjLi) );
|
||||
// compute the miter
|
||||
pMiter = Aig_Exor( pNew, pObjLo->pData, Aig_ObjChild0Copy(pObjLi) );
|
||||
pMiter = Aig_And( pNew, pMiter, pCare );
|
||||
pObjLi->pData = Aig_ObjCreatePo( pNew, pMiter );
|
||||
}
|
||||
Vec_PtrFree( vCopy0 );
|
||||
Vec_PtrFree( vCopy1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
// construct clock-gating miters for each register input
|
||||
Saig_ManForEachLiLo( p->pAig, pObjLi, pObjLo, i )
|
||||
{
|
||||
pMiter = Aig_Exor( pNew, pObjLo->pData, Aig_ObjChild0Copy(pObjLi) );
|
||||
pObjLi->pData = Aig_ObjCreatePo( pNew, pMiter );
|
||||
}
|
||||
}
|
||||
Aig_ManCleanup( pNew );
|
||||
Aig_ManSetPioNumbers( pNew );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Adds relevant constraints.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Obj_t * Cgt_ManConstructCare_rec( Aig_Man_t * pCare, Aig_Obj_t * pObj, Aig_Man_t * pNew )
|
||||
{
|
||||
Aig_Obj_t * pObj0, * pObj1;
|
||||
if ( Aig_ObjIsTravIdCurrent( pCare, pObj ) )
|
||||
return pObj->pData;
|
||||
Aig_ObjSetTravIdCurrent( pCare, pObj );
|
||||
if ( Aig_ObjIsPi(pObj) )
|
||||
return pObj->pData = NULL;
|
||||
pObj0 = Cgt_ManConstructCare_rec( pCare, Aig_ObjFanin0(pObj), pNew );
|
||||
if ( pObj0 == NULL )
|
||||
return pObj->pData = NULL;
|
||||
pObj1 = Cgt_ManConstructCare_rec( pCare, Aig_ObjFanin1(pObj), pNew );
|
||||
if ( pObj1 == NULL )
|
||||
return pObj->pData = NULL;
|
||||
pObj0 = Aig_NotCond( pObj0, Aig_ObjFaninC0(pObj) );
|
||||
pObj1 = Aig_NotCond( pObj1, Aig_ObjFaninC1(pObj) );
|
||||
return pObj->pData = Aig_And( pNew, pObj0, pObj1 );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Builds constraints belonging to the given partition.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Cgt_ManConstructCare( Aig_Man_t * pNew, Aig_Man_t * pCare, Vec_Vec_t * vSuppsInv, Vec_Ptr_t * vLeaves )
|
||||
{
|
||||
Vec_Int_t * vOuts;
|
||||
Aig_Obj_t * pLeaf, * pPi, * pPo, * pObjAig;
|
||||
int i, k, iOut;
|
||||
// go through the PIs of the partition
|
||||
// label the corresponding PIs of the care set
|
||||
Aig_ManIncrementTravId( pCare );
|
||||
Vec_PtrForEachEntry( vLeaves, pLeaf, i )
|
||||
{
|
||||
pPi = Aig_ManPi( pCare, Aig_ObjPioNum(pLeaf) );
|
||||
Aig_ObjSetTravIdCurrent( pCare, pPi );
|
||||
pPi->pData = pLeaf->pData;
|
||||
}
|
||||
// construct the constraints
|
||||
Vec_PtrForEachEntry( vLeaves, pLeaf, i )
|
||||
{
|
||||
vOuts = Vec_VecEntry( vSuppsInv, Aig_ObjPioNum(pLeaf) );
|
||||
Vec_IntForEachEntry( vOuts, iOut, k )
|
||||
{
|
||||
pPo = Aig_ManPo( pCare, iOut );
|
||||
if ( Aig_ObjIsTravIdCurrent( pCare, pPo ) )
|
||||
continue;
|
||||
Aig_ObjSetTravIdCurrent( pCare, pPo );
|
||||
if ( Aig_ObjFanin0(pPo) == Aig_ManConst1(pCare) )
|
||||
continue;
|
||||
pObjAig = Cgt_ManConstructCare_rec( pCare, Aig_ObjFanin0(pPo), pNew );
|
||||
if ( pObjAig == NULL )
|
||||
continue;
|
||||
pObjAig = Aig_NotCond( pObjAig, Aig_ObjFaninC0(pPo) );
|
||||
Aig_ObjCreatePo( pNew, pObjAig );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Duplicates the AIG recursively.]
|
||||
|
|
@ -213,15 +408,19 @@ Aig_Man_t * Cgt_ManDeriveAigForGating( Cgt_Man_t * p )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Obj_t * Cgt_ManDupPartition_rec( Aig_Man_t * pNew, Aig_Man_t * pAig, Aig_Obj_t * pObj )
|
||||
Aig_Obj_t * Cgt_ManDupPartition_rec( Aig_Man_t * pNew, Aig_Man_t * pAig, Aig_Obj_t * pObj, Vec_Ptr_t * vLeaves )
|
||||
{
|
||||
if ( Aig_ObjIsTravIdCurrent(pAig, pObj) )
|
||||
return pObj->pData;
|
||||
Aig_ObjSetTravIdCurrent(pAig, pObj);
|
||||
if ( Aig_ObjIsPi(pObj) )
|
||||
return pObj->pData = Aig_ObjCreatePi( pNew );
|
||||
Cgt_ManDupPartition_rec( pNew, pAig, Aig_ObjFanin0(pObj) );
|
||||
Cgt_ManDupPartition_rec( pNew, pAig, Aig_ObjFanin1(pObj) );
|
||||
{
|
||||
pObj->pData = Aig_ObjCreatePi( pNew );
|
||||
Vec_PtrPush( vLeaves, pObj );
|
||||
return pObj->pData;
|
||||
}
|
||||
Cgt_ManDupPartition_rec( pNew, pAig, Aig_ObjFanin0(pObj), vLeaves );
|
||||
Cgt_ManDupPartition_rec( pNew, pAig, Aig_ObjFanin1(pObj), vLeaves );
|
||||
return pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
|
||||
}
|
||||
|
||||
|
|
@ -236,32 +435,78 @@ Aig_Obj_t * Cgt_ManDupPartition_rec( Aig_Man_t * pNew, Aig_Man_t * pAig, Aig_Obj
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Man_t * Cgt_ManDupPartition( Aig_Man_t * pAig, int nVarsMin, int nFlopsMin, int iStart )
|
||||
Aig_Man_t * Cgt_ManDupPartition( Aig_Man_t * pFrame, int nVarsMin, int nFlopsMin, int iStart, Aig_Man_t * pCare, Vec_Vec_t * vSuppsInv, int * pnOutputs )
|
||||
{
|
||||
Vec_Ptr_t * vRoots, * vLeaves, * vPos;
|
||||
Aig_Man_t * pNew;
|
||||
Aig_Obj_t * pObj;
|
||||
int i;
|
||||
assert( Aig_ManRegNum(pAig) == 0 );
|
||||
assert( Aig_ManRegNum(pFrame) == 0 );
|
||||
vRoots = Vec_PtrAlloc( 100 );
|
||||
vLeaves = Vec_PtrAlloc( 100 );
|
||||
vPos = Vec_PtrAlloc( 100 );
|
||||
pNew = Aig_ManStart( nVarsMin );
|
||||
Aig_ManIncrementTravId( pAig );
|
||||
Aig_ManConst1(pAig)->pData = Aig_ManConst1(pNew);
|
||||
Aig_ObjSetTravIdCurrent( pAig, Aig_ManConst1(pAig) );
|
||||
for ( i = iStart; i < iStart + nFlopsMin && i < Aig_ManPoNum(pAig); i++ )
|
||||
pNew->pName = Aig_UtilStrsav( "partition" );
|
||||
Aig_ManIncrementTravId( pFrame );
|
||||
Aig_ManConst1(pFrame)->pData = Aig_ManConst1(pNew);
|
||||
Aig_ObjSetTravIdCurrent( pFrame, Aig_ManConst1(pFrame) );
|
||||
for ( i = iStart; i < iStart + nFlopsMin && i < Aig_ManPoNum(pFrame); i++ )
|
||||
{
|
||||
pObj = Aig_ManPo( pAig, i );
|
||||
Cgt_ManDupPartition_rec( pNew, pAig, Aig_ObjFanin0(pObj) );
|
||||
pObj->pData = Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) );
|
||||
pObj = Aig_ManPo( pFrame, i );
|
||||
Cgt_ManDupPartition_rec( pNew, pFrame, Aig_ObjFanin0(pObj), vLeaves );
|
||||
Vec_PtrPush( vRoots, Aig_ObjChild0Copy(pObj) );
|
||||
Vec_PtrPush( vPos, pObj );
|
||||
}
|
||||
for ( ; Aig_ManObjNum(pNew) < nVarsMin && i < Aig_ManPoNum(pAig); i++ )
|
||||
for ( ; Aig_ManObjNum(pNew) < nVarsMin && i < Aig_ManPoNum(pFrame); i++ )
|
||||
{
|
||||
pObj = Aig_ManPo( pAig, i );
|
||||
Cgt_ManDupPartition_rec( pNew, pAig, Aig_ObjFanin0(pObj) );
|
||||
pObj->pData = Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) );
|
||||
pObj = Aig_ManPo( pFrame, i );
|
||||
Cgt_ManDupPartition_rec( pNew, pFrame, Aig_ObjFanin0(pObj), vLeaves );
|
||||
Vec_PtrPush( vRoots, Aig_ObjChild0Copy(pObj) );
|
||||
Vec_PtrPush( vPos, pObj );
|
||||
}
|
||||
assert( nFlopsMin >= Aig_ManPoNum(pAig) || Aig_ManPoNum(pNew) >= nFlopsMin );
|
||||
assert( nFlopsMin >= Vec_PtrSize(vRoots) || Vec_PtrSize(vRoots) >= nFlopsMin );
|
||||
// create constaints
|
||||
if ( pCare )
|
||||
Cgt_ManConstructCare( pNew, pCare, vSuppsInv, vLeaves );
|
||||
// create POs
|
||||
Vec_PtrForEachEntry( vPos, pObj, i )
|
||||
pObj->pData = Aig_ObjCreatePo( pNew, Vec_PtrEntry(vRoots, i) );
|
||||
if ( pnOutputs != NULL )
|
||||
*pnOutputs = Vec_PtrSize( vPos );
|
||||
Vec_PtrFree( vRoots );
|
||||
Vec_PtrFree( vLeaves );
|
||||
Vec_PtrFree( vPos );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Implements one clock-gate.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Obj_t * Cgt_ManBuildClockGate( Aig_Man_t * pNew, Vec_Ptr_t * vGates )
|
||||
{
|
||||
Aig_Obj_t * pGate, * pTotal;
|
||||
int i;
|
||||
assert( Vec_PtrSize(vGates) > 0 );
|
||||
pTotal = Aig_ManConst0(pNew);
|
||||
Vec_PtrForEachEntry( vGates, pGate, i )
|
||||
{
|
||||
if ( Aig_Regular(pGate)->pNext )
|
||||
pGate = Aig_NotCond( Aig_Regular(pGate)->pNext, Aig_IsComplement(pGate) );
|
||||
else
|
||||
pGate = Aig_NotCond( Aig_Regular(pGate)->pData, Aig_IsComplement(pGate) );
|
||||
pTotal = Aig_Or( pNew, pTotal, pGate );
|
||||
}
|
||||
return pTotal;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Derives AIG after clock-gating.]
|
||||
|
|
@ -273,34 +518,74 @@ Aig_Man_t * Cgt_ManDupPartition( Aig_Man_t * pAig, int nVarsMin, int nFlopsMin,
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Man_t * Cgt_ManDeriveGatedAig( Aig_Man_t * pAig, Vec_Ptr_t * vGates )
|
||||
Aig_Man_t * Cgt_ManDeriveGatedAig( Aig_Man_t * pAig, Vec_Vec_t * vGates, int fReduce, int * pnUsedNodes )
|
||||
{
|
||||
Aig_Man_t * pNew;
|
||||
Aig_Obj_t * pObj, * pObjNew, * pObjLi, * pObjLo, * pGate, * pGateNew;
|
||||
int i;
|
||||
Aig_Obj_t * pObj, * pObjNew, * pObjLi, * pObjLo, * pGateNew;
|
||||
Vec_Ptr_t * vOne;
|
||||
int i, k;
|
||||
Aig_ManCleanNext( pAig );
|
||||
// label nodes
|
||||
Vec_VecForEachEntry( vGates, pObj, i, k )
|
||||
{
|
||||
if ( Aig_IsComplement(pObj) )
|
||||
Aig_Regular(pObj)->fMarkB = 1;
|
||||
else
|
||||
Aig_Regular(pObj)->fMarkA = 1;
|
||||
}
|
||||
// construct AIG
|
||||
assert( Aig_ManRegNum(pAig) );
|
||||
pNew = Aig_ManStart( Aig_ManObjNumMax(pAig) );
|
||||
pNew->pName = Aig_UtilStrsav( pAig->pName );
|
||||
pNew->pSpec = Aig_UtilStrsav( pAig->pSpec );
|
||||
Aig_ManConst1(pAig)->pData = Aig_ManConst1(pNew);
|
||||
Aig_ManForEachPi( pAig, pObj, i )
|
||||
pObj->pData = Aig_ObjCreatePi( pNew );
|
||||
Aig_ManForEachNode( pAig, pObj, i )
|
||||
pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
|
||||
if ( fReduce )
|
||||
{
|
||||
Aig_ManForEachNode( pAig, pObj, i )
|
||||
{
|
||||
assert( !(pObj->fMarkA && pObj->fMarkB) );
|
||||
pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
|
||||
if ( pObj->fMarkA )
|
||||
{
|
||||
pObj->pNext = pObj->pData;
|
||||
pObj->pData = Aig_ManConst0(pNew);
|
||||
}
|
||||
else if ( pObj->fMarkB )
|
||||
{
|
||||
pObj->pNext = pObj->pData;
|
||||
pObj->pData = Aig_ManConst1(pNew);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Aig_ManForEachNode( pAig, pObj, i )
|
||||
pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
|
||||
}
|
||||
if ( pnUsedNodes != NULL )
|
||||
*pnUsedNodes = Aig_ManNodeNum(pNew);
|
||||
Saig_ManForEachPo( pAig, pObj, i )
|
||||
pObj->pData = Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) );
|
||||
Saig_ManForEachLiLo( pAig, pObjLi, pObjLo, i )
|
||||
{
|
||||
pGate = Vec_PtrEntry( vGates, i );
|
||||
if ( pGate == NULL )
|
||||
vOne = Vec_VecEntry( vGates, i );
|
||||
if ( Vec_PtrSize(vOne) == 0 )
|
||||
pObjNew = Aig_ObjChild0Copy(pObjLi);
|
||||
else
|
||||
{
|
||||
pGateNew = Aig_NotCond( Aig_Regular(pGate)->pData, Aig_IsComplement(pGate) );
|
||||
// pGateNew = Aig_NotCond( Aig_Regular(pGate)->pData, Aig_IsComplement(pGate) );
|
||||
pGateNew = Cgt_ManBuildClockGate( pNew, vOne );
|
||||
pObjNew = Aig_Mux( pNew, pGateNew, pObjLo->pData, Aig_ObjChild0Copy(pObjLi) );
|
||||
}
|
||||
pObjLi->pData = Aig_ObjCreatePo( pNew, pObjNew );
|
||||
}
|
||||
Aig_ManCleanup( pNew );
|
||||
Aig_ManSetRegNum( pNew, Aig_ManRegNum(pAig) );
|
||||
// unlabel nodes
|
||||
Aig_ManCleanMarkAB( pAig );
|
||||
Aig_ManCleanNext( pAig );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
***********************************************************************/
|
||||
|
||||
#include "cgtInt.h"
|
||||
#include "bar.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
|
|
@ -42,13 +43,14 @@
|
|||
void Cgt_SetDefaultParams( Cgt_Par_t * p )
|
||||
{
|
||||
memset( p, 0, sizeof(Cgt_Par_t) );
|
||||
p->nLevelMax = 1000; // the max number of levels to look for clock-gates
|
||||
p->nLevelMax = 25; // the max number of levels to look for clock-gates
|
||||
p->nCandMax = 1000; // the max number of candidates at each node
|
||||
p->nOdcMax = 0; // the max number of ODC levels to consider
|
||||
p->nConfMax = 1000; // the max number of conflicts at a node
|
||||
p->nVarsMin = 5000; // the min number of vars to recycle the SAT solver
|
||||
p->nFlopsMin = 25; // the min number of flops to recycle the SAT solver
|
||||
p->fVerbose = 0; // verbosity flag
|
||||
p->nConfMax = 10; // the max number of conflicts at a node
|
||||
p->nVarsMin = 1000; // the min number of vars to recycle the SAT solver
|
||||
p->nFlopsMin = 5; // the min number of flops to recycle the SAT solver
|
||||
p->fAreaOnly = 0; // derive clock-gating to minimize area
|
||||
p->fVerbose = 1; // verbosity flag
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
@ -62,14 +64,14 @@ void Cgt_SetDefaultParams( Cgt_Par_t * p )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Cgt_SimulationFilter( Cgt_Man_t * p, Aig_Obj_t * pCandFrame, Aig_Obj_t * pMiterFrame )
|
||||
int Cgt_SimulationFilter( Cgt_Man_t * p, Aig_Obj_t * pCandPart, Aig_Obj_t * pMiterPart )
|
||||
{
|
||||
unsigned * pInfoCand, * pInfoMiter;
|
||||
int w, nWords = Aig_BitWordNum( p->nPatts );
|
||||
pInfoCand = Vec_PtrEntry( p->vPatts, Aig_ObjId(Aig_Regular(pCandFrame)) );
|
||||
pInfoMiter = Vec_PtrEntry( p->vPatts, Aig_ObjId(pMiterFrame) );
|
||||
pInfoCand = Vec_PtrEntry( p->vPatts, Aig_ObjId(Aig_Regular(pCandPart)) );
|
||||
pInfoMiter = Vec_PtrEntry( p->vPatts, Aig_ObjId(pMiterPart) );
|
||||
// C => !M -- true is the same as C & M -- false
|
||||
if ( !Aig_IsComplement(pCandFrame) )
|
||||
if ( !Aig_IsComplement(pCandPart) )
|
||||
{
|
||||
for ( w = 0; w < nWords; w++ )
|
||||
if ( pInfoCand[w] & pInfoMiter[w] )
|
||||
|
|
@ -106,6 +108,7 @@ void Cgt_SimulationRecord( Cgt_Man_t * p )
|
|||
if ( p->nPatts == 32 * p->nPattWords )
|
||||
{
|
||||
Vec_PtrReallocSimInfo( p->vPatts );
|
||||
Vec_PtrCleanSimInfo( p->vPatts, p->nPattWords, 2 * p->nPattWords );
|
||||
p->nPattWords *= 2;
|
||||
}
|
||||
}
|
||||
|
|
@ -121,15 +124,16 @@ void Cgt_SimulationRecord( Cgt_Man_t * p )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Cgt_ClockGatingRangeCheck( Cgt_Man_t * p, int iStart )
|
||||
void Cgt_ClockGatingRangeCheck( Cgt_Man_t * p, int iStart, int nOutputs )
|
||||
{
|
||||
Vec_Ptr_t * vNodes = p->vFanout;
|
||||
Aig_Obj_t * pMiter, * pCand, * pMiterFrame, * pCandFrame, * pMiterPart, * pCandPart;
|
||||
int i, k, RetValue;
|
||||
int i, k, RetValue, nCalls;
|
||||
assert( Vec_VecSize(p->vGatesAll) == Aig_ManPoNum(p->pFrame) );
|
||||
// go through all the registers inputs of this range
|
||||
for ( i = iStart; i < iStart + Aig_ManPoNum(p->pPart); i++ )
|
||||
for ( i = iStart; i < iStart + nOutputs; i++ )
|
||||
{
|
||||
nCalls = p->nCalls;
|
||||
pMiter = Saig_ManLi( p->pAig, i );
|
||||
Cgt_ManDetectCandidates( p->pAig, Aig_ObjFanin0(pMiter), p->pPars->nLevelMax, vNodes );
|
||||
// go through the candidates of this PO
|
||||
|
|
@ -153,6 +157,8 @@ void Cgt_ClockGatingRangeCheck( Cgt_Man_t * p, int iStart )
|
|||
if ( RetValue == 0 )
|
||||
Cgt_SimulationRecord( p );
|
||||
}
|
||||
else
|
||||
p->nCallsFiltered++;
|
||||
// try reverse polarity
|
||||
if ( Cgt_SimulationFilter( p, Aig_Not(pCandPart), pMiterPart ) )
|
||||
{
|
||||
|
|
@ -165,9 +171,18 @@ void Cgt_ClockGatingRangeCheck( Cgt_Man_t * p, int iStart )
|
|||
if ( RetValue == 0 )
|
||||
Cgt_SimulationRecord( p );
|
||||
}
|
||||
else
|
||||
p->nCallsFiltered++;
|
||||
}
|
||||
|
||||
if ( p->pPars->fVerbose )
|
||||
{
|
||||
// printf( "Flop %3d : Cand = %4d. Gate = %4d. SAT calls = %3d.\n",
|
||||
// i, Vec_PtrSize(vNodes), Vec_PtrSize(Vec_VecEntry(p->vGatesAll, i)), p->nCalls-nCalls );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
|
|
@ -182,16 +197,33 @@ void Cgt_ClockGatingRangeCheck( Cgt_Man_t * p, int iStart )
|
|||
***********************************************************************/
|
||||
int Cgt_ClockGatingRange( Cgt_Man_t * p, int iStart )
|
||||
{
|
||||
int iStop;
|
||||
p->pPart = Cgt_ManDupPartition( p->pFrame, p->pPars->nVarsMin, p->pPars->nFlopsMin, iStart );
|
||||
p->pCnf = Cnf_DeriveSimple( p->pPart, Aig_ManPoNum(p->pPart) );
|
||||
int nOutputs, iStop, clk, clkTotal = clock();
|
||||
int nCallsUnsat = p->nCallsUnsat;
|
||||
int nCallsSat = p->nCallsSat;
|
||||
int nCallsUndec = p->nCallsUndec;
|
||||
int nCallsFiltered = p->nCallsFiltered;
|
||||
clk = clock();
|
||||
p->pPart = Cgt_ManDupPartition( p->pFrame, p->pPars->nVarsMin, p->pPars->nFlopsMin, iStart, p->pCare, p->vSuppsInv, &nOutputs );
|
||||
p->pCnf = Cnf_DeriveSimple( p->pPart, nOutputs );
|
||||
p->pSat = Cnf_DataWriteIntoSolver( p->pCnf, 1, 0 );
|
||||
sat_solver_compress( p->pSat );
|
||||
p->vPatts = Vec_PtrAllocSimInfo( Aig_ManObjNumMax(p->pPart), 16 );
|
||||
p->vPatts = Vec_PtrAllocSimInfo( Aig_ManObjNumMax(p->pPart), p->nPattWords );
|
||||
Vec_PtrCleanSimInfo( p->vPatts, 0, p->nPattWords );
|
||||
Cgt_ClockGatingRangeCheck( p, iStart );
|
||||
iStop = iStart + Aig_ManPoNum(p->pPart);
|
||||
p->timePrepare += clock() - clk;
|
||||
Cgt_ClockGatingRangeCheck( p, iStart, nOutputs );
|
||||
iStop = iStart + nOutputs;
|
||||
if ( p->pPars->fVeryVerbose )
|
||||
{
|
||||
printf( "%5d : D =%4d. C =%5d. Var =%6d. Pr =%5d. Cex =%5d. F =%4d. Saved =%6d. ",
|
||||
iStart, iStop-iStart, Aig_ManPoNum(p->pPart)-nOutputs, p->pSat->size,
|
||||
p->nCallsUnsat-nCallsUnsat,
|
||||
p->nCallsSat -nCallsSat,
|
||||
p->nCallsUndec-nCallsUndec,
|
||||
p->nCallsFiltered-nCallsFiltered );
|
||||
PRT( "Time", clock() - clkTotal );
|
||||
}
|
||||
Cgt_ManClean( p );
|
||||
p->nRecycles++;
|
||||
return iStop;
|
||||
}
|
||||
|
||||
|
|
@ -208,18 +240,30 @@ int Cgt_ClockGatingRange( Cgt_Man_t * p, int iStart )
|
|||
***********************************************************************/
|
||||
Vec_Vec_t * Cgt_ClockGatingCandidates( Aig_Man_t * pAig, Aig_Man_t * pCare, Cgt_Par_t * pPars )
|
||||
{
|
||||
Cgt_Par_t Pars;
|
||||
Bar_Progress_t * pProgress = NULL;
|
||||
Cgt_Par_t Pars;
|
||||
Cgt_Man_t * p;
|
||||
Vec_Vec_t * vGatesAll;
|
||||
int iStart;
|
||||
int iStart, clk = clock(), clkTotal = clock();
|
||||
// reset random numbers
|
||||
Aig_ManRandom( 1 );
|
||||
if ( pPars == NULL )
|
||||
Cgt_SetDefaultParams( pPars = &Pars );
|
||||
p = Cgt_ManCreate( pAig, pCare, pPars );
|
||||
p->pFrame = Cgt_ManDeriveAigForGating( p );
|
||||
p->timeAig += clock() - clk;
|
||||
assert( Aig_ManPoNum(p->pFrame) == Saig_ManRegNum(p->pAig) );
|
||||
pProgress = Bar_ProgressStart( stdout, Aig_ManPoNum(p->pFrame) );
|
||||
for ( iStart = 0; iStart < Aig_ManPoNum(p->pFrame); )
|
||||
{
|
||||
Bar_ProgressUpdate( pProgress, iStart, NULL );
|
||||
iStart = Cgt_ClockGatingRange( p, iStart );
|
||||
}
|
||||
Bar_ProgressStop( pProgress );
|
||||
vGatesAll = p->vGatesAll;
|
||||
p->vGatesAll = NULL;
|
||||
p->timeTotal = clock() - clkTotal;
|
||||
Cgt_ManStop( p );
|
||||
return vGatesAll;
|
||||
}
|
||||
|
||||
|
|
@ -238,11 +282,29 @@ Aig_Man_t * Cgt_ClockGating( Aig_Man_t * pAig, Aig_Man_t * pCare, Cgt_Par_t * pP
|
|||
{
|
||||
Aig_Man_t * pGated;
|
||||
Vec_Vec_t * vGatesAll;
|
||||
Vec_Ptr_t * vGates;
|
||||
Vec_Vec_t * vGates;
|
||||
int nNodesUsed, clk = clock();
|
||||
vGatesAll = Cgt_ClockGatingCandidates( pAig, pCare, pPars );
|
||||
vGates = Cgt_ManDecideSimple( pAig, vGatesAll );
|
||||
pGated = Cgt_ManDeriveGatedAig( pAig, vGates );
|
||||
Vec_PtrFree( vGates );
|
||||
if ( pPars->fAreaOnly )
|
||||
vGates = Cgt_ManDecideArea( pAig, vGatesAll, pPars->nOdcMax, pPars->fVerbose );
|
||||
else
|
||||
vGates = Cgt_ManDecideSimple( pAig, vGatesAll, pPars->nOdcMax, pPars->fVerbose );
|
||||
if ( pPars->fVerbose )
|
||||
{
|
||||
// printf( "Before CG: " );
|
||||
// Aig_ManPrintStats( pAig );
|
||||
}
|
||||
pGated = Cgt_ManDeriveGatedAig( pAig, vGates, pPars->fAreaOnly, &nNodesUsed );
|
||||
if ( pPars->fVerbose )
|
||||
{
|
||||
// printf( "After CG: " );
|
||||
// Aig_ManPrintStats( pGated );
|
||||
printf( "Nodes: Before CG = %6d. After CG = %6d. (%6.2f %%). Total after CG = %6d.\n",
|
||||
Aig_ManNodeNum(pAig), nNodesUsed,
|
||||
100.0*nNodesUsed/Aig_ManNodeNum(pAig),
|
||||
Aig_ManNodeNum(pGated) );
|
||||
}
|
||||
Vec_VecFree( vGates );
|
||||
Vec_VecFree( vGatesAll );
|
||||
return pGated;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,8 +25,11 @@
|
|||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern int Ssw_SmlCountXorImplication( Ssw_Sml_t * p, Aig_Obj_t * pObjLi, Aig_Obj_t * pObjLo, Aig_Obj_t * pCand );
|
||||
extern int Ssw_SmlCheckXorImplication( Ssw_Sml_t * p, Aig_Obj_t * pObjLi, Aig_Obj_t * pObjLo, Aig_Obj_t * pCand );
|
||||
extern int Ssw_SmlCountXorImplication( Ssw_Sml_t * p, Aig_Obj_t * pObjLi, Aig_Obj_t * pObjLo, Aig_Obj_t * pCand );
|
||||
extern int Ssw_SmlCountEqual( Ssw_Sml_t * p, Aig_Obj_t * pObjLi, Aig_Obj_t * pObjLo );
|
||||
extern int Ssw_SmlNodeCountOnesReal( Ssw_Sml_t * p, Aig_Obj_t * pObj );
|
||||
extern int Ssw_SmlNodeCountOnesRealVec( Ssw_Sml_t * p, Vec_Ptr_t * vObjs );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
|
|
@ -34,7 +37,7 @@ extern int Ssw_SmlCheckXorImplication( Ssw_Sml_t * p, Aig_Obj_t * pObjLi, Aig_Ob
|
|||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Chooses what clock-gate to use for each register.]
|
||||
Synopsis [Collects POs in the transitive fanout.]
|
||||
|
||||
Description []
|
||||
|
||||
|
|
@ -43,11 +46,127 @@ extern int Ssw_SmlCheckXorImplication( Ssw_Sml_t * p, Aig_Obj_t * pObjLi, Aig_Ob
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Ptr_t * Cgt_ManDecide( Aig_Man_t * pAig, Vec_Vec_t * vGatesAll )
|
||||
void Cgt_ManCollectFanoutPos_rec( Aig_Man_t * pAig, Aig_Obj_t * pObj, Vec_Ptr_t * vFanout )
|
||||
{
|
||||
Aig_Obj_t * pFanout;
|
||||
int f, iFanout;
|
||||
if ( Aig_ObjIsTravIdCurrent(pAig, pObj) )
|
||||
return;
|
||||
Aig_ObjSetTravIdCurrent(pAig, pObj);
|
||||
if ( Aig_ObjIsPo(pObj) )
|
||||
{
|
||||
Vec_PtrPush( vFanout, pObj );
|
||||
return;
|
||||
}
|
||||
Aig_ObjForEachFanout( pAig, pObj, pFanout, iFanout, f )
|
||||
Cgt_ManCollectFanoutPos_rec( pAig, pFanout, vFanout );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Collects POs in the transitive fanout.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Cgt_ManCollectFanoutPos( Aig_Man_t * pAig, Aig_Obj_t * pObj, Vec_Ptr_t * vFanout )
|
||||
{
|
||||
Vec_PtrClear( vFanout );
|
||||
Aig_ManIncrementTravId( pAig );
|
||||
Cgt_ManCollectFanoutPos_rec( pAig, pObj, vFanout );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Checks if all PO fanouts can be gated by this node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Cgt_ManCheckGateComplete( Aig_Man_t * pAig, Vec_Vec_t * vGatesAll, Aig_Obj_t * pGate, Vec_Ptr_t * vFanout )
|
||||
{
|
||||
Vec_Ptr_t * vGates;
|
||||
vGates = Vec_PtrStart( Saig_ManRegNum(pAig) );
|
||||
return vGates;
|
||||
Aig_Obj_t * pObj;
|
||||
int i;
|
||||
Vec_PtrForEachEntry( vFanout, pObj, i )
|
||||
{
|
||||
if ( Saig_ObjIsPo(pAig, pObj) )
|
||||
return 0;
|
||||
vGates = Vec_VecEntry( vGatesAll, Aig_ObjPioNum(pObj) - Saig_ManPoNum(pAig) );
|
||||
if ( Vec_PtrFind( vGates, pGate ) == -1 )
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the set of complete clock gates.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Ptr_t * Cgt_ManCompleteGates( Aig_Man_t * pAig, Vec_Vec_t * vGatesAll, int nOdcMax, int fVerbose )
|
||||
{
|
||||
Vec_Ptr_t * vFanout, * vGatesFull;
|
||||
Aig_Obj_t * pGate, * pGateR;
|
||||
int i, k;
|
||||
vFanout = Vec_PtrAlloc( 100 );
|
||||
vGatesFull = Vec_PtrAlloc( 100 );
|
||||
Vec_VecForEachEntry( vGatesAll, pGate, i, k )
|
||||
{
|
||||
pGateR = Aig_Regular(pGate);
|
||||
if ( pGateR->fMarkA )
|
||||
continue;
|
||||
pGateR->fMarkA = 1;
|
||||
Cgt_ManCollectFanoutPos( pAig, pGateR, vFanout );
|
||||
if ( Cgt_ManCheckGateComplete( pAig, vGatesAll, pGate, vFanout ) )
|
||||
Vec_PtrPush( vGatesFull, pGate );
|
||||
}
|
||||
Vec_PtrFree( vFanout );
|
||||
Vec_VecForEachEntry( vGatesAll, pGate, i, k )
|
||||
Aig_Regular(pGate)->fMarkA = 0;
|
||||
return vGatesFull;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Calculates coverage.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
float Cgt_ManComputeCoverage( Aig_Man_t * pAig, Vec_Vec_t * vGates )
|
||||
{
|
||||
int nFrames = 32;
|
||||
int nWords = 1;
|
||||
Ssw_Sml_t * pSml;
|
||||
Vec_Ptr_t * vOne;
|
||||
int i, nTransTotal = 0, nTransSaved = 0;
|
||||
pSml = Ssw_SmlSimulateSeq( pAig, 0, nFrames, nWords );
|
||||
Vec_VecForEachLevel( vGates, vOne, i )
|
||||
{
|
||||
nTransSaved += Ssw_SmlNodeCountOnesRealVec( pSml, vOne );
|
||||
nTransTotal += 32 * nFrames * nWords;
|
||||
}
|
||||
Ssw_SmlStop( pSml );
|
||||
return (float)100.0*nTransSaved/nTransTotal;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
@ -62,14 +181,18 @@ Vec_Ptr_t * Cgt_ManDecide( Aig_Man_t * pAig, Vec_Vec_t * vGatesAll )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Ptr_t * Cgt_ManDecideSimple( Aig_Man_t * pAig, Vec_Vec_t * vGatesAll )
|
||||
Vec_Vec_t * Cgt_ManDecideSimple( Aig_Man_t * pAig, Vec_Vec_t * vGatesAll, int nOdcMax, int fVerbose )
|
||||
{
|
||||
int nFrames = 32;
|
||||
int nWords = 1;
|
||||
Ssw_Sml_t * pSml;
|
||||
Vec_Ptr_t * vGates, * vCands;
|
||||
Vec_Vec_t * vGates;
|
||||
Vec_Ptr_t * vCands;
|
||||
Aig_Obj_t * pObjLi, * pObjLo, * pCand, * pCandBest;
|
||||
int i, k, nHitsCur, nHitsMax;
|
||||
vGates = Vec_PtrStart( Saig_ManRegNum(pAig) );
|
||||
pSml = Ssw_SmlSimulateSeq( pAig, 0, 32, 1 );
|
||||
int i, k, nHitsCur, nHitsMax, Counter = 0, clk = clock();
|
||||
int nTransTotal = 0, nTransSaved = 0;
|
||||
vGates = Vec_VecStart( Saig_ManRegNum(pAig) );
|
||||
pSml = Ssw_SmlSimulateSeq( pAig, 0, nFrames, nWords );
|
||||
Saig_ManForEachLiLo( pAig, pObjLi, pObjLo, i )
|
||||
{
|
||||
nHitsMax = 0;
|
||||
|
|
@ -78,10 +201,10 @@ Vec_Ptr_t * Cgt_ManDecideSimple( Aig_Man_t * pAig, Vec_Vec_t * vGatesAll )
|
|||
Vec_PtrForEachEntry( vCands, pCand, k )
|
||||
{
|
||||
// check if this is indeed a clock-gate
|
||||
if ( !Ssw_SmlCheckXorImplication( pSml, pObjLi, pObjLo, pCand ) )
|
||||
if ( nOdcMax == 0 && !Ssw_SmlCheckXorImplication( pSml, pObjLi, pObjLo, pCand ) )
|
||||
printf( "Clock gate candidate is invalid!\n" );
|
||||
// find its characteristic number
|
||||
nHitsCur = Ssw_SmlCountXorImplication( pSml, pObjLi, pObjLo, pCand );
|
||||
nHitsCur = Ssw_SmlNodeCountOnesReal( pSml, pCand );
|
||||
if ( nHitsMax < nHitsCur )
|
||||
{
|
||||
nHitsMax = nHitsCur;
|
||||
|
|
@ -89,9 +212,80 @@ Vec_Ptr_t * Cgt_ManDecideSimple( Aig_Man_t * pAig, Vec_Vec_t * vGatesAll )
|
|||
}
|
||||
}
|
||||
if ( pCandBest != NULL )
|
||||
Vec_PtrWriteEntry( vGates, i, pCandBest );
|
||||
{
|
||||
Vec_VecPush( vGates, i, pCandBest );
|
||||
Counter++;
|
||||
nTransSaved += nHitsMax;
|
||||
}
|
||||
nTransTotal += 32 * nFrames * nWords;
|
||||
}
|
||||
Ssw_SmlStop( pSml );
|
||||
if ( fVerbose )
|
||||
{
|
||||
printf( "Gating signals = %6d. Gated flops = %6d. (Total flops = %6d.)\n",
|
||||
Vec_VecSizeSize(vGatesAll), Counter, Saig_ManRegNum(pAig) );
|
||||
// printf( "Gated transitions = %5.2f %%. (%5.2f %%.) ",
|
||||
// 100.0*nTransSaved/nTransTotal, Cgt_ManComputeCoverage(pAig, vGates) );
|
||||
printf( "Gated transitions = %5.2f %%. ", Cgt_ManComputeCoverage(pAig, vGates) );
|
||||
PRT( "Time", clock() - clk );
|
||||
}
|
||||
/*
|
||||
{
|
||||
Vec_Ptr_t * vCompletes;
|
||||
vCompletes = Cgt_ManCompleteGates( pAig, vGatesAll, nOdcMax, fVerbose );
|
||||
printf( "Complete gates = %d. \n", Vec_PtrSize(vCompletes) );
|
||||
Vec_PtrFree( vCompletes );
|
||||
}
|
||||
*/
|
||||
return vGates;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the set of complete clock gates.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Vec_t * Cgt_ManDecideArea( Aig_Man_t * pAig, Vec_Vec_t * vGatesAll, int nOdcMax, int fVerbose )
|
||||
{
|
||||
Vec_Vec_t * vGates;
|
||||
Vec_Ptr_t * vCompletes, * vOne;
|
||||
Aig_Obj_t * pGate;
|
||||
int i, k, Counter = 0, clk = clock();
|
||||
// derive and label complete gates
|
||||
vCompletes = Cgt_ManCompleteGates( pAig, vGatesAll, nOdcMax, fVerbose );
|
||||
// label complete gates
|
||||
Vec_PtrForEachEntry( vCompletes, pGate, i )
|
||||
Aig_Regular(pGate)->fMarkA = 1;
|
||||
// select only complete gates
|
||||
vGates = Vec_VecStart( Saig_ManRegNum(pAig) );
|
||||
Vec_VecForEachEntry( vGatesAll, pGate, i, k )
|
||||
if ( Aig_Regular(pGate)->fMarkA )
|
||||
Vec_VecPush( vGates, i, pGate );
|
||||
// unlabel complete gates
|
||||
Vec_PtrForEachEntry( vCompletes, pGate, i )
|
||||
Aig_Regular(pGate)->fMarkA = 0;
|
||||
// count the number of gated flops
|
||||
Vec_VecForEachLevel( vGates, vOne, i )
|
||||
{
|
||||
Counter += (int)(Vec_PtrSize(vOne) > 0);
|
||||
// printf( "%d ", Vec_PtrSize(vOne) );
|
||||
}
|
||||
// printf( "\n" );
|
||||
if ( fVerbose )
|
||||
{
|
||||
printf( "Gating signals = %6d. Gated flops = %6d. (Total flops = %6d.)\n",
|
||||
Vec_VecSizeSize(vGatesAll), Counter, Saig_ManRegNum(pAig) );
|
||||
printf( "Complete gates = %6d. Gated transitions = %5.2f %%. ",
|
||||
Vec_PtrSize(vCompletes), Cgt_ManComputeCoverage(pAig, vGates) );
|
||||
PRT( "Time", clock() - clk );
|
||||
}
|
||||
Vec_PtrFree( vCompletes );
|
||||
return vGates;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -48,12 +48,16 @@ struct Cgt_Man_t_
|
|||
// user's data
|
||||
Cgt_Par_t * pPars; // user's parameters
|
||||
Aig_Man_t * pAig; // user's AIG manager
|
||||
Aig_Man_t * pCare; // user's constraints
|
||||
// user's constraints
|
||||
Aig_Man_t * pCare; // constraint cones
|
||||
Vec_Vec_t * vSuppsInv; // inverse support of the constraints
|
||||
// result of clock-gating
|
||||
Vec_Vec_t * vGatesAll; // the computed clock-gates
|
||||
Vec_Ptr_t * vGates; // the selected clock-gates
|
||||
// internal data
|
||||
Aig_Man_t * pFrame; // clock gate AIG manager
|
||||
Vec_Ptr_t * vFanout; // temporary storage for fanouts
|
||||
Vec_Ptr_t * vVisited; // temporary storage for visited nodes
|
||||
// SAT solving
|
||||
Aig_Man_t * pPart; // partition
|
||||
Cnf_Dat_t * pCnf; // CNF of the partition
|
||||
|
|
@ -62,14 +66,21 @@ struct Cgt_Man_t_
|
|||
int nPatts; // the number of patterns accumulated
|
||||
int nPattWords; // the number of pattern words
|
||||
// statistics
|
||||
int nRecycles; // recycles
|
||||
int nCalls; // total calls
|
||||
int nCallsSat; // satisfiable calls
|
||||
int nCallsUnsat; // unsatisfiable calls
|
||||
int nCallsUndec; // undecided calls
|
||||
int nCallsFiltered; // filtered out calls
|
||||
int timeAig; // constructing AIG
|
||||
int timePrepare; // partitioning and SAT solving
|
||||
int timeSat; // total runtime
|
||||
int timeSatSat; // satisfiable runtime
|
||||
int timeSatUnsat; // unsatisfiable runtime
|
||||
int timeSatUndec; // undecided runtime
|
||||
int timeDecision; // making decision about what gates to use
|
||||
int timeOther; // other runtime
|
||||
int timeTotal; // total runtime
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -83,11 +94,11 @@ struct Cgt_Man_t_
|
|||
/*=== cgtAig.c ==========================================================*/
|
||||
extern void Cgt_ManDetectCandidates( Aig_Man_t * pAig, Aig_Obj_t * pObj, int nLevelMax, Vec_Ptr_t * vCands );
|
||||
extern Aig_Man_t * Cgt_ManDeriveAigForGating( Cgt_Man_t * p );
|
||||
extern Aig_Man_t * Cgt_ManDupPartition( Aig_Man_t * pAig, int nVarsMin, int nFlopsMin, int iStart );
|
||||
extern Aig_Man_t * Cgt_ManDeriveGatedAig( Aig_Man_t * pAig, Vec_Ptr_t * vGates );
|
||||
extern Aig_Man_t * Cgt_ManDupPartition( Aig_Man_t * pAig, int nVarsMin, int nFlopsMin, int iStart, Aig_Man_t * pCare, Vec_Vec_t * vSuppsInv, int * pnOutputs );
|
||||
extern Aig_Man_t * Cgt_ManDeriveGatedAig( Aig_Man_t * pAig, Vec_Vec_t * vGates, int fReduce, int * pnUsedNodes );
|
||||
/*=== cgtDecide.c ==========================================================*/
|
||||
extern Vec_Ptr_t * Cgt_ManDecide( Aig_Man_t * pAig, Vec_Vec_t * vGatesAll );
|
||||
extern Vec_Ptr_t * Cgt_ManDecideSimple( Aig_Man_t * pAig, Vec_Vec_t * vGatesAll );
|
||||
extern Vec_Vec_t * Cgt_ManDecideSimple( Aig_Man_t * pAig, Vec_Vec_t * vGatesAll, int nOdcMax, int fVerbose );
|
||||
extern Vec_Vec_t * Cgt_ManDecideArea( Aig_Man_t * pAig, Vec_Vec_t * vGatesAll, int nOdcMax, int fVerbose );
|
||||
/*=== cgtMan.c ==========================================================*/
|
||||
extern Cgt_Man_t * Cgt_ManCreate( Aig_Man_t * pAig, Aig_Man_t * pCare, Cgt_Par_t * pPars );
|
||||
extern void Cgt_ManClean( Cgt_Man_t * p );
|
||||
|
|
|
|||
|
|
@ -53,7 +53,19 @@ Cgt_Man_t * Cgt_ManCreate( Aig_Man_t * pAig, Aig_Man_t * pCare, Cgt_Par_t * pPar
|
|||
p->pAig = pAig;
|
||||
p->vGatesAll = Vec_VecStart( Saig_ManRegNum(pAig) );
|
||||
p->vFanout = Vec_PtrAlloc( 1000 );
|
||||
p->vVisited = Vec_PtrAlloc( 1000 );
|
||||
p->nPattWords = 16;
|
||||
if ( pCare == NULL )
|
||||
return p;
|
||||
// check out the constraints
|
||||
if ( Aig_ManPiNum(pCare) != Aig_ManPiNum(pAig) )
|
||||
{
|
||||
printf( "The PI count of care (%d) and AIG (%d) differ. Careset is not used.\n",
|
||||
Aig_ManPiNum(pCare), Aig_ManPiNum(pAig) );
|
||||
return p;
|
||||
}
|
||||
p->pCare = pCare;
|
||||
p->vSuppsInv = (Vec_Vec_t *)Aig_ManSupportsInverse( p->pCare );
|
||||
return p;
|
||||
}
|
||||
|
||||
|
|
@ -106,27 +118,16 @@ void Cgt_ManClean( Cgt_Man_t * p )
|
|||
***********************************************************************/
|
||||
void Cgt_ManPrintStats( Cgt_Man_t * p )
|
||||
{
|
||||
printf( "Params: LevMax = %d. CandMax = %d. OdcMax = %d. ConfMax = %d. VarMin = %d. FlopMin = %d.\n",
|
||||
p->pPars->nLevelMax, p->pPars->nCandMax, p->pPars->nOdcMax,
|
||||
p->pPars->nConfMax, p->pPars->nVarsMin, p->pPars->nFlopsMin );
|
||||
printf( "SAT : Calls = %d. Unsat = %d. Sat = %d. Fails = %d. Recycles = %d. ",
|
||||
p->nCalls, p->nCallsUnsat, p->nCallsSat, p->nCallsUndec, p->nRecycles );
|
||||
PRT( "Time", p->timeTotal );
|
||||
/*
|
||||
double nMemory = 1.0*Aig_ManObjNumMax(p->pAig)*p->nFrames*(2*sizeof(int)+2*sizeof(void*))/(1<<20);
|
||||
|
||||
printf( "Parameters: F = %d. AddF = %d. C-lim = %d. Constr = %d. MaxLev = %d. Mem = %0.2f Mb.\n",
|
||||
p->pPars->nFramesK, p->pPars->nFramesAddSim, p->pPars->nBTLimit, p->pPars->nConstrs, p->pPars->nMaxLevs, nMemory );
|
||||
printf( "AIG : PI = %d. PO = %d. Latch = %d. Node = %d. Ave SAT vars = %d.\n",
|
||||
Saig_ManPiNum(p->pAig), Saig_ManPoNum(p->pAig), Saig_ManRegNum(p->pAig), Aig_ManNodeNum(p->pAig),
|
||||
0/p->pPars->nIters );
|
||||
printf( "SAT calls : Proof = %d. Cex = %d. Fail = %d. Lits proved = %d.\n",
|
||||
p->nSatProof, p->nSatCallsSat, p->nSatFailsReal, Cgt_ManCountEquivs(p) );
|
||||
printf( "SAT solver: Vars max = %d. Calls max = %d. Recycles = %d. Sim rounds = %d.\n",
|
||||
p->nVarsMax, p->nCallsMax, p->nRecyclesTotal, p->nSimRounds );
|
||||
printf( "NBeg = %d. NEnd = %d. (Gain = %6.2f %%). RBeg = %d. REnd = %d. (Gain = %6.2f %%).\n",
|
||||
p->nNodesBeg, p->nNodesEnd, 100.0*(p->nNodesBeg-p->nNodesEnd)/(p->nNodesBeg?p->nNodesBeg:1),
|
||||
p->nRegsBeg, p->nRegsEnd, 100.0*(p->nRegsBeg-p->nRegsEnd)/(p->nRegsBeg?p->nRegsBeg:1) );
|
||||
|
||||
p->timeOther = p->timeTotal-p->timeBmc-p->timeReduce-p->timeMarkCones-p->timeSimSat-p->timeSat;
|
||||
PRTP( "BMC ", p->timeBmc, p->timeTotal );
|
||||
PRTP( "Spec reduce", p->timeReduce, p->timeTotal );
|
||||
PRTP( "Mark cones ", p->timeMarkCones, p->timeTotal );
|
||||
PRTP( "Sim SAT ", p->timeSimSat, p->timeTotal );
|
||||
p->timeOther = p->timeTotal-p->timeAig-p->timePrepare-p->timeSat-p->timeDecision;
|
||||
PRTP( "AIG ", p->timeAig, p->timeTotal );
|
||||
PRTP( "Prepare ", p->timePrepare, p->timeTotal );
|
||||
PRTP( "SAT solving", p->timeSat, p->timeTotal );
|
||||
PRTP( " unsat ", p->timeSatUnsat, p->timeTotal );
|
||||
PRTP( " sat ", p->timeSatSat, p->timeTotal );
|
||||
|
|
@ -155,8 +156,13 @@ void Cgt_ManStop( Cgt_Man_t * p )
|
|||
Aig_ManStop( p->pFrame );
|
||||
Cgt_ManClean( p );
|
||||
Vec_PtrFree( p->vFanout );
|
||||
Vec_PtrFree( p->vGates );
|
||||
Vec_VecFree( p->vGatesAll );
|
||||
Vec_PtrFree( p->vVisited );
|
||||
if ( p->vGates )
|
||||
Vec_PtrFree( p->vGates );
|
||||
if ( p->vGatesAll )
|
||||
Vec_VecFree( p->vGatesAll );
|
||||
if ( p->vSuppsInv )
|
||||
Vec_VecFree( p->vSuppsInv );
|
||||
free( p );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -422,7 +422,7 @@ Cnf_Dat_t * Cnf_DeriveSimple( Aig_Man_t * p, int nOutputs )
|
|||
OutVar = pCnf->pVarNums[ Aig_ManConst1(p)->Id ];
|
||||
assert( OutVar <= Aig_ManObjNumMax(p) );
|
||||
*pClas++ = pLits;
|
||||
*pLits++ = 2 * OutVar;
|
||||
*pLits++ = 2 * OutVar;
|
||||
|
||||
// write the output literals
|
||||
Aig_ManForEachPo( p, pObj, i )
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ struct Dar_RwrPar_t_
|
|||
int fFanout; // support fanout representation
|
||||
int fUpdateLevel; // update level
|
||||
int fUseZeros; // performs zero-cost replacement
|
||||
int fPower; // enables power-aware rewriting
|
||||
int fVerbose; // enables verbose output
|
||||
int fVeryVerbose; // enables very verbose output
|
||||
};
|
||||
|
|
@ -92,8 +93,8 @@ extern int Dar_ManRefactor( Aig_Man_t * pAig, Dar_RefPar_t * pPars )
|
|||
/*=== darScript.c ========================================================*/
|
||||
extern Aig_Man_t * Dar_ManRewriteDefault( Aig_Man_t * pAig );
|
||||
extern Aig_Man_t * Dar_ManRwsat( Aig_Man_t * pAig, int fBalance, int fVerbose );
|
||||
extern Aig_Man_t * Dar_ManCompress( Aig_Man_t * pAig, int fBalance, int fUpdateLevel, int fVerbose );
|
||||
extern Aig_Man_t * Dar_ManCompress2( Aig_Man_t * pAig, int fBalance, int fUpdateLevel, int fFanout, int fVerbose );
|
||||
extern Aig_Man_t * Dar_ManCompress( Aig_Man_t * pAig, int fBalance, int fUpdateLevel, int fPower, int fVerbose );
|
||||
extern Aig_Man_t * Dar_ManCompress2( Aig_Man_t * pAig, int fBalance, int fUpdateLevel, int fFanout, int fPower, int fVerbose );
|
||||
extern Aig_Man_t * Dar_ManChoice( Aig_Man_t * pAig, int fBalance, int fUpdateLevel, int fConstruct, int nConfMax, int nLevelMax, int fVerbose );
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ void Dar_ManDefaultRwrParams( Dar_RwrPar_t * pPars )
|
|||
pPars->fFanout = 1;
|
||||
pPars->fUpdateLevel = 0;
|
||||
pPars->fUseZeros = 0;
|
||||
pPars->fPower = 0;
|
||||
pPars->fVerbose = 0;
|
||||
pPars->fVeryVerbose = 0;
|
||||
}
|
||||
|
|
@ -64,6 +65,7 @@ void Dar_ManDefaultRwrParams( Dar_RwrPar_t * pPars )
|
|||
***********************************************************************/
|
||||
int Dar_ManRewrite( Aig_Man_t * pAig, Dar_RwrPar_t * pPars )
|
||||
{
|
||||
extern Vec_Int_t * Saig_ManComputeSwitchProbs( Aig_Man_t * p, int nFrames, int nPref, int fProbOne );
|
||||
Dar_Man_t * p;
|
||||
// Bar_Progress_t * pProgress;
|
||||
Dar_Cut_t * pCut;
|
||||
|
|
@ -74,6 +76,8 @@ int Dar_ManRewrite( Aig_Man_t * pAig, Dar_RwrPar_t * pPars )
|
|||
Dar_LibPrepare( pPars->nSubgMax );
|
||||
// create rewriting manager
|
||||
p = Dar_ManStart( pAig, pPars );
|
||||
if ( pPars->fPower )
|
||||
pAig->vProbs = Saig_ManComputeSwitchProbs( pAig, 48, 16, 1 );
|
||||
// remove dangling nodes
|
||||
Aig_ManCleanup( pAig );
|
||||
// if updating levels is requested, start fanout and timing
|
||||
|
|
@ -182,6 +186,11 @@ p->timeOther = p->timeTotal - p->timeCuts - p->timeEval;
|
|||
// Aig_ManVerifyReverseLevel( pAig );
|
||||
Aig_ManStopReverseLevels( pAig );
|
||||
}
|
||||
if ( pAig->vProbs )
|
||||
{
|
||||
Vec_IntFree( pAig->vProbs );
|
||||
pAig->vProbs = NULL;
|
||||
}
|
||||
// stop the rewriting manager
|
||||
Dar_ManStop( p );
|
||||
Aig_ManCheckPhase( pAig );
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ struct Dar_LibDat_t_ // library object data
|
|||
Aig_Obj_t * pFunc; // the corresponding AIG node if it exists
|
||||
int Level; // level of this node after it is constructured
|
||||
int TravId; // traversal ID of the library object data
|
||||
float dProb; // probability of the node being 1
|
||||
unsigned char fMffc; // set to one if node is part of MFFC
|
||||
unsigned char nLats[3]; // the number of latches on the input/output stem
|
||||
};
|
||||
|
|
@ -698,6 +699,12 @@ int Dar_LibCutMatch( Dar_Man_t * p, Dar_Cut_t * pCut )
|
|||
pFanin = Aig_NotCond(pFanin, ((uPhase >> i) & 1) );
|
||||
s_DarLib->pDatas[i].pFunc = pFanin;
|
||||
s_DarLib->pDatas[i].Level = Aig_Regular(pFanin)->Level;
|
||||
// copy the propability of node being one
|
||||
if ( p->pPars->fPower )
|
||||
{
|
||||
float Prob = Aig_Int2Float( Vec_IntEntry( p->pAig->vProbs, Aig_ObjId(Aig_Regular(pFanin)) ) );
|
||||
s_DarLib->pDatas[i].dProb = Aig_IsComplement(pFanin)? 1.0-Prob : Prob;
|
||||
}
|
||||
}
|
||||
p->nCutsGood++;
|
||||
return 1;
|
||||
|
|
@ -716,14 +723,14 @@ int Dar_LibCutMatch( Dar_Man_t * p, Dar_Cut_t * pCut )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Dar_LibCutMarkMffc( Aig_Man_t * p, Aig_Obj_t * pRoot, int nLeaves )
|
||||
int Dar_LibCutMarkMffc( Aig_Man_t * p, Aig_Obj_t * pRoot, int nLeaves, float * pPower )
|
||||
{
|
||||
int i, nNodes;
|
||||
// mark the cut leaves
|
||||
for ( i = 0; i < nLeaves; i++ )
|
||||
Aig_Regular(s_DarLib->pDatas[i].pFunc)->nRefs++;
|
||||
// label MFFC with current ID
|
||||
nNodes = Aig_NodeMffsLabel( p, pRoot );
|
||||
nNodes = Aig_NodeMffsLabel( p, pRoot, pPower );
|
||||
// unmark the cut leaves
|
||||
for ( i = 0; i < nLeaves; i++ )
|
||||
Aig_Regular(s_DarLib->pDatas[i].pFunc)->nRefs--;
|
||||
|
|
@ -821,10 +828,13 @@ void Dar_LibEvalAssignNums( Dar_Man_t * p, int Class, Aig_Obj_t * pRoot )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Dar_LibEval_rec( Dar_LibObj_t * pObj, int Out, int nNodesSaved, int Required )
|
||||
int Dar_LibEval_rec( Dar_LibObj_t * pObj, int Out, int nNodesSaved, int Required, float * pPower )
|
||||
{
|
||||
float Power0, Power1;
|
||||
Dar_LibDat_t * pData;
|
||||
int Area;
|
||||
if ( pPower )
|
||||
*pPower = (float)0.0;
|
||||
if ( pObj->fTerm )
|
||||
return 0;
|
||||
assert( pObj->Num > 3 );
|
||||
|
|
@ -838,12 +848,21 @@ int Dar_LibEval_rec( Dar_LibObj_t * pObj, int Out, int nNodesSaved, int Required
|
|||
pData->TravId = Out;
|
||||
// this is a new node - get a bound on the area of its branches
|
||||
nNodesSaved--;
|
||||
Area = Dar_LibEval_rec( Dar_LibObj(s_DarLib, pObj->Fan0), Out, nNodesSaved, Required+1 );
|
||||
Area = Dar_LibEval_rec( Dar_LibObj(s_DarLib, pObj->Fan0), Out, nNodesSaved, Required+1, pPower? &Power0 : NULL );
|
||||
if ( Area > nNodesSaved )
|
||||
return 0xff;
|
||||
Area += Dar_LibEval_rec( Dar_LibObj(s_DarLib, pObj->Fan1), Out, nNodesSaved, Required+1 );
|
||||
Area += Dar_LibEval_rec( Dar_LibObj(s_DarLib, pObj->Fan1), Out, nNodesSaved, Required+1, pPower? &Power1 : NULL );
|
||||
if ( Area > nNodesSaved )
|
||||
return 0xff;
|
||||
if ( pPower )
|
||||
{
|
||||
Dar_LibDat_t * pData0 = s_DarLib->pDatas + Dar_LibObj(s_DarLib, pObj->Fan0)->Num;
|
||||
Dar_LibDat_t * pData1 = s_DarLib->pDatas + Dar_LibObj(s_DarLib, pObj->Fan1)->Num;
|
||||
pData->dProb = (pObj->fCompl0? 1.0 - pData0->dProb : pData0->dProb)*
|
||||
(pObj->fCompl1? 1.0 - pData1->dProb : pData1->dProb);
|
||||
*pPower = Power0 + 2.0 * pData0->dProb * (1.0 - pData0->dProb) +
|
||||
Power1 + 2.0 * pData1->dProb * (1.0 - pData1->dProb);
|
||||
}
|
||||
return Area + 1;
|
||||
}
|
||||
|
||||
|
|
@ -861,6 +880,7 @@ int Dar_LibEval_rec( Dar_LibObj_t * pObj, int Out, int nNodesSaved, int Required
|
|||
void Dar_LibEval( Dar_Man_t * p, Aig_Obj_t * pRoot, Dar_Cut_t * pCut, int Required )
|
||||
{
|
||||
int fTraining = 0;
|
||||
float PowerSaved, PowerAdded;
|
||||
Dar_LibObj_t * pObj;
|
||||
int Out, k, Class, nNodesSaved, nNodesAdded, nNodesGained, clk;
|
||||
clk = clock();
|
||||
|
|
@ -870,7 +890,7 @@ void Dar_LibEval( Dar_Man_t * p, Aig_Obj_t * pRoot, Dar_Cut_t * pCut, int Requir
|
|||
if ( !Dar_LibCutMatch(p, pCut) )
|
||||
return;
|
||||
// mark MFFC of the node
|
||||
nNodesSaved = Dar_LibCutMarkMffc( p->pAig, pRoot, pCut->nLeaves );
|
||||
nNodesSaved = Dar_LibCutMarkMffc( p->pAig, pRoot, pCut->nLeaves, p->pPars->fPower? &PowerSaved : NULL );
|
||||
// evaluate the cut
|
||||
Class = s_DarLib->pMap[pCut->uTruth];
|
||||
Dar_LibEvalAssignNums( p, Class, pRoot );
|
||||
|
|
@ -882,8 +902,10 @@ void Dar_LibEval( Dar_Man_t * p, Aig_Obj_t * pRoot, Dar_Cut_t * pCut, int Requir
|
|||
pObj = Dar_LibObj(s_DarLib, s_DarLib->pSubgr0[Class][Out]);
|
||||
if ( Aig_Regular(s_DarLib->pDatas[pObj->Num].pFunc) == pRoot )
|
||||
continue;
|
||||
nNodesAdded = Dar_LibEval_rec( pObj, Out, nNodesSaved - !p->pPars->fUseZeros, Required );
|
||||
nNodesAdded = Dar_LibEval_rec( pObj, Out, nNodesSaved - !p->pPars->fUseZeros, Required, p->pPars->fPower? &PowerAdded : NULL );
|
||||
nNodesGained = nNodesSaved - nNodesAdded;
|
||||
if ( p->pPars->fPower && PowerSaved < PowerAdded )
|
||||
continue;
|
||||
if ( fTraining && nNodesGained >= 0 )
|
||||
Dar_LibIncrementScore( Class, Out, nNodesGained + 1 );
|
||||
if ( nNodesGained < 0 || (nNodesGained == 0 && !p->pPars->fUseZeros) )
|
||||
|
|
|
|||
|
|
@ -235,7 +235,7 @@ int Dar_RefactTryGraph( Aig_Man_t * pAig, Aig_Obj_t * pRoot, Vec_Ptr_t * vCut, K
|
|||
{
|
||||
pNode->pFunc = Vec_PtrEntry(vCut, i);
|
||||
pNode->Level = Aig_Regular(pNode->pFunc)->Level;
|
||||
assert( Aig_Regular(pNode->pFunc)->Level < (1<<14)-1 );
|
||||
assert( Aig_Regular(pNode->pFunc)->Level < (1<<24)-1 );
|
||||
}
|
||||
//printf( "Trying:\n" );
|
||||
// compute the AIG size after adding the internal nodes
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ void Dar_ManHaigPrintStats( Aig_Man_t * pAig )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Man_t * Dar_ManCompress( Aig_Man_t * pAig, int fBalance, int fUpdateLevel, int fVerbose )
|
||||
Aig_Man_t * Dar_ManCompress( Aig_Man_t * pAig, int fBalance, int fUpdateLevel, int fPower, int fVerbose )
|
||||
//alias compress2 "b -l; rw -l; rwz -l; b -l; rwz -l; b -l"
|
||||
{
|
||||
Aig_Man_t * pTemp;
|
||||
|
|
@ -167,6 +167,8 @@ Aig_Man_t * Dar_ManCompress( Aig_Man_t * pAig, int fBalance, int fUpdateLevel, i
|
|||
pParsRwr->fUpdateLevel = fUpdateLevel;
|
||||
pParsRef->fUpdateLevel = fUpdateLevel;
|
||||
|
||||
pParsRwr->fPower = fPower;
|
||||
|
||||
pParsRwr->fVerbose = 0;//fVerbose;
|
||||
pParsRef->fVerbose = 0;//fVerbose;
|
||||
|
||||
|
|
@ -224,7 +226,7 @@ Aig_Man_t * Dar_ManCompress( Aig_Man_t * pAig, int fBalance, int fUpdateLevel, i
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Man_t * Dar_ManCompress2( Aig_Man_t * pAig, int fBalance, int fUpdateLevel, int fFanout, int fVerbose )
|
||||
Aig_Man_t * Dar_ManCompress2( Aig_Man_t * pAig, int fBalance, int fUpdateLevel, int fFanout, int fPower, int fVerbose )
|
||||
//alias compress2 "b -l; rw -l; rf -l; b -l; rw -l; rwz -l; b -l; rfz -l; rwz -l; b -l"
|
||||
{
|
||||
Aig_Man_t * pTemp;
|
||||
|
|
@ -238,6 +240,7 @@ Aig_Man_t * Dar_ManCompress2( Aig_Man_t * pAig, int fBalance, int fUpdateLevel,
|
|||
pParsRwr->fUpdateLevel = fUpdateLevel;
|
||||
pParsRef->fUpdateLevel = fUpdateLevel;
|
||||
pParsRwr->fFanout = fFanout;
|
||||
pParsRwr->fPower = fPower;
|
||||
|
||||
pParsRwr->fVerbose = 0;//fVerbose;
|
||||
pParsRef->fVerbose = 0;//fVerbose;
|
||||
|
|
@ -329,7 +332,7 @@ Aig_Man_t * Dar_ManCompress2( Aig_Man_t * pAig, int fBalance, int fUpdateLevel,
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Ptr_t * Dar_ManChoiceSynthesis( Aig_Man_t * pAig, int fBalance, int fUpdateLevel, int fVerbose )
|
||||
Vec_Ptr_t * Dar_ManChoiceSynthesis( Aig_Man_t * pAig, int fBalance, int fUpdateLevel, int fPower, int fVerbose )
|
||||
//alias resyn "b; rw; rwz; b; rwz; b"
|
||||
//alias resyn2 "b; rw; rf; b; rw; rwz; b; rfz; rwz; b"
|
||||
{
|
||||
|
|
@ -344,7 +347,7 @@ Vec_Ptr_t * Dar_ManChoiceSynthesis( Aig_Man_t * pAig, int fBalance, int fUpdateL
|
|||
Aig_ManForEachObj( pAig, pObj, i )
|
||||
pObj->pHaig = pObj;
|
||||
|
||||
pAig = Dar_ManCompress (pAig, fBalance, fUpdateLevel, fVerbose);
|
||||
pAig = Dar_ManCompress(pAig, fBalance, fUpdateLevel, fPower, fVerbose);
|
||||
Vec_PtrPush( vAigs, pAig );
|
||||
//Aig_ManPrintStats( pAig );
|
||||
|
||||
|
|
@ -354,7 +357,7 @@ Vec_Ptr_t * Dar_ManChoiceSynthesis( Aig_Man_t * pAig, int fBalance, int fUpdateL
|
|||
pObj->pHaig = pObj;
|
||||
}
|
||||
|
||||
pAig = Dar_ManCompress2(pAig, fBalance, fUpdateLevel, 1, fVerbose);
|
||||
pAig = Dar_ManCompress2(pAig, fBalance, fUpdateLevel, 1, fPower, fVerbose);
|
||||
Vec_PtrPush( vAigs, pAig );
|
||||
//Aig_ManPrintStats( pAig );
|
||||
|
||||
|
|
@ -384,7 +387,7 @@ Aig_Man_t * Dar_ManChoice( Aig_Man_t * pAig, int fBalance, int fUpdateLevel, int
|
|||
|
||||
clk = clock();
|
||||
// vAigs = Dar_ManChoiceSynthesisExt();
|
||||
vAigs = Dar_ManChoiceSynthesis( pAig, fBalance, fUpdateLevel, fVerbose );
|
||||
vAigs = Dar_ManChoiceSynthesis( pAig, fBalance, fUpdateLevel, 0, fVerbose );
|
||||
|
||||
// swap the first and last network
|
||||
// this should lead to the primary choice being "better" because of synthesis
|
||||
|
|
@ -441,7 +444,7 @@ Aig_Man_t * Dar_ManChoiceNew( Aig_Man_t * pAig, Dch_Pars_t * pPars )
|
|||
|
||||
clk = clock();
|
||||
// vAigs = Dar_ManChoiceSynthesisExt();
|
||||
vAigs = Dar_ManChoiceSynthesis( pAig, 1, 1, fVerbose );
|
||||
vAigs = Dar_ManChoiceSynthesis( pAig, 1, 1, pPars->fPower, fVerbose );
|
||||
|
||||
// swap the first and last network
|
||||
// this should lead to the primary choice being "better" because of synthesis
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ struct Dch_Pars_t_
|
|||
int fSynthesis; // set to 1 to perform synthesis
|
||||
int fPolarFlip; // uses polarity adjustment
|
||||
int fSimulateTfo; // uses simulatin of TFO classes
|
||||
int fPower; // uses power-aware rewriting
|
||||
int fVerbose; // verbose stats
|
||||
int timeSynth; // synthesis runtime
|
||||
int nNodesAhead; // the lookahead in terms of nodes
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ void Dch_ManSetDefaultParams( Dch_Pars_t * p )
|
|||
p->fSynthesis = 1; // derives three snapshots
|
||||
p->fPolarFlip = 1; // uses polarity adjustment
|
||||
p->fSimulateTfo = 1; // simulate TFO
|
||||
p->fPower = 0; // power-aware rewriting
|
||||
p->fVerbose = 0; // verbose stats
|
||||
p->nNodesAhead = 1000; // the lookahead in terms of nodes
|
||||
p->nCallsRecycle = 100; // calls to perform before recycling SAT solver
|
||||
|
|
|
|||
|
|
@ -404,7 +404,7 @@ clk = clock();
|
|||
pNew = Aig_ManDupOrdered( pTemp = pNew );
|
||||
Aig_ManStop( pTemp );
|
||||
// pNew = Dar_ManRewriteDefault( pTemp = pNew );
|
||||
pNew = Dar_ManCompress2( pTemp = pNew, 1, 0, 1, 0 );
|
||||
pNew = Dar_ManCompress2( pTemp = pNew, 1, 0, 1, 0, 0 );
|
||||
Aig_ManStop( pTemp );
|
||||
if ( pParSec->fVerbose )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,97 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [fsim.h]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Fast sequential AIG simulator.]
|
||||
|
||||
Synopsis [External declarations.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: fsim.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef __FSIM_H__
|
||||
#define __FSIM_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// INCLUDES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// PARAMETERS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// BASIC TYPES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct Fsim_Man_t_ Fsim_Man_t;
|
||||
|
||||
// simulation parameters
|
||||
typedef struct Fsim_ParSim_t_ Fsim_ParSim_t;
|
||||
struct Fsim_ParSim_t_
|
||||
{
|
||||
// user-controlled parameters
|
||||
int nWords; // the number of machine words
|
||||
int nIters; // the number of timeframes
|
||||
int TimeLimit; // time limit in seconds
|
||||
int fCheckMiter; // check if miter outputs are non-zero
|
||||
int fVerbose; // enables verbose output
|
||||
// internal parameters
|
||||
int fCompressAig; // compresses internal data
|
||||
};
|
||||
|
||||
// switching estimation parameters
|
||||
typedef struct Fsim_ParSwitch_t_ Fsim_ParSwitch_t;
|
||||
struct Fsim_ParSwitch_t_
|
||||
{
|
||||
// user-controlled parameters
|
||||
int nWords; // the number of machine words
|
||||
int nIters; // the number of timeframes
|
||||
int nPref; // the number of first timeframes to skip
|
||||
int nRandPiNum; // PI trans prob (0=1/2; 1=1/4; 2=1/8, etc)
|
||||
int fProbOne; // collect probability of one
|
||||
int fProbTrans; // collect probatility of switching
|
||||
int fVerbose; // enables verbose output
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// MACRO DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*=== fsimCore.c ==========================================================*/
|
||||
extern void Fsim_ManSetDefaultParamsSim( Fsim_ParSim_t * p );
|
||||
extern void Fsim_ManSetDefaultParamsSwitch( Fsim_ParSwitch_t * p );
|
||||
/*=== fsimSim.c ==========================================================*/
|
||||
extern int Fsim_ManSimulate( Aig_Man_t * pAig, Fsim_ParSim_t * pPars );
|
||||
/*=== fsimSwitch.c ==========================================================*/
|
||||
extern Vec_Int_t * Fsim_ManSwitchSimulate( Aig_Man_t * pAig, Fsim_ParSwitch_t * pPars );
|
||||
/*=== fsimTsim.c ==========================================================*/
|
||||
extern Vec_Ptr_t * Fsim_ManTerSimulate( Aig_Man_t * pAig, int fVerbose );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [fsimCore.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Fast sequential AIG simulator.]
|
||||
|
||||
Synopsis [Core procedures.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: fsimCore.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "fsimInt.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [This procedure sets default parameters.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fsim_ManSetDefaultParamsSim( Fsim_ParSim_t * p )
|
||||
{
|
||||
memset( p, 0, sizeof(Fsim_ParSim_t) );
|
||||
// user-controlled parameters
|
||||
p->nWords = 8; // the number of machine words
|
||||
p->nIters = 32; // the number of timeframes
|
||||
p->TimeLimit = 60; // time limit in seconds
|
||||
p->fCheckMiter = 0; // check if miter outputs are non-zero
|
||||
p->fVerbose = 1; // enables verbose output
|
||||
// internal parameters
|
||||
p->fCompressAig = 0; // compresses internal data
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [This procedure sets default parameters.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fsim_ManSetDefaultParamsSwitch( Fsim_ParSwitch_t * p )
|
||||
{
|
||||
memset( p, 0, sizeof(Fsim_ParSwitch_t) );
|
||||
// user-controlled parameters
|
||||
p->nWords = 1; // the number of machine words
|
||||
p->nIters = 48; // the number of timeframes
|
||||
p->nPref = 16; // the number of first timeframes to skip
|
||||
p->nRandPiNum = 0; // PI trans prob (0=1/2; 1=1/4; 2=1/8, etc)
|
||||
p->fProbOne = 1; // collect probability of one
|
||||
p->fProbTrans = 1; // collect probatility of switching
|
||||
p->fVerbose = 1; // enables verbose output
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,364 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [fsimFront.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Fast sequential AIG simulator.]
|
||||
|
||||
Synopsis [Simulation frontier.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: fsimFront.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "fsimInt.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Fsim_ManStoreNum( Fsim_Man_t * p, int Num )
|
||||
{
|
||||
unsigned x = (unsigned)Num;
|
||||
assert( Num >= 0 );
|
||||
while ( x & ~0x7f )
|
||||
{
|
||||
*p->pDataCur++ = (x & 0x7f) | 0x80;
|
||||
x >>= 7;
|
||||
}
|
||||
*p->pDataCur++ = x;
|
||||
assert( p->pDataCur - p->pDataAig < p->nDataAig );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Fsim_ManRestoreNum( Fsim_Man_t * p )
|
||||
{
|
||||
int ch, i, x = 0;
|
||||
for ( i = 0; (ch = *p->pDataCur++) & 0x80; i++ )
|
||||
x |= (ch & 0x7f) << (7 * i);
|
||||
assert( p->pDataCur - p->pDataAig < p->nDataAig );
|
||||
return x | (ch << (7 * i));
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Fsim_ManStoreObj( Fsim_Man_t * p, Fsim_Obj_t * pObj )
|
||||
{
|
||||
if ( p->pDataAig2 )
|
||||
{
|
||||
*p->pDataCur2++ = pObj->iNode;
|
||||
*p->pDataCur2++ = pObj->iFan0;
|
||||
*p->pDataCur2++ = pObj->iFan1;
|
||||
return;
|
||||
}
|
||||
if ( pObj->iFan0 && pObj->iFan1 ) // and
|
||||
{
|
||||
assert( pObj->iNode );
|
||||
assert( pObj->iNode >= p->iNodePrev );
|
||||
assert( (pObj->iNode << 1) > pObj->iFan0 );
|
||||
assert( pObj->iFan0 > pObj->iFan1 );
|
||||
Fsim_ManStoreNum( p, ((pObj->iNode - p->iNodePrev) << 2) | 3 );
|
||||
Fsim_ManStoreNum( p, (pObj->iNode << 1) - pObj->iFan0 );
|
||||
Fsim_ManStoreNum( p, pObj->iFan0 - pObj->iFan1 );
|
||||
p->iNodePrev = pObj->iNode;
|
||||
}
|
||||
else if ( !pObj->iFan0 && !pObj->iFan1 ) // ci
|
||||
{
|
||||
assert( pObj->iNode );
|
||||
assert( pObj->iNode >= p->iNodePrev );
|
||||
Fsim_ManStoreNum( p, ((pObj->iNode - p->iNodePrev) << 2) | 1 );
|
||||
p->iNodePrev = pObj->iNode;
|
||||
}
|
||||
else // if ( !pObj->iFan0 && pObj->iFan1 ) // co
|
||||
{
|
||||
assert( pObj->iNode == 0 );
|
||||
assert( pObj->iFan0 != 0 );
|
||||
assert( pObj->iFan1 == 0 );
|
||||
assert( ((p->iNodePrev << 1) | 1) >= pObj->iFan0 );
|
||||
Fsim_ManStoreNum( p, (((p->iNodePrev << 1) | 1) - pObj->iFan0) << 1 );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Fsim_ManRestoreObj( Fsim_Man_t * p, Fsim_Obj_t * pObj )
|
||||
{
|
||||
int iValue = Fsim_ManRestoreNum( p );
|
||||
if ( (iValue & 3) == 3 ) // and
|
||||
{
|
||||
pObj->iNode = (iValue >> 2) + p->iNodePrev;
|
||||
pObj->iFan0 = (pObj->iNode << 1) - Fsim_ManRestoreNum( p );
|
||||
pObj->iFan1 = pObj->iFan0 - Fsim_ManRestoreNum( p );
|
||||
p->iNodePrev = pObj->iNode;
|
||||
}
|
||||
else if ( (iValue & 3) == 1 ) // ci
|
||||
{
|
||||
pObj->iNode = (iValue >> 2) + p->iNodePrev;
|
||||
pObj->iFan0 = 0;
|
||||
pObj->iFan1 = 0;
|
||||
p->iNodePrev = pObj->iNode;
|
||||
}
|
||||
else // if ( (iValue & 1) == 0 ) // co
|
||||
{
|
||||
pObj->iNode = 0;
|
||||
pObj->iFan0 = ((p->iNodePrev << 1) | 1) - (iValue >> 1);
|
||||
pObj->iFan1 = 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Determine the frontier.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Fsim_ManFrontFindNext( Fsim_Man_t * p, char * pFront )
|
||||
{
|
||||
assert( p->iNumber < (1 << 30) - p->nFront );
|
||||
while ( 1 )
|
||||
{
|
||||
if ( p->iNumber % p->nFront == 0 )
|
||||
p->iNumber++;
|
||||
if ( pFront[p->iNumber % p->nFront] == 0 )
|
||||
{
|
||||
pFront[p->iNumber % p->nFront] = 1;
|
||||
return p->iNumber;
|
||||
}
|
||||
p->iNumber++;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Verifies the frontier.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fsim_ManVerifyFront( Fsim_Man_t * p )
|
||||
{
|
||||
Fsim_Obj_t * pObj;
|
||||
int * pFans0, * pFans1; // representation of fanins
|
||||
int * pFrontToId; // mapping of nodes into frontier variables
|
||||
int i, iVar0, iVar1;
|
||||
pFans0 = ALLOC( int, p->nObjs );
|
||||
pFans1 = ALLOC( int, p->nObjs );
|
||||
pFans0[0] = pFans1[0] = 0;
|
||||
pFans0[1] = pFans1[1] = 0;
|
||||
pFrontToId = CALLOC( int, p->nFront );
|
||||
if ( Aig_ObjRefs(Aig_ManConst1(p->pAig)) )
|
||||
pFrontToId[1] = 1;
|
||||
Fsim_ManForEachObj( p, pObj, i )
|
||||
{
|
||||
if ( pObj->iNode )
|
||||
pFrontToId[pObj->iNode % p->nFront] = i;
|
||||
iVar0 = Fsim_Lit2Var(pObj->iFan0);
|
||||
iVar1 = Fsim_Lit2Var(pObj->iFan1);
|
||||
pFans0[i] = Fsim_Var2Lit(pFrontToId[iVar0 % p->nFront], Fsim_LitIsCompl(pObj->iFan0));
|
||||
pFans1[i] = Fsim_Var2Lit(pFrontToId[iVar1 % p->nFront], Fsim_LitIsCompl(pObj->iFan1));
|
||||
}
|
||||
for ( i = 0; i < p->nObjs; i++ )
|
||||
{
|
||||
assert( pFans0[i] == p->pFans0[i] );
|
||||
assert( pFans1[i] == p->pFans1[i] );
|
||||
}
|
||||
free( pFrontToId );
|
||||
free( pFans0 );
|
||||
free( pFans1 );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Determine the frontier.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fsim_ManFront( Fsim_Man_t * p, int fCompressAig )
|
||||
{
|
||||
Fsim_Obj_t Obj, * pObj = &Obj;
|
||||
char * pFront; // places used for the frontier
|
||||
int * pIdToFront; // mapping of nodes into frontier places
|
||||
int i, iVar0, iVar1, nCrossCut = 0, nCrossCutMax = 0;
|
||||
// start the frontier
|
||||
pFront = CALLOC( char, p->nFront );
|
||||
pIdToFront = ALLOC( int, p->nObjs );
|
||||
pIdToFront[0] = -1;
|
||||
pIdToFront[1] = -1;
|
||||
// add constant node
|
||||
p->iNumber = 1;
|
||||
if ( p->pRefs[1] )
|
||||
{
|
||||
pIdToFront[1] = Fsim_ManFrontFindNext( p, pFront );
|
||||
nCrossCut = 1;
|
||||
}
|
||||
// allocate room for data
|
||||
if ( fCompressAig )
|
||||
{
|
||||
p->nDataAig = p->nObjs * 6;
|
||||
p->pDataAig = ALLOC( unsigned char, p->nDataAig );
|
||||
p->pDataCur = p->pDataAig;
|
||||
p->iNodePrev = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
p->pDataAig2 = ALLOC( int, 3 * p->nObjs );
|
||||
p->pDataCur2 = p->pDataAig2 + 6;
|
||||
}
|
||||
// iterate through the objects
|
||||
for ( i = 2; i < p->nObjs; i++ )
|
||||
{
|
||||
if ( p->pFans0[i] == 0 ) // ci
|
||||
{
|
||||
// store node
|
||||
pIdToFront[i] = Fsim_ManFrontFindNext( p, pFront );
|
||||
pObj->iNode = pIdToFront[i];
|
||||
pObj->iFan0 = 0;
|
||||
pObj->iFan1 = 0;
|
||||
Fsim_ManStoreObj( p, pObj );
|
||||
// handle CIs without fanout
|
||||
if ( p->pRefs[i] == 0 )
|
||||
{
|
||||
pFront[pIdToFront[i] % p->nFront] = 0;
|
||||
pIdToFront[i] = -1;
|
||||
}
|
||||
}
|
||||
else if ( p->pFans1[i] == 0 ) // co
|
||||
{
|
||||
assert( p->pRefs[i] == 0 );
|
||||
// get the fanin
|
||||
iVar0 = Fsim_Lit2Var(p->pFans0[i]);
|
||||
assert( pIdToFront[iVar0] > 0 );
|
||||
// store node
|
||||
pObj->iNode = 0;
|
||||
pObj->iFan0 = Fsim_Var2Lit(pIdToFront[iVar0], Fsim_LitIsCompl(p->pFans0[i]));
|
||||
pObj->iFan1 = 0;
|
||||
Fsim_ManStoreObj( p, pObj );
|
||||
// deref the fanin
|
||||
if ( --p->pRefs[iVar0] == 0 )
|
||||
{
|
||||
pFront[pIdToFront[iVar0] % p->nFront] = 0;
|
||||
pIdToFront[iVar0] = -1;
|
||||
nCrossCut--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// get the fanins
|
||||
iVar0 = Fsim_Lit2Var(p->pFans0[i]);
|
||||
assert( pIdToFront[iVar0] > 0 );
|
||||
iVar1 = Fsim_Lit2Var(p->pFans1[i]);
|
||||
assert( pIdToFront[iVar1] > 0 );
|
||||
// store node
|
||||
pIdToFront[i] = Fsim_ManFrontFindNext( p, pFront );
|
||||
pObj->iNode = pIdToFront[i];
|
||||
pObj->iFan0 = Fsim_Var2Lit(pIdToFront[iVar0], Fsim_LitIsCompl(p->pFans0[i]));
|
||||
pObj->iFan1 = Fsim_Var2Lit(pIdToFront[iVar1], Fsim_LitIsCompl(p->pFans1[i]));
|
||||
Fsim_ManStoreObj( p, pObj );
|
||||
// deref the fanins
|
||||
if ( --p->pRefs[iVar0] == 0 )
|
||||
{
|
||||
pFront[pIdToFront[iVar0] % p->nFront] = 0;
|
||||
pIdToFront[iVar0] = -1;
|
||||
nCrossCut--;
|
||||
}
|
||||
if ( --p->pRefs[iVar1] == 0 )
|
||||
{
|
||||
pFront[pIdToFront[iVar1] % p->nFront] = 0;
|
||||
pIdToFront[iVar1] = -1;
|
||||
nCrossCut--;
|
||||
}
|
||||
// handle nodes without fanout (choice nodes)
|
||||
if ( p->pRefs[i] == 0 )
|
||||
{
|
||||
pFront[pIdToFront[i] % p->nFront] = 0;
|
||||
pIdToFront[i] = -1;
|
||||
}
|
||||
}
|
||||
if ( p->pRefs[i] )
|
||||
if ( nCrossCutMax < ++nCrossCut )
|
||||
nCrossCutMax = nCrossCut;
|
||||
}
|
||||
assert( p->pDataAig2 == NULL || p->pDataCur2 - p->pDataAig2 == (3 * p->nObjs) );
|
||||
assert( nCrossCut == 0 );
|
||||
assert( nCrossCutMax == p->nCrossCutMax );
|
||||
for ( i = 0; i < p->nFront; i++ )
|
||||
assert( pFront[i] == 0 );
|
||||
free( pFront );
|
||||
free( pIdToFront );
|
||||
// Fsim_ManVerifyFront( p );
|
||||
FREE( p->pFans0 );
|
||||
FREE( p->pFans1 );
|
||||
FREE( p->pRefs );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,134 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [fsimInt.h]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Fast sequential AIG simulator.]
|
||||
|
||||
Synopsis [Internal declarations.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: fsimInt.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef __FSIM_INT_H__
|
||||
#define __FSIM_INT_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// INCLUDES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "saig.h"
|
||||
#include "fsim.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// PARAMETERS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// BASIC TYPES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// simulation object
|
||||
typedef struct Fsim_Obj_t_ Fsim_Obj_t;
|
||||
struct Fsim_Obj_t_
|
||||
{
|
||||
int iNode; // the node ID
|
||||
int iFan0; // the first fanin
|
||||
int iFan1; // the second fanin
|
||||
};
|
||||
|
||||
// fast sequential simulation manager
|
||||
struct Fsim_Man_t_
|
||||
{
|
||||
// parameters
|
||||
Aig_Man_t * pAig; // the AIG to be used for simulation
|
||||
int nWords; // the number of simulation words
|
||||
// AIG representation
|
||||
int nPis; // the number of primary inputs
|
||||
int nPos; // the number of primary outputs
|
||||
int nCis; // the number of combinational inputs
|
||||
int nCos; // the number of combinational outputs
|
||||
int nNodes; // the number of internal nodes
|
||||
int nObjs; // nCis + nNodes + nCos + 2
|
||||
int * pFans0; // fanin0 for all objects
|
||||
int * pFans1; // fanin1 for all objects
|
||||
int * pRefs; // reference counter for each node
|
||||
int * pRefsCopy; // reference counter for each node
|
||||
Vec_Int_t * vCis2Ids; // mapping of CIs into their PI ids
|
||||
Vec_Int_t * vLos; // register outputs
|
||||
Vec_Int_t * vLis; // register inputs
|
||||
// cross-cut representation
|
||||
int nCrossCut; // temporary cross-cut variable
|
||||
int nCrossCutMax; // maximum cross-cut variable
|
||||
int nFront; // the size of frontier
|
||||
// derived AIG representation
|
||||
int nDataAig; // the length of allocated data
|
||||
unsigned char * pDataAig; // AIG representation
|
||||
unsigned char * pDataCur; // AIG representation (current position)
|
||||
int iNodePrev; // previous extracted value
|
||||
int iNumber; // the number of the last object
|
||||
Fsim_Obj_t Obj; // current object
|
||||
// temporary AIG representation
|
||||
int * pDataAig2; // temporary representation
|
||||
int * pDataCur2; // AIG representation (current position)
|
||||
// simulation information
|
||||
unsigned * pDataSim; // simulation data
|
||||
unsigned * pDataSimCis; // simulation data for CIs
|
||||
unsigned * pDataSimCos; // simulation data for COs
|
||||
// other information
|
||||
int * pData1;
|
||||
int * pData2;
|
||||
};
|
||||
|
||||
static inline unsigned * Fsim_SimData( Fsim_Man_t * p, int i ) { return p->pDataSim + i * p->nWords; }
|
||||
static inline unsigned * Fsim_SimDataCi( Fsim_Man_t * p, int i ) { return p->pDataSimCis + i * p->nWords; }
|
||||
static inline unsigned * Fsim_SimDataCo( Fsim_Man_t * p, int i ) { return p->pDataSimCos + i * p->nWords; }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// MACRO DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static inline int Fsim_Var2Lit( int Var, int fCompl ) { return Var + Var + fCompl; }
|
||||
static inline int Fsim_Lit2Var( int Lit ) { return Lit >> 1; }
|
||||
static inline int Fsim_LitIsCompl( int Lit ) { return Lit & 1; }
|
||||
static inline int Fsim_LitNot( int Lit ) { return Lit ^ 1; }
|
||||
static inline int Fsim_LitNotCond( int Lit, int c ) { return Lit ^ (int)(c > 0); }
|
||||
static inline int Fsim_LitRegular( int Lit ) { return Lit & ~01; }
|
||||
|
||||
#define Fsim_ManForEachObj( p, pObj, i )\
|
||||
for ( i = 2, p->pDataCur = p->pDataAig, p->iNodePrev = 0, pObj = &p->Obj;\
|
||||
i < p->nObjs && Fsim_ManRestoreObj( p, pObj ); i++ )
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*=== fsimFront.c ========================================================*/
|
||||
extern void Fsim_ManFront( Fsim_Man_t * p, int fCompressAig );
|
||||
/*=== fsimMan.c ==========================================================*/
|
||||
extern Fsim_Man_t * Fsim_ManCreate( Aig_Man_t * pAig );
|
||||
extern void Fsim_ManDelete( Fsim_Man_t * p );
|
||||
extern void Fsim_ManTest( Aig_Man_t * pAig );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -0,0 +1,207 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [fsimMan.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Fast sequential AIG simulator.]
|
||||
|
||||
Synopsis [Simulation manager.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: fsimMan.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "fsimInt.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates fast simulation manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Fsim_ManCreate_rec( Fsim_Man_t * p, Aig_Obj_t * pObj )
|
||||
{
|
||||
int iFan0, iFan1, iTemp;
|
||||
assert( !Aig_IsComplement(pObj) );
|
||||
if ( pObj->iData )
|
||||
return pObj->iData;
|
||||
assert( !Aig_ObjIsConst1(pObj) );
|
||||
if ( Aig_ObjIsNode(pObj) )
|
||||
{
|
||||
iFan0 = Fsim_ManCreate_rec( p, Aig_ObjFanin0(pObj) );
|
||||
iFan1 = Fsim_ManCreate_rec( p, Aig_ObjFanin1(pObj) );
|
||||
assert( iFan0 != iFan1 );
|
||||
if ( --p->pRefs[iFan0] == 0 )
|
||||
p->nCrossCut--;
|
||||
iFan0 = Fsim_Var2Lit( iFan0, Aig_ObjFaninC0(pObj) );
|
||||
if ( --p->pRefs[iFan1] == 0 )
|
||||
p->nCrossCut--;
|
||||
iFan1 = Fsim_Var2Lit( iFan1, Aig_ObjFaninC1(pObj) );
|
||||
if ( p->pAig->pEquivs )
|
||||
Fsim_ManCreate_rec( p, Aig_ObjEquiv(p->pAig, pObj) );
|
||||
}
|
||||
else if ( Aig_ObjIsPo(pObj) )
|
||||
{
|
||||
assert( Aig_ObjRefs(pObj) == 0 );
|
||||
iFan0 = Fsim_ManCreate_rec( p, Aig_ObjFanin0(pObj) );
|
||||
if ( --p->pRefs[iFan0] == 0 )
|
||||
p->nCrossCut--;
|
||||
iFan0 = Fsim_Var2Lit( iFan0, Aig_ObjFaninC0(pObj) );
|
||||
iFan1 = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
iFan0 = iFan1 = 0;
|
||||
Vec_IntPush( p->vCis2Ids, Aig_ObjPioNum(pObj) );
|
||||
}
|
||||
if ( iFan0 < iFan1 )
|
||||
iTemp = iFan0, iFan0 = iFan1, iFan1 = iTemp;
|
||||
p->pFans0[p->nObjs] = iFan0;
|
||||
p->pFans1[p->nObjs] = iFan1;
|
||||
p->pRefs[p->nObjs] = Aig_ObjRefs(pObj);
|
||||
if ( p->pRefs[p->nObjs] )
|
||||
if ( p->nCrossCutMax < ++p->nCrossCut )
|
||||
p->nCrossCutMax = p->nCrossCut;
|
||||
return pObj->iData = p->nObjs++;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates fast simulation manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Fsim_Man_t * Fsim_ManCreate( Aig_Man_t * pAig )
|
||||
{
|
||||
Fsim_Man_t * p;
|
||||
Aig_Obj_t * pObj;
|
||||
int i, nObjs;
|
||||
Aig_ManCleanData( pAig );
|
||||
p = (Fsim_Man_t *)ALLOC( Fsim_Man_t, 1 );
|
||||
memset( p, 0, sizeof(Fsim_Man_t) );
|
||||
p->pAig = pAig;
|
||||
p->nPis = Saig_ManPiNum(pAig);
|
||||
p->nPos = Saig_ManPoNum(pAig);
|
||||
p->nCis = Aig_ManPiNum(pAig);
|
||||
p->nCos = Aig_ManPoNum(pAig);
|
||||
p->nNodes = Aig_ManNodeNum(pAig);
|
||||
nObjs = p->nCis + p->nCos + p->nNodes + 2;
|
||||
p->pFans0 = ALLOC( int, nObjs );
|
||||
p->pFans1 = ALLOC( int, nObjs );
|
||||
p->pRefs = ALLOC( int, nObjs );
|
||||
p->vCis2Ids = Vec_IntAlloc( Aig_ManPiNum(pAig) );
|
||||
// add objects (0=unused; 1=const1)
|
||||
p->pFans0[0] = p->pFans1[0] = 0;
|
||||
p->pFans0[1] = p->pFans1[1] = 0;
|
||||
p->pRefs[0] = 0;
|
||||
p->nObjs = 2;
|
||||
pObj = Aig_ManConst1( pAig );
|
||||
pObj->iData = 1;
|
||||
p->pRefs[1] = Aig_ObjRefs(pObj);
|
||||
if ( p->pRefs[1] )
|
||||
p->nCrossCut = 1;
|
||||
Aig_ManForEachPi( pAig, pObj, i )
|
||||
if ( Aig_ObjRefs(pObj) == 0 )
|
||||
Fsim_ManCreate_rec( p, pObj );
|
||||
Aig_ManForEachPo( pAig, pObj, i )
|
||||
Fsim_ManCreate_rec( p, pObj );
|
||||
assert( Vec_IntSize(p->vCis2Ids) == Aig_ManPiNum(pAig) );
|
||||
assert( p->nObjs == nObjs );
|
||||
// check references
|
||||
assert( p->nCrossCut == 0 );
|
||||
Aig_ManForEachObj( pAig, pObj, i )
|
||||
{
|
||||
assert( p->pRefs[pObj->iData] == 0 );
|
||||
p->pRefs[pObj->iData] = Aig_ObjRefs(pObj);
|
||||
}
|
||||
// collect flop outputs
|
||||
p->vLos = Vec_IntAlloc( Aig_ManRegNum(pAig) );
|
||||
Saig_ManForEachLo( pAig, pObj, i )
|
||||
Vec_IntPush( p->vLos, pObj->iData );
|
||||
// collect flop inputs
|
||||
p->vLis = Vec_IntAlloc( Aig_ManRegNum(pAig) );
|
||||
Saig_ManForEachLi( pAig, pObj, i )
|
||||
Vec_IntPush( p->vLis, pObj->iData );
|
||||
// determine the frontier size
|
||||
p->nFront = 1 + (int)(1.1 * p->nCrossCutMax);
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Deletes fast simulation manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fsim_ManDelete( Fsim_Man_t * p )
|
||||
{
|
||||
Vec_IntFree( p->vCis2Ids );
|
||||
Vec_IntFree( p->vLos );
|
||||
Vec_IntFree( p->vLis );
|
||||
FREE( p->pDataAig2 );
|
||||
FREE( p->pDataAig );
|
||||
FREE( p->pFans0 );
|
||||
FREE( p->pFans1 );
|
||||
FREE( p->pRefs );
|
||||
FREE( p->pDataSim );
|
||||
FREE( p->pDataSimCis );
|
||||
FREE( p->pDataSimCos );
|
||||
FREE( p->pData1 );
|
||||
FREE( p->pData2 );
|
||||
FREE( p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Testing procedure.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fsim_ManTest( Aig_Man_t * pAig )
|
||||
{
|
||||
Fsim_Man_t * p;
|
||||
p = Fsim_ManCreate( pAig );
|
||||
Fsim_ManFront( p, 0 );
|
||||
Fsim_ManDelete( p );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,560 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [fsimSim.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Fast sequential AIG simulator.]
|
||||
|
||||
Synopsis [Simulation procedures.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: fsimSim.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "fsimInt.h"
|
||||
#include "ssw.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Fsim_ManSimInfoRandom( Fsim_Man_t * p, unsigned * pInfo )
|
||||
{
|
||||
int w;
|
||||
for ( w = p->nWords-1; w >= 0; w-- )
|
||||
pInfo[w] = Aig_ManRandom( 0 );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Fsim_ManSimInfoZero( Fsim_Man_t * p, unsigned * pInfo )
|
||||
{
|
||||
int w;
|
||||
for ( w = p->nWords-1; w >= 0; w-- )
|
||||
pInfo[w] = 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns index of the first pattern that failed.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Fsim_ManSimInfoIsZero( Fsim_Man_t * p, unsigned * pInfo )
|
||||
{
|
||||
int w;
|
||||
for ( w = p->nWords-1; w >= 0; w-- )
|
||||
if ( pInfo[w] )
|
||||
return 32*(w-1) + Aig_WordFindFirstBit( pInfo[w] );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Fsim_ManSimInfoOne( Fsim_Man_t * p, unsigned * pInfo )
|
||||
{
|
||||
int w;
|
||||
for ( w = p->nWords-1; w >= 0; w-- )
|
||||
pInfo[w] = ~0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Fsim_ManSimInfoCopy( Fsim_Man_t * p, unsigned * pInfo, unsigned * pInfo0 )
|
||||
{
|
||||
int w;
|
||||
for ( w = p->nWords-1; w >= 0; w-- )
|
||||
pInfo[w] = pInfo0[w];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Fsim_ManSimulateCi( Fsim_Man_t * p, int iNode, int iCi )
|
||||
{
|
||||
unsigned * pInfo = Fsim_SimData( p, iNode % p->nFront );
|
||||
unsigned * pInfo0 = Fsim_SimDataCi( p, iCi );
|
||||
int w;
|
||||
for ( w = p->nWords-1; w >= 0; w-- )
|
||||
pInfo[w] = pInfo0[w];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Fsim_ManSimulateCo( Fsim_Man_t * p, int iCo, int iFan0 )
|
||||
{
|
||||
unsigned * pInfo = Fsim_SimDataCo( p, iCo );
|
||||
unsigned * pInfo0 = Fsim_SimData( p, Fsim_Lit2Var(iFan0) % p->nFront );
|
||||
int w;
|
||||
if ( Fsim_LitIsCompl(iFan0) )
|
||||
for ( w = p->nWords-1; w >= 0; w-- )
|
||||
pInfo[w] = ~pInfo0[w];
|
||||
else //if ( !Fsim_LitIsCompl(iFan0) )
|
||||
for ( w = p->nWords-1; w >= 0; w-- )
|
||||
pInfo[w] = pInfo0[w];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Fsim_ManSimulateNode( Fsim_Man_t * p, int iNode, int iFan0, int iFan1 )
|
||||
{
|
||||
unsigned * pInfo = Fsim_SimData( p, iNode % p->nFront );
|
||||
unsigned * pInfo0 = Fsim_SimData( p, Fsim_Lit2Var(iFan0) % p->nFront );
|
||||
unsigned * pInfo1 = Fsim_SimData( p, Fsim_Lit2Var(iFan1) % p->nFront );
|
||||
int w;
|
||||
if ( Fsim_LitIsCompl(iFan0) && Fsim_LitIsCompl(iFan1) )
|
||||
for ( w = p->nWords-1; w >= 0; w-- )
|
||||
pInfo[w] = ~(pInfo0[w] | pInfo1[w]);
|
||||
else if ( Fsim_LitIsCompl(iFan0) && !Fsim_LitIsCompl(iFan1) )
|
||||
for ( w = p->nWords-1; w >= 0; w-- )
|
||||
pInfo[w] = ~pInfo0[w] & pInfo1[w];
|
||||
else if ( !Fsim_LitIsCompl(iFan0) && Fsim_LitIsCompl(iFan1) )
|
||||
for ( w = p->nWords-1; w >= 0; w-- )
|
||||
pInfo[w] = pInfo0[w] & ~pInfo1[w];
|
||||
else //if ( !Fsim_LitIsCompl(iFan0) && !Fsim_LitIsCompl(iFan1) )
|
||||
for ( w = p->nWords-1; w >= 0; w-- )
|
||||
pInfo[w] = pInfo0[w] & pInfo1[w];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Fsim_ManSimInfoInit( Fsim_Man_t * p )
|
||||
{
|
||||
int iPioNum, i;
|
||||
Vec_IntForEachEntry( p->vCis2Ids, iPioNum, i )
|
||||
{
|
||||
if ( iPioNum < p->nPis )
|
||||
Fsim_ManSimInfoRandom( p, Fsim_SimDataCi(p, i) );
|
||||
else
|
||||
Fsim_ManSimInfoZero( p, Fsim_SimDataCi(p, i) );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Fsim_ManSimInfoTransfer( Fsim_Man_t * p )
|
||||
{
|
||||
int iPioNum, i;
|
||||
Vec_IntForEachEntry( p->vCis2Ids, iPioNum, i )
|
||||
{
|
||||
if ( iPioNum < p->nPis )
|
||||
Fsim_ManSimInfoRandom( p, Fsim_SimDataCi(p, i) );
|
||||
else
|
||||
Fsim_ManSimInfoCopy( p, Fsim_SimDataCi(p, i), Fsim_SimDataCo(p, p->nPos+iPioNum-p->nPis) );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Fsim_ManRestoreNum( Fsim_Man_t * p )
|
||||
{
|
||||
int ch, i, x = 0;
|
||||
for ( i = 0; (ch = *p->pDataCur++) & 0x80; i++ )
|
||||
x |= (ch & 0x7f) << (7 * i);
|
||||
assert( p->pDataCur - p->pDataAig < p->nDataAig );
|
||||
return x | (ch << (7 * i));
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Fsim_ManRestoreObj( Fsim_Man_t * p, Fsim_Obj_t * pObj )
|
||||
{
|
||||
int iValue = Fsim_ManRestoreNum( p );
|
||||
if ( (iValue & 3) == 3 ) // and
|
||||
{
|
||||
pObj->iNode = (iValue >> 2) + p->iNodePrev;
|
||||
pObj->iFan0 = (pObj->iNode << 1) - Fsim_ManRestoreNum( p );
|
||||
pObj->iFan1 = pObj->iFan0 - Fsim_ManRestoreNum( p );
|
||||
p->iNodePrev = pObj->iNode;
|
||||
}
|
||||
else if ( (iValue & 3) == 1 ) // ci
|
||||
{
|
||||
pObj->iNode = (iValue >> 2) + p->iNodePrev;
|
||||
pObj->iFan0 = 0;
|
||||
pObj->iFan1 = 0;
|
||||
p->iNodePrev = pObj->iNode;
|
||||
}
|
||||
else // if ( (iValue & 1) == 0 ) // co
|
||||
{
|
||||
pObj->iNode = 0;
|
||||
pObj->iFan0 = ((p->iNodePrev << 1) | 1) - (iValue >> 1);
|
||||
pObj->iFan1 = 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Fsim_ManSimulateRound2( Fsim_Man_t * p )
|
||||
{
|
||||
Fsim_Obj_t * pObj;
|
||||
int i, iCis = 0, iCos = 0;
|
||||
if ( Aig_ObjRefs(Aig_ManConst1(p->pAig)) )
|
||||
Fsim_ManSimInfoOne( p, Fsim_SimData(p, 1) );
|
||||
Fsim_ManForEachObj( p, pObj, i )
|
||||
{
|
||||
if ( pObj->iFan0 == 0 )
|
||||
Fsim_ManSimulateCi( p, pObj->iNode, iCis++ );
|
||||
else if ( pObj->iFan1 == 0 )
|
||||
Fsim_ManSimulateCo( p, iCos++, pObj->iFan0 );
|
||||
else
|
||||
Fsim_ManSimulateNode( p, pObj->iNode, pObj->iFan0, pObj->iFan1 );
|
||||
}
|
||||
assert( iCis == p->nCis );
|
||||
assert( iCos == p->nCos );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Fsim_ManSimulateRound( Fsim_Man_t * p )
|
||||
{
|
||||
int * pCur, * pEnd;
|
||||
int iCis = 0, iCos = 0;
|
||||
if ( p->pDataAig2 == NULL )
|
||||
{
|
||||
Fsim_ManSimulateRound2( p );
|
||||
return;
|
||||
}
|
||||
if ( Aig_ObjRefs(Aig_ManConst1(p->pAig)) )
|
||||
Fsim_ManSimInfoOne( p, Fsim_SimData(p, 1) );
|
||||
pCur = p->pDataAig2 + 6;
|
||||
pEnd = p->pDataAig2 + 3 * p->nObjs;
|
||||
while ( pCur < pEnd )
|
||||
{
|
||||
if ( pCur[1] == 0 )
|
||||
Fsim_ManSimulateCi( p, pCur[0], iCis++ );
|
||||
else if ( pCur[2] == 0 )
|
||||
Fsim_ManSimulateCo( p, iCos++, pCur[1] );
|
||||
else
|
||||
Fsim_ManSimulateNode( p, pCur[0], pCur[1], pCur[2] );
|
||||
pCur += 3;
|
||||
}
|
||||
assert( iCis == p->nCis );
|
||||
assert( iCos == p->nCos );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fsim_ManSimulateRoundTest( Fsim_Man_t * p )
|
||||
{
|
||||
Fsim_Obj_t * pObj;
|
||||
int i, clk = clock();
|
||||
Fsim_ManForEachObj( p, pObj, i )
|
||||
{
|
||||
}
|
||||
// PRT( "Unpacking time", p->pPars->nIters * (clock() - clk) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns index of the PO and pattern that failed it.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Fsim_ManCheckPos( Fsim_Man_t * p, int * piPo, int * piPat )
|
||||
{
|
||||
int i, iPat;
|
||||
for ( i = 0; i < p->nPos; i++ )
|
||||
{
|
||||
iPat = Fsim_ManSimInfoIsZero( p, Fsim_SimDataCo(p, i) );
|
||||
if ( iPat >= 0 )
|
||||
{
|
||||
*piPo = i;
|
||||
*piPat = iPat;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the counter-example.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ssw_Cex_t * Fsim_ManGenerateCounter( Aig_Man_t * pAig, int iFrame, int iOut, int nWords, int iPat, Vec_Int_t * vCis2Ids )
|
||||
{
|
||||
Ssw_Cex_t * p;
|
||||
unsigned * pData;
|
||||
int f, i, w, iPioId, Counter;
|
||||
p = Ssw_SmlAllocCounterExample( Aig_ManRegNum(pAig), Saig_ManPiNum(pAig), iFrame+1 );
|
||||
p->iFrame = iFrame;
|
||||
p->iPo = iOut;
|
||||
// fill in the binary data
|
||||
Aig_ManRandom( 1 );
|
||||
Counter = p->nRegs;
|
||||
pData = ALLOC( unsigned, nWords );
|
||||
for ( f = 0; f <= iFrame; f++, Counter += p->nPis )
|
||||
for ( i = 0; i < Aig_ManPiNum(pAig); i++ )
|
||||
{
|
||||
iPioId = Vec_IntEntry( vCis2Ids, i );
|
||||
if ( iPioId >= p->nPis )
|
||||
continue;
|
||||
for ( w = nWords-1; w >= 0; w-- )
|
||||
pData[w] = Aig_ManRandom( 0 );
|
||||
if ( Aig_InfoHasBit( pData, iPat ) )
|
||||
Aig_InfoSetBit( p->pData, Counter + iPioId );
|
||||
}
|
||||
free( pData );
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Fsim_ManSimulate( Aig_Man_t * pAig, Fsim_ParSim_t * pPars )
|
||||
{
|
||||
Fsim_Man_t * p;
|
||||
Sec_MtrStatus_t Status;
|
||||
int i, iOut, iPat, clk, clkTotal = clock(), clk2, clk2Total = 0;
|
||||
assert( Aig_ManRegNum(pAig) > 0 );
|
||||
Status = Sec_MiterStatus( pAig );
|
||||
if ( Status.nSat > 0 )
|
||||
{
|
||||
printf( "Miter is trivially satisfiable (output %d).\n", Status.iOut );
|
||||
return 1;
|
||||
}
|
||||
if ( Status.nUndec == 0 )
|
||||
{
|
||||
printf( "Miter is trivially unsatisfiable.\n" );
|
||||
return 0;
|
||||
}
|
||||
// create manager
|
||||
clk = clock();
|
||||
p = Fsim_ManCreate( pAig );
|
||||
p->nWords = pPars->nWords;
|
||||
if ( pPars->fVerbose )
|
||||
{
|
||||
printf( "Obj = %8d (%8d). Cut = %6d. Front = %6d. FrtMem = %7.2f Mb. ",
|
||||
p->nObjs, p->nCis + p->nNodes, p->nCrossCutMax, p->nFront,
|
||||
4.0*p->nWords*(p->nFront)/(1<<20) );
|
||||
PRT( "Time", clock() - clk );
|
||||
}
|
||||
// create simulation frontier
|
||||
clk = clock();
|
||||
Fsim_ManFront( p, pPars->fCompressAig );
|
||||
if ( pPars->fVerbose )
|
||||
{
|
||||
printf( "Max ID = %8d. Log max ID = %2d. AigMem = %7.2f Mb (%5.2f byte/obj). ",
|
||||
p->iNumber, Aig_Base2Log(p->iNumber),
|
||||
1.0*(p->pDataCur-p->pDataAig)/(1<<20),
|
||||
1.0*(p->pDataCur-p->pDataAig)/p->nObjs );
|
||||
PRT( "Time", clock() - clk );
|
||||
}
|
||||
// perform simulation
|
||||
Aig_ManRandom( 1 );
|
||||
assert( p->pDataSim == NULL );
|
||||
p->pDataSim = ALLOC( unsigned, p->nWords * p->nFront * sizeof(unsigned) );
|
||||
p->pDataSimCis = ALLOC( unsigned, p->nWords * p->nCis * sizeof(unsigned) );
|
||||
p->pDataSimCos = ALLOC( unsigned, p->nWords * p->nCos * sizeof(unsigned) );
|
||||
Fsim_ManSimInfoInit( p );
|
||||
for ( i = 0; i < pPars->nIters; i++ )
|
||||
{
|
||||
Fsim_ManSimulateRound( p );
|
||||
if ( pPars->fVerbose )
|
||||
{
|
||||
printf( "Frame %4d out of %4d and timeout %3d sec. ", i+1, pPars->nIters, pPars->TimeLimit );
|
||||
printf( "Time = %7.2f sec\r", (1.0*clock()-clkTotal)/CLOCKS_PER_SEC );
|
||||
}
|
||||
if ( pPars->fCheckMiter && Fsim_ManCheckPos( p, &iOut, &iPat ) )
|
||||
{
|
||||
assert( pAig->pSeqModel == NULL );
|
||||
pAig->pSeqModel = Fsim_ManGenerateCounter( pAig, i, iOut, p->nWords, iPat, p->vCis2Ids );
|
||||
if ( pPars->fVerbose )
|
||||
printf( "Miter is satisfiable after simulation (output %d).\n", iOut );
|
||||
break;
|
||||
}
|
||||
if ( (clock() - clkTotal)/CLOCKS_PER_SEC >= pPars->TimeLimit )
|
||||
{
|
||||
printf( "No bug detected after %d frames with time limit %d seconds.\n", i+1, pPars->TimeLimit );
|
||||
break;
|
||||
}
|
||||
clk2 = clock();
|
||||
if ( i < pPars->nIters - 1 )
|
||||
Fsim_ManSimInfoTransfer( p );
|
||||
clk2Total += clock() - clk2;
|
||||
}
|
||||
if ( pPars->fVerbose )
|
||||
{
|
||||
printf( "Maxcut = %8d. AigMem = %7.2f Mb. SimMem = %7.2f Mb. ",
|
||||
p->nCrossCutMax,
|
||||
p->pDataAig2? 12.0*p->nObjs/(1<<20) : 1.0*(p->pDataCur-p->pDataAig)/(1<<20),
|
||||
4.0*p->nWords*(p->nFront+p->nCis+p->nCos)/(1<<20) );
|
||||
PRT( "Sim time", clock() - clkTotal );
|
||||
|
||||
// PRT( "Additional time", clk2Total );
|
||||
// Fsim_ManSimulateRoundTest( p );
|
||||
// Fsim_ManSimulateRoundTest2( p );
|
||||
}
|
||||
Fsim_ManDelete( p );
|
||||
return pAig->pSeqModel != NULL;
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,588 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [fsimSwitch.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Fast sequential AIG simulator.]
|
||||
|
||||
Synopsis [Computing switching activity.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: fsimSwitch.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "fsimInt.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Fsim_ManSwitchSimInfoRandom( Fsim_Man_t * p, unsigned * pInfo, int nProbNum )
|
||||
{
|
||||
unsigned Mask;
|
||||
int w, i;
|
||||
if ( nProbNum )
|
||||
{
|
||||
Mask = Aig_ManRandom( 0 );
|
||||
for ( i = 0; i < nProbNum; i++ )
|
||||
Mask &= Aig_ManRandom( 0 );
|
||||
for ( w = p->nWords-1; w >= 0; w-- )
|
||||
pInfo[w] ^= Mask;
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( w = p->nWords-1; w >= 0; w-- )
|
||||
pInfo[w] = Aig_ManRandom( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Fsim_ManSwitchSimInfoRandomShift( Fsim_Man_t * p, unsigned * pInfo, int nProbNum )
|
||||
{
|
||||
unsigned Mask;
|
||||
int w, i;
|
||||
Mask = Aig_ManRandom( 0 );
|
||||
for ( i = 0; i < nProbNum; i++ )
|
||||
Mask &= Aig_ManRandom( 0 );
|
||||
if ( p->nWords == 1 )
|
||||
pInfo[0] = (pInfo[0] << 16) | ((pInfo[0] ^ Mask) & 0xffff);
|
||||
else
|
||||
{
|
||||
assert( (p->nWords & 1) == 0 ); // should be even number
|
||||
for ( w = p->nWords-1; w >= 0; w-- )
|
||||
if ( w >= p->nWords/2 )
|
||||
pInfo[w] = pInfo[w - p->nWords/2];
|
||||
else
|
||||
pInfo[w] ^= Mask;
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Fsim_ManSwitchSimInfoZero( Fsim_Man_t * p, unsigned * pInfo )
|
||||
{
|
||||
int w;
|
||||
for ( w = p->nWords-1; w >= 0; w-- )
|
||||
pInfo[w] = 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Fsim_ManSwitchSimInfoOne( Fsim_Man_t * p, unsigned * pInfo )
|
||||
{
|
||||
int w;
|
||||
for ( w = p->nWords-1; w >= 0; w-- )
|
||||
pInfo[w] = ~0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Fsim_ManSwitchSimInfoCopy( Fsim_Man_t * p, unsigned * pInfo, unsigned * pInfo0 )
|
||||
{
|
||||
int w;
|
||||
for ( w = p->nWords-1; w >= 0; w-- )
|
||||
pInfo[w] = pInfo0[w];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Fsim_ManSwitchSimInfoCopyShift( Fsim_Man_t * p, unsigned * pInfo, unsigned * pInfo0 )
|
||||
{
|
||||
int w;
|
||||
if ( p->nWords == 1 )
|
||||
pInfo[0] = (pInfo[0] << 16) | (pInfo0[0] & 0xffff);
|
||||
else
|
||||
{
|
||||
assert( (p->nWords & 1) == 0 ); // should be even number
|
||||
for ( w = p->nWords-1; w >= 0; w-- )
|
||||
{
|
||||
if ( w >= p->nWords/2 )
|
||||
pInfo[w] = pInfo[w - p->nWords/2];
|
||||
else
|
||||
pInfo[w] = pInfo0[w];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Fsim_ManSwitchSimulateCi( Fsim_Man_t * p, int iNode, int iCi )
|
||||
{
|
||||
unsigned * pInfo = Fsim_SimData( p, iNode % p->nFront );
|
||||
unsigned * pInfo0 = Fsim_SimDataCi( p, iCi );
|
||||
int w;
|
||||
for ( w = p->nWords-1; w >= 0; w-- )
|
||||
pInfo[w] = pInfo0[w];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Fsim_ManSwitchSimulateCo( Fsim_Man_t * p, int iCo, int iFan0 )
|
||||
{
|
||||
unsigned * pInfo = Fsim_SimDataCo( p, iCo );
|
||||
unsigned * pInfo0 = Fsim_SimData( p, Fsim_Lit2Var(iFan0) % p->nFront );
|
||||
int w;
|
||||
if ( Fsim_LitIsCompl(iFan0) )
|
||||
for ( w = p->nWords-1; w >= 0; w-- )
|
||||
pInfo[w] = ~pInfo0[w];
|
||||
else //if ( !Fsim_LitIsCompl(iFan0) )
|
||||
for ( w = p->nWords-1; w >= 0; w-- )
|
||||
pInfo[w] = pInfo0[w];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Fsim_ManSwitchSimulateNode( Fsim_Man_t * p, int iNode, int iFan0, int iFan1 )
|
||||
{
|
||||
unsigned * pInfo = Fsim_SimData( p, iNode % p->nFront );
|
||||
unsigned * pInfo0 = Fsim_SimData( p, Fsim_Lit2Var(iFan0) % p->nFront );
|
||||
unsigned * pInfo1 = Fsim_SimData( p, Fsim_Lit2Var(iFan1) % p->nFront );
|
||||
int w;
|
||||
if ( Fsim_LitIsCompl(iFan0) && Fsim_LitIsCompl(iFan1) )
|
||||
for ( w = p->nWords-1; w >= 0; w-- )
|
||||
pInfo[w] = ~(pInfo0[w] | pInfo1[w]);
|
||||
else if ( Fsim_LitIsCompl(iFan0) && !Fsim_LitIsCompl(iFan1) )
|
||||
for ( w = p->nWords-1; w >= 0; w-- )
|
||||
pInfo[w] = ~pInfo0[w] & pInfo1[w];
|
||||
else if ( !Fsim_LitIsCompl(iFan0) && Fsim_LitIsCompl(iFan1) )
|
||||
for ( w = p->nWords-1; w >= 0; w-- )
|
||||
pInfo[w] = pInfo0[w] & ~pInfo1[w];
|
||||
else //if ( !Fsim_LitIsCompl(iFan0) && !Fsim_LitIsCompl(iFan1) )
|
||||
for ( w = p->nWords-1; w >= 0; w-- )
|
||||
pInfo[w] = pInfo0[w] & pInfo1[w];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Fsim_ManSwitchSimInfoInit( Fsim_Man_t * p )
|
||||
{
|
||||
int iPioNum, i;
|
||||
Vec_IntForEachEntry( p->vCis2Ids, iPioNum, i )
|
||||
{
|
||||
if ( iPioNum < p->nPis )
|
||||
Fsim_ManSwitchSimInfoRandom( p, Fsim_SimDataCi(p, i), 0 );
|
||||
else
|
||||
Fsim_ManSwitchSimInfoZero( p, Fsim_SimDataCi(p, i) );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Fsim_ManSwitchSimInfoTransfer( Fsim_Man_t * p, int nProbNum )
|
||||
{
|
||||
int iPioNum, i;
|
||||
Vec_IntForEachEntry( p->vCis2Ids, iPioNum, i )
|
||||
{
|
||||
if ( iPioNum < p->nPis )
|
||||
Fsim_ManSwitchSimInfoRandom( p, Fsim_SimDataCi(p, i), nProbNum );
|
||||
else
|
||||
Fsim_ManSwitchSimInfoCopy( p, Fsim_SimDataCi(p, i), Fsim_SimDataCo(p, p->nPos+iPioNum-p->nPis) );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Fsim_ManSwitchSimInfoTransferShift( Fsim_Man_t * p, int nProbNum )
|
||||
{
|
||||
int iPioNum, i;
|
||||
Vec_IntForEachEntry( p->vCis2Ids, iPioNum, i )
|
||||
{
|
||||
if ( iPioNum < p->nPis )
|
||||
Fsim_ManSwitchSimInfoRandomShift( p, Fsim_SimDataCi(p, i), nProbNum );
|
||||
else
|
||||
Fsim_ManSwitchSimInfoCopyShift( p, Fsim_SimDataCi(p, i), Fsim_SimDataCo(p, p->nPos+iPioNum-p->nPis) );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Fsim_ManSwitchSimInfoCountOnes( Fsim_Man_t * p, int iNode )
|
||||
{
|
||||
unsigned * pInfo;
|
||||
int w, Counter = 0;
|
||||
pInfo = Fsim_SimData( p, iNode % p->nFront );
|
||||
for ( w = p->nWords-1; w >= 0; w-- )
|
||||
Counter += Aig_WordCountOnes( pInfo[w] );
|
||||
return Counter;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Fsim_ManSwitchSimInfoCountTrans( Fsim_Man_t * p, int iNode )
|
||||
{
|
||||
unsigned * pInfo;
|
||||
int w, Counter = 0;
|
||||
assert( iNode % p->nFront );
|
||||
pInfo = Fsim_SimData( p, iNode % p->nFront );
|
||||
if ( p->nWords == 1 )
|
||||
return Aig_WordCountOnes( (pInfo[0] ^ (pInfo[0] >> 16)) & 0xffff );
|
||||
for ( w = p->nWords/2-1; w >= 0; w-- )
|
||||
Counter += Aig_WordCountOnes( pInfo[w] ^ pInfo[w + p->nWords/2] );
|
||||
return Counter;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Fsim_ManSwitchSimulateRound( Fsim_Man_t * p, int fCount )
|
||||
{
|
||||
int * pCur, * pEnd;
|
||||
int i, iCis = 0, iCos = 0;
|
||||
if ( Aig_ObjRefs(Aig_ManConst1(p->pAig)) )
|
||||
Fsim_ManSwitchSimInfoOne( p, Fsim_SimData(p, 1) );
|
||||
pCur = p->pDataAig2 + 6;
|
||||
pEnd = p->pDataAig2 + 3 * p->nObjs;
|
||||
for ( i = 2; pCur < pEnd; i++ )
|
||||
{
|
||||
if ( pCur[1] == 0 )
|
||||
Fsim_ManSwitchSimulateCi( p, pCur[0], iCis++ );
|
||||
else if ( pCur[2] == 0 )
|
||||
Fsim_ManSwitchSimulateCo( p, iCos++, pCur[1] );
|
||||
else
|
||||
Fsim_ManSwitchSimulateNode( p, pCur[0], pCur[1], pCur[2] );
|
||||
if ( fCount && pCur[0] )
|
||||
{
|
||||
if ( p->pData1 )
|
||||
p->pData1[i] += Fsim_ManSwitchSimInfoCountOnes( p, pCur[0] );
|
||||
if ( p->pData2 )
|
||||
p->pData2[i] += Fsim_ManSwitchSimInfoCountTrans( p, pCur[0] );
|
||||
}
|
||||
pCur += 3;
|
||||
}
|
||||
assert( iCis == p->nCis );
|
||||
assert( iCos == p->nCos );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes switching activity of one node.]
|
||||
|
||||
Description [Uses the formula: Switching = 2 * nOnes * nZeros / (nTotal ^ 2) ]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
float Fsim_ManSwitchComputeSwitching( int nOnes, int nSimWords )
|
||||
{
|
||||
int nTotal = 32 * nSimWords;
|
||||
return (float)2.0 * nOnes / nTotal * (nTotal - nOnes) / nTotal;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes switching activity of one node.]
|
||||
|
||||
Description [Uses the formula: Switching = 2 * nOnes * nZeros / (nTotal ^ 2) ]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
float Fsim_ManSwitchComputeProbOne( int nOnes, int nSimWords )
|
||||
{
|
||||
int nTotal = 32 * nSimWords;
|
||||
return (float)nOnes / nTotal;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Fsim_ManSwitchSimulate( Aig_Man_t * pAig, Fsim_ParSwitch_t * pPars )
|
||||
{
|
||||
Vec_Int_t * vSwitching;
|
||||
float * pSwitching;
|
||||
Aig_Obj_t * pObj;
|
||||
Fsim_Man_t * p;
|
||||
int i, clk, clkTotal = clock();
|
||||
// create manager
|
||||
clk = clock();
|
||||
p = Fsim_ManCreate( pAig );
|
||||
p->nWords = pPars->nWords;
|
||||
// if the number of words is larger then 1, it should be even
|
||||
if ( p->nWords > 1 && (p->nWords & 1) )
|
||||
p->nWords++;
|
||||
// print stats
|
||||
if ( pPars->fVerbose )
|
||||
{
|
||||
printf( "Obj = %8d (%8d). Cut = %6d. Front = %6d. FrtMem = %7.2f Mb. ",
|
||||
p->nObjs, p->nCis + p->nNodes, p->nCrossCutMax, p->nFront,
|
||||
4.0*pPars->nWords*(p->nFront)/(1<<20) );
|
||||
PRT( "Time", clock() - clk );
|
||||
}
|
||||
// create simulation frontier
|
||||
clk = clock();
|
||||
Fsim_ManFront( p, 0 );
|
||||
if ( pPars->fVerbose )
|
||||
{
|
||||
printf( "Max ID = %8d. Log max ID = %2d. AigMem = %7.2f Mb (%5.2f byte/obj). ",
|
||||
p->iNumber, Aig_Base2Log(p->iNumber),
|
||||
1.0*(p->pDataCur-p->pDataAig)/(1<<20),
|
||||
1.0*(p->pDataCur-p->pDataAig)/p->nObjs );
|
||||
PRT( "Time", clock() - clk );
|
||||
}
|
||||
// perform simulation
|
||||
Aig_ManRandom( 1 );
|
||||
assert( p->pDataSim == NULL );
|
||||
p->pDataSim = ALLOC( unsigned, pPars->nWords * p->nFront * sizeof(unsigned) );
|
||||
p->pDataSimCis = ALLOC( unsigned, pPars->nWords * p->nCis * sizeof(unsigned) );
|
||||
p->pDataSimCos = ALLOC( unsigned, pPars->nWords * p->nCos * sizeof(unsigned) );
|
||||
if ( pPars->fProbOne )
|
||||
p->pData1 = CALLOC( int, p->nObjs * sizeof(int) );
|
||||
if ( pPars->fProbTrans )
|
||||
p->pData2 = CALLOC( int, p->nObjs * sizeof(int) );
|
||||
Fsim_ManSwitchSimInfoInit( p );
|
||||
for ( i = 0; i < pPars->nIters; i++ )
|
||||
{
|
||||
Fsim_ManSwitchSimulateRound( p, i >= pPars->nPref );
|
||||
if ( i < pPars->nIters - 1 )
|
||||
{
|
||||
// if ( pPars->fProbTrans )
|
||||
Fsim_ManSwitchSimInfoTransferShift( p, pPars->nRandPiNum );
|
||||
// else
|
||||
// Fsim_ManSwitchSimInfoTransfer( p, pPars->nRandPiNum );
|
||||
}
|
||||
}
|
||||
if ( pPars->fVerbose )
|
||||
{
|
||||
printf( "Maxcut = %8d. AigMem = %7.2f Mb. SimMem = %7.2f Mb. ",
|
||||
p->nCrossCutMax,
|
||||
p->pDataAig2? 12.0*p->nObjs/(1<<20) : 1.0*(p->pDataCur-p->pDataAig)/(1<<20),
|
||||
4.0*pPars->nWords*(p->nFront+p->nCis+p->nCos)/(1<<20) );
|
||||
PRT( "Sim time", clock() - clkTotal );
|
||||
}
|
||||
// derive the result
|
||||
vSwitching = Vec_IntStart( Aig_ManObjNumMax(pAig) );
|
||||
pSwitching = (float *)vSwitching->pArray;
|
||||
/*
|
||||
if ( pPars->fProbOne && pPars->fProbTrans )
|
||||
{
|
||||
Aig_ManForEachObj( pAig, pObj, i )
|
||||
// pSwitching[pObj->Id] = Fsim_ManSwitchComputeSwitching( p->pData1[pObj->iData], pPars->nWords*(pPars->nIters-pPars->nPref) );
|
||||
pSwitching[pObj->Id] = Fsim_ManSwitchComputeProbOne( p->pData2[pObj->iData], pPars->nWords*(pPars->nIters-pPars->nPref)/2 );
|
||||
}
|
||||
else if ( !pPars->fProbOne && pPars->fProbTrans )
|
||||
{
|
||||
Aig_ManForEachObj( pAig, pObj, i )
|
||||
pSwitching[pObj->Id] = Fsim_ManSwitchComputeProbOne( p->pData2[pObj->iData], pPars->nWords*(pPars->nIters-pPars->nPref)/2 );
|
||||
}
|
||||
else if ( pPars->fProbOne && !pPars->fProbTrans )
|
||||
{
|
||||
Aig_ManForEachObj( pAig, pObj, i )
|
||||
pSwitching[pObj->Id] = Fsim_ManSwitchComputeProbOne( p->pData1[pObj->iData], pPars->nWords*(pPars->nIters-pPars->nPref) );
|
||||
}
|
||||
else
|
||||
assert( 0 );
|
||||
*/
|
||||
if ( pPars->fProbOne && !pPars->fProbTrans )
|
||||
{
|
||||
Aig_ManForEachObj( pAig, pObj, i )
|
||||
pSwitching[pObj->Id] = Fsim_ManSwitchComputeProbOne( p->pData1[pObj->iData], pPars->nWords*(pPars->nIters-pPars->nPref) );
|
||||
}
|
||||
else if ( !pPars->fProbOne && pPars->fProbTrans )
|
||||
{
|
||||
Aig_ManForEachObj( pAig, pObj, i )
|
||||
pSwitching[pObj->Id] = Fsim_ManSwitchComputeProbOne( p->pData2[pObj->iData], pPars->nWords*(pPars->nIters-pPars->nPref)/2 );
|
||||
}
|
||||
else
|
||||
assert( 0 );
|
||||
Fsim_ManDelete( p );
|
||||
return vSwitching;
|
||||
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes probability of switching (or of being 1).]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Saig_ManComputeSwitchProbs4( Aig_Man_t * p, int nFrames, int nPref, int fProbOne )
|
||||
{
|
||||
Fsim_ParSwitch_t Pars, * pPars = &Pars;
|
||||
Fsim_ManSetDefaultParamsSwitch( pPars );
|
||||
pPars->nWords = 1;
|
||||
pPars->nIters = nFrames;
|
||||
pPars->nPref = nPref;
|
||||
if ( fProbOne )
|
||||
{
|
||||
pPars->fProbOne = 1;
|
||||
pPars->fProbTrans = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
pPars->fProbOne = 0;
|
||||
pPars->fProbTrans = 1;
|
||||
}
|
||||
pPars->fVerbose = 0;
|
||||
return Fsim_ManSwitchSimulate( p, pPars );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,410 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [fsimTsim.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Fast sequential AIG simulator.]
|
||||
|
||||
Synopsis [Varius utilities.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: fsimTsim.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "fsimInt.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define FSIM_ZER 1
|
||||
#define FSIM_ONE 2
|
||||
#define FSIM_UND 3
|
||||
|
||||
static inline int Aig_XsimNotCond( int Value, int fCompl )
|
||||
{
|
||||
if ( Value == FSIM_UND )
|
||||
return FSIM_UND;
|
||||
if ( Value == FSIM_ZER + fCompl )
|
||||
return FSIM_ZER;
|
||||
return FSIM_ONE;
|
||||
}
|
||||
static inline int Aig_XsimAndCond( int Value0, int Value1, int fCompl0, int fCompl1 )
|
||||
{
|
||||
if ( Value0 == FSIM_UND || Value1 == FSIM_UND )
|
||||
return FSIM_UND;
|
||||
if ( Value0 == FSIM_ZER + fCompl0 || Value1 == FSIM_ZER + fCompl1 )
|
||||
return FSIM_ZER;
|
||||
return FSIM_ONE;
|
||||
}
|
||||
|
||||
static inline int Fsim_ManTerSimInfoGet( unsigned * pInfo, int i )
|
||||
{
|
||||
return 3 & (pInfo[i >> 4] >> ((i & 15) << 1));
|
||||
}
|
||||
static inline void Fsim_ManTerSimInfoSet( unsigned * pInfo, int i, int Value )
|
||||
{
|
||||
assert( Value >= FSIM_ZER && Value <= FSIM_UND );
|
||||
Value ^= Fsim_ManTerSimInfoGet( pInfo, i );
|
||||
pInfo[i >> 4] ^= (Value << ((i & 15) << 1));
|
||||
}
|
||||
|
||||
static inline unsigned * Fsim_ManTerStateNext( unsigned * pState, int nWords ) { return *((unsigned **)(pState + nWords)); }
|
||||
static inline void Fsim_ManTerStateSetNext( unsigned * pState, int nWords, unsigned * pNext ) { *((unsigned **)(pState + nWords)) = pNext; }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Fsim_ManTerSimulateCi( Fsim_Man_t * p, int iNode, int iCi )
|
||||
{
|
||||
Fsim_ManTerSimInfoSet( p->pDataSim, iNode, Fsim_ManTerSimInfoGet(p->pDataSimCis, iCi) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Fsim_ManTerSimulateCo( Fsim_Man_t * p, int iCo, int iFan0 )
|
||||
{
|
||||
int Value = Fsim_ManTerSimInfoGet( p->pDataSim, Fsim_Lit2Var(iFan0) );
|
||||
Fsim_ManTerSimInfoSet( p->pDataSimCos, iCo, Aig_XsimNotCond( Value, Fsim_LitIsCompl(iFan0) ) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Fsim_ManTerSimulateNode( Fsim_Man_t * p, int iNode, int iFan0, int iFan1 )
|
||||
{
|
||||
int Value0 = Fsim_ManTerSimInfoGet( p->pDataSim, Fsim_Lit2Var(iFan0) );
|
||||
int Value1 = Fsim_ManTerSimInfoGet( p->pDataSim, Fsim_Lit2Var(iFan1) );
|
||||
Fsim_ManTerSimInfoSet( p->pDataSim, iNode, Aig_XsimAndCond( Value0, Value1, Fsim_LitIsCompl(iFan0), Fsim_LitIsCompl(iFan1) ) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Fsim_ManTerSimInfoInit( Fsim_Man_t * p )
|
||||
{
|
||||
int iPioNum, i;
|
||||
Vec_IntForEachEntry( p->vCis2Ids, iPioNum, i )
|
||||
{
|
||||
if ( iPioNum < p->nPis )
|
||||
Fsim_ManTerSimInfoSet( p->pDataSimCis, i, FSIM_UND );
|
||||
else
|
||||
Fsim_ManTerSimInfoSet( p->pDataSimCis, i, FSIM_ZER );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Fsim_ManTerSimInfoTransfer( Fsim_Man_t * p )
|
||||
{
|
||||
int iPioNum, i;
|
||||
Vec_IntForEachEntry( p->vCis2Ids, iPioNum, i )
|
||||
{
|
||||
if ( iPioNum < p->nPis )
|
||||
Fsim_ManTerSimInfoSet( p->pDataSimCis, i, FSIM_UND );
|
||||
else
|
||||
Fsim_ManTerSimInfoSet( p->pDataSimCis, i, Fsim_ManTerSimInfoGet( p->pDataSimCos, p->nPos+iPioNum-p->nPis ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes hash value of the node using its simulation info.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Fsim_ManTerStateHash( unsigned * pState, int nWords, int nTableSize )
|
||||
{
|
||||
static int s_FPrimes[128] = {
|
||||
1009, 1049, 1093, 1151, 1201, 1249, 1297, 1361, 1427, 1459,
|
||||
1499, 1559, 1607, 1657, 1709, 1759, 1823, 1877, 1933, 1997,
|
||||
2039, 2089, 2141, 2213, 2269, 2311, 2371, 2411, 2467, 2543,
|
||||
2609, 2663, 2699, 2741, 2797, 2851, 2909, 2969, 3037, 3089,
|
||||
3169, 3221, 3299, 3331, 3389, 3461, 3517, 3557, 3613, 3671,
|
||||
3719, 3779, 3847, 3907, 3943, 4013, 4073, 4129, 4201, 4243,
|
||||
4289, 4363, 4441, 4493, 4549, 4621, 4663, 4729, 4793, 4871,
|
||||
4933, 4973, 5021, 5087, 5153, 5227, 5281, 5351, 5417, 5471,
|
||||
5519, 5573, 5651, 5693, 5749, 5821, 5861, 5923, 6011, 6073,
|
||||
6131, 6199, 6257, 6301, 6353, 6397, 6481, 6563, 6619, 6689,
|
||||
6737, 6803, 6863, 6917, 6977, 7027, 7109, 7187, 7237, 7309,
|
||||
7393, 7477, 7523, 7561, 7607, 7681, 7727, 7817, 7877, 7933,
|
||||
8011, 8039, 8059, 8081, 8093, 8111, 8123, 8147
|
||||
};
|
||||
unsigned uHash;
|
||||
int i;
|
||||
uHash = 0;
|
||||
for ( i = 0; i < nWords; i++ )
|
||||
uHash ^= pState[i] * s_FPrimes[i & 0x7F];
|
||||
return uHash % nTableSize;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Inserts value into the table.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Fsim_ManTerStateLookup( unsigned * pState, int nWords, unsigned ** pBins, int nBins )
|
||||
{
|
||||
unsigned * pEntry;
|
||||
int Hash;
|
||||
Hash = Fsim_ManTerStateHash( pState, nWords, nBins );
|
||||
for ( pEntry = pBins[Hash]; pEntry; pEntry = Fsim_ManTerStateNext(pEntry, nWords) )
|
||||
if ( !memcmp( pEntry, pState, sizeof(unsigned) * nWords ) )
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Inserts value into the table.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fsim_ManTerStateInsert( unsigned * pState, int nWords, unsigned ** pBins, int nBins )
|
||||
{
|
||||
int Hash = Fsim_ManTerStateHash( pState, nWords, nBins );
|
||||
assert( !Fsim_ManTerStateLookup( pState, nWords, pBins, nBins ) );
|
||||
Fsim_ManTerStateSetNext( pState, nWords, pBins[Hash] );
|
||||
pBins[Hash] = pState;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Inserts value into the table.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
unsigned * Fsim_ManTerStateCreate( unsigned * pInfo, int nPis, int nCis, int nWords )
|
||||
{
|
||||
unsigned * pRes;
|
||||
int i;
|
||||
pRes = (unsigned *)CALLOC( char, sizeof(unsigned) * nWords + sizeof(unsigned *) );
|
||||
for ( i = nPis; i < nCis; i++ )
|
||||
Fsim_ManTerSimInfoSet( pRes, i-nPis, Fsim_ManTerSimInfoGet(pInfo, i) );
|
||||
return pRes;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Inserts value into the table.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fsim_ManTerStatePrint( unsigned * pState, int nRegs )
|
||||
{
|
||||
int i, Value, nZeros = 0, nOnes = 0, nDcs = 0;
|
||||
for ( i = 0; i < nRegs; i++ )
|
||||
{
|
||||
Value = (Aig_InfoHasBit( pState, 2 * i + 1 ) << 1) | Aig_InfoHasBit( pState, 2 * i );
|
||||
if ( Value == 1 )
|
||||
printf( "0" ), nZeros++;
|
||||
else if ( Value == 2 )
|
||||
printf( "1" ), nOnes++;
|
||||
else if ( Value == 3 )
|
||||
printf( "x" ), nDcs++;
|
||||
else
|
||||
assert( 0 );
|
||||
}
|
||||
printf( " (0=%5d, 1=%5d, x=%5d)\n", nZeros, nOnes, nDcs );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Fsim_ManTerSimulateRound( Fsim_Man_t * p )
|
||||
{
|
||||
int * pCur, * pEnd;
|
||||
int iCis = 0, iCos = 0;
|
||||
if ( Aig_ObjRefs(Aig_ManConst1(p->pAig)) )
|
||||
Fsim_ManTerSimInfoSet( p->pDataSimCis, 1, FSIM_ONE );
|
||||
pCur = p->pDataAig2 + 6;
|
||||
pEnd = p->pDataAig2 + 3 * p->nObjs;
|
||||
while ( pCur < pEnd )
|
||||
{
|
||||
if ( pCur[1] == 0 )
|
||||
Fsim_ManTerSimulateCi( p, pCur[0], iCis++ );
|
||||
else if ( pCur[2] == 0 )
|
||||
Fsim_ManTerSimulateCo( p, iCos++, pCur[1] );
|
||||
else
|
||||
Fsim_ManTerSimulateNode( p, pCur[0], pCur[1], pCur[2] );
|
||||
pCur += 3;
|
||||
}
|
||||
assert( iCis == p->nCis );
|
||||
assert( iCos == p->nCos );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Ptr_t * Fsim_ManTerSimulate( Aig_Man_t * pAig, int fVerbose )
|
||||
{
|
||||
Fsim_Man_t * p;
|
||||
Vec_Ptr_t * vStates;
|
||||
unsigned ** pBins, * pState;
|
||||
int i, nWords, nBins, clk, clkTotal = clock();
|
||||
assert( Aig_ManRegNum(pAig) > 0 );
|
||||
// create manager
|
||||
clk = clock();
|
||||
p = Fsim_ManCreate( pAig );
|
||||
if ( fVerbose )
|
||||
{
|
||||
printf( "Obj = %8d (%8d). Cut = %6d. Front = %6d. FrtMem = %7.2f Mb. ",
|
||||
p->nObjs, p->nCis + p->nNodes, p->nCrossCutMax, p->nFront,
|
||||
4.0*Aig_BitWordNum(2 * p->nFront)/(1<<20) );
|
||||
PRT( "Time", clock() - clk );
|
||||
}
|
||||
// create simulation frontier
|
||||
clk = clock();
|
||||
Fsim_ManFront( p, 0 );
|
||||
if ( fVerbose )
|
||||
{
|
||||
printf( "Max ID = %8d. Log max ID = %2d. AigMem = %7.2f Mb (%5.2f byte/obj). ",
|
||||
p->iNumber, Aig_Base2Log(p->iNumber),
|
||||
1.0*(p->pDataCur-p->pDataAig)/(1<<20),
|
||||
1.0*(p->pDataCur-p->pDataAig)/p->nObjs );
|
||||
PRT( "Time", clock() - clk );
|
||||
}
|
||||
// allocate storage for terminary states
|
||||
nWords = Aig_BitWordNum( 2*Aig_ManRegNum(pAig) );
|
||||
vStates = Vec_PtrAlloc( 1000 );
|
||||
nBins = Aig_PrimeCudd( 500 );
|
||||
pBins = ALLOC( unsigned *, nBins );
|
||||
memset( pBins, 0, sizeof(unsigned *) * nBins );
|
||||
// perform simulation
|
||||
assert( p->pDataSim == NULL );
|
||||
p->pDataSim = ALLOC( unsigned, Aig_BitWordNum(2 * p->nFront) * sizeof(unsigned) );
|
||||
p->pDataSimCis = ALLOC( unsigned, Aig_BitWordNum(2 * p->nCis) * sizeof(unsigned) );
|
||||
p->pDataSimCos = ALLOC( unsigned, Aig_BitWordNum(2 * p->nCos) * sizeof(unsigned) );
|
||||
Fsim_ManTerSimInfoInit( p );
|
||||
// hash the first state
|
||||
pState = Fsim_ManTerStateCreate( p->pDataSimCis, p->nPis, p->nCis, nWords );
|
||||
Vec_PtrPush( vStates, pState );
|
||||
Fsim_ManTerStateInsert( pState, nWords, pBins, nBins );
|
||||
// perform simuluation till convergence
|
||||
for ( i = 0; ; i++ )
|
||||
{
|
||||
Fsim_ManTerSimulateRound( p );
|
||||
Fsim_ManTerSimInfoTransfer( p );
|
||||
// hash the first state
|
||||
pState = Fsim_ManTerStateCreate( p->pDataSimCis, p->nPis, p->nCis, nWords );
|
||||
Vec_PtrPush( vStates, pState );
|
||||
if ( Fsim_ManTerStateLookup(pState, nWords, pBins, nBins) )
|
||||
break;
|
||||
Fsim_ManTerStateInsert( pState, nWords, pBins, nBins );
|
||||
}
|
||||
if ( fVerbose )
|
||||
{
|
||||
printf( "Maxcut = %8d. AigMem = %7.2f Mb. SimMem = %7.2f Mb. ",
|
||||
p->nCrossCutMax,
|
||||
p->pDataAig2? 12.0*p->nObjs/(1<<20) : 1.0*(p->pDataCur-p->pDataAig)/(1<<20),
|
||||
4.0*(Aig_BitWordNum(2 * p->nFront)+Aig_BitWordNum(2 * p->nCis)+Aig_BitWordNum(2 * p->nCos))/(1<<20) );
|
||||
PRT( "Sim time", clock() - clkTotal );
|
||||
}
|
||||
free( pBins );
|
||||
Fsim_ManDelete( p );
|
||||
return vStates;
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
SRC += src/aig/fsim/fsimCore.c \
|
||||
src/aig/fsim/fsimFront.c \
|
||||
src/aig/fsim/fsimMan.c \
|
||||
src/aig/fsim/fsimSim.c \
|
||||
src/aig/fsim/fsimSwitch.c \
|
||||
src/aig/fsim/fsimTsim.c
|
||||
|
|
@ -64,7 +64,10 @@ typedef enum {
|
|||
struct Hop_Obj_t_ // 6 words
|
||||
{
|
||||
void * pData; // misc
|
||||
Hop_Obj_t * pNext; // strashing table
|
||||
union {
|
||||
Hop_Obj_t * pNext; // strashing table
|
||||
int PioNum; // the number of PI/PO
|
||||
};
|
||||
Hop_Obj_t * pFanin0; // fanin
|
||||
Hop_Obj_t * pFanin1; // fanin
|
||||
unsigned int Type : 3; // object type
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ Hop_Obj_t * Hop_ObjCreatePi( Hop_Man_t * p )
|
|||
Hop_Obj_t * pObj;
|
||||
pObj = Hop_ManFetchMemory( p );
|
||||
pObj->Type = AIG_PI;
|
||||
pObj->PioNum = Vec_PtrSize( p->vPis );
|
||||
Vec_PtrPush( p->vPis, pObj );
|
||||
p->nObjs[AIG_PI]++;
|
||||
return pObj;
|
||||
|
|
|
|||
|
|
@ -44,6 +44,12 @@ static inline void Hop_ManTruthFill( unsigned * pOut, int nVars )
|
|||
for ( w = Hop_ManTruthWordNum(nVars)-1; w >= 0; w-- )
|
||||
pOut[w] = ~(unsigned)0;
|
||||
}
|
||||
static inline void Hop_ManTruthNot( unsigned * pOut, unsigned * pIn, int nVars )
|
||||
{
|
||||
int w;
|
||||
for ( w = Hop_ManTruthWordNum(nVars)-1; w >= 0; w-- )
|
||||
pOut[w] = ~pIn[w];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
|
|
@ -155,7 +161,7 @@ unsigned * Hop_ManConvertAigToTruth( Hop_Man_t * p, Hop_Obj_t * pRoot, int nVars
|
|||
vTtElems = NULL;
|
||||
|
||||
// clear the data fields and set marks
|
||||
nNodes = Hop_ManConvertAigToTruth_rec1( pRoot );
|
||||
nNodes = Hop_ManConvertAigToTruth_rec1( Hop_Regular(pRoot) );
|
||||
// prepare memory
|
||||
nWords = Hop_TruthWordNum( nVars );
|
||||
Vec_IntClear( vTruth );
|
||||
|
|
@ -199,9 +205,11 @@ unsigned * Hop_ManConvertAigToTruth( Hop_Man_t * p, Hop_Obj_t * pRoot, int nVars
|
|||
}
|
||||
}
|
||||
// clear the marks and compute the truth table
|
||||
pTruth2 = Hop_ManConvertAigToTruth_rec2( pRoot, vTruth, nWords );
|
||||
pTruth2 = Hop_ManConvertAigToTruth_rec2( Hop_Regular(pRoot), vTruth, nWords );
|
||||
// copy the result
|
||||
Hop_ManTruthCopy( pTruth, pTruth2, nVars );
|
||||
if ( Hop_IsComplement(pRoot) )
|
||||
Hop_ManTruthNot( pTruth, pTruth, nVars );
|
||||
if ( vTtElems )
|
||||
Vec_PtrFree( vTtElems );
|
||||
return pTruth;
|
||||
|
|
|
|||
|
|
@ -258,6 +258,12 @@ void Ioa_WriteAiger( Aig_Man_t * pMan, char * pFileName, int fWriteSymbols, int
|
|||
unsigned char * pBuffer;
|
||||
unsigned uLit0, uLit1, uLit;
|
||||
|
||||
if ( Aig_ManPoNum(pMan) == 0 )
|
||||
{
|
||||
printf( "AIG cannot be written because it has no POs.\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
// assert( Aig_ManIsStrash(pMan) );
|
||||
// start the output stream
|
||||
pFile = fopen( pFileName, "wb" );
|
||||
|
|
|
|||
|
|
@ -141,14 +141,14 @@ struct Kit_DsdMan_t_
|
|||
};
|
||||
|
||||
#ifdef WIN32
|
||||
#define DLLEXPORT __declspec(dllexport)
|
||||
#define DLLIMPORT __declspec(dllimport)
|
||||
#define ABC_DLLEXPORT __declspec(dllexport)
|
||||
#define ABC_DLLIMPORT __declspec(dllimport)
|
||||
#else /* defined(WIN32) */
|
||||
#define DLLIMPORT
|
||||
#define ABC_DLLIMPORT
|
||||
#endif /* defined(WIN32) */
|
||||
|
||||
#ifndef ABC_DLL
|
||||
#define ABC_DLL DLLIMPORT
|
||||
#define ABC_DLL ABC_DLLIMPORT
|
||||
#endif
|
||||
|
||||
static inline int Kit_DsdVar2Lit( int Var, int fCompl ) { return Var + Var + fCompl; }
|
||||
|
|
@ -169,7 +169,9 @@ static inline unsigned Kit_DsdLitSupport( Kit_DsdNtk_t * pNtk, int Lit )
|
|||
#define Kit_DsdNtkForEachObj( pNtk, pObj, i ) \
|
||||
for ( i = 0; (i < (pNtk)->nNodes) && ((pObj) = (pNtk)->pNodes[i]); i++ )
|
||||
#define Kit_DsdObjForEachFanin( pNtk, pObj, iLit, i ) \
|
||||
for ( i = 0; (i < (pObj)->nFans) && ((iLit) = (pObj)->pFans[i], 1); i++ )
|
||||
for ( i = 0; (i < (int)(pObj)->nFans) && ((iLit) = (pObj)->pFans[i], 1); i++ )
|
||||
#define Kit_DsdObjForEachFaninReverse( pNtk, pObj, iLit, i ) \
|
||||
for ( i = (int)(pObj)->nFans - 1; (i >= 0) && ((iLit) = (pObj)->pFans[i], 1); i-- )
|
||||
|
||||
#define Kit_PlaForEachCube( pSop, nFanins, pCube ) \
|
||||
for ( pCube = (pSop); *pCube; pCube += (nFanins) + 3 )
|
||||
|
|
@ -528,6 +530,7 @@ extern Kit_DsdNtk_t * Kit_DsdDecomposeMux( unsigned * pTruth, int nVars, int nD
|
|||
extern void Kit_DsdVerify( Kit_DsdNtk_t * pNtk, unsigned * pTruth, int nVars );
|
||||
extern void Kit_DsdNtkFree( Kit_DsdNtk_t * pNtk );
|
||||
extern int Kit_DsdNonDsdSizeMax( Kit_DsdNtk_t * pNtk );
|
||||
extern Kit_DsdObj_t * Kit_DsdNonDsdPrimeMax( Kit_DsdNtk_t * pNtk );
|
||||
extern unsigned Kit_DsdNonDsdSupports( Kit_DsdNtk_t * pNtk );
|
||||
extern unsigned Kit_DsdGetSupports( Kit_DsdNtk_t * p );
|
||||
extern Kit_DsdNtk_t * Kit_DsdExpand( Kit_DsdNtk_t * p );
|
||||
|
|
@ -586,6 +589,7 @@ extern void Kit_SopBestLiteralCover( Kit_Sop_t * cResult, Kit_Sop_t *
|
|||
/*=== kitTruth.c ==========================================================*/
|
||||
extern void Kit_TruthSwapAdjacentVars( unsigned * pOut, unsigned * pIn, int nVars, int Start );
|
||||
extern void Kit_TruthStretch( unsigned * pOut, unsigned * pIn, int nVars, int nVarsAll, unsigned Phase, int fReturnIn );
|
||||
extern void Kit_TruthPermute( unsigned * pOut, unsigned * pIn, int nVars, char * pPerm, int fReturnIn );
|
||||
extern void Kit_TruthShrink( unsigned * pOut, unsigned * pIn, int nVars, int nVarsAll, unsigned Phase, int fReturnIn );
|
||||
extern int Kit_TruthVarInSupport( unsigned * pTruth, int nVars, int iVar );
|
||||
extern int Kit_TruthSupportSize( unsigned * pTruth, int nVars );
|
||||
|
|
@ -608,6 +612,7 @@ extern void Kit_TruthChangePhase( unsigned * pTruth, int nVars, int i
|
|||
extern int Kit_TruthMinCofSuppOverlap( unsigned * pTruth, int nVars, int * pVarMin );
|
||||
extern int Kit_TruthBestCofVar( unsigned * pTruth, int nVars, unsigned * pCof0, unsigned * pCof1 );
|
||||
extern void Kit_TruthCountOnesInCofs( unsigned * pTruth, int nVars, short * pStore );
|
||||
extern void Kit_TruthCountOnesInCofs0( unsigned * pTruth, int nVars, short * pStore );
|
||||
extern void Kit_TruthCountOnesInCofsSlow( unsigned * pTruth, int nVars, short * pStore, unsigned * pAux );
|
||||
extern unsigned Kit_TruthHash( unsigned * pIn, int nWords );
|
||||
extern unsigned Kit_TruthSemiCanonicize( unsigned * pInOut, unsigned * pAux, int nVars, char * pCanonPerm, short * pStore );
|
||||
|
|
|
|||
|
|
@ -139,9 +139,9 @@ Kit_DsdNtk_t * Kit_DsdNtkAlloc( int nVars )
|
|||
Kit_DsdNtk_t * pNtk;
|
||||
pNtk = ALLOC( Kit_DsdNtk_t, 1 );
|
||||
memset( pNtk, 0, sizeof(Kit_DsdNtk_t) );
|
||||
pNtk->pNodes = ALLOC( Kit_DsdObj_t *, nVars );
|
||||
pNtk->pNodes = ALLOC( Kit_DsdObj_t *, nVars+1 );
|
||||
pNtk->nVars = nVars;
|
||||
pNtk->nNodesAlloc = nVars;
|
||||
pNtk->nNodesAlloc = nVars+1;
|
||||
pNtk->pMem = ALLOC( unsigned, 6 * Kit_TruthWordNum(nVars) );
|
||||
return pNtk;
|
||||
}
|
||||
|
|
@ -303,10 +303,13 @@ void Kit_DsdPrintExpanded( Kit_DsdNtk_t * pNtk )
|
|||
***********************************************************************/
|
||||
void Kit_DsdPrintFromTruth( unsigned * pTruth, int nVars )
|
||||
{
|
||||
Kit_DsdNtk_t * pTemp;
|
||||
Kit_DsdNtk_t * pTemp, * pTemp2;
|
||||
pTemp = Kit_DsdDecomposeMux( pTruth, nVars, 5 );
|
||||
Kit_DsdVerify( pTemp, pTruth, nVars );
|
||||
Kit_DsdPrintExpanded( pTemp );
|
||||
// Kit_DsdPrintExpanded( pTemp );
|
||||
pTemp2 = Kit_DsdExpand( pTemp );
|
||||
Kit_DsdPrint( stdout, pTemp2 );
|
||||
Kit_DsdVerify( pTemp2, pTruth, nVars );
|
||||
Kit_DsdNtkFree( pTemp2 );
|
||||
Kit_DsdNtkFree( pTemp );
|
||||
}
|
||||
|
||||
|
|
@ -392,7 +395,6 @@ unsigned * Kit_DsdTruthComputeNode_rec( Kit_DsdMan_t * p, Kit_DsdNtk_t * pNtk, i
|
|||
pTruthPrime = Kit_DsdObjTruth( pObj );
|
||||
// get storage for the temporary minterm
|
||||
pTruthMint = Vec_PtrEntry(p->vTtNodes, pNtk->nVars + pNtk->nNodes);
|
||||
|
||||
// go through the minterms
|
||||
nMints = (1 << pObj->nFans);
|
||||
Kit_TruthClear( pTruthRes, pNtk->nVars );
|
||||
|
|
@ -406,6 +408,9 @@ unsigned * Kit_DsdTruthComputeNode_rec( Kit_DsdMan_t * p, Kit_DsdNtk_t * pNtk, i
|
|||
Kit_TruthOr( pTruthRes, pTruthRes, pTruthMint, pNtk->nVars );
|
||||
}
|
||||
*/
|
||||
Kit_DsdObjForEachFanin( pNtk, pObj, iLit, i )
|
||||
if ( Kit_DsdLitIsCompl(iLit) )
|
||||
Kit_TruthNot( pTruthFans[i], pTruthFans[i], pNtk->nVars );
|
||||
pTruthTemp = Kit_TruthCompose( p->dd, Kit_DsdObjTruth(pObj), pObj->nFans, pTruthFans, pNtk->nVars, p->vTtBdds, p->vNodes );
|
||||
Kit_TruthCopy( pTruthRes, pTruthTemp, pNtk->nVars );
|
||||
return pTruthRes;
|
||||
|
|
@ -550,7 +555,6 @@ unsigned * Kit_DsdTruthComputeNodeOne_rec( Kit_DsdMan_t * p, Kit_DsdNtk_t * pNtk
|
|||
pTruthPrime = Kit_DsdObjTruth( pObj );
|
||||
// get storage for the temporary minterm
|
||||
pTruthMint = Vec_PtrEntry(p->vTtNodes, pNtk->nVars + pNtk->nNodes);
|
||||
|
||||
// go through the minterms
|
||||
nMints = (1 << pObj->nFans);
|
||||
Kit_TruthClear( pTruthRes, pNtk->nVars );
|
||||
|
|
@ -564,6 +568,9 @@ unsigned * Kit_DsdTruthComputeNodeOne_rec( Kit_DsdMan_t * p, Kit_DsdNtk_t * pNtk
|
|||
Kit_TruthOr( pTruthRes, pTruthRes, pTruthMint, pNtk->nVars );
|
||||
}
|
||||
*/
|
||||
Kit_DsdObjForEachFanin( pNtk, pObj, iLit, i )
|
||||
if ( Kit_DsdLitIsCompl(iLit) )
|
||||
Kit_TruthNot( pTruthFans[i], pTruthFans[i], pNtk->nVars );
|
||||
pTruthTemp = Kit_TruthCompose( p->dd, Kit_DsdObjTruth(pObj), pObj->nFans, pTruthFans, pNtk->nVars, p->vTtBdds, p->vNodes );
|
||||
Kit_TruthCopy( pTruthRes, pTruthTemp, pNtk->nVars );
|
||||
return pTruthRes;
|
||||
|
|
@ -747,7 +754,6 @@ unsigned * Kit_DsdTruthComputeNodeTwo_rec( Kit_DsdMan_t * p, Kit_DsdNtk_t * pNtk
|
|||
pTruthPrime = Kit_DsdObjTruth( pObj );
|
||||
// get storage for the temporary minterm
|
||||
pTruthMint = Vec_PtrEntry(p->vTtNodes, pNtk->nVars + pNtk->nNodes);
|
||||
|
||||
// go through the minterms
|
||||
nMints = (1 << pObj->nFans);
|
||||
Kit_TruthClear( pTruthRes, pNtk->nVars );
|
||||
|
|
@ -761,8 +767,11 @@ unsigned * Kit_DsdTruthComputeNodeTwo_rec( Kit_DsdMan_t * p, Kit_DsdNtk_t * pNtk
|
|||
Kit_TruthOr( pTruthRes, pTruthRes, pTruthMint, pNtk->nVars );
|
||||
}
|
||||
*/
|
||||
// Kit_DsdObjForEachFanin( pNtk, pObj, iLit, i )
|
||||
// assert( !Kit_DsdLitIsCompl(iLit) );
|
||||
Kit_DsdObjForEachFanin( pNtk, pObj, iLit, i )
|
||||
assert( !Kit_DsdLitIsCompl(iLit) );
|
||||
if ( Kit_DsdLitIsCompl(iLit) )
|
||||
Kit_TruthNot( pTruthFans[i], pTruthFans[i], pNtk->nVars );
|
||||
pTruthTemp = Kit_TruthCompose( p->dd, Kit_DsdObjTruth(pObj), pObj->nFans, pTruthFans, pNtk->nVars, p->vTtBdds, p->vNodes );
|
||||
Kit_TruthCopy( pTruthRes, pTruthTemp, pNtk->nVars );
|
||||
return pTruthRes;
|
||||
|
|
@ -957,7 +966,7 @@ int Kit_DsdCountLuts( Kit_DsdNtk_t * pNtk, int nLutSize )
|
|||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Counts the number of blocks of the given number of inputs.]
|
||||
Synopsis [Returns the size of the largest non-DSD block.]
|
||||
|
||||
Description []
|
||||
|
||||
|
|
@ -980,6 +989,34 @@ int Kit_DsdNonDsdSizeMax( Kit_DsdNtk_t * pNtk )
|
|||
return nSizeMax;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the largest non-DSD block.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Kit_DsdObj_t * Kit_DsdNonDsdPrimeMax( Kit_DsdNtk_t * pNtk )
|
||||
{
|
||||
Kit_DsdObj_t * pObj, * pObjMax = NULL;
|
||||
unsigned i, nSizeMax = 0;
|
||||
Kit_DsdNtkForEachObj( pNtk, pObj, i )
|
||||
{
|
||||
if ( pObj->Type != KIT_DSD_PRIME )
|
||||
continue;
|
||||
if ( nSizeMax < pObj->nFans )
|
||||
{
|
||||
nSizeMax = pObj->nFans;
|
||||
pObjMax = pObj;
|
||||
}
|
||||
}
|
||||
return pObjMax;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Finds the union of supports of the non-DSD blocks.]
|
||||
|
|
@ -1125,10 +1162,46 @@ int Kit_DsdExpandNode_rec( Kit_DsdNtk_t * pNew, Kit_DsdNtk_t * p, int iLit )
|
|||
Kit_TruthChangePhase( pTruthNew, pObjNew->nFans, i );
|
||||
}
|
||||
}
|
||||
// if the incoming phase is complemented, absorb it into the prime node
|
||||
if ( Kit_DsdLitIsCompl(iLit) )
|
||||
Kit_TruthNot( pTruthNew, pTruthNew, pObj->nFans );
|
||||
return Kit_DsdVar2Lit( pObjNew->Id, 0 );
|
||||
|
||||
if ( pObj->nFans == 3 &&
|
||||
(pTruthNew[0] == 0xCACACACA || pTruthNew[0] == 0xC5C5C5C5 ||
|
||||
pTruthNew[0] == 0x3A3A3A3A || pTruthNew[0] == 0x35353535) )
|
||||
{
|
||||
// translate into regular MUXes
|
||||
if ( pTruthNew[0] == 0xC5C5C5C5 )
|
||||
pObjNew->pFans[0] = Kit_DsdLitNot(pObjNew->pFans[0]);
|
||||
else if ( pTruthNew[0] == 0x3A3A3A3A )
|
||||
pObjNew->pFans[1] = Kit_DsdLitNot(pObjNew->pFans[1]);
|
||||
else if ( pTruthNew[0] == 0x35353535 )
|
||||
{
|
||||
pObjNew->pFans[0] = Kit_DsdLitNot(pObjNew->pFans[0]);
|
||||
pObjNew->pFans[1] = Kit_DsdLitNot(pObjNew->pFans[1]);
|
||||
}
|
||||
pTruthNew[0] = 0xCACACACA;
|
||||
// resolve the complemented control input
|
||||
if ( Kit_DsdLitIsCompl(pObjNew->pFans[2]) )
|
||||
{
|
||||
unsigned char Temp = pObjNew->pFans[0];
|
||||
pObjNew->pFans[0] = pObjNew->pFans[1];
|
||||
pObjNew->pFans[1] = Temp;
|
||||
pObjNew->pFans[2] = Kit_DsdLitNot(pObjNew->pFans[2]);
|
||||
}
|
||||
// resolve the complemented true input
|
||||
if ( Kit_DsdLitIsCompl(pObjNew->pFans[1]) )
|
||||
{
|
||||
iLit = Kit_DsdLitNot(iLit);
|
||||
pObjNew->pFans[0] = Kit_DsdLitNot(pObjNew->pFans[0]);
|
||||
pObjNew->pFans[1] = Kit_DsdLitNot(pObjNew->pFans[1]);
|
||||
}
|
||||
return Kit_DsdVar2Lit( pObjNew->Id, Kit_DsdLitIsCompl(iLit) );
|
||||
}
|
||||
else
|
||||
{
|
||||
// if the incoming phase is complemented, absorb it into the prime node
|
||||
if ( Kit_DsdLitIsCompl(iLit) )
|
||||
Kit_TruthNot( pTruthNew, pTruthNew, pObj->nFans );
|
||||
return Kit_DsdVar2Lit( pObjNew->Id, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
@ -1834,7 +1907,7 @@ void Kit_DsdDecompose_rec( Kit_DsdNtk_t * pNtk, Kit_DsdObj_t * pObj, unsigned uS
|
|||
return;
|
||||
}
|
||||
}
|
||||
/*
|
||||
|
||||
// if all decomposition methods failed and we are still above the limit, perform MUX-decomposition
|
||||
if ( nDecMux > 0 && (int)pObj->nFans > nDecMux )
|
||||
{
|
||||
|
|
@ -1852,14 +1925,14 @@ void Kit_DsdDecompose_rec( Kit_DsdNtk_t * pNtk, Kit_DsdObj_t * pObj, unsigned uS
|
|||
assert( pObj->Type == KIT_DSD_PRIME );
|
||||
pTruth[0] = 0xCACACACA;
|
||||
pObj->nFans = 3;
|
||||
pObj->pFans[2] = pObj->pFans[iBestVar];
|
||||
pObj->pFans[0] = 2*pRes0->Id; pRes0->nRefs++;
|
||||
pObj->pFans[1] = 2*pRes1->Id; pRes1->nRefs++;
|
||||
pObj->pFans[2] = pObj->pFans[iBestVar];
|
||||
// call recursively
|
||||
Kit_DsdDecompose_rec( pNtk, pRes0, uSupp0, pObj->pFans + 0, nDecMux );
|
||||
Kit_DsdDecompose_rec( pNtk, pRes1, uSupp1, pObj->pFans + 1, nDecMux );
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
@ -1959,6 +2032,27 @@ Kit_DsdNtk_t * Kit_DsdDecomposeExpand( unsigned * pTruth, int nVars )
|
|||
***********************************************************************/
|
||||
Kit_DsdNtk_t * Kit_DsdDecomposeMux( unsigned * pTruth, int nVars, int nDecMux )
|
||||
{
|
||||
/*
|
||||
Kit_DsdNtk_t * pNew;
|
||||
Kit_DsdObj_t * pObjNew;
|
||||
assert( nVars <= 16 );
|
||||
// create a new network
|
||||
pNew = Kit_DsdNtkAlloc( nVars );
|
||||
// consider simple special cases
|
||||
if ( nVars == 0 )
|
||||
{
|
||||
pObjNew = Kit_DsdObjAlloc( pNew, KIT_DSD_CONST1, 0 );
|
||||
pNew->Root = Kit_DsdVar2Lit( pObjNew->Id, (int)(pTruth[0] == 0) );
|
||||
return pNew;
|
||||
}
|
||||
if ( nVars == 1 )
|
||||
{
|
||||
pObjNew = Kit_DsdObjAlloc( pNew, KIT_DSD_VAR, 1 );
|
||||
pObjNew->pFans[0] = Kit_DsdVar2Lit( 0, 0 );
|
||||
pNew->Root = Kit_DsdVar2Lit( pObjNew->Id, (int)(pTruth[0] != 0xAAAAAAAA) );
|
||||
return pNew;
|
||||
}
|
||||
*/
|
||||
return Kit_DsdDecomposeInt( pTruth, nVars, nDecMux );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -155,7 +155,7 @@ void Kit_TruthSwapAdjacentVars2( unsigned * pIn, unsigned * pOut, int nVars, int
|
|||
of variables is nVars. The total number of variables in nVarsAll. The last argument
|
||||
(Phase) contains shows where the variables should go.]
|
||||
|
||||
SideEffects []
|
||||
SideEffects [The input truth table is modified.]
|
||||
|
||||
SeeAlso []
|
||||
|
||||
|
|
@ -189,7 +189,7 @@ void Kit_TruthStretch( unsigned * pOut, unsigned * pIn, int nVars, int nVarsAll,
|
|||
of variables is nVars. The total number of variables in nVarsAll. The last argument
|
||||
(Phase) contains shows what variables should remain.]
|
||||
|
||||
SideEffects []
|
||||
SideEffects [The input truth table is modified.]
|
||||
|
||||
SeeAlso []
|
||||
|
||||
|
|
@ -215,6 +215,43 @@ void Kit_TruthShrink( unsigned * pOut, unsigned * pIn, int nVars, int nVarsAll,
|
|||
Kit_TruthCopy( pOut, pIn, nVarsAll );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Implement give permutation.]
|
||||
|
||||
Description [The input and output truth tables are in pIn/pOut.
|
||||
The number of variables is nVars. Permutation is in pPerm.]
|
||||
|
||||
SideEffects [The input truth table is modified.]
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Kit_TruthPermute( unsigned * pOut, unsigned * pIn, int nVars, char * pPerm, int fReturnIn )
|
||||
{
|
||||
int * pTemp;
|
||||
int i, Temp, fChange, Counter = 0;
|
||||
do {
|
||||
fChange = 0;
|
||||
for ( i = 0; i < nVars-1; i++ )
|
||||
{
|
||||
assert( pPerm[i] != pPerm[i+1] );
|
||||
if ( pPerm[i] <= pPerm[i+1] )
|
||||
continue;
|
||||
Counter++;
|
||||
fChange = 1;
|
||||
|
||||
Temp = pPerm[i];
|
||||
pPerm[i] = pPerm[i+1];
|
||||
pPerm[i+1] = Temp;
|
||||
|
||||
Kit_TruthSwapAdjacentVars( pOut, pIn, nVars, i );
|
||||
pTemp = pIn; pIn = pOut; pOut = pTemp;
|
||||
}
|
||||
} while ( fChange );
|
||||
if ( fReturnIn ^ !(Counter & 1) )
|
||||
Kit_TruthCopy( pOut, pIn, nVars );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
|
|
@ -1289,6 +1326,60 @@ void Kit_TruthCountOnesInCofs( unsigned * pTruth, int nVars, short * pStore )
|
|||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Counts the number of 1's in each negative cofactor.]
|
||||
|
||||
Description [The resulting numbers are stored in the array of shorts,
|
||||
whose length is nVars. The number of 1's is counted in a different
|
||||
space than the original function. For example, if the function depends
|
||||
on k variables, the cofactors are assumed to depend on k-1 variables.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Kit_TruthCountOnesInCofs0( unsigned * pTruth, int nVars, short * pStore )
|
||||
{
|
||||
int nWords = Kit_TruthWordNum( nVars );
|
||||
int i, k, Counter;
|
||||
memset( pStore, 0, sizeof(short) * nVars );
|
||||
if ( nVars <= 5 )
|
||||
{
|
||||
if ( nVars > 0 )
|
||||
pStore[0] = Kit_WordCountOnes( pTruth[0] & 0x55555555 );
|
||||
if ( nVars > 1 )
|
||||
pStore[1] = Kit_WordCountOnes( pTruth[0] & 0x33333333 );
|
||||
if ( nVars > 2 )
|
||||
pStore[2] = Kit_WordCountOnes( pTruth[0] & 0x0F0F0F0F );
|
||||
if ( nVars > 3 )
|
||||
pStore[3] = Kit_WordCountOnes( pTruth[0] & 0x00FF00FF );
|
||||
if ( nVars > 4 )
|
||||
pStore[4] = Kit_WordCountOnes( pTruth[0] & 0x0000FFFF );
|
||||
return;
|
||||
}
|
||||
// nVars >= 6
|
||||
// count 1's for all other variables
|
||||
for ( k = 0; k < nWords; k++ )
|
||||
{
|
||||
Counter = Kit_WordCountOnes( pTruth[k] );
|
||||
for ( i = 5; i < nVars; i++ )
|
||||
if ( (k & (1 << (i-5))) == 0 )
|
||||
pStore[i] += Counter;
|
||||
}
|
||||
// count 1's for the first five variables
|
||||
for ( k = 0; k < nWords/2; k++ )
|
||||
{
|
||||
pStore[0] += Kit_WordCountOnes( (pTruth[0] & 0x55555555) | ((pTruth[1] & 0x55555555) << 1) );
|
||||
pStore[1] += Kit_WordCountOnes( (pTruth[0] & 0x33333333) | ((pTruth[1] & 0x33333333) << 2) );
|
||||
pStore[2] += Kit_WordCountOnes( (pTruth[0] & 0x0F0F0F0F) | ((pTruth[1] & 0x0F0F0F0F) << 4) );
|
||||
pStore[3] += Kit_WordCountOnes( (pTruth[0] & 0x00FF00FF) | ((pTruth[1] & 0x00FF00FF) << 8) );
|
||||
pStore[4] += Kit_WordCountOnes( (pTruth[0] & 0x0000FFFF) | ((pTruth[1] & 0x0000FFFF) << 16) );
|
||||
pTruth += 2;
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Counts the number of 1's in each cofactor.]
|
||||
|
|
@ -1440,16 +1531,17 @@ unsigned Kit_TruthSemiCanonicize( unsigned * pInOut, unsigned * pAux, int nVars,
|
|||
*/
|
||||
// collect the minterm counts
|
||||
Kit_TruthCountOnesInCofs( pIn, nVars, pStore );
|
||||
// Kit_TruthCountOnesInCofsSlow( pIn, nVars, pStore2, pAux );
|
||||
// for ( i = 0; i < 2*nVars; i++ )
|
||||
// {
|
||||
// assert( pStore[i] == pStore2[i] );
|
||||
// }
|
||||
|
||||
/*
|
||||
Kit_TruthCountOnesInCofsSlow( pIn, nVars, pStore2, pAux );
|
||||
for ( i = 0; i < 2*nVars; i++ )
|
||||
{
|
||||
assert( pStore[i] == pStore2[i] );
|
||||
}
|
||||
*/
|
||||
// canonicize phase
|
||||
for ( i = 0; i < nVars; i++ )
|
||||
{
|
||||
if ( pStore[2*i+0] >= pStore[2*i+1] )
|
||||
if ( pStore[2*i+0] <= pStore[2*i+1] )
|
||||
continue;
|
||||
uCanonPhase |= (1 << i);
|
||||
Temp = pStore[2*i+0];
|
||||
|
|
@ -1463,11 +1555,12 @@ unsigned Kit_TruthSemiCanonicize( unsigned * pInOut, unsigned * pAux, int nVars,
|
|||
|
||||
// permute
|
||||
Counter = 0;
|
||||
|
||||
do {
|
||||
fChange = 0;
|
||||
for ( i = 0; i < nVars-1; i++ )
|
||||
{
|
||||
if ( pStore[2*i] >= pStore[2*(i+1)] )
|
||||
if ( pStore[2*i] <= pStore[2*(i+1)] )
|
||||
continue;
|
||||
Counter++;
|
||||
fChange = 1;
|
||||
|
|
@ -1485,17 +1578,18 @@ unsigned Kit_TruthSemiCanonicize( unsigned * pInOut, unsigned * pAux, int nVars,
|
|||
pStore[2*(i+1)+1] = Temp;
|
||||
|
||||
// if the polarity of variables is different, swap them
|
||||
if ( ((uCanonPhase & (1 << i)) > 0) != ((uCanonPhase & (1 << (i+1))) > 0) )
|
||||
{
|
||||
uCanonPhase ^= (1 << i);
|
||||
uCanonPhase ^= (1 << (i+1));
|
||||
}
|
||||
// if ( ((uCanonPhase & (1 << i)) > 0) != ((uCanonPhase & (1 << (i+1))) > 0) )
|
||||
// {
|
||||
// uCanonPhase ^= (1 << i);
|
||||
// uCanonPhase ^= (1 << (i+1));
|
||||
// }
|
||||
|
||||
Kit_TruthSwapAdjacentVars( pOut, pIn, nVars, i );
|
||||
pTemp = pIn; pIn = pOut; pOut = pTemp;
|
||||
}
|
||||
} while ( fChange );
|
||||
|
||||
|
||||
/*
|
||||
Extra_PrintBinary( stdout, &uCanonPhase, nVars+1 ); printf( " : " );
|
||||
for ( i = 0; i < nVars; i++ )
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ struct Mfx_Par_t_
|
|||
int fMoreEffort; // performs high-affort minimization
|
||||
int fSwapEdge; // performs edge swapping
|
||||
int fDelay; // performs optimization for delay
|
||||
int fPower; // performs power-aware optimization
|
||||
int fVerbose; // enable basic stats
|
||||
int fVeryVerbose; // enable detailed stats
|
||||
};
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ void Mfx_ParsDefault( Mfx_Par_t * pPars )
|
|||
pPars->fArea = 0;
|
||||
pPars->fMoreEffort = 0;
|
||||
pPars->fSwapEdge = 0;
|
||||
pPars->fPower = 0;
|
||||
pPars->fVerbose = 0;
|
||||
pPars->fVeryVerbose = 0;
|
||||
}
|
||||
|
|
@ -105,7 +106,9 @@ clk = clock();
|
|||
return 1;
|
||||
}
|
||||
// solve the SAT problem
|
||||
if ( p->pPars->fSwapEdge )
|
||||
if ( p->pPars->fPower )
|
||||
Mfx_EdgePower( p, pNode );
|
||||
else if ( p->pPars->fSwapEdge )
|
||||
Mfx_EdgeSwapEval( p, pNode );
|
||||
else
|
||||
{
|
||||
|
|
@ -132,7 +135,7 @@ int Mfx_Node( Mfx_Man_t * p, Nwk_Obj_t * pNode )
|
|||
{
|
||||
Hop_Obj_t * pObj;
|
||||
int RetValue;
|
||||
|
||||
float dProb;
|
||||
int nGain, clk;
|
||||
p->nNodesTried++;
|
||||
// prepare data structure for this node
|
||||
|
|
@ -170,7 +173,8 @@ p->timeSat += clock() - clk;
|
|||
}
|
||||
// minimize the local function of the node using bi-decomposition
|
||||
assert( p->nFanins == Nwk_ObjFaninNum(pNode) );
|
||||
pObj = Nwk_NodeIfNodeResyn( p->pManDec, pNode->pMan->pManHop, pNode->pFunc, p->nFanins, p->vTruth, p->uCare );
|
||||
dProb = p->pPars->fPower? ((float *)p->vProbs->pArray)[pNode->Id] : -1.0;
|
||||
pObj = Nwk_NodeIfNodeResyn( p->pManDec, pNode->pMan->pManHop, pNode->pFunc, p->nFanins, p->vTruth, p->uCare, dProb );
|
||||
nGain = Hop_DagSize(pNode->pFunc) - Hop_DagSize(pObj);
|
||||
if ( nGain >= 0 )
|
||||
{
|
||||
|
|
@ -182,6 +186,45 @@ p->timeSat += clock() - clk;
|
|||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Marks nodes for power-optimization.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Nwk_ManPowerEstimate( Nwk_Man_t * pNtk, int fProbOne )
|
||||
{
|
||||
extern Vec_Int_t * Saig_ManComputeSwitchProbs( Aig_Man_t * p, int nFrames, int nPref, int fProbOne );
|
||||
Vec_Int_t * vProbs;
|
||||
Vec_Int_t * vSwitching;
|
||||
float * pProbability;
|
||||
float * pSwitching;
|
||||
Aig_Man_t * pAig;
|
||||
Aig_Obj_t * pObjAig;
|
||||
Nwk_Obj_t * pObjAbc;
|
||||
int i;
|
||||
// start the resulting array
|
||||
vProbs = Vec_IntStart( Nwk_ManObjNumMax(pNtk) );
|
||||
pProbability = (float *)vProbs->pArray;
|
||||
// map network into an AIG
|
||||
pAig = Nwk_ManStrash( pNtk );
|
||||
vSwitching = Saig_ManComputeSwitchProbs( pAig, 48, 16, fProbOne );
|
||||
pSwitching = (float *)vSwitching->pArray;
|
||||
Nwk_ManForEachObj( pNtk, pObjAbc, i )
|
||||
{
|
||||
if ( (pObjAig = Aig_Regular(pObjAbc->pCopy)) )
|
||||
pProbability[pObjAbc->Id] = pSwitching[pObjAig->Id];
|
||||
}
|
||||
Vec_IntFree( vSwitching );
|
||||
Aig_ManStop( pAig );
|
||||
return vProbs;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
|
@ -253,6 +296,17 @@ int Mfx_Perform( Nwk_Man_t * pNtk, Mfx_Par_t * pPars, If_Lib_t * pLutLib )
|
|||
p->pManDec = Bdc_ManAlloc( pDecPars );
|
||||
}
|
||||
|
||||
// precomputer power-aware metrics
|
||||
if ( pPars->fPower )
|
||||
{
|
||||
extern Vec_Int_t * Nwk_ManPowerEstimate( Nwk_Man_t * pNtk, int fProbOne );
|
||||
if ( pPars->fResub )
|
||||
p->vProbs = Nwk_ManPowerEstimate( pNtk, 0 );
|
||||
else
|
||||
p->vProbs = Nwk_ManPowerEstimate( pNtk, 1 );
|
||||
printf( "Total switching before = %7.2f.\n", Nwl_ManComputeTotalSwitching(pNtk) );
|
||||
}
|
||||
|
||||
// compute don't-cares for each node
|
||||
nNodes = 0;
|
||||
p->nTotalNodesBeg = nTotalNodesBeg;
|
||||
|
|
@ -276,6 +330,7 @@ int Mfx_Perform( Nwk_Man_t * pNtk, Mfx_Par_t * pPars, If_Lib_t * pLutLib )
|
|||
{
|
||||
pProgress = Bar_ProgressStart( stdout, Nwk_ManNodeNum(pNtk) );
|
||||
vLevels = Nwk_ManLevelize( pNtk );
|
||||
|
||||
Vec_VecForEachLevelStart( vLevels, vNodes, k, 1 )
|
||||
{
|
||||
if ( !p->pPars->fVeryVerbose )
|
||||
|
|
@ -303,6 +358,7 @@ int Mfx_Perform( Nwk_Man_t * pNtk, Mfx_Par_t * pPars, If_Lib_t * pLutLib )
|
|||
PRT( "Time", clock() - clk2 );
|
||||
}
|
||||
}
|
||||
|
||||
Bar_ProgressStop( pProgress );
|
||||
Vec_VecFree( vLevels );
|
||||
}
|
||||
|
|
@ -312,6 +368,9 @@ int Mfx_Perform( Nwk_Man_t * pNtk, Mfx_Par_t * pPars, If_Lib_t * pLutLib )
|
|||
assert( Nwk_ManVerifyLevel( pNtk ) );
|
||||
assert( Nwk_ManVerifyTiming( pNtk ) );
|
||||
|
||||
if ( pPars->fPower )
|
||||
printf( "Total switching after = %7.2f.\n", Nwl_ManComputeTotalSwitching(pNtk) );
|
||||
|
||||
// free the manager
|
||||
p->timeTotal = clock() - clk;
|
||||
Mfx_ManStop( p );
|
||||
|
|
|
|||
|
|
@ -81,6 +81,8 @@ struct Mfx_Man_t_
|
|||
Vec_Ptr_t * vFanins; // the new set of fanins
|
||||
int nTotConfLim; // total conflict limit
|
||||
int nTotConfLevel; // total conflicts on this level
|
||||
// switching activity
|
||||
Vec_Int_t * vProbs;
|
||||
// the result of solving
|
||||
int nFanins; // the number of fanins
|
||||
int nWords; // the number of words
|
||||
|
|
@ -136,6 +138,7 @@ extern void Mfx_ManStop( Mfx_Man_t * p );
|
|||
extern void Mfx_ManClean( Mfx_Man_t * p );
|
||||
/*=== mfxResub.c ==========================================================*/
|
||||
extern void Mfx_PrintResubStats( Mfx_Man_t * p );
|
||||
extern int Mfx_EdgePower( Mfx_Man_t * p, Nwk_Obj_t * pNode );
|
||||
extern int Mfx_EdgeSwapEval( Mfx_Man_t * p, Nwk_Obj_t * pNode );
|
||||
extern int Mfx_ResubNode( Mfx_Man_t * p, Nwk_Obj_t * pNode );
|
||||
extern int Mfx_ResubNode2( Mfx_Man_t * p, Nwk_Obj_t * pNode );
|
||||
|
|
|
|||
|
|
@ -168,6 +168,8 @@ void Mfx_ManStop( Mfx_Man_t * p )
|
|||
Aig_ManStop( p->pCare );
|
||||
if ( p->vSuppsInv )
|
||||
Vec_VecFree( (Vec_Vec_t *)p->vSuppsInv );
|
||||
if ( p->vProbs )
|
||||
Vec_IntFree( p->vProbs );
|
||||
Mfx_ManClean( p );
|
||||
Int_ManFree( p->pMan );
|
||||
Vec_IntFree( p->vMem );
|
||||
|
|
|
|||
|
|
@ -206,6 +206,8 @@ p->timeInt += clock() - clk;
|
|||
iVar = -1;
|
||||
while ( 1 )
|
||||
{
|
||||
float * pProbab = (float *)(p->vProbs? p->vProbs->pArray : NULL);
|
||||
assert( (pProbab != NULL) == p->pPars->fPower );
|
||||
if ( fVeryVerbose )
|
||||
{
|
||||
printf( "%3d: %2d ", p->nCexes, iVar );
|
||||
|
|
@ -222,6 +224,13 @@ p->timeInt += clock() - clk;
|
|||
assert( nWords <= p->nDivWords );
|
||||
for ( iVar = 0; iVar < Vec_PtrSize(p->vDivs)-Nwk_ObjFaninNum(pNode); iVar++ )
|
||||
{
|
||||
if ( p->pPars->fPower )
|
||||
{
|
||||
Nwk_Obj_t * pDiv = Vec_PtrEntry(p->vDivs, iVar);
|
||||
// only accept the divisor if it is "cool"
|
||||
if ( pProbab[Nwk_ObjId(pDiv)] >= 0.2 )
|
||||
continue;
|
||||
}
|
||||
pData = Vec_PtrEntry( p->vDivCexes, iVar );
|
||||
for ( w = 0; w < nWords; w++ )
|
||||
if ( pData[w] != ~0 )
|
||||
|
|
@ -429,6 +438,33 @@ int Mfx_EdgeSwapEval( Mfx_Man_t * p, Nwk_Obj_t * pNode )
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Evaluates the possibility of replacing given edge by another edge.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Mfx_EdgePower( Mfx_Man_t * p, Nwk_Obj_t * pNode )
|
||||
{
|
||||
Nwk_Obj_t * pFanin;
|
||||
float * pProbab = (float *)p->vProbs->pArray;
|
||||
int i;
|
||||
// try replacing area critical fanins
|
||||
Nwk_ObjForEachFanin( pNode, pFanin, i )
|
||||
if ( pProbab[pFanin->Id] >= 0.4 )
|
||||
{
|
||||
if ( Mfx_SolveSatResub( p, pNode, i, 0, 0 ) )
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs resubstitution for the node.]
|
||||
|
|
|
|||
|
|
@ -79,6 +79,10 @@ struct Ntl_Man_t_
|
|||
Aig_Man_t * pAig; // the extracted AIG
|
||||
Tim_Man_t * pManTime; // the timing manager
|
||||
int iLastCi; // the last true CI
|
||||
void * pNal; // additional data
|
||||
void (*pNalF)(void *); // additional data
|
||||
void (*pNalD)(void *,void *); // additional data
|
||||
void (*pNalW)(void *,void *); // additional data
|
||||
// hashing names into models
|
||||
Ntl_Mod_t ** pModTable; // the hash table of names into models
|
||||
int nModTableSize; // the allocated table size
|
||||
|
|
@ -93,6 +97,7 @@ struct Ntl_Mod_t_
|
|||
Vec_Ptr_t * vObjs; // the array of all objects
|
||||
Vec_Ptr_t * vPis; // the array of PI objects
|
||||
Vec_Ptr_t * vPos; // the array of PO objects
|
||||
Vec_Ptr_t * vNets; // the array of nets
|
||||
int nObjs[NTL_OBJ_VOID]; // counter of objects of each type
|
||||
// box attributes
|
||||
unsigned int attrWhite :1; // box has known logic
|
||||
|
|
@ -104,6 +109,9 @@ struct Ntl_Mod_t_
|
|||
Ntl_Net_t ** pTable; // the hash table of names into nets
|
||||
int nTableSize; // the allocated table size
|
||||
int nEntries; // the number of entries in the hash table
|
||||
// clocks of the model
|
||||
Vec_Ptr_t * vClocks; // the clock signals
|
||||
Vec_Vec_t * vClockFlops; // the flops of each clock
|
||||
// delay information
|
||||
Vec_Int_t * vDelays;
|
||||
Vec_Int_t * vTimeInputs;
|
||||
|
|
@ -154,6 +162,7 @@ struct Ntl_Net_t_
|
|||
int iTemp; // other data
|
||||
};
|
||||
Ntl_Obj_t * pDriver; // driver of the net
|
||||
int NetId; // unique ID of the net
|
||||
char nVisits; // the number of times the net is visited
|
||||
char fMark; // temporary mark
|
||||
char pName[0]; // the name of this net
|
||||
|
|
@ -175,18 +184,19 @@ struct Ntl_Lut_t_
|
|||
////////////////////////////////////////////////////////////////////////
|
||||
/// INLINED FUNCTIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef WIN32
|
||||
#define DLLEXPORT __declspec(dllexport)
|
||||
#define DLLIMPORT __declspec(dllimport)
|
||||
#define ABC_DLLEXPORT __declspec(dllexport)
|
||||
#define ABC_DLLIMPORT __declspec(dllimport)
|
||||
#else /* defined(WIN32) */
|
||||
#define DLLIMPORT
|
||||
#define ABC_DLLIMPORT
|
||||
#endif /* defined(WIN32) */
|
||||
|
||||
#ifndef ABC_DLL
|
||||
#define ABC_DLL DLLIMPORT
|
||||
#define ABC_DLL ABC_DLLIMPORT
|
||||
#endif
|
||||
|
||||
static inline Ntl_Mod_t * Ntl_ManRootModel( Ntl_Man_t * p ) { return (Ntl_Mod_t *)Vec_PtrEntry( p->vModels, 0 ); }
|
||||
static inline Ntl_Mod_t * Ntl_ManRootModel( Ntl_Man_t * p ) { return (Ntl_Mod_t *)Vec_PtrEntry( p->vModels, 0 ); }
|
||||
|
||||
static inline int Ntl_ModelPiNum( Ntl_Mod_t * p ) { return p->nObjs[NTL_OBJ_PI]; }
|
||||
static inline int Ntl_ModelPoNum( Ntl_Mod_t * p ) { return p->nObjs[NTL_OBJ_PO]; }
|
||||
|
|
@ -195,8 +205,10 @@ static inline int Ntl_ModelLut1Num( Ntl_Mod_t * p ) { return p->nO
|
|||
static inline int Ntl_ModelLatchNum( Ntl_Mod_t * p ) { return p->nObjs[NTL_OBJ_LATCH]; }
|
||||
static inline int Ntl_ModelBoxNum( Ntl_Mod_t * p ) { return p->nObjs[NTL_OBJ_BOX]; }
|
||||
|
||||
static inline Ntl_Obj_t * Ntl_ModelPi( Ntl_Mod_t * p, int i ) { return (Ntl_Obj_t *)Vec_PtrEntry(p->vPis, i); }
|
||||
static inline Ntl_Obj_t * Ntl_ModelPo( Ntl_Mod_t * p, int i ) { return (Ntl_Obj_t *)Vec_PtrEntry(p->vPos, i); }
|
||||
static inline Ntl_Obj_t * Ntl_ModelPi( Ntl_Mod_t * p, int i ) { return (Ntl_Obj_t *)Vec_PtrEntry(p->vPis, i); }
|
||||
static inline Ntl_Obj_t * Ntl_ModelPo( Ntl_Mod_t * p, int i ) { return (Ntl_Obj_t *)Vec_PtrEntry(p->vPos, i); }
|
||||
static inline Ntl_Obj_t * Ntl_ModelObj( Ntl_Mod_t * p, int i ) { return (Ntl_Obj_t *)Vec_PtrEntry(p->vObjs, i); }
|
||||
static inline Ntl_Net_t * Ntl_ModelNet( Ntl_Mod_t * p, int i ) { return (Ntl_Net_t *)Vec_PtrEntry(p->vNets, i); }
|
||||
|
||||
static inline char * Ntl_ModelPiName( Ntl_Mod_t * p, int i ) { return Ntl_ModelPi(p, i)->pFanio[0]->pName; }
|
||||
static inline char * Ntl_ModelPoName( Ntl_Mod_t * p, int i ) { return Ntl_ModelPo(p, i)->pFanio[0]->pName; }
|
||||
|
|
@ -253,8 +265,8 @@ static inline int Ntl_ObjIsSeqRoot( Ntl_Obj_t * p ) { return Ntl_O
|
|||
#define Ntl_ModelForEachPo( pNwk, pObj, i ) \
|
||||
for ( i = 0; (i < Vec_PtrSize(pNwk->vPos)) && (((pObj) = (Ntl_Obj_t*)Vec_PtrEntry(pNwk->vPos, i)), 1); i++ )
|
||||
#define Ntl_ModelForEachNet( pNwk, pNet, i ) \
|
||||
for ( i = 0; i < pNwk->nTableSize; i++ ) \
|
||||
for ( pNet = pNwk->pTable[i]; pNet; pNet = pNet->pNext )
|
||||
Vec_PtrForEachEntry( pNwk->vNets, pNet, i ) \
|
||||
if ( pNet == NULL ) {} else
|
||||
#define Ntl_ModelForEachObj( pNwk, pObj, i ) \
|
||||
for ( i = 0; (i < Vec_PtrSize(pNwk->vObjs)) && (((pObj) = (Ntl_Obj_t*)Vec_PtrEntry(pNwk->vObjs, i)), 1); i++ ) \
|
||||
if ( pObj == NULL ) {} else
|
||||
|
|
@ -359,6 +371,7 @@ extern ABC_DLL int Ntl_ModelFindPioNumber( Ntl_Mod_t * p, int fPiOnl
|
|||
extern ABC_DLL int Ntl_ModelSetNetDriver( Ntl_Obj_t * pObj, Ntl_Net_t * pNet );
|
||||
extern ABC_DLL int Ntl_ModelClearNetDriver( Ntl_Obj_t * pObj, Ntl_Net_t * pNet );
|
||||
extern ABC_DLL void Ntl_ModelDeleteNet( Ntl_Mod_t * p, Ntl_Net_t * pNet );
|
||||
extern ABC_DLL void Ntl_ModelInsertNet( Ntl_Mod_t * p, Ntl_Net_t * pNet );
|
||||
extern ABC_DLL int Ntl_ModelCountNets( Ntl_Mod_t * p );
|
||||
extern ABC_DLL int Ntl_ManAddModel( Ntl_Man_t * p, Ntl_Mod_t * pModel );
|
||||
extern ABC_DLL Ntl_Mod_t * Ntl_ManFindModel( Ntl_Man_t * p, const char * pName );
|
||||
|
|
|
|||
|
|
@ -206,11 +206,13 @@ checkobjs:
|
|||
printf( "Net in bin %d does not have a name\n", i );
|
||||
fStatus = 0;
|
||||
}
|
||||
/*
|
||||
if ( pNet->pDriver == NULL )
|
||||
{
|
||||
printf( "Net %s does not have a driver\n", pNet->pName );
|
||||
fStatus = 0;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// check objects
|
||||
|
|
|
|||
|
|
@ -43,14 +43,14 @@
|
|||
Aig_Man_t * Ntl_ManPerformChoicing( Aig_Man_t * pAig, int fBalance, int fUpdateLevel, int fConstruct, int nConfMax, int nLevelMax, int fVerbose )
|
||||
{
|
||||
extern Aig_Man_t * Dar_ManBalance( Aig_Man_t * pAig, int fUpdateLevel );
|
||||
extern Aig_Man_t * Dar_ManCompress( Aig_Man_t * pAig, int fBalance, int fUpdateLevel, int fVerbose );
|
||||
extern Aig_Man_t * Dar_ManCompress( Aig_Man_t * pAig, int fBalance, int fUpdateLevel, int fPower, int fVerbose );
|
||||
extern Aig_Man_t * Dar_ManChoice( Aig_Man_t * pAig, int fBalance, int fUpdateLevel, int fConstruct, int nConfMax, int nLevelMax, int fVerbose );
|
||||
Aig_Man_t * pTemp;
|
||||
// perform synthesis
|
||||
//printf( "Pre-synthesis AIG: " );
|
||||
//Aig_ManPrintStats( pAig );
|
||||
// pTemp = Dar_ManBalance( pAig, 1 );
|
||||
// pTemp = Dar_ManCompress( pAig, 1, 1, 0 );
|
||||
// pTemp = Dar_ManCompress( pAig, 1, 1, 0, 0 );
|
||||
pTemp = Dar_ManChoice( pAig, fBalance, fUpdateLevel, fConstruct, nConfMax, nLevelMax, fVerbose );
|
||||
//printf( "Post-synthesis AIG: " );
|
||||
//Aig_ManPrintStats( pTemp );
|
||||
|
|
|
|||
|
|
@ -175,7 +175,7 @@ int Ntl_ManExtract_rec( Ntl_Man_t * p, Ntl_Net_t * pNet )
|
|||
if ( !Ntl_ManExtract_rec( p, pNetFanin ) )
|
||||
return 0;
|
||||
// add box inputs/outputs to COs/CIs
|
||||
if ( Ntl_ObjIsBox(pObj) )
|
||||
if ( Ntl_ObjIsBox(pObj) )
|
||||
{
|
||||
int LevelCur, LevelMax = -TIM_ETERNITY;
|
||||
assert( Ntl_BoxIsComb(pObj) );
|
||||
|
|
@ -370,7 +370,7 @@ int Ntl_ManCollapseBoxSeq1_rec( Ntl_Man_t * p, Ntl_Obj_t * pBox, int fSeq )
|
|||
pNet->pCopy = Aig_Not(pNet->pCopy);
|
||||
pNet->nVisits = 2;
|
||||
// remember the class of this register
|
||||
Vec_IntPush( p->vRegClasses, pObj->LatchId.regClass );
|
||||
Vec_IntPush( p->vRegClasses, p->pNal ? pBox->iTemp : pObj->LatchId.regClass );
|
||||
}
|
||||
// compute AIG for the internal nodes
|
||||
Ntl_ModelForEachPo( pModel, pObj, i )
|
||||
|
|
|
|||
|
|
@ -215,9 +215,9 @@ Aig_Obj_t ** Ntl_ManFraigDeriveClasses( Aig_Man_t * pAig, Ntl_Man_t * pNew, Aig_
|
|||
void Ntl_ManReduce( Ntl_Man_t * p, Aig_Man_t * pAig )
|
||||
{
|
||||
Aig_Obj_t * pObj, * pObjRepr;
|
||||
Ntl_Net_t * pNet, * pNetRepr;
|
||||
Ntl_Net_t * pNet, * pNetRepr, * pNetNew;
|
||||
Ntl_Mod_t * pRoot;
|
||||
Ntl_Obj_t * pNode;
|
||||
Ntl_Obj_t * pNode, * pNodeOld;
|
||||
int i, fCompl, Counter = 0;
|
||||
assert( pAig->pReprs );
|
||||
pRoot = Ntl_ManRootModel( p );
|
||||
|
|
@ -271,10 +271,23 @@ void Ntl_ManReduce( Ntl_Man_t * p, Aig_Man_t * pAig )
|
|||
pNode->pSop = fCompl? Ntl_ManStoreSop( p->pMemSops, "0 1\n" ) : Ntl_ManStoreSop( p->pMemSops, "1 1\n" );
|
||||
Ntl_ObjSetFanin( pNode, pNetRepr, 0 );
|
||||
// make the new node drive the equivalent net (pNet)
|
||||
pNodeOld = pNet->pDriver;
|
||||
if ( !Ntl_ModelClearNetDriver( pNet->pDriver, pNet ) )
|
||||
printf( "Ntl_ManReduce(): Internal error! Net already has no driver.\n" );
|
||||
if ( !Ntl_ModelSetNetDriver( pNode, pNet ) )
|
||||
printf( "Ntl_ManReduce(): Internal error! Net already has a driver.\n" );
|
||||
|
||||
// remove this net from the hash table (but do not remove from the array)
|
||||
Ntl_ModelDeleteNet( pRoot, pNet );
|
||||
// create new net with the same name
|
||||
pNetNew = Ntl_ModelFindOrCreateNet( pRoot, pNet->pName );
|
||||
// clean the name
|
||||
pNet->pName[0] = 0;
|
||||
|
||||
// make the old node drive the new net without fanouts
|
||||
if ( !Ntl_ModelSetNetDriver( pNodeOld, pNetNew ) )
|
||||
printf( "Ntl_ManReduce(): Internal error! Net already has a driver.\n" );
|
||||
|
||||
Counter++;
|
||||
}
|
||||
}
|
||||
|
|
@ -372,6 +385,11 @@ Ntl_Man_t * Ntl_ManFraig( Ntl_Man_t * p, int nPartSize, int nConfLimit, int nLev
|
|||
pAig = Ntl_ManExtract( p );
|
||||
pNew = Ntl_ManInsertAig( p, pAig );
|
||||
pAigCol = Ntl_ManCollapseComb( pNew );
|
||||
if ( pAigCol == NULL )
|
||||
{
|
||||
Aig_ManStop( pAig );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
// perform fraiging for the given design
|
||||
nPartSize = nPartSize? nPartSize : Aig_ManPoNum(pAigCol);
|
||||
|
|
@ -406,13 +424,15 @@ Ntl_Man_t * Ntl_ManScl( Ntl_Man_t * p, int fLatchConst, int fLatchEqual, int fVe
|
|||
pAig = Ntl_ManExtract( p );
|
||||
pNew = Ntl_ManInsertAig( p, pAig );
|
||||
pAigCol = Ntl_ManCollapseSeq( pNew, 0 );
|
||||
//Saig_ManDumpBlif( pAigCol, "1s.blif" );
|
||||
if ( pAigCol == NULL )
|
||||
{
|
||||
Aig_ManStop( pAig );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
// perform SCL for the given design
|
||||
pTemp = Aig_ManScl( pAigCol, fLatchConst, fLatchEqual, fVerbose );
|
||||
Aig_ManStop( pTemp );
|
||||
if ( pNew->vRegClasses && Vec_IntSize(pNew->vRegClasses) && pAigCol->pReprs )
|
||||
Ntl_ManFilterRegisterClasses( pAigCol, pNew->vRegClasses, fVerbose );
|
||||
|
||||
// finalize the transformation
|
||||
pNew = Ntl_ManFinalize( pAux = pNew, pAig, pAigCol, fVerbose );
|
||||
|
|
@ -435,25 +455,26 @@ Ntl_Man_t * Ntl_ManScl( Ntl_Man_t * p, int fLatchConst, int fLatchEqual, int fVe
|
|||
***********************************************************************/
|
||||
Ntl_Man_t * Ntl_ManLcorr( Ntl_Man_t * p, int nConfMax, int fVerbose )
|
||||
{
|
||||
Ssw_Pars_t Pars, * pPars = &Pars;
|
||||
Ntl_Man_t * pNew, * pAux;
|
||||
Aig_Man_t * pAig, * pAigCol, * pTemp;
|
||||
Ssw_Pars_t Pars, * pPars = &Pars;
|
||||
Ssw_ManSetDefaultParamsLcorr( pPars );
|
||||
pPars->nBTLimit = nConfMax;
|
||||
pPars->fVerbose = fVerbose;
|
||||
|
||||
// collapse the AIG
|
||||
pAig = Ntl_ManExtract( p );
|
||||
pNew = Ntl_ManInsertAig( p, pAig );
|
||||
pAigCol = Ntl_ManCollapseSeq( pNew, 0 );
|
||||
pAigCol = Ntl_ManCollapseSeq( pNew, pPars->nMinDomSize );
|
||||
if ( pAigCol == NULL )
|
||||
{
|
||||
Aig_ManStop( pAig );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
// perform SCL for the given design
|
||||
// pTemp = Fra_FraigLatchCorrespondence( pAigCol, 0, nConfMax, 0, fVerbose, NULL, 0 );
|
||||
Ssw_ManSetDefaultParamsLcorr( pPars );
|
||||
pPars->nBTLimit = nConfMax;
|
||||
pPars->fVerbose = fVerbose;
|
||||
// perform LCORR for the given design
|
||||
pTemp = Ssw_LatchCorrespondence( pAigCol, pPars );
|
||||
|
||||
Aig_ManStop( pTemp );
|
||||
if ( p->vRegClasses && Vec_IntSize(p->vRegClasses) && pAigCol->pReprs )
|
||||
Ntl_ManFilterRegisterClasses( pAigCol, p->vRegClasses, fVerbose );
|
||||
|
||||
// finalize the transformation
|
||||
pNew = Ntl_ManFinalize( pAux = pNew, pAig, pAigCol, fVerbose );
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@
|
|||
***********************************************************************/
|
||||
Ntl_Man_t * Ntl_ManInsertMapping( Ntl_Man_t * p, Vec_Ptr_t * vMapping, Aig_Man_t * pAig )
|
||||
{
|
||||
char Buffer[100];
|
||||
char Buffer[1000];
|
||||
Vec_Ptr_t * vCopies;
|
||||
Vec_Int_t * vCover;
|
||||
Ntl_Mod_t * pRoot;
|
||||
|
|
@ -141,7 +141,7 @@ Ntl_Man_t * Ntl_ManInsertMapping( Ntl_Man_t * p, Vec_Ptr_t * vMapping, Aig_Man_t
|
|||
***********************************************************************/
|
||||
Ntl_Man_t * Ntl_ManInsertAig( Ntl_Man_t * p, Aig_Man_t * pAig )
|
||||
{
|
||||
char Buffer[100];
|
||||
char Buffer[1000];
|
||||
Ntl_Mod_t * pRoot;
|
||||
Ntl_Obj_t * pNode;
|
||||
Ntl_Net_t * pNet, * pNetCo;
|
||||
|
|
@ -243,7 +243,6 @@ Ntl_Man_t * Ntl_ManInsertAig( Ntl_Man_t * p, Aig_Man_t * pAig )
|
|||
return p;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Inserts the given mapping into the netlist.]
|
||||
|
|
@ -257,7 +256,7 @@ Ntl_Man_t * Ntl_ManInsertAig( Ntl_Man_t * p, Aig_Man_t * pAig )
|
|||
***********************************************************************/
|
||||
Ntl_Man_t * Ntl_ManInsertNtk( Ntl_Man_t * p, Nwk_Man_t * pNtk )
|
||||
{
|
||||
char Buffer[100];
|
||||
char Buffer[1000];
|
||||
Vec_Ptr_t * vObjs;
|
||||
Vec_Int_t * vTruth;
|
||||
Vec_Int_t * vCover;
|
||||
|
|
@ -276,8 +275,8 @@ Ntl_Man_t * Ntl_ManInsertNtk( Ntl_Man_t * p, Nwk_Man_t * pNtk )
|
|||
Ntl_ManForEachCiNet( p, pNet, i )
|
||||
Nwk_ManCi( pNtk, i )->pCopy = pNet;
|
||||
// create a new node for each LUT
|
||||
vTruth = Vec_IntAlloc( 1 << 16 );
|
||||
vCover = Vec_IntAlloc( 1 << 16 );
|
||||
vTruth = Vec_IntAlloc( 1 << 16 );
|
||||
vCover = Vec_IntAlloc( 1 << 16 );
|
||||
nDigits = Aig_Base10Log( Nwk_ManNodeNum(pNtk) );
|
||||
// go through the nodes in the topological order
|
||||
vObjs = Nwk_ManDfs( pNtk );
|
||||
|
|
@ -289,7 +288,6 @@ Ntl_Man_t * Ntl_ManInsertNtk( Ntl_Man_t * p, Nwk_Man_t * pNtk )
|
|||
pTruth = Hop_ManConvertAigToTruth( pNtk->pManHop, Hop_Regular(pObj->pFunc), Nwk_ObjFaninNum(pObj), vTruth, 0 );
|
||||
if ( Hop_IsComplement(pObj->pFunc) )
|
||||
Kit_TruthNot( pTruth, pTruth, Nwk_ObjFaninNum(pObj) );
|
||||
pNode->pSop = Kit_PlaFromTruth( p->pMemSops, pTruth, Nwk_ObjFaninNum(pObj), vCover );
|
||||
if ( !Kit_TruthIsConst0(pTruth, Nwk_ObjFaninNum(pObj)) && !Kit_TruthIsConst1(pTruth, Nwk_ObjFaninNum(pObj)) )
|
||||
{
|
||||
Nwk_ObjForEachFanin( pObj, pFanin, k )
|
||||
|
|
@ -303,8 +301,17 @@ Ntl_Man_t * Ntl_ManInsertNtk( Ntl_Man_t * p, Nwk_Man_t * pNtk )
|
|||
Ntl_ObjSetFanin( pNode, pNet, k );
|
||||
}
|
||||
}
|
||||
else
|
||||
else if ( Kit_TruthIsConst0(pTruth, Nwk_ObjFaninNum(pObj)) )
|
||||
{
|
||||
pObj->pFunc = Hop_ManConst0(pNtk->pManHop);
|
||||
pNode->nFanins = 0;
|
||||
}
|
||||
else if ( Kit_TruthIsConst1(pTruth, Nwk_ObjFaninNum(pObj)) )
|
||||
{
|
||||
pObj->pFunc = Hop_ManConst1(pNtk->pManHop);
|
||||
pNode->nFanins = 0;
|
||||
}
|
||||
pNode->pSop = Kit_PlaFromTruth( p->pMemSops, pTruth, Nwk_ObjFaninNum(pObj), vCover );
|
||||
sprintf( Buffer, "lut%0*d", nDigits, i );
|
||||
if ( (pNet = Ntl_ModelFindNet( pRoot, Buffer )) )
|
||||
{
|
||||
|
|
@ -334,11 +341,29 @@ Ntl_Man_t * Ntl_ManInsertNtk( Ntl_Man_t * p, Nwk_Man_t * pNtk )
|
|||
// get the corresponding PO and its driver
|
||||
pObj = Nwk_ManCo( pNtk, i );
|
||||
pFanin = Nwk_ObjFanin0( pObj );
|
||||
// get the net driving the driver
|
||||
pNet = pFanin->pCopy;
|
||||
pNode = Ntl_ModelCreateNode( pRoot, 1 );
|
||||
pNode->pSop = pObj->fInvert? Ntl_ManStoreSop( p->pMemSops, "0 1\n" ) : Ntl_ManStoreSop( p->pMemSops, "1 1\n" );
|
||||
Ntl_ObjSetFanin( pNode, pNet, 0 );
|
||||
// get the net driving this PO
|
||||
pNet = pFanin->pCopy;
|
||||
if ( Nwk_ObjFanoutNum(pFanin) == 1 && Ntl_ObjIsNode(pNet->pDriver) )
|
||||
{
|
||||
pNode = pNet->pDriver;
|
||||
if ( !Ntl_ModelClearNetDriver( pNode, pNet ) )
|
||||
{
|
||||
printf( "Ntl_ManInsertNtk(): Internal error! Net already has no driver.\n" );
|
||||
return NULL;
|
||||
}
|
||||
// remove this net
|
||||
Ntl_ModelDeleteNet( pRoot, pNet );
|
||||
Vec_PtrWriteEntry( pRoot->vNets, pNet->NetId, NULL );
|
||||
// update node's function
|
||||
if ( pObj->fInvert )
|
||||
Kit_PlaComplement( pNode->pSop );
|
||||
}
|
||||
else
|
||||
{
|
||||
pNode = Ntl_ModelCreateNode( pRoot, 1 );
|
||||
pNode->pSop = pObj->fInvert? Ntl_ManStoreSop( p->pMemSops, "0 1\n" ) : Ntl_ManStoreSop( p->pMemSops, "1 1\n" );
|
||||
Ntl_ObjSetFanin( pNode, pNet, 0 );
|
||||
}
|
||||
// update the CO driver net
|
||||
assert( pNetCo->pDriver == NULL );
|
||||
if ( !Ntl_ModelSetNetDriver( pNode, pNetCo ) )
|
||||
|
|
|
|||
|
|
@ -108,6 +108,7 @@ Ntl_Man_t * Ntl_ManStartFrom( Ntl_Man_t * pOld )
|
|||
pNew->pName = Ntl_ManStoreFileName( pNew, pOld->pName );
|
||||
pNew->pSpec = Ntl_ManStoreName( pNew, pOld->pName );
|
||||
Vec_PtrForEachEntry( pOld->vModels, pModel, i )
|
||||
{
|
||||
if ( i == 0 )
|
||||
{
|
||||
Ntl_ManMarkCiCoNets( pOld );
|
||||
|
|
@ -116,15 +117,21 @@ Ntl_Man_t * Ntl_ManStartFrom( Ntl_Man_t * pOld )
|
|||
}
|
||||
else
|
||||
pModel->pCopy = Ntl_ModelDup( pNew, pModel );
|
||||
}
|
||||
Vec_PtrForEachEntry( pOld->vModels, pModel, i )
|
||||
Ntl_ModelForEachBox( pModel, pBox, k )
|
||||
{
|
||||
((Ntl_Obj_t *)pBox->pCopy)->pImplem = pBox->pImplem->pCopy;
|
||||
((Ntl_Obj_t *)pBox->pCopy)->iTemp = pBox->iTemp;
|
||||
}
|
||||
Ntl_ManForEachCiNet( pOld, pNet, i )
|
||||
Vec_PtrPush( pNew->vCis, pNet->pCopy );
|
||||
Ntl_ManForEachCoNet( pOld, pNet, i )
|
||||
Vec_PtrPush( pNew->vCos, pNet->pCopy );
|
||||
if ( pOld->pManTime )
|
||||
pNew->pManTime = Tim_ManDup( pOld->pManTime, 0 );
|
||||
if ( pOld->pNal )
|
||||
pOld->pNalD( pOld, pNew );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
|
|
@ -195,13 +202,14 @@ void Ntl_ManFree( Ntl_Man_t * p )
|
|||
if ( p->pMemSops ) Aig_MmFlexStop( p->pMemSops, 0 );
|
||||
if ( p->pAig ) Aig_ManStop( p->pAig );
|
||||
if ( p->pManTime ) Tim_ManStop( p->pManTime );
|
||||
if ( p->pNal ) p->pNalF( p->pNal );
|
||||
FREE( p->pModTable );
|
||||
free( p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Deallocates the netlist manager.]
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
|
|
@ -219,6 +227,7 @@ void Ntl_ManPrintStats( Ntl_Man_t * p )
|
|||
printf( "po = %5d ", Ntl_ModelPoNum(pRoot) );
|
||||
printf( "lat = %5d ", Ntl_ModelLatchNum(pRoot) );
|
||||
printf( "node = %5d ", Ntl_ModelNodeNum(pRoot) );
|
||||
printf( "\n " );
|
||||
printf( "inv/buf = %5d ", Ntl_ModelLut1Num(pRoot) );
|
||||
printf( "box = %4d ", Ntl_ModelBoxNum(pRoot) );
|
||||
printf( "mod = %3d ", Vec_PtrSize(p->vModels) );
|
||||
|
|
@ -230,6 +239,50 @@ void Ntl_ManPrintStats( Ntl_Man_t * p )
|
|||
fflush( stdout );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Nwk_ManPrintStatsShort( Ntl_Man_t * p, Aig_Man_t * pAig, Nwk_Man_t * pNtk )
|
||||
{
|
||||
Ntl_Mod_t * pRoot;
|
||||
Ntl_Obj_t * pObj;
|
||||
int i, Counter = 0;
|
||||
pRoot = Ntl_ManRootModel( p );
|
||||
Ntl_ModelForEachBox( pRoot, pObj, i )
|
||||
if ( strcmp(pObj->pImplem->pName, "dff") == 0 )
|
||||
Counter++;
|
||||
printf( "%-15s : ", p->pName );
|
||||
printf( "pi =%5d ", Ntl_ModelPiNum(pRoot) );
|
||||
printf( "po =%5d ", Ntl_ModelPoNum(pRoot) );
|
||||
printf( "ff =%5d ", Counter );
|
||||
if ( pAig != NULL )
|
||||
{
|
||||
Counter = Aig_ManCountChoices( pAig );
|
||||
if ( Counter )
|
||||
printf( "cho =%7d ", Counter );
|
||||
else
|
||||
printf( "aig =%7d ", Aig_ManNodeNum(pAig) );
|
||||
}
|
||||
if ( pNtk == NULL )
|
||||
printf( "Mapping is not available.\n" );
|
||||
else
|
||||
{
|
||||
printf( "lut =%5d ", Nwk_ManNodeNum(pNtk) );
|
||||
printf( "lev =%3d ", Nwk_ManLevel(pNtk) );
|
||||
// printf( "del =%5.2f ", Nwk_ManDelayTraceLut(pNtk) );
|
||||
printf( "\n" );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Deallocates the netlist manager.]
|
||||
|
|
@ -283,6 +336,8 @@ void Ntl_ManSaveBoxType( Ntl_Obj_t * pObj )
|
|||
***********************************************************************/
|
||||
void Ntl_ManPrintTypes( Ntl_Man_t * p )
|
||||
{
|
||||
Vec_Ptr_t * vFlops;
|
||||
Ntl_Net_t * pNet;
|
||||
Ntl_Mod_t * pModel;
|
||||
Ntl_Obj_t * pObj;
|
||||
int i;
|
||||
|
|
@ -296,7 +351,7 @@ void Ntl_ManPrintTypes( Ntl_Man_t * p )
|
|||
{
|
||||
if ( !p->BoxTypes[i] )
|
||||
continue;
|
||||
printf( "%5d :", p->BoxTypes[i] );
|
||||
printf( "Type %2d Num = %7d :", i, p->BoxTypes[i] );
|
||||
printf( " %s", ((i & 1) > 0)? "white ": "black " );
|
||||
printf( " %s", ((i & 2) > 0)? "box ": "logic " );
|
||||
printf( " %s", ((i & 4) > 0)? "comb ": "seq " );
|
||||
|
|
@ -304,9 +359,22 @@ void Ntl_ManPrintTypes( Ntl_Man_t * p )
|
|||
printf( " %s", ((i & 16) > 0)? "no_merge": "merge " );
|
||||
printf( "\n" );
|
||||
}
|
||||
printf( "Total box instances = %6d.\n\n", Ntl_ModelBoxNum(pModel) );
|
||||
printf( "MODEL STATISTICS:\n" );
|
||||
Ntl_ManForEachModel( p, pModel, i )
|
||||
if ( i ) printf( "Model %2d : Name = %10s Used = %6d.\n", i, pModel->pName, pModel->nUsed );
|
||||
for ( i = 0; i < 32; i++ )
|
||||
p->BoxTypes[i] = 0;
|
||||
pModel = Ntl_ManRootModel( p );
|
||||
if ( pModel->vClockFlops )
|
||||
{
|
||||
printf( "CLOCK STATISTICS:\n" );
|
||||
Vec_VecForEachLevel( pModel->vClockFlops, vFlops, i )
|
||||
{
|
||||
pNet = Vec_PtrEntry( pModel->vClocks, i );
|
||||
printf( "Clock %2d : Name = %30s Flops = %6d.\n", i+1, pNet->pName, Vec_PtrSize(vFlops) );
|
||||
}
|
||||
}
|
||||
printf( "\n" );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
@ -336,6 +404,7 @@ Ntl_Mod_t * Ntl_ModelAlloc( Ntl_Man_t * pMan, char * pName )
|
|||
p->vObjs = Vec_PtrAlloc( 100 );
|
||||
p->vPis = Vec_PtrAlloc( 10 );
|
||||
p->vPos = Vec_PtrAlloc( 10 );
|
||||
p->vNets = Vec_PtrAlloc( 100 );
|
||||
// start the table
|
||||
p->nTableSize = Aig_PrimeCudd( 100 );
|
||||
p->pTable = ALLOC( Ntl_Net_t *, p->nTableSize );
|
||||
|
|
@ -382,7 +451,9 @@ Ntl_Mod_t * Ntl_ModelStartFrom( Ntl_Man_t * pManNew, Ntl_Mod_t * pModelOld )
|
|||
}
|
||||
Ntl_ModelForEachNet( pModelOld, pNet, i )
|
||||
{
|
||||
if ( pNet->fMark )
|
||||
if ( pNet->pDriver == NULL )
|
||||
pNet->pCopy = Ntl_ModelFindOrCreateNet( pModelNew, pNet->pName );
|
||||
else if ( pNet->fMark )
|
||||
{
|
||||
pNet->pCopy = Ntl_ModelFindOrCreateNet( pModelNew, pNet->pName );
|
||||
((Ntl_Net_t *)pNet->pCopy)->pDriver = pNet->pDriver->pCopy;
|
||||
|
|
@ -485,6 +556,9 @@ void Ntl_ModelFree( Ntl_Mod_t * p )
|
|||
if ( p->vTimeOutputs ) Vec_IntFree( p->vTimeOutputs );
|
||||
if ( p->vTimeInputs ) Vec_IntFree( p->vTimeInputs );
|
||||
if ( p->vDelays ) Vec_IntFree( p->vDelays );
|
||||
if ( p->vClocks ) Vec_PtrFree( p->vClocks );
|
||||
if ( p->vClockFlops ) Vec_VecFree( p->vClockFlops );
|
||||
Vec_PtrFree( p->vNets );
|
||||
Vec_PtrFree( p->vObjs );
|
||||
Vec_PtrFree( p->vPis );
|
||||
Vec_PtrFree( p->vPos );
|
||||
|
|
|
|||
|
|
@ -1322,6 +1322,7 @@ static char * Ioa_ReadParseTableBlif( Ioa_ReadMod_t * p, char * pTable, int nFan
|
|||
char * pProduct, * pOutput;
|
||||
int i, Polarity = -1;
|
||||
|
||||
|
||||
p->pMan->nTablesRead++;
|
||||
// get the tokens
|
||||
Ioa_ReadSplitIntoTokens( vTokens, pTable, '.' );
|
||||
|
|
@ -1330,6 +1331,8 @@ static char * Ioa_ReadParseTableBlif( Ioa_ReadMod_t * p, char * pTable, int nFan
|
|||
if ( Vec_PtrSize(vTokens) == 1 )
|
||||
{
|
||||
pOutput = Vec_PtrEntry( vTokens, 0 );
|
||||
if ( *pOutput == '\"' )
|
||||
return Ntl_ManStoreSop( p->pMan->pDesign->pMemSops, pOutput );
|
||||
if ( ((pOutput[0] - '0') & 0x8E) || pOutput[1] )
|
||||
{
|
||||
sprintf( p->pMan->sError, "Line %d: Constant table has wrong output value \"%s\".", Ioa_ReadGetLine(p->pMan, pOutput), pOutput );
|
||||
|
|
|
|||
|
|
@ -139,8 +139,11 @@ int Ntl_ManSweep( Ntl_Man_t * p, int fVerbose )
|
|||
}
|
||||
// remove the fanout nets
|
||||
Ntl_ObjForEachFanout( pObj, pNet, k )
|
||||
if ( pNet != NULL )
|
||||
if ( pNet != NULL && pNet->pName[0] != 0 )
|
||||
{
|
||||
Ntl_ModelDeleteNet( pRoot, pNet );
|
||||
Vec_PtrWriteEntry( pRoot->vNets, pNet->NetId, NULL );
|
||||
}
|
||||
// remove the object
|
||||
if ( Ntl_ObjIsNode(pObj) && Ntl_ObjFaninNum(pObj) == 1 )
|
||||
pRoot->nObjs[NTL_OBJ_LUT1]--;
|
||||
|
|
@ -150,7 +153,7 @@ int Ntl_ManSweep( Ntl_Man_t * p, int fVerbose )
|
|||
pObj->Type = NTL_OBJ_NONE;
|
||||
Counter++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// print detailed statistics of sweeping
|
||||
|
|
@ -191,7 +194,7 @@ int Ntl_ManSweep( Ntl_Man_t * p, int fVerbose )
|
|||
}
|
||||
}
|
||||
}
|
||||
printf("\nLUTboxType =%d\n", numLutBox);
|
||||
// printf("\nLUTboxType =%d\n", numLutBox);
|
||||
}
|
||||
}
|
||||
if ( !Ntl_ManCheck( p ) )
|
||||
|
|
|
|||
|
|
@ -58,6 +58,8 @@ Ntl_Net_t * Ntl_ModelCreateNet( Ntl_Mod_t * p, const char * pName )
|
|||
pNet = (Ntl_Net_t *)Aig_MmFlexEntryFetch( p->pMan->pMemObjs, sizeof(Ntl_Net_t) + strlen(pName) + 1 );
|
||||
memset( pNet, 0, sizeof(Ntl_Net_t) );
|
||||
strcpy( pNet->pName, pName );
|
||||
pNet->NetId = Vec_PtrSize( p->vNets );
|
||||
Vec_PtrPush( p->vNets, pNet );
|
||||
return pNet;
|
||||
}
|
||||
|
||||
|
|
@ -104,7 +106,7 @@ clk = clock();
|
|||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Finds or creates the net.]
|
||||
Synopsis [Finds net.]
|
||||
|
||||
Description []
|
||||
|
||||
|
|
@ -125,7 +127,7 @@ Ntl_Net_t * Ntl_ModelFindNet( Ntl_Mod_t * p, const char * pName )
|
|||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Finds or creates the net.]
|
||||
Synopsis [Deletes net from the hash table.]
|
||||
|
||||
Description []
|
||||
|
||||
|
|
@ -150,6 +152,26 @@ void Ntl_ModelDeleteNet( Ntl_Mod_t * p, Ntl_Net_t * pNet )
|
|||
p->pTable[Key] = pEnt->pNext;
|
||||
else
|
||||
pPrev->pNext = pEnt->pNext;
|
||||
p->nEntries--;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Inserts net into the hash table.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ntl_ModelInsertNet( Ntl_Mod_t * p, Ntl_Net_t * pNet )
|
||||
{
|
||||
unsigned Key = Ntl_HashString( pNet->pName, p->nTableSize );
|
||||
assert( Ntl_ModelFindNet( p, pNet->pName ) == NULL );
|
||||
pNet->pNext = p->pTable[Key];
|
||||
p->pTable[Key] = pNet;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
@ -178,6 +200,17 @@ Ntl_Net_t * Ntl_ModelFindOrCreateNet( Ntl_Mod_t * p, const char * pName )
|
|||
return pEnt;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates new net.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ntl_Net_t * Ntl_ModelDontFindCreateNet( Ntl_Mod_t * p, const char * pName )
|
||||
{
|
||||
Ntl_Net_t * pEnt;
|
||||
|
|
|
|||
|
|
@ -424,7 +424,7 @@ Vec_Vec_t * Ntl_ManTransformRegClasses( Ntl_Man_t * pMan, int nSizeMax, int fVer
|
|||
vParts = Vec_PtrAlloc( 100 );
|
||||
for ( i = 0; i <= ClassMax; i++ )
|
||||
{
|
||||
if ( pClassNums[i] < nSizeMax )
|
||||
if ( pClassNums[i] == 0 || pClassNums[i] < nSizeMax )
|
||||
continue;
|
||||
vPart = Vec_IntAlloc( pClassNums[i] );
|
||||
Vec_IntForEachEntry( pMan->vRegClasses, Class, k )
|
||||
|
|
|
|||
|
|
@ -140,6 +140,8 @@ void Ioa_WriteBlifModel( FILE * pFile, Ntl_Mod_t * pModel, int fMain )
|
|||
fprintf( pFile, " %s", pNet->pName );
|
||||
fprintf( pFile, " %s\n", Ntl_ObjFanout0(pObj)->pName );
|
||||
fprintf( pFile, "%s", pObj->pSop );
|
||||
if ( *pObj->pSop == '\"' )
|
||||
fprintf( pFile, "\n" );
|
||||
}
|
||||
else if ( Ntl_ObjIsLatch(pObj) )
|
||||
{
|
||||
|
|
@ -390,6 +392,8 @@ void Ioa_WriteBlifModelGz( gzFile pFile, Ntl_Mod_t * pModel, int fMain )
|
|||
gzprintf( pFile, " %s", pNet->pName );
|
||||
gzprintf( pFile, " %s\n", Ntl_ObjFanout0(pObj)->pName );
|
||||
gzprintf( pFile, "%s", pObj->pSop );
|
||||
if ( *pObj->pSop == '\"' )
|
||||
gzprintf( pFile, "\n" );
|
||||
}
|
||||
else if ( Ntl_ObjIsLatch(pObj) )
|
||||
{
|
||||
|
|
@ -567,6 +571,8 @@ void Ioa_WriteBlifModelBz2( bz2file * b, Ntl_Mod_t * pModel, int fMain )
|
|||
fprintfBz2( b, " %s", pNet->pName );
|
||||
fprintfBz2( b, " %s\n", Ntl_ObjFanout0(pObj)->pName );
|
||||
fprintfBz2( b, "%s", pObj->pSop );
|
||||
if ( *pObj->pSop == '\"' )
|
||||
fprintfBz2( b, "\n" );
|
||||
}
|
||||
else if ( Ntl_ObjIsLatch(pObj) )
|
||||
{
|
||||
|
|
@ -625,7 +631,11 @@ void Ioa_WriteBlif( Ntl_Man_t * p, char * pFileName )
|
|||
Ntl_Mod_t * pModel;
|
||||
int i, bzError;
|
||||
bz2file b;
|
||||
|
||||
if ( p->pNal )
|
||||
{
|
||||
p->pNalW( p, pFileName );
|
||||
return;
|
||||
}
|
||||
// write the GZ file
|
||||
if (!strncmp(pFileName+strlen(pFileName)-3,".gz",3))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -123,14 +123,14 @@ struct Nwk_Obj_t_
|
|||
//#pragma warning( disable : 4273 )
|
||||
|
||||
#ifdef WIN32
|
||||
#define DLLEXPORT __declspec(dllexport)
|
||||
#define DLLIMPORT __declspec(dllimport)
|
||||
#define ABC_DLLEXPORT __declspec(dllexport)
|
||||
#define ABC_DLLIMPORT __declspec(dllimport)
|
||||
#else /* defined(WIN32) */
|
||||
#define DLLIMPORT
|
||||
#define ABC_DLLIMPORT
|
||||
#endif /* defined(WIN32) */
|
||||
|
||||
#ifndef ABC_DLL
|
||||
#define ABC_DLL DLLIMPORT
|
||||
#define ABC_DLL ABC_DLLIMPORT
|
||||
#endif
|
||||
|
||||
static inline int Nwk_ManCiNum( Nwk_Man_t * p ) { return p->nObjs[NWK_OBJ_CI]; }
|
||||
|
|
@ -234,7 +234,7 @@ static inline int Nwk_ManTimeMore( float f1, float f2, float Eps ) { r
|
|||
extern ABC_DLL Vec_Ptr_t * Nwk_ManDeriveRetimingCut( Aig_Man_t * p, int fForward, int fVerbose );
|
||||
/*=== nwkBidec.c ==========================================================*/
|
||||
extern ABC_DLL void Nwk_ManBidecResyn( Nwk_Man_t * pNtk, int fVerbose );
|
||||
extern ABC_DLL Hop_Obj_t * Nwk_NodeIfNodeResyn( Bdc_Man_t * p, Hop_Man_t * pHop, Hop_Obj_t * pRoot, int nVars, Vec_Int_t * vTruth, unsigned * puCare );
|
||||
extern ABC_DLL Hop_Obj_t * Nwk_NodeIfNodeResyn( Bdc_Man_t * p, Hop_Man_t * pHop, Hop_Obj_t * pRoot, int nVars, Vec_Int_t * vTruth, unsigned * puCare, float dProb );
|
||||
/*=== nwkCheck.c ==========================================================*/
|
||||
extern ABC_DLL int Nwk_ManCheck( Nwk_Man_t * p );
|
||||
/*=== nwkDfs.c ==========================================================*/
|
||||
|
|
@ -265,7 +265,8 @@ extern ABC_DLL Vec_Ptr_t * Nwk_ManRetimeCutBackward( Nwk_Man_t * pMan, int n
|
|||
/*=== nwkMan.c ============================================================*/
|
||||
extern ABC_DLL Nwk_Man_t * Nwk_ManAlloc();
|
||||
extern ABC_DLL void Nwk_ManFree( Nwk_Man_t * p );
|
||||
extern ABC_DLL void Nwk_ManPrintStats( Nwk_Man_t * p, If_Lib_t * pLutLib, int fSaveBest, int fDumpResult, void * pNtl );
|
||||
extern ABC_DLL float Nwl_ManComputeTotalSwitching( Nwk_Man_t * pNtk );
|
||||
extern ABC_DLL void Nwk_ManPrintStats( Nwk_Man_t * p, If_Lib_t * pLutLib, int fSaveBest, int fDumpResult, int fPower, void * pNtl );
|
||||
/*=== nwkMap.c ============================================================*/
|
||||
extern ABC_DLL Nwk_Man_t * Nwk_MappingIf( Aig_Man_t * p, Tim_Man_t * pManTime, If_Par_t * pPars );
|
||||
/*=== nwkObj.c ============================================================*/
|
||||
|
|
|
|||
|
|
@ -24,6 +24,26 @@
|
|||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static inline int Extra_TruthWordNum( int nVars ) { return nVars <= 5 ? 1 : (1 << (nVars - 5)); }
|
||||
static inline void Extra_TruthNot( unsigned * pOut, unsigned * pIn, int nVars )
|
||||
{
|
||||
int w;
|
||||
for ( w = Extra_TruthWordNum(nVars)-1; w >= 0; w-- )
|
||||
pOut[w] = ~pIn[w];
|
||||
}
|
||||
static inline void Extra_TruthOr( unsigned * pOut, unsigned * pIn0, unsigned * pIn1, int nVars )
|
||||
{
|
||||
int w;
|
||||
for ( w = Extra_TruthWordNum(nVars)-1; w >= 0; w-- )
|
||||
pOut[w] = pIn0[w] | pIn1[w];
|
||||
}
|
||||
static inline void Extra_TruthSharp( unsigned * pOut, unsigned * pIn0, unsigned * pIn1, int nVars )
|
||||
{
|
||||
int w;
|
||||
for ( w = Extra_TruthWordNum(nVars)-1; w >= 0; w-- )
|
||||
pOut[w] = pIn0[w] & ~pIn1[w];
|
||||
}
|
||||
|
||||
static inline Hop_Obj_t * Bdc_FunCopyHop( Bdc_Fun_t * pObj ) { return Hop_NotCond( Bdc_FuncCopy(Bdc_Regular(pObj)), Bdc_IsComplement(pObj) ); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -41,7 +61,7 @@ static inline Hop_Obj_t * Bdc_FunCopyHop( Bdc_Fun_t * pObj ) { return Hop_NotCo
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Hop_Obj_t * Nwk_NodeIfNodeResyn( Bdc_Man_t * p, Hop_Man_t * pHop, Hop_Obj_t * pRoot, int nVars, Vec_Int_t * vTruth, unsigned * puCare )
|
||||
Hop_Obj_t * Nwk_NodeIfNodeResyn( Bdc_Man_t * p, Hop_Man_t * pHop, Hop_Obj_t * pRoot, int nVars, Vec_Int_t * vTruth, unsigned * puCare, float dProb )
|
||||
{
|
||||
unsigned * pTruth;
|
||||
Bdc_Fun_t * pFunc;
|
||||
|
|
@ -52,8 +72,33 @@ Hop_Obj_t * Nwk_NodeIfNodeResyn( Bdc_Man_t * p, Hop_Man_t * pHop, Hop_Obj_t * pR
|
|||
if ( Hop_IsComplement(pRoot) )
|
||||
for ( i = Aig_TruthWordNum(nVars)-1; i >= 0; i-- )
|
||||
pTruth[i] = ~pTruth[i];
|
||||
// decompose truth table
|
||||
Bdc_ManDecompose( p, pTruth, puCare, nVars, NULL, 1000 );
|
||||
// perform power-aware decomposition
|
||||
if ( dProb >= 0.0 )
|
||||
{
|
||||
float Prob = (float)2.0 * dProb * (1.0 - dProb);
|
||||
assert( Prob >= 0.0 && Prob <= 0.5 );
|
||||
if ( Prob >= 0.4 )
|
||||
{
|
||||
Extra_TruthNot( puCare, puCare, nVars );
|
||||
if ( dProb > 0.5 ) // more 1s than 0s
|
||||
Extra_TruthOr( pTruth, pTruth, puCare, nVars );
|
||||
else
|
||||
Extra_TruthSharp( pTruth, pTruth, puCare, nVars );
|
||||
Extra_TruthNot( puCare, puCare, nVars );
|
||||
// decompose truth table
|
||||
Bdc_ManDecompose( p, pTruth, NULL, nVars, NULL, 1000 );
|
||||
}
|
||||
else
|
||||
{
|
||||
// decompose truth table
|
||||
Bdc_ManDecompose( p, pTruth, puCare, nVars, NULL, 1000 );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// decompose truth table
|
||||
Bdc_ManDecompose( p, pTruth, puCare, nVars, NULL, 1000 );
|
||||
}
|
||||
// convert back into HOP
|
||||
Bdc_FuncSetCopy( Bdc_ManFunc( p, 0 ), Hop_ManConst1( pHop ) );
|
||||
for ( i = 0; i < nVars; i++ )
|
||||
|
|
@ -106,7 +151,7 @@ void Nwk_ManBidecResyn( Nwk_Man_t * pNtk, int fVerbose )
|
|||
if ( Nwk_ObjFaninNum(pObj) > 15 )
|
||||
continue;
|
||||
nNodes1 = Hop_DagSize(pObj->pFunc);
|
||||
pObj->pFunc = Nwk_NodeIfNodeResyn( p, pNtk->pManHop, pObj->pFunc, Nwk_ObjFaninNum(pObj), vTruth, NULL );
|
||||
pObj->pFunc = Nwk_NodeIfNodeResyn( p, pNtk->pManHop, pObj->pFunc, Nwk_ObjFaninNum(pObj), vTruth, NULL, -1.0 );
|
||||
nNodes2 = Hop_DagSize(pObj->pFunc);
|
||||
nGainTotal += nNodes1 - nNodes2;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -181,6 +181,42 @@ char * Nwk_FileNameGeneric( char * FileName )
|
|||
return pRes;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Marks nodes for power-optimization.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
float Nwl_ManComputeTotalSwitching( Nwk_Man_t * pNtk )
|
||||
{
|
||||
extern Vec_Int_t * Saig_ManComputeSwitchProbs( Aig_Man_t * p, int nFrames, int nPref, int fProbOne );
|
||||
Vec_Int_t * vSwitching;
|
||||
float * pSwitching;
|
||||
Aig_Man_t * pAig;
|
||||
Aig_Obj_t * pObjAig;
|
||||
Nwk_Obj_t * pObjAbc;
|
||||
float Result = (float)0;
|
||||
int i;
|
||||
// strash the network
|
||||
// map network into an AIG
|
||||
pAig = Nwk_ManStrash( pNtk );
|
||||
vSwitching = Saig_ManComputeSwitchProbs( pAig, 48, 16, 0 );
|
||||
pSwitching = (float *)vSwitching->pArray;
|
||||
Nwk_ManForEachObj( pNtk, pObjAbc, i )
|
||||
{
|
||||
if ( (pObjAig = Aig_Regular(pObjAbc->pCopy)) )
|
||||
Result += Nwk_ObjFanoutNum(pObjAbc) * pSwitching[pObjAig->Id];
|
||||
}
|
||||
Vec_IntFree( vSwitching );
|
||||
Aig_ManStop( pAig );
|
||||
return Result;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Prints stats of the manager.]
|
||||
|
|
@ -192,7 +228,7 @@ char * Nwk_FileNameGeneric( char * FileName )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Nwk_ManPrintStats( Nwk_Man_t * pNtk, If_Lib_t * pLutLib, int fSaveBest, int fDumpResult, void * pNtl )
|
||||
void Nwk_ManPrintStats( Nwk_Man_t * pNtk, If_Lib_t * pLutLib, int fSaveBest, int fDumpResult, int fPower, void * pNtl )
|
||||
{
|
||||
extern int Ntl_ManLatchNum( void * p );
|
||||
extern void Ioa_WriteBlifLogic( Nwk_Man_t * pNtk, void * pNtl, char * pFileName );
|
||||
|
|
@ -221,7 +257,9 @@ void Nwk_ManPrintStats( Nwk_Man_t * pNtk, If_Lib_t * pLutLib, int fSaveBest, int
|
|||
printf( "aig = %6d ", Nwk_ManGetAigNodeNum(pNtk) );
|
||||
printf( "lev = %3d ", Nwk_ManLevel(pNtk) );
|
||||
// printf( "lev2 = %3d ", Nwk_ManLevelBackup(pNtk) );
|
||||
printf( "delay = %5.2f ", Nwk_ManDelayTraceLut(pNtk) );
|
||||
printf( "delay = %5.2f ", Nwk_ManDelayTraceLut(pNtk) );
|
||||
if ( fPower )
|
||||
printf( "power = %7.2f ", Nwl_ManComputeTotalSwitching(pNtk) );
|
||||
Nwk_ManPrintLutSizes( pNtk, pLutLib );
|
||||
printf( "\n" );
|
||||
// Nwk_ManDelayTracePrint( pNtk, pLutLib );
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ void Nwk_ManSetIfParsDefault( If_Par_t * pPars )
|
|||
pPars->fExpRed = 1; ////
|
||||
pPars->fLatchPaths = 0;
|
||||
pPars->fEdge = 1;
|
||||
pPars->fPower = 0;
|
||||
pPars->fCutMin = 0;
|
||||
pPars->fSeqMap = 0;
|
||||
pPars->fVerbose = 0;
|
||||
|
|
@ -98,12 +99,29 @@ void Nwk_ManSetIfParsDefault( If_Par_t * pPars )
|
|||
***********************************************************************/
|
||||
If_Man_t * Nwk_ManToIf( Aig_Man_t * p, If_Par_t * pPars, Vec_Ptr_t * vAigToIf )
|
||||
{
|
||||
extern Vec_Int_t * Saig_ManComputeSwitchProbs( Aig_Man_t * p, int nFrames, int nPref, int fProbOne );
|
||||
Vec_Int_t * vSwitching = NULL, * vSwitching2 = NULL;
|
||||
float * pSwitching, * pSwitching2;
|
||||
If_Man_t * pIfMan;
|
||||
If_Obj_t * pIfObj;
|
||||
Aig_Obj_t * pNode, * pFanin, * pPrev;
|
||||
int i;
|
||||
int i, clk = clock();
|
||||
// set the number of registers (switch activity will be combinational)
|
||||
Aig_ManSetRegNum( p, 0 );
|
||||
if ( pPars->fPower )
|
||||
{
|
||||
vSwitching = Saig_ManComputeSwitchProbs( p, 48, 16, 0 );
|
||||
if ( pPars->fVerbose )
|
||||
{
|
||||
PRT( "Computing switching activity", clock() - clk );
|
||||
}
|
||||
pSwitching = (float *)vSwitching->pArray;
|
||||
vSwitching2 = Vec_IntStart( Aig_ManObjNumMax(p) );
|
||||
pSwitching2 = (float *)vSwitching2->pArray;
|
||||
}
|
||||
// start the mapping manager and set its parameters
|
||||
pIfMan = If_ManStart( pPars );
|
||||
pIfMan->vSwitching = vSwitching2;
|
||||
// load the AIG into the mapper
|
||||
Aig_ManForEachObj( p, pNode, i )
|
||||
{
|
||||
|
|
@ -116,6 +134,8 @@ If_Man_t * Nwk_ManToIf( Aig_Man_t * p, If_Par_t * pPars, Vec_Ptr_t * vAigToIf )
|
|||
pIfObj = If_ManCreateCi( pIfMan );
|
||||
If_ObjSetLevel( pIfObj, Aig_ObjLevel(pNode) );
|
||||
// printf( "pi=%d ", pIfObj->Level );
|
||||
if ( pIfMan->nLevelMax < (int)pIfObj->Level )
|
||||
pIfMan->nLevelMax = (int)pIfObj->Level;
|
||||
}
|
||||
else if ( Aig_ObjIsPo(pNode) )
|
||||
{
|
||||
|
|
@ -130,6 +150,8 @@ If_Man_t * Nwk_ManToIf( Aig_Man_t * p, If_Par_t * pPars, Vec_Ptr_t * vAigToIf )
|
|||
assert( Vec_PtrEntry(vAigToIf, i) == NULL );
|
||||
Vec_PtrWriteEntry( vAigToIf, i, pIfObj );
|
||||
pNode->pData = pIfObj;
|
||||
if ( vSwitching2 )
|
||||
pSwitching2[pIfObj->Id] = pSwitching[pNode->Id];
|
||||
// set up the choice node
|
||||
if ( Aig_ObjIsChoice( p, pNode ) )
|
||||
{
|
||||
|
|
@ -140,6 +162,8 @@ If_Man_t * Nwk_ManToIf( Aig_Man_t * p, If_Par_t * pPars, Vec_Ptr_t * vAigToIf )
|
|||
}
|
||||
// assert( If_ObjLevel(pIfObj) == Aig_ObjLevel(pNode) );
|
||||
}
|
||||
if ( vSwitching )
|
||||
Vec_IntFree( vSwitching );
|
||||
return pIfMan;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -913,7 +913,7 @@ int Nwk_ManCountTotalFanins( Nwk_Obj_t * pLut, Nwk_Obj_t * pCand )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Nwl_ManCollectOverlapCands( Nwk_Obj_t * pLut, Vec_Ptr_t * vCands, Nwk_LMPars_t * pPars )
|
||||
void Nwk_ManCollectOverlapCands( Nwk_Obj_t * pLut, Vec_Ptr_t * vCands, Nwk_LMPars_t * pPars )
|
||||
{
|
||||
Nwk_Obj_t * pFanin, * pObj;
|
||||
int i, k;
|
||||
|
|
@ -985,7 +985,7 @@ Vec_Int_t * Nwk_ManLutMerge( Nwk_Man_t * pNtk, Nwk_LMPars_t * pPars )
|
|||
{
|
||||
if ( Nwk_ObjFaninNum(pLut) > pPars->nMaxLutSize )
|
||||
continue;
|
||||
Nwl_ManCollectOverlapCands( pLut, vCands1, pPars );
|
||||
Nwk_ManCollectOverlapCands( pLut, vCands1, pPars );
|
||||
if ( pPars->fUseDiffSupp )
|
||||
Nwk_ManCollectNonOverlapCands( pLut, vStart, vNext, vCands2, pPars );
|
||||
if ( Vec_PtrSize(vCands1) == 0 && Vec_PtrSize(vCands2) == 0 )
|
||||
|
|
@ -1022,9 +1022,11 @@ Vec_Int_t * Nwk_ManLutMerge( Nwk_Man_t * pNtk, Nwk_LMPars_t * pPars )
|
|||
Nwk_ManGraphReportMemoryUsage( p );
|
||||
}
|
||||
vResult = p->vPairs; p->vPairs = NULL;
|
||||
/*
|
||||
for ( i = 0; i < vResult->nSize; i += 2 )
|
||||
printf( "(%d,%d) ", vResult->pArray[i], vResult->pArray[i+1] );
|
||||
printf( "\n" );
|
||||
*/
|
||||
Nwk_ManGraphFree( p );
|
||||
return vResult;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -133,6 +133,7 @@ Aig_Man_t * Nwk_ManStrash( Nwk_Man_t * pNtk )
|
|||
}
|
||||
Vec_PtrFree( vObjs );
|
||||
Aig_ManCleanup( pMan );
|
||||
Aig_ManSetRegNum( pMan, 0 );
|
||||
return pMan;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -242,7 +242,7 @@ extern void Nwk_ObjReplace( Nwk_Obj_t * pNodeOld, Nwk_Obj_t * pNodeNe
|
|||
/*=== nwkMan.c ============================================================*/
|
||||
extern Nwk_Man_t * Nwk_ManAlloc();
|
||||
extern void Nwk_ManFree( Nwk_Man_t * p );
|
||||
//extern void Nwk_ManPrintStats( Nwk_Man_t * p, If_Lib_t * pLutLib, int fSaveBest, int fDumpResult, void * pNtl );
|
||||
//extern void Nwk_ManPrintStats( Nwk_Man_t * p, If_Lib_t * pLutLib, int fSaveBest, int fDumpResult, int fPower, void * pNtl );
|
||||
/*=== nwkObj.c ============================================================*/
|
||||
extern Nwk_Obj_t * Nwk_ManCreateCi( Nwk_Man_t * pMan, int nFanouts );
|
||||
extern Nwk_Obj_t * Nwk_ManCreateCo( Nwk_Man_t * pMan );
|
||||
|
|
|
|||
|
|
@ -195,7 +195,7 @@ char * Nwk_FileNameGeneric( char * FileName )
|
|||
|
||||
***********************************************************************/
|
||||
/*
|
||||
void Nwk_ManPrintStats( Nwk_Man_t * pNtk, If_Lib_t * pLutLib, int fSaveBest, int fDumpResult, void * pNtl )
|
||||
void Nwk_ManPrintStats( Nwk_Man_t * pNtk, If_Lib_t * pLutLib, int fSaveBest, int fDumpResult, int fPower, void * pNtl )
|
||||
{
|
||||
extern int Ntl_ManLatchNum( void * p );
|
||||
extern void Ioa_WriteBlifLogic( Nwk_Man_t * pNtk, void * pNtl, char * pFileName );
|
||||
|
|
|
|||
|
|
@ -6,12 +6,18 @@ SRC += src/aig/saig/saigAbs.c \
|
|||
src/aig/saig/saigHaig.c \
|
||||
src/aig/saig/saigInd.c \
|
||||
src/aig/saig/saigIoa.c \
|
||||
src/aig/saig/saigLoc.c \
|
||||
src/aig/saig/saigMiter.c \
|
||||
src/aig/saig/saigPhase.c \
|
||||
src/aig/saig/saigRetFwd.c \
|
||||
src/aig/saig/saigRetMin.c \
|
||||
src/aig/saig/saigRetStep.c \
|
||||
src/aig/saig/saigScl.c \
|
||||
src/aig/saig/saigSimExt.c \
|
||||
src/aig/saig/saigSimFast.c \
|
||||
src/aig/saig/saigSimMv.c \
|
||||
src/aig/saig/saigSimSeq.c \
|
||||
src/aig/saig/saigStrSim.c \
|
||||
src/aig/saig/saigSwitch.c \
|
||||
src/aig/saig/saigSynch.c \
|
||||
src/aig/saig/saigTrans.c
|
||||
src/aig/saig/saigTrans.c \
|
||||
src/aig/saig/saigWnd.c
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@ extern "C" {
|
|||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "aig.h"
|
||||
#include "int.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// PARAMETERS ///
|
||||
|
|
@ -40,6 +39,18 @@ extern "C" {
|
|||
/// BASIC TYPES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct Sec_MtrStatus_t_ Sec_MtrStatus_t;
|
||||
struct Sec_MtrStatus_t_
|
||||
{
|
||||
int nInputs; // the total number of inputs
|
||||
int nNodes; // the total number of nodes
|
||||
int nOutputs; // the total number of outputs
|
||||
int nUnsat; // the number of UNSAT outputs
|
||||
int nSat; // the number of SAT outputs
|
||||
int nUndec; // the number of undecided outputs
|
||||
int iOut; // the satisfied output
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// MACRO DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -79,7 +90,7 @@ static inline Aig_Obj_t * Saig_ObjLiToLo( Aig_Man_t * p, Aig_Obj_t * pObj ) {
|
|||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*=== sswAbs.c ==========================================================*/
|
||||
extern Aig_Man_t * Saig_ManProofAbstraction( Aig_Man_t * p, int nFrames, int nConfMax, int fDynamic, int fExtend, int fVerbose );
|
||||
extern Aig_Man_t * Saig_ManProofAbstraction( Aig_Man_t * p, int nFrames, int nConfMax, int fDynamic, int fExtend, int fSkipProof, int fVerbose );
|
||||
/*=== saigBmc.c ==========================================================*/
|
||||
extern int Saig_ManBmcSimple( Aig_Man_t * pAig, int nFrames, int nSizeMax, int nBTLimit, int fRewrite, int fVerbose, int * piFrame );
|
||||
extern void Saig_BmcPerform( Aig_Man_t * pAig, int nFramesMax, int nNodesMax, int nConfMaxOne, int nConfMaxAll, int fVerbose );
|
||||
|
|
@ -95,11 +106,11 @@ extern int Saig_ManInduction( Aig_Man_t * p, int nFramesMax, int n
|
|||
/*=== saigIoa.c ==========================================================*/
|
||||
extern void Saig_ManDumpBlif( Aig_Man_t * p, char * pFileName );
|
||||
extern Aig_Man_t * Saig_ManReadBlif( char * pFileName );
|
||||
/*=== saigInter.c ==========================================================*/
|
||||
extern int Saig_Interpolate( Aig_Man_t * pAig, Inter_ManParams_t * pPars, int * pDepth );
|
||||
/*=== saigMiter.c ==========================================================*/
|
||||
extern Sec_MtrStatus_t Sec_MiterStatus( Aig_Man_t * p );
|
||||
extern Aig_Man_t * Saig_ManCreateMiter( Aig_Man_t * p1, Aig_Man_t * p2, int Oper );
|
||||
extern Aig_Man_t * Saig_ManCreateMiterComb( Aig_Man_t * p1, Aig_Man_t * p2, int Oper );
|
||||
extern Aig_Man_t * Saig_ManDualRail( Aig_Man_t * p, int fMiter );
|
||||
extern Aig_Man_t * Saig_ManCreateMiterTwo( Aig_Man_t * pOld, Aig_Man_t * pNew, int nFrames );
|
||||
extern int Saig_ManDemiterSimple( Aig_Man_t * p, Aig_Man_t ** ppAig0, Aig_Man_t ** ppAig1 );
|
||||
extern int Saig_ManDemiterSimpleDiff( Aig_Man_t * p, Aig_Man_t ** ppAig0, Aig_Man_t ** ppAig1 );
|
||||
|
|
@ -115,10 +126,23 @@ extern Aig_Man_t * Saig_ManRetimeMinArea( Aig_Man_t * p, int nMaxIters, in
|
|||
extern int Saig_ManRetimeSteps( Aig_Man_t * p, int nSteps, int fForward, int fAddBugs );
|
||||
/*=== saigScl.c ==========================================================*/
|
||||
extern void Saig_ManReportUselessRegisters( Aig_Man_t * pAig );
|
||||
/*=== saigSimExt.c ==========================================================*/
|
||||
//extern Vec_Int_t * Saig_ManExtendCounterExample( Aig_Man_t * p, int iFirstPi, Ssw_Cex_t * pCex, Vec_Ptr_t * vSimInfo );
|
||||
//extern Vec_Int_t * Saig_ManExtendCounterExampleTest( Aig_Man_t * p, int iFirstPi, Ssw_Cex_t * pCex );
|
||||
/*=== saigSimMv.c ==========================================================*/
|
||||
extern int Saig_MvManSimulate( Aig_Man_t * pAig, int fVerbose );
|
||||
/*=== saigStrSim.c ==========================================================*/
|
||||
extern Vec_Int_t * Saig_StrSimPerformMatching( Aig_Man_t * p0, Aig_Man_t * p1, int nDist, int fVerbose, Aig_Man_t ** ppMiter );
|
||||
/*=== saigSwitch.c ==========================================================*/
|
||||
extern Vec_Int_t * Saig_ManComputeSwitchProbs( Aig_Man_t * p, int nFrames, int nPref, int fProbOne );
|
||||
/*=== saigSynch.c ==========================================================*/
|
||||
extern Aig_Man_t * Saig_ManDupInitZero( Aig_Man_t * p );
|
||||
/*=== saigTrans.c ==========================================================*/
|
||||
extern Aig_Man_t * Saig_ManTimeframeSimplify( Aig_Man_t * pAig, int nFrames, int nFramesMax, int fInit, int fVerbose );
|
||||
/*=== saigWnd.c ==========================================================*/
|
||||
extern Aig_Man_t * Saig_ManWindowExtract( Aig_Man_t * p, Aig_Obj_t * pObj, int nDist );
|
||||
extern Aig_Man_t * Saig_ManWindowInsert( Aig_Man_t * p, Aig_Obj_t * pObj, int nDist, Aig_Man_t * pWnd );
|
||||
extern Aig_Obj_t * Saig_ManFindPivot( Aig_Man_t * p );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#include "cnf.h"
|
||||
#include "satSolver.h"
|
||||
#include "satStore.h"
|
||||
#include "ssw.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
|
|
@ -105,7 +106,11 @@ int Saig_AbsMarkVisited_rec( Aig_Man_t * p, Vec_Str_t * vObj2Visit, Aig_Obj_t *
|
|||
if ( Saig_ObjIsPi( p, pObj ) )
|
||||
return 1;
|
||||
if ( Saig_ObjIsLo( p, pObj ) )
|
||||
{
|
||||
if ( i == 0 )
|
||||
return 1;
|
||||
return Saig_AbsMarkVisited_rec( p, vObj2Visit, Saig_ObjLoToLi(p, pObj), i-1 );
|
||||
}
|
||||
if ( Aig_ObjIsPo( pObj ) )
|
||||
return Saig_AbsMarkVisited_rec( p, vObj2Visit, Aig_ObjFanin0(pObj), i );
|
||||
Saig_AbsMarkVisited_rec( p, vObj2Visit, Aig_ObjFanin0(pObj), i );
|
||||
|
|
@ -130,8 +135,8 @@ Vec_Str_t * Saig_AbsMarkVisited( Aig_Man_t * p, int nFramesMax )
|
|||
Aig_Obj_t * pObj;
|
||||
int i, f;
|
||||
vObj2Visit = Vec_StrStart( Aig_ManObjNumMax(p) * nFramesMax );
|
||||
Saig_ManForEachLo( p, pObj, i )
|
||||
Saig_AbsSetVisited( vObj2Visit, Aig_ManObjNumMax(p), pObj, 0 );
|
||||
// Saig_ManForEachLo( p, pObj, i )
|
||||
// Saig_AbsSetVisited( vObj2Visit, Aig_ManObjNumMax(p), pObj, 0 );
|
||||
for ( f = 0; f < nFramesMax; f++ )
|
||||
{
|
||||
Saig_AbsSetVisited( vObj2Visit, Aig_ManObjNumMax(p), Aig_ManConst1(p), f );
|
||||
|
|
@ -193,18 +198,19 @@ Vec_Ptr_t * Saig_AbsCreateFrames( Aig_Man_t * p, int nFramesMax, int fVerbose )
|
|||
Vec_PtrClear( vLoObjs );
|
||||
Vec_PtrClear( vLiObjs );
|
||||
Aig_ManForEachPi( p, pObj, i )
|
||||
{
|
||||
{
|
||||
if ( Saig_AbsVisited( vObj2Visit, Aig_ManObjNumMax(p), pObj, f ) )
|
||||
{
|
||||
pObj->pData = Aig_ObjCreatePi(pFrame);
|
||||
if ( i >= Saig_ManPiNum(p) )
|
||||
Vec_PtrPush( vLoObjs, pObj );
|
||||
}
|
||||
}
|
||||
}
|
||||
// remember the number of (implicit) registers in this frame
|
||||
pFrame->nAsserts = Vec_PtrSize(vLoObjs);
|
||||
// create POs
|
||||
Aig_ManForEachPo( p, pObj, i )
|
||||
{
|
||||
if ( Saig_AbsVisited( vObj2Visit, Aig_ManObjNumMax(p), pObj, f ) )
|
||||
{
|
||||
Saig_AbsCreateFrames_rec( pFrame, Aig_ObjFanin0(pObj) );
|
||||
|
|
@ -212,8 +218,10 @@ Vec_Ptr_t * Saig_AbsCreateFrames( Aig_Man_t * p, int nFramesMax, int fVerbose )
|
|||
if ( i >= Saig_ManPoNum(p) )
|
||||
Vec_PtrPush( vLiObjs, pObj );
|
||||
}
|
||||
Vec_PtrPush( vFrames, Cnf_Derive(pFrame, Aig_ManPoNum(pFrame)) );
|
||||
// set the new PIs to point to the recorresponding registers
|
||||
}
|
||||
// Vec_PtrPush( vFrames, Cnf_Derive(pFrame, Aig_ManPoNum(pFrame)) );
|
||||
Vec_PtrPush( vFrames, Cnf_DeriveSimple(pFrame, Aig_ManPoNum(pFrame)) );
|
||||
// set the new PIs to point to the corresponding registers
|
||||
Aig_ManCleanData( pFrame );
|
||||
Vec_PtrForEachEntry( vLoObjs, pObj, i )
|
||||
((Aig_Obj_t *)pObj->pData)->pData = pObj;
|
||||
|
|
@ -290,7 +298,10 @@ sat_solver * Saig_AbsCreateSolverDyn( Aig_Man_t * p, Vec_Ptr_t * vFrames )
|
|||
// add auxiliary clauses (output, connectors, initial)
|
||||
// add output clause
|
||||
if ( !sat_solver_addclause( pSat, Vec_IntArray(vPoLits), Vec_IntArray(vPoLits) + Vec_IntSize(vPoLits) ) )
|
||||
{
|
||||
printf( "SAT solver is not created correctly.\n" );
|
||||
assert( 0 );
|
||||
}
|
||||
Vec_IntFree( vPoLits );
|
||||
|
||||
// add connecting clauses
|
||||
|
|
@ -625,6 +636,52 @@ void Saig_AbsExtendOneStep( Aig_Man_t * p, Vec_Int_t * vFlops )
|
|||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Derive a new counter-example.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ssw_Cex_t * Saig_ManCexShrink( Aig_Man_t * p, Aig_Man_t * pAbs, Ssw_Cex_t * pCexAbs )
|
||||
{
|
||||
Ssw_Cex_t * pCex;
|
||||
Aig_Obj_t * pObj;
|
||||
int i, f;
|
||||
// start the counter-example
|
||||
pCex = Ssw_SmlAllocCounterExample( Aig_ManRegNum(p), Saig_ManPiNum(p), pCexAbs->iFrame+1 );
|
||||
pCex->iFrame = pCexAbs->iFrame;
|
||||
pCex->iPo = pCexAbs->iPo;
|
||||
// copy the bit data
|
||||
for ( f = 0; f <= pCexAbs->iFrame; f++ )
|
||||
{
|
||||
Saig_ManForEachPi( pAbs, pObj, i )
|
||||
{
|
||||
if ( i == Saig_ManPiNum(p) )
|
||||
break;
|
||||
if ( Aig_InfoHasBit( pCexAbs->pData, pCexAbs->nRegs + pCexAbs->nPis * f + i ) )
|
||||
Aig_InfoSetBit( pCex->pData, pCex->nRegs + pCex->nPis * f + i );
|
||||
}
|
||||
}
|
||||
// verify the counter example
|
||||
if ( !Ssw_SmlRunCounterExample( p, pCex ) )
|
||||
{
|
||||
printf( "Saig_ManCexShrink(): Counter-example is invalid.\n" );
|
||||
Ssw_SmlFreeCounterExample( pCex );
|
||||
pCex = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf( "Counter-example verification is successful.\n" );
|
||||
printf( "Output %d was asserted in frame %d (use \"write_counter\" to dump a witness). \n", pCex->iPo, pCex->iFrame );
|
||||
}
|
||||
return pCex;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs proof-based abstraction using BMC of the given depth.]
|
||||
|
|
@ -636,63 +693,148 @@ void Saig_AbsExtendOneStep( Aig_Man_t * p, Vec_Int_t * vFlops )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Man_t * Saig_ManProofAbstraction( Aig_Man_t * p, int nFrames, int nConfMax, int fDynamic, int fExtend, int fVerbose )
|
||||
Aig_Man_t * Saig_ManProofRefine( Aig_Man_t * p, Aig_Man_t * pAbs, Vec_Int_t * vFlops, int fVerbose )
|
||||
{
|
||||
Aig_Man_t * pResult;
|
||||
extern void Saig_BmcPerform( Aig_Man_t * pAig, int nFramesMax, int nNodesMax, int nConfMaxOne, int nConfMaxAll, int fVerbose );
|
||||
extern Vec_Int_t * Saig_ManExtendCounterExampleTest( Aig_Man_t * p, int iFirstPi, void * pCex, int fVerbose );
|
||||
|
||||
Vec_Int_t * vFlopsNew, * vPiToReg;
|
||||
Aig_Obj_t * pObj;
|
||||
int i, Entry, iFlop;
|
||||
Saig_BmcPerform( pAbs, 2000, 2000, 5000, 1000000, fVerbose );
|
||||
if ( pAbs->pSeqModel == NULL )
|
||||
return NULL;
|
||||
// Saig_ManExtendCounterExampleTest( p->pAig, 0, p->pAig->pSeqModel );
|
||||
vFlopsNew = Saig_ManExtendCounterExampleTest( pAbs, Saig_ManPiNum(p), pAbs->pSeqModel, fVerbose );
|
||||
if ( Vec_IntSize(vFlopsNew) == 0 )
|
||||
{
|
||||
printf( "Discovered a true counter-example!\n" );
|
||||
p->pSeqModel = Saig_ManCexShrink( p, pAbs, pAbs->pSeqModel );
|
||||
Vec_IntFree( vFlopsNew );
|
||||
return NULL;
|
||||
}
|
||||
if ( fVerbose )
|
||||
printf( "Adding %d registers to the abstraction.\n", Vec_IntSize(vFlopsNew) );
|
||||
// vFlopsNew contains PI number that should be kept in pAbs
|
||||
|
||||
// for each additional PI, collect the number of a register it stands for
|
||||
Vec_IntForEachEntry( vFlops, Entry, i )
|
||||
{
|
||||
pObj = Saig_ManLo( p, Entry );
|
||||
pObj->fMarkA = 1;
|
||||
}
|
||||
vPiToReg = Vec_IntAlloc( 1000 );
|
||||
Aig_ManForEachPi( p, pObj, i )
|
||||
{
|
||||
if ( pObj->fMarkA )
|
||||
{
|
||||
pObj->fMarkA = 0;
|
||||
continue;
|
||||
}
|
||||
if ( i < Saig_ManPiNum(p) )
|
||||
Vec_IntPush( vPiToReg, -1 );
|
||||
else
|
||||
Vec_IntPush( vPiToReg, Aig_ObjPioNum(pObj)-Saig_ManPiNum(p) );
|
||||
}
|
||||
// collect registers
|
||||
Vec_IntForEachEntry( vFlopsNew, Entry, i )
|
||||
{
|
||||
iFlop = Vec_IntEntry( vPiToReg, Entry );
|
||||
assert( iFlop >= 0 );
|
||||
assert( iFlop < Aig_ManRegNum(p) );
|
||||
Vec_IntPush( vFlops, iFlop );
|
||||
}
|
||||
Vec_IntFree( vPiToReg );
|
||||
Vec_IntFree( vFlopsNew );
|
||||
|
||||
Vec_IntSort( vFlops, 0 );
|
||||
Vec_IntForEachEntryStart( vFlops, Entry, i, 1 )
|
||||
assert( Vec_IntEntry(vFlops, i-1) != Entry );
|
||||
|
||||
return Saig_ManAbstraction( p, vFlops );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs proof-based abstraction using BMC of the given depth.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Man_t * Saig_ManProofAbstraction( Aig_Man_t * p, int nFrames, int nConfMax, int fDynamic, int fExtend, int fSkipProof, int fVerbose )
|
||||
{
|
||||
Aig_Man_t * pResult, * pTemp;
|
||||
Cnf_Dat_t * pCnf;
|
||||
Vec_Ptr_t * vFrames;
|
||||
sat_solver * pSat;
|
||||
Vec_Int_t * vCore;
|
||||
Vec_Int_t * vFlops;
|
||||
int clk = clock(), clk2 = clock();
|
||||
int Iter, clk = clock(), clk2 = clock();
|
||||
assert( Aig_ManRegNum(p) > 0 );
|
||||
Aig_ManSetPioNumbers( p );
|
||||
if ( fVerbose )
|
||||
printf( "Performing proof-based abstraction with %d frames and %d max conflicts.\n", nFrames, nConfMax );
|
||||
if ( fDynamic )
|
||||
|
||||
if ( fSkipProof )
|
||||
{
|
||||
// create CNF for the frames
|
||||
vFrames = Saig_AbsCreateFrames( p, nFrames, fVerbose );
|
||||
// create dynamic solver
|
||||
pSat = Saig_AbsCreateSolverDyn( p, vFrames );
|
||||
assert( 0 );
|
||||
if ( fVerbose )
|
||||
printf( "Performing counter-example-based refinement.\n" );
|
||||
// vFlops = Vec_IntStartNatural( 100 );
|
||||
// Vec_IntPush( vFlops, 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
// create CNF for the AIG
|
||||
pCnf = Cnf_DeriveSimple( p, Aig_ManPoNum(p) );
|
||||
// create SAT solver for the unrolled AIG
|
||||
pSat = Saig_AbsCreateSolver( pCnf, nFrames );
|
||||
}
|
||||
if ( fVerbose )
|
||||
{
|
||||
printf( "SAT solver: Vars = %7d. Clauses = %7d. ", pSat->size, pSat->stats.clauses );
|
||||
PRT( "Time", clock() - clk2 );
|
||||
}
|
||||
// compute UNSAT core
|
||||
vCore = Saig_AbsSolverUnsatCore( pSat, nConfMax, fVerbose );
|
||||
sat_solver_delete( pSat );
|
||||
if ( vCore == NULL )
|
||||
{
|
||||
Saig_AbsFreeCnfs( vFrames );
|
||||
return NULL;
|
||||
}
|
||||
// collect registers
|
||||
if ( fDynamic )
|
||||
{
|
||||
vFlops = Saig_AbsCollectRegistersDyn( p, vFrames, vCore );
|
||||
Saig_AbsFreeCnfs( vFrames );
|
||||
}
|
||||
else
|
||||
{
|
||||
vFlops = Saig_AbsCollectRegisters( pCnf, nFrames, vCore );
|
||||
Cnf_DataFree( pCnf );
|
||||
}
|
||||
Vec_IntFree( vCore );
|
||||
if ( fVerbose )
|
||||
{
|
||||
printf( "The number of relevant registers is %d (out of %d). ", Vec_IntSize(vFlops), Aig_ManRegNum(p) );
|
||||
PRT( "Time", clock() - clk );
|
||||
if ( fVerbose )
|
||||
printf( "Performing proof-based abstraction with %d frames and %d max conflicts.\n", nFrames, nConfMax );
|
||||
if ( fDynamic )
|
||||
{
|
||||
// create CNF for the frames
|
||||
vFrames = Saig_AbsCreateFrames( p, nFrames, fVerbose );
|
||||
// create dynamic solver
|
||||
pSat = Saig_AbsCreateSolverDyn( p, vFrames );
|
||||
}
|
||||
else
|
||||
{
|
||||
// create CNF for the AIG
|
||||
pCnf = Cnf_DeriveSimple( p, Aig_ManPoNum(p) );
|
||||
// create SAT solver for the unrolled AIG
|
||||
pSat = Saig_AbsCreateSolver( pCnf, nFrames );
|
||||
}
|
||||
if ( fVerbose )
|
||||
{
|
||||
printf( "SAT solver: Vars = %7d. Clauses = %7d. ", pSat->size, pSat->stats.clauses );
|
||||
PRT( "Time", clock() - clk2 );
|
||||
}
|
||||
// compute UNSAT core
|
||||
vCore = Saig_AbsSolverUnsatCore( pSat, nConfMax, fVerbose );
|
||||
sat_solver_delete( pSat );
|
||||
if ( vCore == NULL )
|
||||
{
|
||||
Saig_AbsFreeCnfs( vFrames );
|
||||
return NULL;
|
||||
}
|
||||
// collect registers
|
||||
if ( fDynamic )
|
||||
{
|
||||
vFlops = Saig_AbsCollectRegistersDyn( p, vFrames, vCore );
|
||||
Saig_AbsFreeCnfs( vFrames );
|
||||
}
|
||||
else
|
||||
{
|
||||
vFlops = Saig_AbsCollectRegisters( pCnf, nFrames, vCore );
|
||||
Cnf_DataFree( pCnf );
|
||||
}
|
||||
Vec_IntFree( vCore );
|
||||
if ( fVerbose )
|
||||
{
|
||||
printf( "The number of relevant registers is %d (out of %d). ", Vec_IntSize(vFlops), Aig_ManRegNum(p) );
|
||||
PRT( "Time", clock() - clk );
|
||||
}
|
||||
}
|
||||
/*
|
||||
// extend the abstraction
|
||||
if ( fExtend )
|
||||
{
|
||||
|
|
@ -702,8 +844,33 @@ Aig_Man_t * Saig_ManProofAbstraction( Aig_Man_t * p, int nFrames, int nConfMax,
|
|||
if ( fVerbose )
|
||||
printf( " %d flops.\n", Vec_IntSize(vFlops) );
|
||||
}
|
||||
*/
|
||||
// create the resulting AIG
|
||||
pResult = Saig_ManAbstraction( p, vFlops );
|
||||
|
||||
if ( fExtend )
|
||||
{
|
||||
if ( !fVerbose )
|
||||
{
|
||||
printf( "Init : " );
|
||||
Aig_ManPrintStats( pResult );
|
||||
}
|
||||
printf( "Refining abstraction...\n" );
|
||||
for ( Iter = 0; ; Iter++ )
|
||||
{
|
||||
pTemp = Saig_ManProofRefine( p, pResult, vFlops, fVerbose );
|
||||
if ( pTemp == NULL )
|
||||
break;
|
||||
Aig_ManStop( pResult );
|
||||
pResult = pTemp;
|
||||
printf( "%4d : ", Iter );
|
||||
if ( !fVerbose )
|
||||
Aig_ManPrintStats( pResult );
|
||||
else
|
||||
printf( " -----------------------------------------------------\n" );
|
||||
}
|
||||
}
|
||||
|
||||
Vec_IntFree( vFlops );
|
||||
return pResult;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -207,7 +207,7 @@ Aig_Obj_t * Saig_BmcIntervalExplore_rec( Saig_Bmc_t * p, Aig_Obj_t * pObj, int i
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Obj_t * Saig_BmcIntervalConstruct_rec( Saig_Bmc_t * p, Aig_Obj_t * pObj, int i )
|
||||
Aig_Obj_t * Saig_BmcIntervalConstruct_rec_OLD( Saig_Bmc_t * p, Aig_Obj_t * pObj, int i )
|
||||
{
|
||||
Aig_Obj_t * pRes;
|
||||
pRes = Saig_BmcObjFrame( p, pObj, i );
|
||||
|
|
@ -217,16 +217,16 @@ Aig_Obj_t * Saig_BmcIntervalConstruct_rec( Saig_Bmc_t * p, Aig_Obj_t * pObj, int
|
|||
if ( Saig_ObjIsPi( p->pAig, pObj ) )
|
||||
pRes = Aig_ObjCreatePi(p->pFrm);
|
||||
else if ( Saig_ObjIsLo( p->pAig, pObj ) )
|
||||
pRes = Saig_BmcIntervalConstruct_rec( p, Saig_ObjLoToLi(p->pAig, pObj), i-1 );
|
||||
pRes = Saig_BmcIntervalConstruct_rec_OLD( p, Saig_ObjLoToLi(p->pAig, pObj), i-1 );
|
||||
else if ( Aig_ObjIsPo( pObj ) )
|
||||
{
|
||||
Saig_BmcIntervalConstruct_rec( p, Aig_ObjFanin0(pObj), i );
|
||||
Saig_BmcIntervalConstruct_rec_OLD( p, Aig_ObjFanin0(pObj), i );
|
||||
pRes = Saig_BmcObjChild0( p, pObj, i );
|
||||
}
|
||||
else
|
||||
{
|
||||
Saig_BmcIntervalConstruct_rec( p, Aig_ObjFanin0(pObj), i );
|
||||
Saig_BmcIntervalConstruct_rec( p, Aig_ObjFanin1(pObj), i );
|
||||
Saig_BmcIntervalConstruct_rec_OLD( p, Aig_ObjFanin0(pObj), i );
|
||||
Saig_BmcIntervalConstruct_rec_OLD( p, Aig_ObjFanin1(pObj), i );
|
||||
pRes = Aig_And( p->pFrm, Saig_BmcObjChild0(p, pObj, i), Saig_BmcObjChild1(p, pObj, i) );
|
||||
}
|
||||
assert( pRes != AIG_VISITED );
|
||||
|
|
@ -234,6 +234,45 @@ Aig_Obj_t * Saig_BmcIntervalConstruct_rec( Saig_Bmc_t * p, Aig_Obj_t * pObj, int
|
|||
return pRes;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs the actual construction of the output.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Obj_t * Saig_BmcIntervalConstruct_rec( Saig_Bmc_t * p, Aig_Obj_t * pObj, int i, Vec_Ptr_t * vVisited )
|
||||
{
|
||||
Aig_Obj_t * pRes;
|
||||
pRes = Saig_BmcObjFrame( p, pObj, i );
|
||||
if ( pRes != NULL )
|
||||
return pRes;
|
||||
if ( Saig_ObjIsPi( p->pAig, pObj ) )
|
||||
pRes = Aig_ObjCreatePi(p->pFrm);
|
||||
else if ( Saig_ObjIsLo( p->pAig, pObj ) )
|
||||
pRes = Saig_BmcIntervalConstruct_rec( p, Saig_ObjLoToLi(p->pAig, pObj), i-1, vVisited );
|
||||
else if ( Aig_ObjIsPo( pObj ) )
|
||||
{
|
||||
Saig_BmcIntervalConstruct_rec( p, Aig_ObjFanin0(pObj), i, vVisited );
|
||||
pRes = Saig_BmcObjChild0( p, pObj, i );
|
||||
}
|
||||
else
|
||||
{
|
||||
Saig_BmcIntervalConstruct_rec( p, Aig_ObjFanin0(pObj), i, vVisited );
|
||||
Saig_BmcIntervalConstruct_rec( p, Aig_ObjFanin1(pObj), i, vVisited );
|
||||
pRes = Aig_And( p->pFrm, Saig_BmcObjChild0(p, pObj, i), Saig_BmcObjChild1(p, pObj, i) );
|
||||
}
|
||||
assert( pRes != NULL );
|
||||
Saig_BmcObjSetFrame( p, pObj, i, pRes );
|
||||
Vec_PtrPush( vVisited, pObj );
|
||||
Vec_PtrPush( vVisited, (void *)i );
|
||||
return pRes;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Adds new AIG nodes to the frames.]
|
||||
|
|
@ -248,8 +287,8 @@ Aig_Obj_t * Saig_BmcIntervalConstruct_rec( Saig_Bmc_t * p, Aig_Obj_t * pObj, int
|
|||
void Saig_BmcInterval( Saig_Bmc_t * p )
|
||||
{
|
||||
Aig_Obj_t * pTarget;
|
||||
// Aig_Obj_t * pObj;
|
||||
// int i;
|
||||
Aig_Obj_t * pObj, * pRes;
|
||||
int i, iFrame;
|
||||
int nNodes = Aig_ManObjNum( p->pFrm );
|
||||
Vec_PtrClear( p->vTargets );
|
||||
p->iFramePrev = p->iFrameLast;
|
||||
|
|
@ -258,21 +297,25 @@ void Saig_BmcInterval( Saig_Bmc_t * p )
|
|||
if ( p->iOutputLast == 0 )
|
||||
{
|
||||
Saig_BmcObjSetFrame( p, Aig_ManConst1(p->pAig), p->iFrameLast, Aig_ManConst1(p->pFrm) );
|
||||
// Saig_ManForEachPi( p->pAig, pObj, i )
|
||||
// Saig_BmcObjSetFrame( p, pObj, p->iFrameLast, Aig_ObjCreatePi(p->pFrm) );
|
||||
}
|
||||
for ( ; p->iOutputLast < Saig_ManPoNum(p->pAig); p->iOutputLast++ )
|
||||
{
|
||||
if ( Aig_ManObjNum(p->pFrm) >= nNodes + p->nNodesMax )
|
||||
return;
|
||||
Saig_BmcIntervalExplore_rec( p, Aig_ManPo(p->pAig, p->iOutputLast), p->iFrameLast );
|
||||
pTarget = Saig_BmcIntervalConstruct_rec( p, Aig_ManPo(p->pAig, p->iOutputLast), p->iFrameLast );
|
||||
|
||||
/////////
|
||||
// if ( Aig_ObjIsConst1(Aig_Regular(pTarget)) )
|
||||
// continue;
|
||||
|
||||
// Saig_BmcIntervalExplore_rec( p, Aig_ManPo(p->pAig, p->iOutputLast), p->iFrameLast );
|
||||
Vec_PtrClear( p->vVisited );
|
||||
pTarget = Saig_BmcIntervalConstruct_rec( p, Aig_ManPo(p->pAig, p->iOutputLast), p->iFrameLast, p->vVisited );
|
||||
Vec_PtrPush( p->vTargets, pTarget );
|
||||
Aig_ObjCreatePo( p->pFrm, pTarget );
|
||||
Aig_ManCleanup( p->pFrm );
|
||||
// check if the node is gone
|
||||
Vec_PtrForEachEntry( p->vVisited, pObj, i )
|
||||
{
|
||||
iFrame = (int)(PORT_PTRINT_T)Vec_PtrEntry( p->vVisited, 1+i++ );
|
||||
pRes = Saig_BmcObjFrame( p, pObj, iFrame );
|
||||
if ( Aig_ObjIsNone( Aig_Regular(pRes) ) )
|
||||
Saig_BmcObjSetFrame( p, pObj, iFrame, NULL );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -489,6 +532,11 @@ int Saig_BmcSolveTargets( Saig_Bmc_t * p )
|
|||
// generate counter-example
|
||||
Saig_BmcDeriveFailed( p, i );
|
||||
p->pAig->pSeqModel = Saig_BmcGenerateCounterExample( p );
|
||||
|
||||
{
|
||||
// extern Vec_Int_t * Saig_ManExtendCounterExampleTest( Aig_Man_t * p, int iFirstPi, void * pCex );
|
||||
// Saig_ManExtendCounterExampleTest( p->pAig, 0, p->pAig->pSeqModel );
|
||||
}
|
||||
return l_True;
|
||||
}
|
||||
return l_False;
|
||||
|
|
@ -564,7 +612,7 @@ void Saig_BmcPerform( Aig_Man_t * pAig, int nFramesMax, int nNodesMax, int nConf
|
|||
RetValue = Saig_BmcSolveTargets( p );
|
||||
if ( fVerbose )
|
||||
{
|
||||
printf( "%3d : F = %3d. O = %3d. And = %7d. Var = %7d. Conf = %7d. ",
|
||||
printf( "%3d : F = %3d. O =%4d. And = %7d. Var = %7d. Conf = %7d. ",
|
||||
Iter, p->iFrameLast, p->iOutputLast, Aig_ManNodeNum(p->pFrm), p->nSatVars, (int)p->pSat->stats.conflicts );
|
||||
PRT( "Time", clock() - clk2 );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ Aig_Man_t * Said_ManDupOrpos( Aig_Man_t * pAig )
|
|||
int i;
|
||||
// start the new manager
|
||||
pAigNew = Aig_ManStart( Aig_ManNodeNum(pAig) );
|
||||
pAigNew->pName = Aig_UtilStrsav( pAig->pName );
|
||||
// map the constant node
|
||||
Aig_ManConst1(pAig)->pData = Aig_ManConst1( pAigNew );
|
||||
// create variables for PIs
|
||||
|
|
@ -80,11 +81,12 @@ Aig_Man_t * Said_ManDupOrpos( Aig_Man_t * pAig )
|
|||
***********************************************************************/
|
||||
Aig_Man_t * Saig_ManAbstraction( Aig_Man_t * pAig, Vec_Int_t * vFlops )
|
||||
{
|
||||
Aig_Man_t * pAigNew;
|
||||
Aig_Man_t * pAigNew;//, * pTemp;
|
||||
Aig_Obj_t * pObj, * pObjLi, * pObjLo;
|
||||
int i, Entry;
|
||||
// start the new manager
|
||||
pAigNew = Aig_ManStart( Aig_ManNodeNum(pAig) );
|
||||
pAigNew->pName = Aig_UtilStrsav( pAig->pName );
|
||||
// map the constant node
|
||||
Aig_ManConst1(pAig)->pData = Aig_ManConst1( pAigNew );
|
||||
// label included flops
|
||||
|
|
@ -123,6 +125,8 @@ Aig_Man_t * Saig_ManAbstraction( Aig_Man_t * pAig, Vec_Int_t * vFlops )
|
|||
}
|
||||
Aig_ManSetRegNum( pAigNew, Vec_IntSize(vFlops) );
|
||||
Aig_ManSeqCleanup( pAigNew );
|
||||
// pAigNew = Aig_ManDupSimpleDfs( pTemp = pAigNew );
|
||||
// Aig_ManStop( pTemp );
|
||||
return pAigNew;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,60 @@
|
|||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Checks the status of the miter.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Sec_MtrStatus_t Sec_MiterStatus( Aig_Man_t * p )
|
||||
{
|
||||
Sec_MtrStatus_t Status;
|
||||
Aig_Obj_t * pObj, * pChild;
|
||||
int i;
|
||||
memset( &Status, 0, sizeof(Sec_MtrStatus_t) );
|
||||
Status.iOut = -1;
|
||||
Status.nInputs = Saig_ManPiNum( p );
|
||||
Status.nNodes = Aig_ManNodeNum( p );
|
||||
Status.nOutputs = Saig_ManPoNum(p);
|
||||
Saig_ManForEachPo( p, pObj, i )
|
||||
{
|
||||
pChild = Aig_ObjChild0(pObj);
|
||||
// check if the output is constant 0
|
||||
if ( pChild == Aig_ManConst0(p) )
|
||||
Status.nUnsat++;
|
||||
// check if the output is constant 1
|
||||
else if ( pChild == Aig_ManConst1(p) )
|
||||
{
|
||||
Status.nSat++;
|
||||
if ( Status.iOut == -1 )
|
||||
Status.iOut = i;
|
||||
}
|
||||
// check if the output is a primary input
|
||||
else if ( Saig_ObjIsPi(p, Aig_Regular(pChild)) )
|
||||
{
|
||||
Status.nSat++;
|
||||
if ( Status.iOut == -1 )
|
||||
Status.iOut = i;
|
||||
}
|
||||
// check if the output is 1 for the 0000 pattern
|
||||
else if ( Aig_Regular(pChild)->fPhase != (unsigned)Aig_IsComplement(pChild) )
|
||||
{
|
||||
Status.nSat++;
|
||||
if ( Status.iOut == -1 )
|
||||
Status.iOut = i;
|
||||
}
|
||||
else
|
||||
Status.nUndec++;
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates sequential miter.]
|
||||
|
|
@ -141,6 +195,116 @@ Aig_Man_t * Saig_ManCreateMiterComb( Aig_Man_t * p0, Aig_Man_t * p1, int Oper )
|
|||
return pNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Derives dual-rail AIG.]
|
||||
|
||||
Description [Orders nodes as follows: PIs, ANDs, POs.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Saig_AndDualRail( Aig_Man_t * pNew, Aig_Obj_t * pObj, Aig_Obj_t ** ppData, Aig_Obj_t ** ppNext )
|
||||
{
|
||||
Aig_Obj_t * pFanin0 = Aig_ObjFanin0(pObj);
|
||||
Aig_Obj_t * pFanin1 = Aig_ObjFanin1(pObj);
|
||||
Aig_Obj_t * p0Data = Aig_ObjFaninC0(pObj)? pFanin0->pNext : pFanin0->pData;
|
||||
Aig_Obj_t * p0Next = Aig_ObjFaninC0(pObj)? pFanin0->pData : pFanin0->pNext;
|
||||
Aig_Obj_t * p1Data = Aig_ObjFaninC1(pObj)? pFanin1->pNext : pFanin1->pData;
|
||||
Aig_Obj_t * p1Next = Aig_ObjFaninC1(pObj)? pFanin1->pData : pFanin1->pNext;
|
||||
*ppData = Aig_Or( pNew,
|
||||
Aig_And(pNew, p0Data, Aig_Not(p0Next)),
|
||||
Aig_And(pNew, p1Data, Aig_Not(p1Next)) );
|
||||
*ppNext = Aig_And( pNew,
|
||||
Aig_And(pNew, Aig_Not(p0Data), p0Next),
|
||||
Aig_And(pNew, Aig_Not(p1Data), p1Next) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Derives dual-rail AIG.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Man_t * Saig_ManDualRail( Aig_Man_t * p, int fMiter )
|
||||
{
|
||||
Aig_Man_t * pNew;
|
||||
Aig_Obj_t * pObj, * pMiter;
|
||||
int i;
|
||||
Aig_ManCleanData( p );
|
||||
Aig_ManCleanNext( p );
|
||||
// create the new manager
|
||||
pNew = Aig_ManStart( 4*Aig_ManObjNumMax(p) );
|
||||
pNew->pName = Aig_UtilStrsav( p->pName );
|
||||
pNew->pSpec = Aig_UtilStrsav( p->pSpec );
|
||||
// create the PIs
|
||||
Aig_ManConst1(p)->pData = Aig_ManConst0(pNew);
|
||||
Aig_ManConst1(p)->pNext = Aig_ManConst1(pNew);
|
||||
Aig_ManForEachPi( p, pObj, i )
|
||||
{
|
||||
pObj->pData = Aig_ObjCreatePi( pNew );
|
||||
pObj->pNext = Aig_ObjCreatePi( pNew );
|
||||
}
|
||||
// duplicate internal nodes
|
||||
Aig_ManForEachNode( p, pObj, i )
|
||||
Saig_AndDualRail( pNew, pObj, (Aig_Obj_t **)&pObj->pData, &pObj->pNext );
|
||||
// add the POs
|
||||
if ( fMiter )
|
||||
{
|
||||
pMiter = Aig_ManConst1(pNew);
|
||||
Saig_ManForEachLo( p, pObj, i )
|
||||
{
|
||||
pMiter = Aig_And( pNew, pMiter,
|
||||
Aig_Or(pNew, pObj->pData, pObj->pNext) );
|
||||
}
|
||||
Aig_ObjCreatePo( pNew, pMiter );
|
||||
Saig_ManForEachLi( p, pObj, i )
|
||||
{
|
||||
if ( !Aig_ObjFaninC0(pObj) )
|
||||
{
|
||||
Aig_ObjCreatePo( pNew, Aig_ObjFanin0(pObj)->pData );
|
||||
Aig_ObjCreatePo( pNew, Aig_ObjFanin0(pObj)->pNext );
|
||||
}
|
||||
else
|
||||
{
|
||||
Aig_ObjCreatePo( pNew, Aig_ObjFanin0(pObj)->pNext );
|
||||
Aig_ObjCreatePo( pNew, Aig_ObjFanin0(pObj)->pData );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Aig_ManForEachPo( p, pObj, i )
|
||||
{
|
||||
if ( !Aig_ObjFaninC0(pObj) )
|
||||
{
|
||||
Aig_ObjCreatePo( pNew, Aig_ObjFanin0(pObj)->pData );
|
||||
Aig_ObjCreatePo( pNew, Aig_ObjFanin0(pObj)->pNext );
|
||||
}
|
||||
else
|
||||
{
|
||||
Aig_ObjCreatePo( pNew, Aig_ObjFanin0(pObj)->pNext );
|
||||
Aig_ObjCreatePo( pNew, Aig_ObjFanin0(pObj)->pData );
|
||||
}
|
||||
}
|
||||
}
|
||||
Aig_ManSetRegNum( pNew, 2*Aig_ManRegNum(p) );
|
||||
Aig_ManCleanData( p );
|
||||
Aig_ManCleanNext( p );
|
||||
Aig_ManCleanup( pNew );
|
||||
// check the resulting network
|
||||
if ( !Aig_ManCheck(pNew) )
|
||||
printf( "Aig_ManDupSimple(): The check has failed.\n" );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Create combinational timeframes by unrolling sequential circuits.]
|
||||
|
|
@ -392,7 +556,7 @@ int Saig_ManDemiterSimpleDiff( Aig_Man_t * p, Aig_Man_t ** ppAig0, Aig_Man_t **
|
|||
Vec_Ptr_t * vSet0, * vSet1;
|
||||
Aig_Obj_t * pObj, * pFanin, * pObj0, * pObj1;
|
||||
int i, Counter = 0;
|
||||
assert( Saig_ManRegNum(p) % 2 == 0 );
|
||||
// assert( Saig_ManRegNum(p) % 2 == 0 );
|
||||
vSet0 = Vec_PtrAlloc( Saig_ManPoNum(p) );
|
||||
vSet1 = Vec_PtrAlloc( Saig_ManPoNum(p) );
|
||||
Saig_ManForEachPo( p, pObj, i )
|
||||
|
|
@ -773,27 +937,47 @@ PRT( "Time", clock() - clkTotal );
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ssw_SecSpecialMiter( Aig_Man_t * pMiter, int fVerbose )
|
||||
int Ssw_SecSpecialMiter( Aig_Man_t * p0, Aig_Man_t * p1, int nFrames, int fVerbose )
|
||||
{
|
||||
int nFrames = 2; // modify to enable comparison over any number of frames
|
||||
Aig_Man_t * pPart0, * pPart1;
|
||||
int RetValue;
|
||||
if ( fVerbose )
|
||||
Aig_ManPrintStats( pMiter );
|
||||
// demiter the miter
|
||||
if ( !Saig_ManDemiterSimple( pMiter, &pPart0, &pPart1 ) )
|
||||
printf( "Performing sequential verification combinational A/B miter.\n" );
|
||||
// consider the case when a miter is given
|
||||
if ( p1 == NULL )
|
||||
{
|
||||
printf( "Demitering has failed.\n" );
|
||||
return -1;
|
||||
if ( fVerbose )
|
||||
{
|
||||
Aig_ManPrintStats( p0 );
|
||||
}
|
||||
// demiter the miter
|
||||
if ( !Saig_ManDemiterSimpleDiff( p0, &pPart0, &pPart1 ) )
|
||||
{
|
||||
printf( "Demitering has failed.\n" );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pPart0 = Aig_ManDupSimple( p0 );
|
||||
pPart1 = Aig_ManDupSimple( p1 );
|
||||
}
|
||||
if ( fVerbose )
|
||||
{
|
||||
Aig_ManPrintStats( pPart0 );
|
||||
Aig_ManPrintStats( pPart1 );
|
||||
Aig_ManDumpBlif( pPart0, "part0.blif", NULL, NULL );
|
||||
Aig_ManDumpBlif( pPart1, "part1.blif", NULL, NULL );
|
||||
printf( "The result of demitering is written into files \"%s\" and \"%s\".\n", "part0.blif", "part1.blif" );
|
||||
// Aig_ManPrintStats( pPart0 );
|
||||
// Aig_ManPrintStats( pPart1 );
|
||||
if ( p1 == NULL )
|
||||
{
|
||||
// Aig_ManDumpBlif( pPart0, "part0.blif", NULL, NULL );
|
||||
// Aig_ManDumpBlif( pPart1, "part1.blif", NULL, NULL );
|
||||
// printf( "The result of demitering is written into files \"%s\" and \"%s\".\n", "part0.blif", "part1.blif" );
|
||||
}
|
||||
}
|
||||
assert( Aig_ManRegNum(pPart0) > 0 );
|
||||
assert( Aig_ManRegNum(pPart1) > 0 );
|
||||
assert( Saig_ManPiNum(pPart0) == Saig_ManPiNum(pPart1) );
|
||||
assert( Saig_ManPoNum(pPart0) == Saig_ManPoNum(pPart1) );
|
||||
assert( Aig_ManRegNum(pPart0) == Aig_ManRegNum(pPart1) );
|
||||
RetValue = Ssw_SecSpecial( pPart0, pPart1, nFrames, fVerbose );
|
||||
Aig_ManStop( pPart0 );
|
||||
Aig_ManStop( pPart1 );
|
||||
|
|
|
|||
|
|
@ -468,7 +468,7 @@ void Saig_TsiStateOrAll( Saig_Tsim_t * pTsi, unsigned * pState )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Saig_Tsim_t * Saig_ManReachableTernary( Aig_Man_t * p, Vec_Int_t * vInits )
|
||||
Saig_Tsim_t * Saig_ManReachableTernary( Aig_Man_t * p, Vec_Int_t * vInits, int fVerbose )
|
||||
{
|
||||
Saig_Tsim_t * pTsi;
|
||||
Aig_Obj_t * pObj, * pObjLi, * pObjLo;
|
||||
|
|
@ -507,7 +507,11 @@ Saig_Tsim_t * Saig_ManReachableTernary( Aig_Man_t * p, Vec_Int_t * vInits )
|
|||
// Saig_TsiStatePrint( pTsi, pState );
|
||||
// check if this state exists
|
||||
if ( Saig_TsiStateLookup( pTsi, pState, pTsi->nWords ) )
|
||||
{
|
||||
if ( fVerbose )
|
||||
printf( "Ternary simulation converged after %d iterations.\n", f );
|
||||
return pTsi;
|
||||
}
|
||||
// insert this state
|
||||
Saig_TsiStateInsert( pTsi, pState, pTsi->nWords );
|
||||
// simulate internal nodes
|
||||
|
|
@ -781,7 +785,7 @@ Aig_Man_t * Saig_ManPhaseAbstract( Aig_Man_t * p, Vec_Int_t * vInits, int nFrame
|
|||
assert( Saig_ManPiNum(p) );
|
||||
assert( Saig_ManPoNum(p) );
|
||||
// perform terminary simulation
|
||||
pTsi = Saig_ManReachableTernary( p, vInits );
|
||||
pTsi = Saig_ManReachableTernary( p, vInits, fVerbose );
|
||||
if ( pTsi == NULL )
|
||||
return NULL;
|
||||
// derive information
|
||||
|
|
@ -837,7 +841,7 @@ Aig_Man_t * Saig_ManPhaseAbstractAuto( Aig_Man_t * p, int fVerbose )
|
|||
assert( Saig_ManPiNum(p) );
|
||||
assert( Saig_ManPoNum(p) );
|
||||
// perform terminary simulation
|
||||
pTsi = Saig_ManReachableTernary( p, NULL );
|
||||
pTsi = Saig_ManReachableTernary( p, NULL, fVerbose );
|
||||
if ( pTsi == NULL )
|
||||
return NULL;
|
||||
// derive information
|
||||
|
|
|
|||
|
|
@ -0,0 +1,325 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [saigSimExt.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Sequential AIG package.]
|
||||
|
||||
Synopsis [Extending simulation trace to contain ternary values.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: saigSimExt.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "saig.h"
|
||||
#include "ssw.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define SAIG_ZER 1
|
||||
#define SAIG_ONE 2
|
||||
#define SAIG_UND 3
|
||||
|
||||
static inline int Saig_ManSimInfoNot( int Value )
|
||||
{
|
||||
if ( Value == SAIG_ZER )
|
||||
return SAIG_ONE;
|
||||
if ( Value == SAIG_ONE )
|
||||
return SAIG_ZER;
|
||||
return SAIG_UND;
|
||||
}
|
||||
|
||||
static inline int Saig_ManSimInfoAnd( int Value0, int Value1 )
|
||||
{
|
||||
if ( Value0 == SAIG_ZER || Value1 == SAIG_ZER )
|
||||
return SAIG_ZER;
|
||||
if ( Value0 == SAIG_ONE && Value1 == SAIG_ONE )
|
||||
return SAIG_ONE;
|
||||
return SAIG_UND;
|
||||
}
|
||||
|
||||
static inline int Saig_ManSimInfoGet( Vec_Ptr_t * vSimInfo, Aig_Obj_t * pObj, int iFrame )
|
||||
{
|
||||
unsigned * pInfo = Vec_PtrEntry( vSimInfo, Aig_ObjId(pObj) );
|
||||
return 3 & (pInfo[iFrame >> 4] >> ((iFrame & 15) << 1));
|
||||
}
|
||||
|
||||
static inline void Saig_ManSimInfoSet( Vec_Ptr_t * vSimInfo, Aig_Obj_t * pObj, int iFrame, int Value )
|
||||
{
|
||||
unsigned * pInfo = Vec_PtrEntry( vSimInfo, Aig_ObjId(pObj) );
|
||||
assert( Value >= SAIG_ZER && Value <= SAIG_UND );
|
||||
Value ^= Saig_ManSimInfoGet( vSimInfo, pObj, iFrame );
|
||||
pInfo[iFrame >> 4] ^= (Value << ((iFrame & 15) << 1));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs ternary simulation for one node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Saig_ManExtendOneEval( Vec_Ptr_t * vSimInfo, Aig_Obj_t * pObj, int iFrame )
|
||||
{
|
||||
int Value0, Value1, Value;
|
||||
Value0 = Saig_ManSimInfoGet( vSimInfo, Aig_ObjFanin0(pObj), iFrame );
|
||||
if ( Aig_ObjFaninC0(pObj) )
|
||||
Value0 = Saig_ManSimInfoNot( Value0 );
|
||||
if ( Aig_ObjIsPo(pObj) )
|
||||
{
|
||||
Saig_ManSimInfoSet( vSimInfo, pObj, iFrame, Value0 );
|
||||
return Value0;
|
||||
}
|
||||
assert( Aig_ObjIsNode(pObj) );
|
||||
Value1 = Saig_ManSimInfoGet( vSimInfo, Aig_ObjFanin1(pObj), iFrame );
|
||||
if ( Aig_ObjFaninC1(pObj) )
|
||||
Value1 = Saig_ManSimInfoNot( Value1 );
|
||||
Value = Saig_ManSimInfoAnd( Value0, Value1 );
|
||||
Saig_ManSimInfoSet( vSimInfo, pObj, iFrame, Value );
|
||||
return Value;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs ternary simulation for one design.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Saig_ManSimDataInit( Aig_Man_t * p, Ssw_Cex_t * pCex, Vec_Ptr_t * vSimInfo, Vec_Int_t * vRes )
|
||||
{
|
||||
Aig_Obj_t * pObj, * pObjLi, * pObjLo;
|
||||
int i, f, Entry, iBit = 0;
|
||||
Saig_ManForEachLo( p, pObj, i )
|
||||
Saig_ManSimInfoSet( vSimInfo, pObj, 0, Aig_InfoHasBit(pCex->pData, iBit++)?SAIG_ONE:SAIG_ZER );
|
||||
for ( f = 0; f <= pCex->iFrame; f++ )
|
||||
{
|
||||
Saig_ManSimInfoSet( vSimInfo, Aig_ManConst1(p), f, SAIG_ONE );
|
||||
Saig_ManForEachPi( p, pObj, i )
|
||||
Saig_ManSimInfoSet( vSimInfo, pObj, f, Aig_InfoHasBit(pCex->pData, iBit++)?SAIG_ONE:SAIG_ZER );
|
||||
if ( vRes )
|
||||
Vec_IntForEachEntry( vRes, Entry, i )
|
||||
Saig_ManSimInfoSet( vSimInfo, Aig_ManPi(p, Entry), f, SAIG_UND );
|
||||
Aig_ManForEachNode( p, pObj, i )
|
||||
Saig_ManExtendOneEval( vSimInfo, pObj, f );
|
||||
Aig_ManForEachPo( p, pObj, i )
|
||||
Saig_ManExtendOneEval( vSimInfo, pObj, f );
|
||||
if ( f == pCex->iFrame )
|
||||
break;
|
||||
Saig_ManForEachLiLo( p, pObjLi, pObjLo, i )
|
||||
Saig_ManSimInfoSet( vSimInfo, pObjLo, f+1, Saig_ManSimInfoGet(vSimInfo, pObjLi, f) );
|
||||
}
|
||||
// make sure the output of the property failed
|
||||
pObj = Aig_ManPo( p, pCex->iPo );
|
||||
return Saig_ManSimInfoGet( vSimInfo, pObj, pCex->iFrame );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Tries to assign ternary value to one of the primary inputs.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Saig_ManExtendOne( Aig_Man_t * p, Ssw_Cex_t * pCex, Vec_Ptr_t * vSimInfo,
|
||||
int iPi, int iFrame, Vec_Int_t * vUndo, Vec_Int_t * vVis, Vec_Int_t * vVis2 )
|
||||
{
|
||||
Aig_Obj_t * pFanout, * pObj = Aig_ManPi(p, iPi);
|
||||
int i, k, f, iFanout, Value, Value2, Entry;
|
||||
// save original value
|
||||
Value = Saig_ManSimInfoGet( vSimInfo, pObj, iFrame );
|
||||
assert( Value == SAIG_ZER || Value == SAIG_ONE );
|
||||
Vec_IntPush( vUndo, Aig_ObjId(pObj) );
|
||||
Vec_IntPush( vUndo, iFrame );
|
||||
Vec_IntPush( vUndo, Value );
|
||||
// update original value
|
||||
Saig_ManSimInfoSet( vSimInfo, pObj, iFrame, SAIG_UND );
|
||||
// traverse
|
||||
Vec_IntClear( vVis );
|
||||
Vec_IntPush( vVis, Aig_ObjId(pObj) );
|
||||
for ( f = iFrame; f <= pCex->iFrame; f++ )
|
||||
{
|
||||
Vec_IntClear( vVis2 );
|
||||
Vec_IntForEachEntry( vVis, Entry, i )
|
||||
{
|
||||
pObj = Aig_ManObj( p, Entry );
|
||||
Aig_ObjForEachFanout( p, pObj, pFanout, iFanout, k )
|
||||
{
|
||||
assert( Aig_ObjId(pObj) < Aig_ObjId(pFanout) );
|
||||
Value = Saig_ManSimInfoGet( vSimInfo, pFanout, f );
|
||||
if ( Value == SAIG_UND )
|
||||
continue;
|
||||
Value2 = Saig_ManExtendOneEval( vSimInfo, pFanout, f );
|
||||
if ( Value2 == Value )
|
||||
continue;
|
||||
assert( Value2 == SAIG_UND );
|
||||
// assert( Vec_IntFind(vVis, Aig_ObjId(pFanout)) == -1 );
|
||||
if ( Aig_ObjIsNode(pFanout) )
|
||||
Vec_IntPushOrder( vVis, Aig_ObjId(pFanout) );
|
||||
else if ( Saig_ObjIsLi(p, pFanout) )
|
||||
Vec_IntPush( vVis2, Aig_ObjId(pFanout) );
|
||||
Vec_IntPush( vUndo, Aig_ObjId(pFanout) );
|
||||
Vec_IntPush( vUndo, f );
|
||||
Vec_IntPush( vUndo, Value );
|
||||
}
|
||||
}
|
||||
if ( Vec_IntSize(vVis2) == 0 )
|
||||
break;
|
||||
if ( f == pCex->iFrame )
|
||||
break;
|
||||
// transfer
|
||||
Vec_IntClear( vVis );
|
||||
Vec_IntForEachEntry( vVis2, Entry, i )
|
||||
{
|
||||
pObj = Aig_ManObj( p, Entry );
|
||||
assert( Saig_ObjIsLi(p, pObj) );
|
||||
pFanout = Saig_ObjLiToLo( p, pObj );
|
||||
Vec_IntPushOrder( vVis, Aig_ObjId(pFanout) );
|
||||
Value = Saig_ManSimInfoGet( vSimInfo, pObj, f );
|
||||
Saig_ManSimInfoSet( vSimInfo, pFanout, f+1, Value );
|
||||
}
|
||||
}
|
||||
// check the output
|
||||
pObj = Aig_ManPo( p, pCex->iPo );
|
||||
Value = Saig_ManSimInfoGet( vSimInfo, pObj, pCex->iFrame );
|
||||
assert( Value == SAIG_ONE || Value == SAIG_UND );
|
||||
return (int)(Value == SAIG_ONE);
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Saig_ManExtendUndo( Aig_Man_t * p, Vec_Ptr_t * vSimInfo, Vec_Int_t * vUndo )
|
||||
{
|
||||
Aig_Obj_t * pObj;
|
||||
int i, iFrame, Value;
|
||||
for ( i = 0; i < Vec_IntSize(vUndo); i += 3 )
|
||||
{
|
||||
pObj = Aig_ManObj( p, Vec_IntEntry(vUndo, i) );
|
||||
iFrame = Vec_IntEntry(vUndo, i+1);
|
||||
Value = Vec_IntEntry(vUndo, i+2);
|
||||
assert( Saig_ManSimInfoGet(vSimInfo, pObj, iFrame) == SAIG_UND );
|
||||
Saig_ManSimInfoSet( vSimInfo, pObj, iFrame, Value );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the array of PIs for flops that should not be absracted.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Saig_ManExtendCounterExample( Aig_Man_t * p, int iFirstPi, Ssw_Cex_t * pCex, Vec_Ptr_t * vSimInfo, int fVerbose )
|
||||
{
|
||||
Vec_Int_t * vRes, * vResInv, * vUndo, * vVis, * vVis2;
|
||||
int i, f, Value;
|
||||
assert( Aig_ManRegNum(p) > 0 );
|
||||
assert( (unsigned *)Vec_PtrEntry(vSimInfo,1) - (unsigned *)Vec_PtrEntry(vSimInfo,0) >= Aig_BitWordNum(2*(pCex->iFrame+1)) );
|
||||
// start simulation data
|
||||
Value = Saig_ManSimDataInit( p, pCex, vSimInfo, NULL );
|
||||
assert( Value == SAIG_ONE );
|
||||
// select the result
|
||||
vRes = Vec_IntAlloc( 1000 );
|
||||
vResInv = Vec_IntAlloc( 1000 );
|
||||
vVis = Vec_IntAlloc( 1000 );
|
||||
vVis2 = Vec_IntAlloc( 1000 );
|
||||
vUndo = Vec_IntAlloc( 1000 );
|
||||
for ( i = iFirstPi; i < Saig_ManPiNum(p); i++ )
|
||||
{
|
||||
Vec_IntClear( vUndo );
|
||||
for ( f = pCex->iFrame; f >= 0; f-- )
|
||||
if ( !Saig_ManExtendOne( p, pCex, vSimInfo, i, f, vUndo, vVis, vVis2 ) )
|
||||
{
|
||||
Saig_ManExtendUndo( p, vSimInfo, vUndo );
|
||||
break;
|
||||
}
|
||||
if ( f >= 0 )
|
||||
Vec_IntPush( vRes, i );
|
||||
else
|
||||
Vec_IntPush( vResInv, i );
|
||||
}
|
||||
Vec_IntFree( vVis );
|
||||
Vec_IntFree( vVis2 );
|
||||
Vec_IntFree( vUndo );
|
||||
// resimulate to make sure it is valid
|
||||
Value = Saig_ManSimDataInit( p, pCex, vSimInfo, vResInv );
|
||||
assert( Value == SAIG_ONE );
|
||||
Vec_IntFree( vResInv );
|
||||
return vRes;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the array of PIs for flops that should not be absracted.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Saig_ManExtendCounterExampleTest( Aig_Man_t * p, int iFirstPi, Ssw_Cex_t * pCex, int fVerbose )
|
||||
{
|
||||
Vec_Int_t * vRes;
|
||||
Vec_Ptr_t * vSimInfo;
|
||||
int clk;
|
||||
Aig_ManFanoutStart( p );
|
||||
vSimInfo = Vec_PtrAllocSimInfo( Aig_ManObjNumMax(p), Aig_BitWordNum(2*(pCex->iFrame+1)) );
|
||||
clk = clock();
|
||||
vRes = Saig_ManExtendCounterExample( p, iFirstPi, pCex, vSimInfo, fVerbose );
|
||||
if ( fVerbose )
|
||||
{
|
||||
printf( "Total new PIs = %3d. Non-removable PIs = %3d. ", Saig_ManPiNum(p)-iFirstPi, Vec_IntSize(vRes) );
|
||||
PRT( "Time", clock() - clk );
|
||||
}
|
||||
Vec_PtrFree( vSimInfo );
|
||||
Aig_ManFanoutStop( p );
|
||||
return vRes;
|
||||
// Vec_IntFree( vRes );
|
||||
// return NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,443 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [saigSimFast.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Sequential AIG package.]
|
||||
|
||||
Synopsis [Fast sequential AIG simulator.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: saigSimFast.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "saig.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// the AIG manager
|
||||
typedef struct Faig_Man_t_ Faig_Man_t;
|
||||
struct Faig_Man_t_
|
||||
{
|
||||
// parameters
|
||||
int nPis;
|
||||
int nPos;
|
||||
int nCis;
|
||||
int nCos;
|
||||
int nFfs;
|
||||
int nNos;
|
||||
// offsets
|
||||
int nPis1;
|
||||
int nCis1;
|
||||
int nCisNos1;
|
||||
int nCisNosPos1;
|
||||
int nObjs;
|
||||
// allocated data
|
||||
int nWords;
|
||||
int pObjs[0];
|
||||
};
|
||||
|
||||
static inline int Faig_CheckIdPi( Faig_Man_t * p, int i ) { return i >= 1 && i < p->nPis1; }
|
||||
static inline int Faig_CheckIdLo( Faig_Man_t * p, int i ) { return i >= p->nPis1 && i < p->nCis1; }
|
||||
static inline int Faig_CheckIdNo( Faig_Man_t * p, int i ) { return i >= p->nCis1 && i < p->nCisNos1; }
|
||||
static inline int Faig_CheckIdPo( Faig_Man_t * p, int i ) { return i >= p->nCisNos1 && i < p->nCisNosPos1; }
|
||||
static inline int Faig_CheckIdLi( Faig_Man_t * p, int i ) { return i >= p->nCisNosPos1 && i < p->nObjs; }
|
||||
static inline int Faig_CheckIdCo( Faig_Man_t * p, int i ) { return i >= p->nCisNos1 && i < p->nObjs; }
|
||||
static inline int Faig_CheckIdObj( Faig_Man_t * p, int i ) { return i >= 0 && i < p->nObjs; }
|
||||
|
||||
static inline int Faig_ObjIdToNumPi( Faig_Man_t * p, int i ) { assert( Faig_CheckIdPi(p,i) ); return i - 1; }
|
||||
static inline int Faig_ObjIdToNumLo( Faig_Man_t * p, int i ) { assert( Faig_CheckIdLo(p,i) ); return i - p->nPis1; }
|
||||
static inline int Faig_ObjIdToNumNo( Faig_Man_t * p, int i ) { assert( Faig_CheckIdNo(p,i) ); return i - p->nCis1; }
|
||||
static inline int Faig_ObjIdToNumPo( Faig_Man_t * p, int i ) { assert( Faig_CheckIdPo(p,i) ); return i - p->nCisNos1; }
|
||||
static inline int Faig_ObjIdToNumLi( Faig_Man_t * p, int i ) { assert( Faig_CheckIdLi(p,i) ); return i - p->nCisNosPos1; }
|
||||
static inline int Faig_ObjIdToNumCo( Faig_Man_t * p, int i ) { assert( Faig_CheckIdCo(p,i) ); return i - p->nCisNos1; }
|
||||
|
||||
static inline int Faig_ObjLoToLi( Faig_Man_t * p, int i ) { assert( Faig_CheckIdLo(p,i) ); return p->nObjs - (p->nCis1 - i); }
|
||||
static inline int Faig_ObjLiToLo( Faig_Man_t * p, int i ) { assert( Faig_CheckIdLi(p,i) ); return p->nCis1 - (p->nObjs - i); }
|
||||
|
||||
static inline int Faig_NodeChild0( Faig_Man_t * p, int n ) { return p->pObjs[n<<1]; }
|
||||
static inline int Faig_NodeChild1( Faig_Man_t * p, int n ) { return p->pObjs[(n<<1)+1]; }
|
||||
static inline int Faig_CoChild0( Faig_Man_t * p, int n ) { return p->pObjs[(p->nNos<<1)+n]; }
|
||||
static inline int Faig_ObjFaninC( int iFan ) { return iFan & 1; }
|
||||
static inline int Faig_ObjFanin( int iFan ) { return iFan >> 1; }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Checks if the manager is correct.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Faig_ManIsCorrect( Aig_Man_t * pAig )
|
||||
{
|
||||
return Aig_ManObjNumMax(pAig) ==
|
||||
1 + Aig_ManPiNum(pAig) + Aig_ManNodeNum(pAig) + Aig_ManPoNum(pAig);
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates fast simulation manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Faig_Man_t * Faig_ManAlloc( Aig_Man_t * pAig )
|
||||
{
|
||||
Faig_Man_t * p;
|
||||
int nWords;
|
||||
// assert( Faig_ManIsCorrect(pAig) );
|
||||
nWords = 2 * Aig_ManNodeNum(pAig) + Aig_ManPoNum(pAig);
|
||||
p = (Faig_Man_t *)ALLOC( char, sizeof(Faig_Man_t) + sizeof(int) * nWords );
|
||||
//printf( "Allocating %7.2f Mb.\n", 1.0 * (sizeof(Faig_Man_t) + sizeof(int) * nWords)/(1<<20) );
|
||||
memset( p, 0, sizeof(Faig_Man_t) );
|
||||
p->nPis = Aig_ManPiNum(pAig) - Aig_ManRegNum(pAig);
|
||||
p->nPos = Aig_ManPoNum(pAig) - Aig_ManRegNum(pAig);
|
||||
p->nCis = Aig_ManPiNum(pAig);
|
||||
p->nCos = Aig_ManPoNum(pAig);
|
||||
p->nFfs = Aig_ManRegNum(pAig);
|
||||
p->nNos = Aig_ManNodeNum(pAig);
|
||||
// offsets
|
||||
p->nPis1 = p->nPis + 1;
|
||||
p->nCis1 = p->nCis + 1;
|
||||
p->nCisNos1 = p->nCis + p->nNos + 1;
|
||||
p->nCisNosPos1 = p->nCis + p->nNos + p->nPos + 1;
|
||||
p->nObjs = p->nCis + p->nNos + p->nCos + 1;
|
||||
p->nWords = nWords;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates fast simulation manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Faig_Man_t * Faig_ManCreate( Aig_Man_t * pAig )
|
||||
{
|
||||
Faig_Man_t * p;
|
||||
Aig_Obj_t * pObj;
|
||||
int i, iWord = 0;
|
||||
p = Faig_ManAlloc( pAig );
|
||||
Aig_ManForEachNode( pAig, pObj, i )
|
||||
{
|
||||
p->pObjs[iWord++] = (Aig_ObjFaninId0(pObj) << 1) | Aig_ObjFaninC0(pObj);
|
||||
p->pObjs[iWord++] = (Aig_ObjFaninId1(pObj) << 1) | Aig_ObjFaninC1(pObj);
|
||||
}
|
||||
Aig_ManForEachPo( pAig, pObj, i )
|
||||
p->pObjs[iWord++] = (Aig_ObjFaninId0(pObj) << 1) | Aig_ObjFaninC0(pObj);
|
||||
assert( iWord == p->nWords );
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Simulates one node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline unsigned Faig_SimulateNode( Faig_Man_t * p, int Id, unsigned * pSimInfo )
|
||||
{
|
||||
int n = Faig_ObjIdToNumNo( p, Id );
|
||||
int iFan0 = Faig_NodeChild0( p, n );
|
||||
int iFan1 = Faig_NodeChild1( p, n );
|
||||
if ( Faig_ObjFaninC(iFan0) && Faig_ObjFaninC(iFan1) )
|
||||
return ~(pSimInfo[Faig_ObjFanin(iFan0)] | pSimInfo[Faig_ObjFanin(iFan1)]);
|
||||
if ( Faig_ObjFaninC(iFan0) && !Faig_ObjFaninC(iFan1) )
|
||||
return (~pSimInfo[Faig_ObjFanin(iFan0)] & pSimInfo[Faig_ObjFanin(iFan1)]);
|
||||
if ( !Faig_ObjFaninC(iFan0) && Faig_ObjFaninC(iFan1) )
|
||||
return (pSimInfo[Faig_ObjFanin(iFan0)] & ~pSimInfo[Faig_ObjFanin(iFan1)]);
|
||||
// if ( !Faig_ObjFaninC(iFan0) && !Faig_ObjFaninC(iFan1) )
|
||||
return (pSimInfo[Faig_ObjFanin(iFan0)] & pSimInfo[Faig_ObjFanin(iFan1)]);
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Simulates one node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline unsigned Faig_SimulateCo( Faig_Man_t * p, int Id, unsigned * pSimInfo )
|
||||
{
|
||||
int n = Faig_ObjIdToNumCo( p, Id );
|
||||
int iFan0 = Faig_CoChild0( p, n );
|
||||
if ( Faig_ObjFaninC(iFan0) )
|
||||
return ~pSimInfo[Faig_ObjFanin(iFan0)];
|
||||
// if ( !Faig_ObjFaninC(iFan0) )
|
||||
return pSimInfo[Faig_ObjFanin(iFan0)];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline unsigned Faig_SimulateRandomShift( unsigned uOld )
|
||||
{
|
||||
return (uOld << 16) | ((uOld ^ Aig_ManRandom(0)) & 0xffff);
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline unsigned Faig_SimulateTransferShift( unsigned uOld, unsigned uNew )
|
||||
{
|
||||
return (uOld << 16) | (uNew & 0xffff);
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Simulates the timeframes.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int * Faig_ManSimulateFrames( Faig_Man_t * p, int nFrames, int nPref, int fTrans )
|
||||
{
|
||||
int * pNumOnes = CALLOC( unsigned, p->nObjs );
|
||||
unsigned * pSimInfo = ALLOC( unsigned, p->nObjs );
|
||||
int f, i;
|
||||
//printf( "Allocating %7.2f Mb.\n", 1.0 * 4 * p->nObjs/(1<<20) );
|
||||
//printf( "Allocating %7.2f Mb.\n", 1.0 * 4 * p->nObjs/(1<<20) );
|
||||
// set constant 1
|
||||
pSimInfo[0] = ~0;
|
||||
for ( f = 0; f < nFrames; f++ )
|
||||
{
|
||||
if ( fTrans )
|
||||
{
|
||||
for ( i = 1; i < p->nPis1; i++ )
|
||||
pSimInfo[i] = f? Faig_SimulateRandomShift( pSimInfo[i] ) : Aig_ManRandom( 0 );
|
||||
for ( ; i < p->nCis1; i++ )
|
||||
pSimInfo[i] = f? Faig_SimulateTransferShift( pSimInfo[i], pSimInfo[Faig_ObjLoToLi(p,i)] ) : 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( i = 1; i < p->nPis1; i++ )
|
||||
pSimInfo[i] = Aig_ManRandom( 0 );
|
||||
for ( ; i < p->nCis1; i++ )
|
||||
pSimInfo[i] = f? pSimInfo[Faig_ObjLoToLi(p,i)] : 0;
|
||||
}
|
||||
for ( ; i < p->nCisNos1; i++ )
|
||||
pSimInfo[i] = Faig_SimulateNode( p, i, pSimInfo );
|
||||
for ( ; i < p->nObjs; i++ )
|
||||
pSimInfo[i] = Faig_SimulateCo( p, i, pSimInfo );
|
||||
if ( f < nPref )
|
||||
continue;
|
||||
if ( fTrans )
|
||||
{
|
||||
for ( i = 0; i < p->nObjs; i++ )
|
||||
pNumOnes[i] += Aig_WordCountOnes( (pSimInfo[i] ^ (pSimInfo[i] >> 16)) & 0xffff );
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( i = 0; i < p->nObjs; i++ )
|
||||
pNumOnes[i] += Aig_WordCountOnes( pSimInfo[i] );
|
||||
}
|
||||
}
|
||||
free( pSimInfo );
|
||||
return pNumOnes;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes switching activity of one node.]
|
||||
|
||||
Description [Uses the formula: Switching = 2 * nOnes * nZeros / (nTotal ^ 2) ]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
float Faig_ManComputeSwitching( int nOnes, int nSimWords )
|
||||
{
|
||||
int nTotal = 32 * nSimWords;
|
||||
return (float)2.0 * nOnes / nTotal * (nTotal - nOnes) / nTotal;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes switching activity of one node.]
|
||||
|
||||
Description [Uses the formula: Switching = 2 * nOnes * nZeros / (nTotal ^ 2) ]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
float Faig_ManComputeProbOne( int nOnes, int nSimWords )
|
||||
{
|
||||
int nTotal = 32 * nSimWords;
|
||||
return (float)nOnes / nTotal;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Faig_ManComputeSwitchProbs( Aig_Man_t * p, int nFrames, int nPref, int fProbOne )
|
||||
{
|
||||
extern char * Abc_FrameReadFlag( char * pFlag );
|
||||
int fTrans = 1;
|
||||
Faig_Man_t * pAig;
|
||||
Vec_Int_t * vSwitching;
|
||||
int * pProbs;
|
||||
float * pSwitching;
|
||||
int nFramesReal, clk, clkTotal = clock();
|
||||
if ( fProbOne )
|
||||
fTrans = 0;
|
||||
vSwitching = Vec_IntStart( Aig_ManObjNumMax(p) );
|
||||
pSwitching = (float *)vSwitching->pArray;
|
||||
clk = clock();
|
||||
pAig = Faig_ManCreate( p );
|
||||
//PRT( "\nCreation ", clock() - clk );
|
||||
Aig_ManRandom( 1 );
|
||||
// get the number of frames to simulate
|
||||
// if the parameter "seqsimframes" is defined, use it
|
||||
// otherwise, use the given number of frames "nFrames"
|
||||
nFramesReal = nFrames;
|
||||
if ( Abc_FrameReadFlag("seqsimframes") )
|
||||
nFramesReal = atoi( Abc_FrameReadFlag("seqsimframes") );
|
||||
if ( nFramesReal <= nPref )
|
||||
{
|
||||
printf( "The total number of frames (%d) should exceed prefix (%d).\n", nFramesReal, nPref );
|
||||
printf( "Setting the total number of frames to be %d.\n", nFrames );
|
||||
nFramesReal = nFrames;
|
||||
}
|
||||
//printf( "Simulating %d frames.\n", nFramesReal );
|
||||
clk = clock();
|
||||
pProbs = Faig_ManSimulateFrames( pAig, nFramesReal, nPref, fTrans );
|
||||
//PRT( "Simulation", clock() - clk );
|
||||
clk = clock();
|
||||
if ( fTrans )
|
||||
{
|
||||
Aig_Obj_t * pObj;
|
||||
int i, Counter = 0;
|
||||
pObj = Aig_ManConst1(p);
|
||||
pSwitching[pObj->Id] = Faig_ManComputeProbOne( pProbs[Counter++], (nFramesReal - nPref)/2 );
|
||||
Aig_ManForEachPi( p, pObj, i )
|
||||
pSwitching[pObj->Id] = Faig_ManComputeProbOne( pProbs[Counter++], (nFramesReal - nPref)/2 );
|
||||
Aig_ManForEachNode( p, pObj, i )
|
||||
pSwitching[pObj->Id] = Faig_ManComputeProbOne( pProbs[Counter++], (nFramesReal - nPref)/2 );
|
||||
Aig_ManForEachPo( p, pObj, i )
|
||||
pSwitching[pObj->Id] = Faig_ManComputeProbOne( pProbs[Counter++], (nFramesReal - nPref)/2 );
|
||||
assert( Counter == pAig->nObjs );
|
||||
}
|
||||
else if ( fProbOne )
|
||||
{
|
||||
Aig_Obj_t * pObj;
|
||||
int i, Counter = 0;
|
||||
pObj = Aig_ManConst1(p);
|
||||
pSwitching[pObj->Id] = Faig_ManComputeProbOne( pProbs[Counter++], nFramesReal - nPref );
|
||||
Aig_ManForEachPi( p, pObj, i )
|
||||
pSwitching[pObj->Id] = Faig_ManComputeProbOne( pProbs[Counter++], nFramesReal - nPref );
|
||||
Aig_ManForEachNode( p, pObj, i )
|
||||
pSwitching[pObj->Id] = Faig_ManComputeProbOne( pProbs[Counter++], nFramesReal - nPref );
|
||||
Aig_ManForEachPo( p, pObj, i )
|
||||
pSwitching[pObj->Id] = Faig_ManComputeProbOne( pProbs[Counter++], nFramesReal - nPref );
|
||||
assert( Counter == pAig->nObjs );
|
||||
}
|
||||
else
|
||||
{
|
||||
Aig_Obj_t * pObj;
|
||||
int i, Counter = 0;
|
||||
pObj = Aig_ManConst1(p);
|
||||
pSwitching[pObj->Id] = Faig_ManComputeSwitching( pProbs[Counter++], nFramesReal - nPref );
|
||||
Aig_ManForEachPi( p, pObj, i )
|
||||
pSwitching[pObj->Id] = Faig_ManComputeSwitching( pProbs[Counter++], nFramesReal - nPref );
|
||||
Aig_ManForEachNode( p, pObj, i )
|
||||
pSwitching[pObj->Id] = Faig_ManComputeSwitching( pProbs[Counter++], nFramesReal - nPref );
|
||||
Aig_ManForEachPo( p, pObj, i )
|
||||
pSwitching[pObj->Id] = Faig_ManComputeSwitching( pProbs[Counter++], nFramesReal - nPref );
|
||||
assert( Counter == pAig->nObjs );
|
||||
}
|
||||
free( pProbs );
|
||||
free( pAig );
|
||||
//PRT( "Switch ", clock() - clk );
|
||||
//PRT( "TOTAL ", clock() - clkTotal );
|
||||
return vSwitching;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes probability of switching (or of being 1).]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Saig_ManComputeSwitchProbs( Aig_Man_t * p, int nFrames, int nPref, int fProbOne )
|
||||
{
|
||||
return Faig_ManComputeSwitchProbs( p, nFrames, nPref, fProbOne );
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,726 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [saigSimMv.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Sequential AIG package.]
|
||||
|
||||
Synopsis [Multi-valued simulation.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: saigSimMv.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "saig.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define SAIG_DIFF_VALUES 8
|
||||
#define SAIG_UNDEF_VALUE 0x1ffffffe //536870910
|
||||
|
||||
// old AIG
|
||||
typedef struct Saig_MvObj_t_ Saig_MvObj_t;
|
||||
struct Saig_MvObj_t_
|
||||
{
|
||||
int iFan0;
|
||||
int iFan1;
|
||||
unsigned Type : 3;
|
||||
unsigned Value : 29;
|
||||
};
|
||||
|
||||
// new AIG
|
||||
typedef struct Saig_MvAnd_t_ Saig_MvAnd_t;
|
||||
struct Saig_MvAnd_t_
|
||||
{
|
||||
int iFan0;
|
||||
int iFan1;
|
||||
int iNext;
|
||||
};
|
||||
|
||||
// simulation manager
|
||||
typedef struct Saig_MvMan_t_ Saig_MvMan_t;
|
||||
struct Saig_MvMan_t_
|
||||
{
|
||||
// user data
|
||||
Aig_Man_t * pAig; // original AIG
|
||||
// parameters
|
||||
int nStatesMax; // maximum number of states
|
||||
int nLevelsMax; // maximum number of levels
|
||||
int nValuesMax; // maximum number of values
|
||||
int nFlops; // number of flops
|
||||
// compacted AIG
|
||||
Saig_MvObj_t * pAigOld; // AIG objects
|
||||
Vec_Ptr_t * vFlops; // collected flops
|
||||
Vec_Ptr_t * vTired; // collected flops
|
||||
int * pTStates; // hash table for states
|
||||
int nTStatesSize; // hash table size
|
||||
Aig_MmFixed_t * pMemStates; // memory for states
|
||||
Vec_Ptr_t * vStates; // reached states
|
||||
int * pRegsUndef; // count the number of undef values
|
||||
int ** pRegsValues; // write the first different values
|
||||
int * nRegsValues; // count the number of different values
|
||||
int nRUndefs; // the number of undef registers
|
||||
int nRValues[SAIG_DIFF_VALUES+1]; // the number of registers with given values
|
||||
// internal AIG
|
||||
Saig_MvAnd_t * pAigNew; // AIG nodes
|
||||
int nObjsAlloc; // the number of objects allocated
|
||||
int nObjs; // the number of objects
|
||||
int nPis; // the number of primary inputs
|
||||
int * pTNodes; // hash table
|
||||
int nTNodesSize; // hash table size
|
||||
unsigned char * pLevels; // levels of AIG nodes
|
||||
};
|
||||
|
||||
static inline int Saig_MvObjFaninC0( Saig_MvObj_t * pObj ) { return pObj->iFan0 & 1; }
|
||||
static inline int Saig_MvObjFaninC1( Saig_MvObj_t * pObj ) { return pObj->iFan1 & 1; }
|
||||
static inline int Saig_MvObjFanin0( Saig_MvObj_t * pObj ) { return pObj->iFan0 >> 1; }
|
||||
static inline int Saig_MvObjFanin1( Saig_MvObj_t * pObj ) { return pObj->iFan1 >> 1; }
|
||||
|
||||
static inline int Saig_MvConst0() { return 1; }
|
||||
static inline int Saig_MvConst1() { return 0; }
|
||||
static inline int Saig_MvConst( int c ) { return !c; }
|
||||
static inline int Saig_MvUndef() { return SAIG_UNDEF_VALUE; }
|
||||
|
||||
static inline int Saig_MvIsConst0( int iNode ) { return iNode == 1; }
|
||||
static inline int Saig_MvIsConst1( int iNode ) { return iNode == 0; }
|
||||
static inline int Saig_MvIsConst( int iNode ) { return iNode < 2; }
|
||||
static inline int Saig_MvIsUndef( int iNode ) { return iNode == SAIG_UNDEF_VALUE;}
|
||||
|
||||
static inline int Saig_MvRegular( int iNode ) { return (iNode & ~01); }
|
||||
static inline int Saig_MvNot( int iNode ) { return (iNode ^ 01); }
|
||||
static inline int Saig_MvNotCond( int iNode, int c ) { return (iNode ^ (c)); }
|
||||
static inline int Saig_MvIsComplement( int iNode ) { return (int)(iNode & 01); }
|
||||
|
||||
static inline int Saig_MvLit2Var( int iNode ) { return (iNode >> 1); }
|
||||
static inline int Saig_MvVar2Lit( int iVar ) { return (iVar << 1); }
|
||||
static inline int Saig_MvLev( Saig_MvMan_t * p, int iNode ) { return p->pLevels[iNode >> 1]; }
|
||||
|
||||
// iterator over compacted objects
|
||||
#define Saig_MvManForEachObj( pAig, pEntry ) \
|
||||
for ( pEntry = pAig; pEntry->Type != AIG_OBJ_VOID; pEntry++ )
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates reduced manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Saig_MvObj_t * Saig_ManCreateReducedAig( Aig_Man_t * p, Vec_Ptr_t ** pvFlops )
|
||||
{
|
||||
Saig_MvObj_t * pAig, * pEntry;
|
||||
Aig_Obj_t * pObj;
|
||||
int i;
|
||||
*pvFlops = Vec_PtrAlloc( Aig_ManRegNum(p) );
|
||||
pAig = CALLOC( Saig_MvObj_t, Aig_ManObjNumMax(p)+1 );
|
||||
Aig_ManForEachObj( p, pObj, i )
|
||||
{
|
||||
pEntry = pAig + i;
|
||||
pEntry->Type = pObj->Type;
|
||||
if ( Aig_ObjIsPi(pObj) || i == 0 )
|
||||
{
|
||||
if ( Saig_ObjIsLo(p, pObj) )
|
||||
{
|
||||
pEntry->iFan0 = (Saig_ObjLoToLi(p, pObj)->Id << 1);
|
||||
pEntry->iFan1 = -1;
|
||||
Vec_PtrPush( *pvFlops, pEntry );
|
||||
}
|
||||
continue;
|
||||
}
|
||||
pEntry->iFan0 = (Aig_ObjFaninId0(pObj) << 1) | Aig_ObjFaninC0(pObj);
|
||||
if ( Aig_ObjIsPo(pObj) )
|
||||
continue;
|
||||
assert( Aig_ObjIsNode(pObj) );
|
||||
pEntry->iFan1 = (Aig_ObjFaninId1(pObj) << 1) | Aig_ObjFaninC1(pObj);
|
||||
}
|
||||
pEntry = pAig + Aig_ManObjNumMax(p);
|
||||
pEntry->Type = AIG_OBJ_VOID;
|
||||
return pAig;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates a new node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Saig_MvCreateObj( Saig_MvMan_t * p, int iFan0, int iFan1 )
|
||||
{
|
||||
Saig_MvAnd_t * pNode;
|
||||
if ( p->nObjs == p->nObjsAlloc )
|
||||
{
|
||||
p->pAigNew = REALLOC( Saig_MvAnd_t, p->pAigNew, 2*p->nObjsAlloc );
|
||||
p->pLevels = REALLOC( unsigned char, p->pLevels, 2*p->nObjsAlloc );
|
||||
p->nObjsAlloc *= 2;
|
||||
}
|
||||
pNode = p->pAigNew + p->nObjs;
|
||||
pNode->iFan0 = iFan0;
|
||||
pNode->iFan1 = iFan1;
|
||||
pNode->iNext = 0;
|
||||
if ( iFan0 || iFan1 )
|
||||
p->pLevels[p->nObjs] = 1 + AIG_MAX( Saig_MvLev(p, iFan0), Saig_MvLev(p, iFan1) );
|
||||
else
|
||||
p->pLevels[p->nObjs] = 0, p->nPis++;
|
||||
return p->nObjs++;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates multi-valued simulation manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Saig_MvMan_t * Saig_MvManStart( Aig_Man_t * pAig )
|
||||
{
|
||||
Saig_MvMan_t * p;
|
||||
int i;
|
||||
assert( Aig_ManRegNum(pAig) > 0 );
|
||||
p = (Saig_MvMan_t *)ALLOC( Saig_MvMan_t, 1 );
|
||||
memset( p, 0, sizeof(Saig_MvMan_t) );
|
||||
// set parameters
|
||||
p->pAig = pAig;
|
||||
p->nStatesMax = 200;
|
||||
p->nLevelsMax = 4;
|
||||
p->nValuesMax = SAIG_DIFF_VALUES;
|
||||
p->nFlops = Aig_ManRegNum(pAig);
|
||||
// compacted AIG
|
||||
p->pAigOld = Saig_ManCreateReducedAig( pAig, &p->vFlops );
|
||||
p->nTStatesSize = Aig_PrimeCudd( p->nStatesMax );
|
||||
p->pTStates = CALLOC( int, p->nTStatesSize );
|
||||
p->pMemStates = Aig_MmFixedStart( sizeof(int) * (p->nFlops+1), p->nStatesMax );
|
||||
p->vStates = Vec_PtrAlloc( p->nStatesMax );
|
||||
Vec_PtrPush( p->vStates, NULL );
|
||||
p->pRegsUndef = CALLOC( int, p->nFlops );
|
||||
p->pRegsValues = ALLOC( int *, p->nFlops );
|
||||
p->pRegsValues[0] = ALLOC( int, p->nValuesMax * p->nFlops );
|
||||
for ( i = 1; i < p->nFlops; i++ )
|
||||
p->pRegsValues[i] = p->pRegsValues[i-1] + p->nValuesMax;
|
||||
p->nRegsValues = CALLOC( int, p->nFlops );
|
||||
p->vTired = Vec_PtrAlloc( 100 );
|
||||
// internal AIG
|
||||
p->nObjsAlloc = 1000000;
|
||||
p->pAigNew = ALLOC( Saig_MvAnd_t, p->nObjsAlloc );
|
||||
p->nTNodesSize = Aig_PrimeCudd( p->nObjsAlloc / 3 );
|
||||
p->pTNodes = CALLOC( int, p->nTNodesSize );
|
||||
p->pLevels = ALLOC( unsigned char, p->nObjsAlloc );
|
||||
Saig_MvCreateObj( p, 0, 0 );
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Destroys multi-valued simulation manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Saig_MvManStop( Saig_MvMan_t * p )
|
||||
{
|
||||
Aig_MmFixedStop( p->pMemStates, 0 );
|
||||
Vec_PtrFree( p->vStates );
|
||||
Vec_PtrFree( p->vFlops );
|
||||
Vec_PtrFree( p->vTired );
|
||||
free( p->pRegsValues[0] );
|
||||
free( p->pRegsValues );
|
||||
free( p->nRegsValues );
|
||||
free( p->pRegsUndef );
|
||||
free( p->pAigOld );
|
||||
free( p->pTStates );
|
||||
free( p->pAigNew );
|
||||
free( p->pTNodes );
|
||||
free( p->pLevels );
|
||||
free( p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Hashing the node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Saig_MvHash( int iFan0, int iFan1, int TableSize )
|
||||
{
|
||||
unsigned Key = 0;
|
||||
assert( iFan0 < iFan1 );
|
||||
Key ^= Saig_MvLit2Var(iFan0) * 7937;
|
||||
Key ^= Saig_MvLit2Var(iFan1) * 2971;
|
||||
Key ^= Saig_MvIsComplement(iFan0) * 911;
|
||||
Key ^= Saig_MvIsComplement(iFan1) * 353;
|
||||
return (int)(Key % TableSize);
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the place where this node is stored (or should be stored).]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int * Saig_MvTableFind( Saig_MvMan_t * p, int iFan0, int iFan1 )
|
||||
{
|
||||
Saig_MvAnd_t * pEntry;
|
||||
int * pPlace = p->pTNodes + Saig_MvHash( iFan0, iFan1, p->nTNodesSize );
|
||||
for ( pEntry = (*pPlace)? p->pAigNew + *pPlace : NULL; pEntry;
|
||||
pPlace = &pEntry->iNext, pEntry = (*pPlace)? p->pAigNew + *pPlace : NULL )
|
||||
if ( pEntry->iFan0 == iFan0 && pEntry->iFan1 == iFan1 )
|
||||
break;
|
||||
return pPlace;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs an AND-operation.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Saig_MvAnd( Saig_MvMan_t * p, int iFan0, int iFan1 )
|
||||
{
|
||||
if ( iFan0 == iFan1 )
|
||||
return iFan0;
|
||||
if ( iFan0 == Saig_MvNot(iFan1) )
|
||||
return Saig_MvConst0();
|
||||
if ( Saig_MvIsConst(iFan0) )
|
||||
return Saig_MvIsConst1(iFan0) ? iFan1 : Saig_MvConst0();
|
||||
if ( Saig_MvIsConst(iFan1) )
|
||||
return Saig_MvIsConst1(iFan1) ? iFan0 : Saig_MvConst0();
|
||||
if ( Saig_MvIsUndef(iFan0) || Saig_MvIsUndef(iFan1) )
|
||||
return Saig_MvUndef();
|
||||
if ( Saig_MvLev(p, iFan0) >= p->nLevelsMax || Saig_MvLev(p, iFan1) >= p->nLevelsMax )
|
||||
return Saig_MvUndef();
|
||||
|
||||
// return Saig_MvUndef();
|
||||
|
||||
if ( iFan0 > iFan1 )
|
||||
{
|
||||
int Temp = iFan0;
|
||||
iFan0 = iFan1;
|
||||
iFan1 = Temp;
|
||||
}
|
||||
{
|
||||
int * pPlace;
|
||||
pPlace = Saig_MvTableFind( p, iFan0, iFan1 );
|
||||
if ( *pPlace == 0 )
|
||||
*pPlace = Saig_MvCreateObj( p, iFan0, iFan1 );
|
||||
return Saig_MvVar2Lit( *pPlace );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Propagates one edge.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Saig_MvSimulateValue0( Saig_MvObj_t * pAig, Saig_MvObj_t * pObj )
|
||||
{
|
||||
Saig_MvObj_t * pObj0 = pAig + Saig_MvObjFanin0(pObj);
|
||||
if ( Saig_MvIsUndef( pObj0->Value ) )
|
||||
return Saig_MvUndef();
|
||||
return Saig_MvNotCond( pObj0->Value, Saig_MvObjFaninC0(pObj) );
|
||||
}
|
||||
static inline int Saig_MvSimulateValue1( Saig_MvObj_t * pAig, Saig_MvObj_t * pObj )
|
||||
{
|
||||
Saig_MvObj_t * pObj1 = pAig + Saig_MvObjFanin1(pObj);
|
||||
if ( Saig_MvIsUndef( pObj1->Value ) )
|
||||
return Saig_MvUndef();
|
||||
return Saig_MvNotCond( pObj1->Value, Saig_MvObjFaninC1(pObj) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs one iteration of simulation.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Saig_MvSimulateFrame( Saig_MvMan_t * p, int fFirst )
|
||||
{
|
||||
int fPrintState = 0;
|
||||
Saig_MvObj_t * pEntry;
|
||||
int i, NewValue;
|
||||
Saig_MvManForEachObj( p->pAigOld, pEntry )
|
||||
{
|
||||
if ( pEntry->Type == AIG_OBJ_AND )
|
||||
{
|
||||
pEntry->Value = Saig_MvAnd( p,
|
||||
Saig_MvSimulateValue0(p->pAigOld, pEntry),
|
||||
Saig_MvSimulateValue1(p->pAigOld, pEntry) );
|
||||
/*
|
||||
printf( "%d = %d%s * %d%s --> %d\n", pEntry - p->pAigOld,
|
||||
Saig_MvObjFanin0(pEntry), Saig_MvObjFaninC0(pEntry)? "-":"+",
|
||||
Saig_MvObjFanin1(pEntry), Saig_MvObjFaninC1(pEntry)? "-":"+", pEntry->Value );
|
||||
*/
|
||||
}
|
||||
else if ( pEntry->Type == AIG_OBJ_PO )
|
||||
pEntry->Value = Saig_MvSimulateValue0(p->pAigOld, pEntry);
|
||||
else if ( pEntry->Type == AIG_OBJ_PI )
|
||||
{
|
||||
if ( pEntry->iFan1 == 0 ) // true PI
|
||||
pEntry->Value = Saig_MvVar2Lit( Saig_MvCreateObj( p, 0, 0 ) );
|
||||
// else if ( fFirst ) // register output
|
||||
// pEntry->Value = Saig_MvConst0();
|
||||
// else
|
||||
// pEntry->Value = Saig_MvSimulateValue0(p->pAigOld, pEntry);
|
||||
}
|
||||
else if ( pEntry->Type == AIG_OBJ_CONST1 )
|
||||
pEntry->Value = Saig_MvConst1();
|
||||
else if ( pEntry->Type != AIG_OBJ_NONE )
|
||||
assert( 0 );
|
||||
}
|
||||
Vec_PtrClear( p->vTired );
|
||||
Vec_PtrForEachEntry( p->vFlops, pEntry, i )
|
||||
{
|
||||
NewValue = Saig_MvSimulateValue0(p->pAigOld, pEntry);
|
||||
if ( NewValue != (int)pEntry->Value )
|
||||
Vec_PtrPush( p->vTired, pEntry );
|
||||
pEntry->Value = NewValue;
|
||||
if ( !fPrintState )
|
||||
continue;
|
||||
if ( pEntry->Value == 536870910 )
|
||||
printf( "* " );
|
||||
else
|
||||
printf( "%d ", pEntry->Value );
|
||||
}
|
||||
if ( fPrintState )
|
||||
printf( "\n" );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes hash value of the node using its simulation info.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Saig_MvSimHash( int * pState, int nFlops, int TableSize )
|
||||
{
|
||||
static int s_SPrimes[128] = {
|
||||
1009, 1049, 1093, 1151, 1201, 1249, 1297, 1361, 1427, 1459,
|
||||
1499, 1559, 1607, 1657, 1709, 1759, 1823, 1877, 1933, 1997,
|
||||
2039, 2089, 2141, 2213, 2269, 2311, 2371, 2411, 2467, 2543,
|
||||
2609, 2663, 2699, 2741, 2797, 2851, 2909, 2969, 3037, 3089,
|
||||
3169, 3221, 3299, 3331, 3389, 3461, 3517, 3557, 3613, 3671,
|
||||
3719, 3779, 3847, 3907, 3943, 4013, 4073, 4129, 4201, 4243,
|
||||
4289, 4363, 4441, 4493, 4549, 4621, 4663, 4729, 4793, 4871,
|
||||
4933, 4973, 5021, 5087, 5153, 5227, 5281, 5351, 5417, 5471,
|
||||
5519, 5573, 5651, 5693, 5749, 5821, 5861, 5923, 6011, 6073,
|
||||
6131, 6199, 6257, 6301, 6353, 6397, 6481, 6563, 6619, 6689,
|
||||
6737, 6803, 6863, 6917, 6977, 7027, 7109, 7187, 7237, 7309,
|
||||
7393, 7477, 7523, 7561, 7607, 7681, 7727, 7817, 7877, 7933,
|
||||
8011, 8039, 8059, 8081, 8093, 8111, 8123, 8147
|
||||
};
|
||||
unsigned uHash = 0;
|
||||
int i;
|
||||
for ( i = 0; i < nFlops; i++ )
|
||||
uHash ^= pState[i] * s_SPrimes[i & 0x7F];
|
||||
return (int)(uHash % TableSize);
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the place where this state is stored (or should be stored).]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int * Saig_MvSimTableFind( Saig_MvMan_t * p, int * pState )
|
||||
{
|
||||
int * pEntry;
|
||||
int * pPlace = p->pTStates + Saig_MvSimHash( pState+1, p->nFlops, p->nTStatesSize );
|
||||
for ( pEntry = (*pPlace)? Vec_PtrEntry(p->vStates, *pPlace) : NULL; pEntry;
|
||||
pPlace = pEntry, pEntry = (*pPlace)? Vec_PtrEntry(p->vStates, *pPlace) : NULL )
|
||||
if ( memcmp( pEntry+1, pState+1, sizeof(int)*p->nFlops ) == 0 )
|
||||
break;
|
||||
return pPlace;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Saves current state.]
|
||||
|
||||
Description [Returns -1 if there is no fixed point.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Saig_MvSaveState( Saig_MvMan_t * p, int * piReg )
|
||||
{
|
||||
Saig_MvObj_t * pEntry;
|
||||
int i, k, * pState, * pPlace, nMaxUndefs = 0;
|
||||
int iTimesOld, iTimesNew;
|
||||
*piReg = -1;
|
||||
pState = (int *)Aig_MmFixedEntryFetch( p->pMemStates );
|
||||
pState[0] = 0;
|
||||
Vec_PtrForEachEntry( p->vFlops, pEntry, i )
|
||||
{
|
||||
iTimesOld = p->nRegsValues[i];
|
||||
// count the number of different def values
|
||||
if ( !Saig_MvIsUndef( pEntry->Value ) && p->nRegsValues[i] < p->nValuesMax )
|
||||
{
|
||||
for ( k = 0; k < p->nRegsValues[i]; k++ )
|
||||
if ( p->pRegsValues[i][k] == (int)pEntry->Value )
|
||||
break;
|
||||
if ( k == p->nRegsValues[i] )
|
||||
p->pRegsValues[i][ p->nRegsValues[i]++ ] = pEntry->Value;
|
||||
}
|
||||
else // retire this register (consider moving this up!)
|
||||
{
|
||||
pEntry->Value = Saig_MvUndef();
|
||||
p->nRegsValues[i] = SAIG_DIFF_VALUES+1;
|
||||
}
|
||||
iTimesNew = p->nRegsValues[i];
|
||||
// count the number of times
|
||||
if ( iTimesOld != iTimesNew )
|
||||
{
|
||||
if ( iTimesOld > 0 )
|
||||
p->nRValues[iTimesOld]--;
|
||||
if ( iTimesNew <= SAIG_DIFF_VALUES )
|
||||
p->nRValues[iTimesNew]++;
|
||||
}
|
||||
// count the number of undef values
|
||||
if ( Saig_MvIsUndef( pEntry->Value ) )
|
||||
{
|
||||
if ( p->pRegsUndef[i]++ == 0 )
|
||||
p->nRUndefs++;
|
||||
}
|
||||
// find def reg with the max number of undef values
|
||||
if ( nMaxUndefs < p->pRegsUndef[i] )
|
||||
{
|
||||
nMaxUndefs = p->pRegsUndef[i];
|
||||
*piReg = i;
|
||||
}
|
||||
// remember state
|
||||
pState[i+1] = pEntry->Value;
|
||||
|
||||
// if ( pEntry->Value == 536870910 )
|
||||
// printf( "* " );
|
||||
// else
|
||||
// printf( "%d ", pEntry->Value );
|
||||
}
|
||||
//printf( "\n" );
|
||||
pPlace = Saig_MvSimTableFind( p, pState );
|
||||
if ( *pPlace )
|
||||
return *pPlace;
|
||||
*pPlace = Vec_PtrSize( p->vStates );
|
||||
Vec_PtrPush( p->vStates, pState );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs multi-valued simulation.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Saig_MvManPostProcess( Saig_MvMan_t * p, int iState )
|
||||
{
|
||||
Saig_MvObj_t * pEntry;
|
||||
int i, k, j, nTotal = 0, * pState, Counter = 0, iFlop;
|
||||
Vec_Int_t * vUniques = Vec_IntAlloc( 100 );
|
||||
Vec_Int_t * vCounter = Vec_IntAlloc( 100 );
|
||||
// count registers that never became undef
|
||||
Vec_PtrForEachEntry( p->vFlops, pEntry, i )
|
||||
if ( p->pRegsUndef[i] == 0 )
|
||||
nTotal++;
|
||||
printf( "The number of registers that never became undef = %d. (Total = %d.)\n", nTotal, p->nFlops );
|
||||
Vec_PtrForEachEntry( p->vFlops, pEntry, i )
|
||||
{
|
||||
if ( p->pRegsUndef[i] )
|
||||
continue;
|
||||
Vec_IntForEachEntry( vUniques, iFlop, k )
|
||||
{
|
||||
Vec_PtrForEachEntryStart( p->vStates, pState, j, 1 )
|
||||
if ( pState[iFlop+1] != pState[i+1] )
|
||||
break;
|
||||
if ( j == Vec_PtrSize(p->vStates) )
|
||||
{
|
||||
Vec_IntAddToEntry( vCounter, k, 1 );
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( k == Vec_IntSize(vUniques) )
|
||||
{
|
||||
Vec_IntPush( vUniques, i );
|
||||
Vec_IntPush( vCounter, 1 );
|
||||
}
|
||||
}
|
||||
Vec_IntForEachEntry( vUniques, iFlop, i )
|
||||
{
|
||||
printf( "FLOP %5d : (%3d) ", iFlop, Vec_IntEntry(vCounter,i) );
|
||||
/*
|
||||
for ( k = 0; k < p->nRegsValues[iFlop]; k++ )
|
||||
if ( p->pRegsValues[iFlop][k] == 536870910 )
|
||||
printf( "* " );
|
||||
else
|
||||
printf( "%d ", p->pRegsValues[iFlop][k] );
|
||||
printf( "\n" );
|
||||
*/
|
||||
Vec_PtrForEachEntryStart( p->vStates, pState, k, 1 )
|
||||
{
|
||||
if ( k == iState+1 )
|
||||
printf( " # " );
|
||||
if ( pState[iFlop+1] == 536870910 )
|
||||
printf( "*" );
|
||||
else
|
||||
printf( "%d", pState[iFlop+1] );
|
||||
}
|
||||
printf( "\n" );
|
||||
// if ( ++Counter == 10 )
|
||||
// break;
|
||||
}
|
||||
|
||||
Vec_IntFree( vUniques );
|
||||
Vec_IntFree( vCounter );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs multi-valued simulation.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Saig_MvManSimulate( Aig_Man_t * pAig, int fVerbose )
|
||||
{
|
||||
Saig_MvMan_t * p;
|
||||
Saig_MvObj_t * pEntry;
|
||||
int f, i, k, iRegMax, iState, clk = clock();
|
||||
// start the manager
|
||||
p = Saig_MvManStart( pAig );
|
||||
PRT( "Constructing the problem", clock() - clk );
|
||||
clk = clock();
|
||||
// initiliaze registers
|
||||
Vec_PtrForEachEntry( p->vFlops, pEntry, i )
|
||||
{
|
||||
pEntry->Value = Saig_MvConst0();
|
||||
if ( pEntry->iFan0 == 1 )
|
||||
printf( "Constant value %d\n", i );
|
||||
}
|
||||
|
||||
Saig_MvSaveState( p, &iRegMax );
|
||||
// simulate until convergence
|
||||
for ( f = 0; ; f++ )
|
||||
{
|
||||
/*
|
||||
if ( fVerbose )
|
||||
{
|
||||
printf( "%3d : ", f+1 );
|
||||
printf( "*=%6d ", p->nRUndefs );
|
||||
for ( k = 1; k < SAIG_DIFF_VALUES; k++ )
|
||||
if ( p->nRValues[k] == 0 )
|
||||
printf( " " );
|
||||
else
|
||||
printf( "%d=%6d ", k, p->nRValues[k] );
|
||||
printf( "aig=%6d", p->nObjs );
|
||||
printf( "\n" );
|
||||
}
|
||||
*/
|
||||
Saig_MvSimulateFrame( p, f==0 );
|
||||
iState = Saig_MvSaveState( p, &iRegMax );
|
||||
if ( iState >= 0 )
|
||||
{
|
||||
printf( "Converged after %d frames with lasso in state %d. Cycle = %d.\n", f+1, iState-1, f+2-iState );
|
||||
printf( "Total number of PIs = %d. AND nodes = %d.\n", p->nPis, p->nObjs - p->nPis );
|
||||
break;
|
||||
}
|
||||
if ( f >= p->nStatesMax && iRegMax >= 0 )
|
||||
{
|
||||
/*
|
||||
pEntry = Vec_PtrEntry( p->vFlops, iRegMax );
|
||||
assert( pEntry->Value != (unsigned)Saig_MvUndef() );
|
||||
pEntry->Value = Saig_MvUndef();
|
||||
printf( "Retiring flop %d.\n", iRegMax );
|
||||
*/
|
||||
// printf( "Retiring %d flops.\n", Vec_PtrSize(p->vTired) );
|
||||
Vec_PtrForEachEntry( p->vTired, pEntry, k )
|
||||
pEntry->Value = Saig_MvUndef();
|
||||
}
|
||||
}
|
||||
PRT( "Multi-value simulation", clock() - clk );
|
||||
// implement equivalences
|
||||
Saig_MvManPostProcess( p, iState-1 );
|
||||
Saig_MvManStop( p );
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,513 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [saigSimSeq.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Sequential AIG package.]
|
||||
|
||||
Synopsis [Fast sequential AIG simulator.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: saigSimSeq.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "saig.h"
|
||||
#include "ssw.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// combinational simulation manager
|
||||
typedef struct Raig_Man_t_ Raig_Man_t;
|
||||
struct Raig_Man_t_
|
||||
{
|
||||
// parameters
|
||||
Aig_Man_t * pAig; // the AIG to be used for simulation
|
||||
int nWords; // the number of words to simulate
|
||||
// AIG representation
|
||||
int nPis; // the number of primary inputs
|
||||
int nPos; // the number of primary outputs
|
||||
int nCis; // the number of combinational inputs
|
||||
int nCos; // the number of combinational outputs
|
||||
int nNodes; // the number of internal nodes
|
||||
int nObjs; // nCis + nNodes + nCos + 2
|
||||
int * pFans0; // fanin0 for all objects
|
||||
int * pFans1; // fanin1 for all objects
|
||||
Vec_Int_t * vCis2Ids; // mapping of CIs into their PI ids
|
||||
Vec_Int_t * vLos; // register outputs
|
||||
Vec_Int_t * vLis; // register inputs
|
||||
// simulation info
|
||||
int * pRefs; // reference counter for each node
|
||||
unsigned * pSims; // simlulation information for each node
|
||||
// recycable memory
|
||||
unsigned * pMems; // allocated simulaton memory
|
||||
int nWordsAlloc; // the number of allocated entries
|
||||
int nMems; // the number of used entries
|
||||
int nMemsMax; // the max number of used entries
|
||||
int MemFree; // next free entry
|
||||
};
|
||||
|
||||
static inline int Raig_Var2Lit( int Var, int fCompl ) { return Var + Var + fCompl; }
|
||||
static inline int Raig_Lit2Var( int Lit ) { return Lit >> 1; }
|
||||
static inline int Raig_LitIsCompl( int Lit ) { return Lit & 1; }
|
||||
static inline int Raig_LitNot( int Lit ) { return Lit ^ 1; }
|
||||
static inline int Raig_LitNotCond( int Lit, int c ) { return Lit ^ (int)(c > 0); }
|
||||
static inline int Raig_LitRegular( int Lit ) { return Lit & ~01; }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Find the PO corresponding to the PO driver.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Raig_ManFindPo( Aig_Man_t * pAig, int iNode )
|
||||
{
|
||||
Aig_Obj_t * pObj;
|
||||
int i;
|
||||
Saig_ManForEachPo( pAig, pObj, i )
|
||||
if ( pObj->iData == iNode )
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates fast simulation manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Raig_ManCreate_rec( Raig_Man_t * p, Aig_Obj_t * pObj )
|
||||
{
|
||||
int iFan0, iFan1;
|
||||
assert( !Aig_IsComplement(pObj) );
|
||||
if ( pObj->iData )
|
||||
return pObj->iData;
|
||||
assert( !Aig_ObjIsConst1(pObj) );
|
||||
if ( Aig_ObjIsNode(pObj) )
|
||||
{
|
||||
iFan0 = Raig_ManCreate_rec( p, Aig_ObjFanin0(pObj) );
|
||||
iFan0 = (iFan0 << 1) | Aig_ObjFaninC0(pObj);
|
||||
iFan1 = Raig_ManCreate_rec( p, Aig_ObjFanin1(pObj) );
|
||||
iFan1 = (iFan1 << 1) | Aig_ObjFaninC1(pObj);
|
||||
}
|
||||
else if ( Aig_ObjIsPo(pObj) )
|
||||
{
|
||||
iFan0 = Raig_ManCreate_rec( p, Aig_ObjFanin0(pObj) );
|
||||
iFan0 = (iFan0 << 1) | Aig_ObjFaninC0(pObj);
|
||||
iFan1 = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
iFan0 = iFan1 = 0;
|
||||
Vec_IntPush( p->vCis2Ids, Aig_ObjPioNum(pObj) );
|
||||
}
|
||||
p->pFans0[p->nObjs] = iFan0;
|
||||
p->pFans1[p->nObjs] = iFan1;
|
||||
p->pRefs[p->nObjs] = Aig_ObjRefs(pObj);
|
||||
return pObj->iData = p->nObjs++;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates fast simulation manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Raig_Man_t * Raig_ManCreate( Aig_Man_t * pAig )
|
||||
{
|
||||
Raig_Man_t * p;
|
||||
Aig_Obj_t * pObj;
|
||||
int i, nObjs;
|
||||
Aig_ManCleanData( pAig );
|
||||
p = (Raig_Man_t *)ALLOC( Raig_Man_t, 1 );
|
||||
memset( p, 0, sizeof(Raig_Man_t) );
|
||||
p->pAig = pAig;
|
||||
p->nPis = Saig_ManPiNum(pAig);
|
||||
p->nPos = Saig_ManPoNum(pAig);
|
||||
p->nCis = Aig_ManPiNum(pAig);
|
||||
p->nCos = Aig_ManPoNum(pAig);
|
||||
p->nNodes = Aig_ManNodeNum(pAig);
|
||||
nObjs = p->nCis + p->nCos + p->nNodes + 2;
|
||||
p->pFans0 = ALLOC( int, nObjs );
|
||||
p->pFans1 = ALLOC( int, nObjs );
|
||||
p->pRefs = ALLOC( int, nObjs );
|
||||
p->pSims = CALLOC( unsigned, nObjs );
|
||||
p->vCis2Ids = Vec_IntAlloc( Aig_ManPiNum(pAig) );
|
||||
// add objects (0=unused; 1=const1)
|
||||
p->nObjs = 2;
|
||||
pObj = Aig_ManConst1( pAig );
|
||||
pObj->iData = 1;
|
||||
Aig_ManForEachPi( pAig, pObj, i )
|
||||
if ( Aig_ObjRefs(pObj) == 0 )
|
||||
Raig_ManCreate_rec( p, pObj );
|
||||
Aig_ManForEachPo( pAig, pObj, i )
|
||||
Raig_ManCreate_rec( p, pObj );
|
||||
assert( Vec_IntSize(p->vCis2Ids) == Aig_ManPiNum(pAig) );
|
||||
assert( p->nObjs == nObjs );
|
||||
// collect flop outputs
|
||||
p->vLos = Vec_IntAlloc( Aig_ManRegNum(pAig) );
|
||||
Saig_ManForEachLo( pAig, pObj, i )
|
||||
Vec_IntPush( p->vLos, pObj->iData );
|
||||
// collect flop inputs
|
||||
p->vLis = Vec_IntAlloc( Aig_ManRegNum(pAig) );
|
||||
Saig_ManForEachLi( pAig, pObj, i )
|
||||
{
|
||||
Vec_IntPush( p->vLis, pObj->iData );
|
||||
assert( p->pRefs[ pObj->iData ] == 0 );
|
||||
p->pRefs[ pObj->iData ]++;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates fast simulation manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Raig_ManDelete( Raig_Man_t * p )
|
||||
{
|
||||
Vec_IntFree( p->vCis2Ids );
|
||||
Vec_IntFree( p->vLos );
|
||||
Vec_IntFree( p->vLis );
|
||||
FREE( p->pFans0 );
|
||||
FREE( p->pFans1 );
|
||||
FREE( p->pRefs );
|
||||
FREE( p->pSims );
|
||||
FREE( p->pMems );
|
||||
FREE( p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [References simulation info.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
unsigned * Raig_ManSimRef( Raig_Man_t * p, int i )
|
||||
{
|
||||
unsigned * pSim;
|
||||
assert( i > 1 );
|
||||
assert( p->pSims[i] == 0 );
|
||||
if ( p->MemFree == 0 )
|
||||
{
|
||||
int * pPlace, Ent;
|
||||
if ( p->nWordsAlloc == 0 )
|
||||
{
|
||||
assert( p->pMems == NULL );
|
||||
p->nWordsAlloc = (1<<17); // -> 1Mb
|
||||
p->nMems = 1;
|
||||
}
|
||||
p->nWordsAlloc *= 2;
|
||||
p->pMems = REALLOC( unsigned, p->pMems, p->nWordsAlloc );
|
||||
memset( p->pMems, 0xff, sizeof(unsigned) * (p->nWords + 1) );
|
||||
pPlace = &p->MemFree;
|
||||
for ( Ent = p->nMems * (p->nWords + 1);
|
||||
Ent + p->nWords + 1 < p->nWordsAlloc;
|
||||
Ent += p->nWords + 1 )
|
||||
{
|
||||
*pPlace = Ent;
|
||||
pPlace = p->pMems + Ent;
|
||||
}
|
||||
*pPlace = 0;
|
||||
}
|
||||
p->pSims[i] = p->MemFree;
|
||||
pSim = p->pMems + p->MemFree;
|
||||
p->MemFree = pSim[0];
|
||||
pSim[0] = p->pRefs[i];
|
||||
p->nMems++;
|
||||
if ( p->nMemsMax < p->nMems )
|
||||
p->nMemsMax = p->nMems;
|
||||
return pSim;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Dereference simulaton info.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
unsigned * Raig_ManSimDeref( Raig_Man_t * p, int i )
|
||||
{
|
||||
unsigned * pSim;
|
||||
assert( i );
|
||||
if ( i == 1 ) // const 1
|
||||
return p->pMems;
|
||||
assert( p->pSims[i] > 0 );
|
||||
pSim = p->pMems + p->pSims[i];
|
||||
if ( --pSim[0] == 0 )
|
||||
{
|
||||
pSim[0] = p->MemFree;
|
||||
p->MemFree = p->pSims[i];
|
||||
p->pSims[i] = 0;
|
||||
p->nMems--;
|
||||
}
|
||||
return pSim;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Simulates one round.]
|
||||
|
||||
Description [Returns the number of PO entry if failed; 0 otherwise.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Raig_ManSimulateRound( Raig_Man_t * p, int fMiter, int fFirst, int * piPat )
|
||||
{
|
||||
unsigned * pRes0, * pRes1, * pRes;
|
||||
int i, w, nCis, nCos, iFan0, iFan1, iPioNum;
|
||||
// nove the values to the register outputs
|
||||
Vec_IntForEachEntry( p->vCis2Ids, iPioNum, i )
|
||||
{
|
||||
if ( iPioNum < p->nPis )
|
||||
continue;
|
||||
pRes = Raig_ManSimRef( p, Vec_IntEntry(p->vLos, iPioNum-p->nPis) );
|
||||
if ( fFirst )
|
||||
memset( pRes + 1, 0, sizeof(unsigned) * p->nWords );
|
||||
else
|
||||
{
|
||||
pRes0 = Raig_ManSimDeref( p, Vec_IntEntry(p->vLis, iPioNum-p->nPis) );
|
||||
for ( w = 1; w <= p->nWords; w++ )
|
||||
pRes[w] = pRes0[w];
|
||||
}
|
||||
// handle unused PIs
|
||||
if ( pRes[0] == 0 )
|
||||
{
|
||||
pRes[0] = 1;
|
||||
Raig_ManSimDeref( p, Vec_IntEntry(p->vLos, iPioNum-p->nPis) );
|
||||
}
|
||||
}
|
||||
// simulate the logic
|
||||
nCis = nCos = 0;
|
||||
for ( i = 2; i < p->nObjs; i++ )
|
||||
{
|
||||
if ( p->pFans0[i] == 0 ) // ci always has zero first fanin
|
||||
{
|
||||
iPioNum = Vec_IntEntry( p->vCis2Ids, nCis );
|
||||
if ( iPioNum < p->nPis )
|
||||
{
|
||||
pRes = Raig_ManSimRef( p, i );
|
||||
for ( w = 1; w <= p->nWords; w++ )
|
||||
pRes[w] = Aig_ManRandom( 0 );
|
||||
// handle unused PIs
|
||||
if ( pRes[0] == 0 )
|
||||
{
|
||||
pRes[0] = 1;
|
||||
Raig_ManSimDeref( p, i );
|
||||
}
|
||||
}
|
||||
else
|
||||
assert( Vec_IntEntry(p->vLos, iPioNum-p->nPis) == i );
|
||||
nCis++;
|
||||
continue;
|
||||
}
|
||||
if ( p->pFans1[i] == 0 ) // co always has non-zero 1st fanin and zero 2nd fanin
|
||||
{
|
||||
pRes0 = Raig_ManSimDeref( p, Raig_Lit2Var(p->pFans0[i]) );
|
||||
if ( nCos < p->nPos && fMiter )
|
||||
{
|
||||
unsigned Const = Raig_LitIsCompl(p->pFans0[i])? ~0 : 0;
|
||||
for ( w = 1; w <= p->nWords; w++ )
|
||||
if ( pRes0[w] != Const )
|
||||
{
|
||||
*piPat = 32*(w-1) + Aig_WordFindFirstBit( pRes0[w] ^ Const );
|
||||
return i;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pRes = Raig_ManSimRef( p, i );
|
||||
assert( pRes[0] == 1 );
|
||||
if ( Raig_LitIsCompl(p->pFans0[i]) )
|
||||
for ( w = 1; w <= p->nWords; w++ )
|
||||
pRes[w] = ~pRes0[w];
|
||||
else
|
||||
for ( w = 1; w <= p->nWords; w++ )
|
||||
pRes[w] = pRes0[w];
|
||||
}
|
||||
nCos++;
|
||||
continue;
|
||||
}
|
||||
pRes = Raig_ManSimRef( p, i );
|
||||
assert( pRes[0] > 0 );
|
||||
iFan0 = p->pFans0[i];
|
||||
iFan1 = p->pFans1[i];
|
||||
pRes0 = Raig_ManSimDeref( p, Raig_Lit2Var(p->pFans0[i]) );
|
||||
pRes1 = Raig_ManSimDeref( p, Raig_Lit2Var(p->pFans1[i]) );
|
||||
if ( Raig_LitIsCompl(iFan0) && Raig_LitIsCompl(iFan1) )
|
||||
for ( w = 1; w <= p->nWords; w++ )
|
||||
pRes[w] = ~(pRes0[w] | pRes1[w]);
|
||||
else if ( Raig_LitIsCompl(iFan0) && !Raig_LitIsCompl(iFan1) )
|
||||
for ( w = 1; w <= p->nWords; w++ )
|
||||
pRes[w] = ~pRes0[w] & pRes1[w];
|
||||
else if ( !Raig_LitIsCompl(iFan0) && Raig_LitIsCompl(iFan1) )
|
||||
for ( w = 1; w <= p->nWords; w++ )
|
||||
pRes[w] = pRes0[w] & ~pRes1[w];
|
||||
else if ( !Raig_LitIsCompl(iFan0) && !Raig_LitIsCompl(iFan1) )
|
||||
for ( w = 1; w <= p->nWords; w++ )
|
||||
pRes[w] = pRes0[w] & pRes1[w];
|
||||
}
|
||||
assert( nCis == p->nCis );
|
||||
assert( nCos == p->nCos );
|
||||
assert( p->nMems == 1 + Vec_IntSize(p->vLis) );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the counter-example.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ssw_Cex_t * Raig_ManGenerateCounter( Aig_Man_t * pAig, int iFrame, int iOut, int nWords, int iPat, Vec_Int_t * vCis2Ids )
|
||||
{
|
||||
Ssw_Cex_t * p;
|
||||
unsigned * pData;
|
||||
int f, i, w, iPioId, Counter;
|
||||
p = Ssw_SmlAllocCounterExample( Aig_ManRegNum(pAig), Saig_ManPiNum(pAig), iFrame+1 );
|
||||
p->iFrame = iFrame;
|
||||
p->iPo = iOut;
|
||||
// fill in the binary data
|
||||
Aig_ManRandom( 1 );
|
||||
Counter = p->nRegs;
|
||||
pData = ALLOC( unsigned, nWords );
|
||||
for ( f = 0; f <= iFrame; f++, Counter += p->nPis )
|
||||
for ( i = 0; i < Aig_ManPiNum(pAig); i++ )
|
||||
{
|
||||
iPioId = Vec_IntEntry( vCis2Ids, i );
|
||||
if ( iPioId >= p->nPis )
|
||||
continue;
|
||||
for ( w = 0; w < nWords; w++ )
|
||||
pData[w] = Aig_ManRandom( 0 );
|
||||
if ( Aig_InfoHasBit( pData, iPat ) )
|
||||
Aig_InfoSetBit( p->pData, Counter + iPioId );
|
||||
}
|
||||
free( pData );
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns 1 if the bug is detected, 0 otherwise.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Raig_ManSimulate( Aig_Man_t * pAig, int nWords, int nIters, int TimeLimit, int fMiter, int fVerbose )
|
||||
{
|
||||
Raig_Man_t * p;
|
||||
Sec_MtrStatus_t Status;
|
||||
int i, iPat, RetValue = 0;
|
||||
int clk, clkTotal = clock();
|
||||
assert( Aig_ManRegNum(pAig) > 0 );
|
||||
Status = Sec_MiterStatus( pAig );
|
||||
if ( Status.nSat > 0 )
|
||||
{
|
||||
printf( "Miter is trivially satisfiable (output %d).\n", Status.iOut );
|
||||
return 1;
|
||||
}
|
||||
if ( Status.nUndec == 0 )
|
||||
{
|
||||
printf( "Miter is trivially unsatisfiable.\n" );
|
||||
return 0;
|
||||
}
|
||||
Aig_ManRandom( 1 );
|
||||
p = Raig_ManCreate( pAig );
|
||||
p->nWords = nWords;
|
||||
// iterate through objects
|
||||
for ( i = 0; i < nIters; i++ )
|
||||
{
|
||||
clk = clock();
|
||||
RetValue = Raig_ManSimulateRound( p, fMiter, i==0, &iPat );
|
||||
if ( fVerbose )
|
||||
{
|
||||
printf( "Frame %4d out of %4d and timeout %3d sec. ", i+1, nIters, TimeLimit );
|
||||
printf("Time = %7.2f sec\r", (1.0*clock()-clkTotal)/CLOCKS_PER_SEC);
|
||||
}
|
||||
if ( RetValue > 0 )
|
||||
{
|
||||
int iOut = Raig_ManFindPo(p->pAig, RetValue);
|
||||
assert( pAig->pSeqModel == NULL );
|
||||
pAig->pSeqModel = Raig_ManGenerateCounter( pAig, i, iOut, nWords, iPat, p->vCis2Ids );
|
||||
if ( fVerbose )
|
||||
printf( "Miter is satisfiable after simulation (output %d).\n", iOut );
|
||||
break;
|
||||
}
|
||||
if ( (clock() - clk)/CLOCKS_PER_SEC >= TimeLimit )
|
||||
{
|
||||
printf( "No bug detected after %d frames with time limit %d seconds.\n", i+1, TimeLimit );
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( fVerbose )
|
||||
{
|
||||
printf( "Maxcut = %8d. AigMem = %7.2f Mb. SimMem = %7.2f Mb. ",
|
||||
p->nMemsMax,
|
||||
1.0*(p->nObjs * 16)/(1<<20),
|
||||
1.0*(p->nMemsMax * 4 * (nWords+1))/(1<<20) );
|
||||
PRT( "Total time", clock() - clkTotal );
|
||||
}
|
||||
Raig_ManDelete( p );
|
||||
return RetValue > 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,971 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [saigStrSim.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Sequential AIG package.]
|
||||
|
||||
Synopsis [Structural matching using simulation.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: saigStrSim.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "saig.h"
|
||||
#include "ssw.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define SAIG_WORDS 16
|
||||
|
||||
static inline Aig_Obj_t * Saig_ObjNext( Aig_Obj_t ** ppNexts, Aig_Obj_t * pObj ) { return ppNexts[pObj->Id]; }
|
||||
static inline void Saig_ObjSetNext( Aig_Obj_t ** ppNexts, Aig_Obj_t * pObj, Aig_Obj_t * pNext ) { ppNexts[pObj->Id] = pNext; }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes hash value of the node using its simulation info.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
unsigned Saig_StrSimHash( Aig_Obj_t * pObj )
|
||||
{
|
||||
static int s_SPrimes[128] = {
|
||||
1009, 1049, 1093, 1151, 1201, 1249, 1297, 1361, 1427, 1459,
|
||||
1499, 1559, 1607, 1657, 1709, 1759, 1823, 1877, 1933, 1997,
|
||||
2039, 2089, 2141, 2213, 2269, 2311, 2371, 2411, 2467, 2543,
|
||||
2609, 2663, 2699, 2741, 2797, 2851, 2909, 2969, 3037, 3089,
|
||||
3169, 3221, 3299, 3331, 3389, 3461, 3517, 3557, 3613, 3671,
|
||||
3719, 3779, 3847, 3907, 3943, 4013, 4073, 4129, 4201, 4243,
|
||||
4289, 4363, 4441, 4493, 4549, 4621, 4663, 4729, 4793, 4871,
|
||||
4933, 4973, 5021, 5087, 5153, 5227, 5281, 5351, 5417, 5471,
|
||||
5519, 5573, 5651, 5693, 5749, 5821, 5861, 5923, 6011, 6073,
|
||||
6131, 6199, 6257, 6301, 6353, 6397, 6481, 6563, 6619, 6689,
|
||||
6737, 6803, 6863, 6917, 6977, 7027, 7109, 7187, 7237, 7309,
|
||||
7393, 7477, 7523, 7561, 7607, 7681, 7727, 7817, 7877, 7933,
|
||||
8011, 8039, 8059, 8081, 8093, 8111, 8123, 8147
|
||||
};
|
||||
unsigned * pSims;
|
||||
unsigned uHash = 0;
|
||||
int i;
|
||||
assert( SAIG_WORDS <= 128 );
|
||||
pSims = pObj->pData;
|
||||
for ( i = 0; i < SAIG_WORDS; i++ )
|
||||
uHash ^= pSims[i] * s_SPrimes[i & 0x7F];
|
||||
return uHash;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes hash value of the node using its simulation info.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Saig_StrSimIsEqual( Aig_Obj_t * pObj0, Aig_Obj_t * pObj1 )
|
||||
{
|
||||
unsigned * pSims0 = pObj0->pData;
|
||||
unsigned * pSims1 = pObj1->pData;
|
||||
int i;
|
||||
for ( i = 0; i < SAIG_WORDS; i++ )
|
||||
if ( pSims0[i] != pSims1[i] )
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns 1 if simulation info is zero.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Saig_StrSimIsZero( Aig_Obj_t * pObj )
|
||||
{
|
||||
unsigned * pSims = pObj->pData;
|
||||
int i;
|
||||
for ( i = 0; i < SAIG_WORDS; i++ )
|
||||
if ( pSims[i] != 0 )
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns 1 if simulation info is one.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Saig_StrSimIsOne( Aig_Obj_t * pObj )
|
||||
{
|
||||
unsigned * pSims = pObj->pData;
|
||||
int i;
|
||||
for ( i = 0; i < SAIG_WORDS; i++ )
|
||||
if ( pSims[i] != ~0 )
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Assigns random simulation info.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Saig_StrSimAssignRandom( Aig_Obj_t * pObj )
|
||||
{
|
||||
unsigned * pSims = pObj->pData;
|
||||
int i;
|
||||
for ( i = 0; i < SAIG_WORDS; i++ )
|
||||
pSims[i] = Aig_ManRandom(0);
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Assigns constant 0 simulation info.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Saig_StrSimAssignOne( Aig_Obj_t * pObj )
|
||||
{
|
||||
unsigned * pSims = pObj->pData;
|
||||
int i;
|
||||
for ( i = 0; i < SAIG_WORDS; i++ )
|
||||
pSims[i] = ~0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Assigns constant 0 simulation info.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Saig_StrSimAssignZeroInit( Aig_Obj_t * pObj )
|
||||
{
|
||||
unsigned * pSims = pObj->pData;
|
||||
pSims[0] = 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Simulated one node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Saig_StrSimulateNode( Aig_Obj_t * pObj, int i )
|
||||
{
|
||||
unsigned * pSims = pObj->pData;
|
||||
unsigned * pSims0 = Aig_ObjFanin0(pObj)->pData;
|
||||
unsigned * pSims1 = Aig_ObjFanin1(pObj)->pData;
|
||||
if ( Aig_ObjFaninC0(pObj) && Aig_ObjFaninC1(pObj) )
|
||||
pSims[i] = ~(pSims0[i] | pSims1[i]);
|
||||
else if ( Aig_ObjFaninC0(pObj) && !Aig_ObjFaninC1(pObj) )
|
||||
pSims[i] = (~pSims0[i] & pSims1[i]);
|
||||
else if ( !Aig_ObjFaninC0(pObj) && Aig_ObjFaninC1(pObj) )
|
||||
pSims[i] = (pSims0[i] & ~pSims1[i]);
|
||||
else // if ( !Aig_ObjFaninC0(pObj) && !Aig_ObjFaninC1(pObj) )
|
||||
pSims[i] = (pSims0[i] & pSims1[i]);
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Saves output of one node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Saig_StrSimSaveOutput( Aig_Obj_t * pObj, int i )
|
||||
{
|
||||
unsigned * pSims = pObj->pData;
|
||||
unsigned * pSims0 = Aig_ObjFanin0(pObj)->pData;
|
||||
if ( Aig_ObjFaninC0(pObj) )
|
||||
pSims[i] = ~pSims0[i];
|
||||
else
|
||||
pSims[i] = pSims0[i];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Transfers simulation output to another node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Saig_StrSimTransfer( Aig_Obj_t * pObj0, Aig_Obj_t * pObj1 )
|
||||
{
|
||||
unsigned * pSims0 = pObj0->pData;
|
||||
unsigned * pSims1 = pObj1->pData;
|
||||
int i;
|
||||
for ( i = 0; i < SAIG_WORDS; i++ )
|
||||
pSims1[i] = pSims0[i];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Transfers simulation output to another node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Saig_StrSimTransferNext( Aig_Obj_t * pObj0, Aig_Obj_t * pObj1, int i )
|
||||
{
|
||||
unsigned * pSims0 = pObj0->pData;
|
||||
unsigned * pSims1 = pObj1->pData;
|
||||
assert( i < SAIG_WORDS - 1 );
|
||||
pSims1[i+1] = pSims0[i];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Perform one round of simulation.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Saig_StrSimulateRound( Aig_Man_t * p0, Aig_Man_t * p1 )
|
||||
{
|
||||
Aig_Obj_t * pObj0, * pObj1;
|
||||
int f, i;
|
||||
// simulate the nodes
|
||||
Aig_ManForEachObj( p0, pObj0, i )
|
||||
{
|
||||
if ( !Aig_ObjIsPi(pObj0) && !Aig_ObjIsNode(pObj0) )
|
||||
continue;
|
||||
pObj1 = Aig_ObjRepr(p0, pObj0);
|
||||
if ( pObj1 == NULL )
|
||||
continue;
|
||||
assert( Aig_ObjRepr(p1, pObj1) == pObj0 );
|
||||
Saig_StrSimAssignRandom( pObj0 );
|
||||
Saig_StrSimTransfer( pObj0, pObj1 );
|
||||
}
|
||||
// simulate the timeframes
|
||||
for ( f = 0; f < SAIG_WORDS; f++ )
|
||||
{
|
||||
// simulate the first AIG
|
||||
Aig_ManForEachNode( p0, pObj0, i )
|
||||
if ( Aig_ObjRepr(p0, pObj0) == NULL )
|
||||
Saig_StrSimulateNode( pObj0, f );
|
||||
Saig_ManForEachLi( p0, pObj0, i )
|
||||
Saig_StrSimSaveOutput( pObj0, f );
|
||||
if ( f < SAIG_WORDS - 1 )
|
||||
Saig_ManForEachLiLo( p0, pObj0, pObj1, i )
|
||||
Saig_StrSimTransferNext( pObj0, pObj1, f );
|
||||
// simulate the second AIG
|
||||
Aig_ManForEachNode( p1, pObj1, i )
|
||||
if ( Aig_ObjRepr(p1, pObj1) == NULL )
|
||||
Saig_StrSimulateNode( pObj1, f );
|
||||
Saig_ManForEachLi( p1, pObj1, i )
|
||||
Saig_StrSimSaveOutput( pObj1, f );
|
||||
if ( f < SAIG_WORDS - 1 )
|
||||
Saig_ManForEachLiLo( p1, pObj1, pObj0, i )
|
||||
Saig_StrSimTransferNext( pObj1, pObj0, f );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Checks if the entry exists in the table.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Obj_t * Saig_StrSimTableLookup( Aig_Obj_t ** ppTable, Aig_Obj_t ** ppNexts, int nTableSize, Aig_Obj_t * pObj )
|
||||
{
|
||||
Aig_Obj_t * pEntry;
|
||||
int iEntry;
|
||||
// find the hash entry
|
||||
iEntry = Saig_StrSimHash( pObj ) % nTableSize;
|
||||
// check if there are nodes with this signatures
|
||||
for ( pEntry = ppTable[iEntry]; pEntry; pEntry = Saig_ObjNext(ppNexts,pEntry) )
|
||||
if ( Saig_StrSimIsEqual( pEntry, pObj ) )
|
||||
return pEntry;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Inserts the entry into the table.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Saig_StrSimTableInsert( Aig_Obj_t ** ppTable, Aig_Obj_t ** ppNexts, int nTableSize, Aig_Obj_t * pObj )
|
||||
{
|
||||
// find the hash entry
|
||||
int iEntry = Saig_StrSimHash( pObj ) % nTableSize;
|
||||
// check if there are nodes with this signatures
|
||||
if ( ppTable[iEntry] == NULL )
|
||||
ppTable[iEntry] = pObj;
|
||||
else
|
||||
{
|
||||
Saig_ObjSetNext( ppNexts, pObj, Saig_ObjNext(ppNexts, ppTable[iEntry]) );
|
||||
Saig_ObjSetNext( ppNexts, ppTable[iEntry], pObj );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Perform one round of matching.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Saig_StrSimDetectUnique( Aig_Man_t * p0, Aig_Man_t * p1 )
|
||||
{
|
||||
Aig_Obj_t ** ppTable, ** ppNexts, ** ppCands;
|
||||
Aig_Obj_t * pObj, * pEntry;
|
||||
int i, nTableSize, Counter;
|
||||
|
||||
// allocate the hash table hashing simulation info into nodes
|
||||
nTableSize = Aig_PrimeCudd( Aig_ManObjNum(p0)/2 );
|
||||
ppTable = CALLOC( Aig_Obj_t *, nTableSize );
|
||||
ppNexts = CALLOC( Aig_Obj_t *, Aig_ManObjNumMax(p0) );
|
||||
ppCands = CALLOC( Aig_Obj_t *, Aig_ManObjNumMax(p0) );
|
||||
|
||||
// hash nodes of the first AIG
|
||||
Aig_ManForEachObj( p0, pObj, i )
|
||||
{
|
||||
if ( !Aig_ObjIsPi(pObj) && !Aig_ObjIsNode(pObj) )
|
||||
continue;
|
||||
if ( Aig_ObjRepr(p0, pObj) )
|
||||
continue;
|
||||
if ( Saig_StrSimIsZero(pObj) || Saig_StrSimIsOne(pObj) )
|
||||
continue;
|
||||
// check if the entry exists
|
||||
pEntry = Saig_StrSimTableLookup( ppTable, ppNexts, nTableSize, pObj );
|
||||
if ( pEntry == NULL ) // insert
|
||||
Saig_StrSimTableInsert( ppTable, ppNexts, nTableSize, pObj );
|
||||
else // mark the entry as not unique
|
||||
pEntry->fMarkA = 1;
|
||||
}
|
||||
|
||||
// hash nodes from the second AIG
|
||||
Aig_ManForEachObj( p1, pObj, i )
|
||||
{
|
||||
if ( !Aig_ObjIsPi(pObj) && !Aig_ObjIsNode(pObj) )
|
||||
continue;
|
||||
if ( Aig_ObjRepr(p1, pObj) )
|
||||
continue;
|
||||
if ( Saig_StrSimIsZero(pObj) || Saig_StrSimIsOne(pObj) )
|
||||
continue;
|
||||
// check if the entry exists
|
||||
pEntry = Saig_StrSimTableLookup( ppTable, ppNexts, nTableSize, pObj );
|
||||
if ( pEntry == NULL ) // skip
|
||||
continue;
|
||||
// if there is no candidate, label it
|
||||
if ( Saig_ObjNext( ppCands, pEntry ) == NULL )
|
||||
Saig_ObjSetNext( ppCands, pEntry, pObj );
|
||||
else // mark the entry as not unique
|
||||
pEntry->fMarkA = 1;
|
||||
}
|
||||
|
||||
// create representatives for the unique entries
|
||||
Counter = 0;
|
||||
for ( i = 0; i < nTableSize; i++ )
|
||||
for ( pEntry = ppTable[i]; pEntry; pEntry = Saig_ObjNext(ppNexts,pEntry) )
|
||||
if ( !pEntry->fMarkA && (pObj = Saig_ObjNext( ppCands, pEntry )) )
|
||||
{
|
||||
// assert( Aig_ObjIsNode(pEntry) == Aig_ObjIsNode(pObj) );
|
||||
if ( Aig_ObjType(pEntry) != Aig_ObjType(pObj) )
|
||||
continue;
|
||||
Aig_ObjSetRepr( p0, pEntry, pObj );
|
||||
Aig_ObjSetRepr( p1, pObj, pEntry );
|
||||
Counter++;
|
||||
}
|
||||
|
||||
// cleanup
|
||||
Aig_ManCleanMarkA( p0 );
|
||||
free( ppTable );
|
||||
free( ppNexts );
|
||||
free( ppCands );
|
||||
return Counter;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Counts the number of matched flops.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Saig_StrSimCountMatchedFlops( Aig_Man_t * p )
|
||||
{
|
||||
Aig_Obj_t * pObj;
|
||||
int i, Counter = 0;
|
||||
Saig_ManForEachLo( p, pObj, i )
|
||||
if ( Aig_ObjRepr(p, pObj) )
|
||||
Counter++;
|
||||
return Counter;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Counts the number of matched nodes.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Saig_StrSimCountMatchedNodes( Aig_Man_t * p )
|
||||
{
|
||||
Aig_Obj_t * pObj;
|
||||
int i, Counter = 0;
|
||||
Aig_ManForEachNode( p, pObj, i )
|
||||
if ( Aig_ObjRepr(p, pObj) )
|
||||
Counter++;
|
||||
return Counter;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs structural matching of two AIGs using simulation.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Saig_StrSimPrepareAig( Aig_Man_t * p )
|
||||
{
|
||||
Aig_Obj_t * pObj;
|
||||
int i;
|
||||
Aig_ManReprStart( p, Aig_ManObjNumMax(p) );
|
||||
// allocate simulation info
|
||||
p->pData2 = Vec_PtrAllocSimInfo( Aig_ManObjNumMax(p), SAIG_WORDS );
|
||||
Aig_ManForEachObj( p, pObj, i )
|
||||
pObj->pData = Vec_PtrEntry( p->pData2, i );
|
||||
// set simulation info for constant1 and register outputs
|
||||
Saig_StrSimAssignOne( Aig_ManConst1(p) );
|
||||
Saig_ManForEachLo( p, pObj, i )
|
||||
Saig_StrSimAssignZeroInit( pObj );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs structural matching of two AIGs using simulation.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Saig_StrSimSetInitMatching( Aig_Man_t * p0, Aig_Man_t * p1 )
|
||||
{
|
||||
Aig_Obj_t * pObj0, * pObj1;
|
||||
int i;
|
||||
pObj0 = Aig_ManConst1( p0 );
|
||||
pObj1 = Aig_ManConst1( p1 );
|
||||
Aig_ObjSetRepr( p0, pObj0, pObj1 );
|
||||
Aig_ObjSetRepr( p1, pObj1, pObj0 );
|
||||
Saig_ManForEachPi( p0, pObj0, i )
|
||||
{
|
||||
pObj1 = Aig_ManPi( p1, i );
|
||||
Aig_ObjSetRepr( p0, pObj0, pObj1 );
|
||||
Aig_ObjSetRepr( p1, pObj1, pObj0 );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs structural matching of two AIGs using simulation.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Saig_StrSimSetFinalMatching( Aig_Man_t * p0, Aig_Man_t * p1 )
|
||||
{
|
||||
Aig_Obj_t * pObj0, * pObj1;
|
||||
Aig_Obj_t * pFanin00, * pFanin01;
|
||||
Aig_Obj_t * pFanin10, * pFanin11;
|
||||
int i, CountAll = 0, CountNot = 0;
|
||||
Aig_ManIncrementTravId( p0 );
|
||||
Aig_ManForEachObj( p0, pObj0, i )
|
||||
{
|
||||
pObj1 = Aig_ObjRepr( p0, pObj0 );
|
||||
if ( pObj1 == NULL )
|
||||
continue;
|
||||
CountAll++;
|
||||
assert( pObj0 == Aig_ObjRepr( p1, pObj1 ) );
|
||||
if ( Aig_ObjIsNode(pObj0) )
|
||||
{
|
||||
assert( Aig_ObjIsNode(pObj1) );
|
||||
pFanin00 = Aig_ObjFanin0(pObj0);
|
||||
pFanin01 = Aig_ObjFanin1(pObj0);
|
||||
pFanin10 = Aig_ObjFanin0(pObj1);
|
||||
pFanin11 = Aig_ObjFanin1(pObj1);
|
||||
if ( Aig_ObjRepr(p0, pFanin00) != pFanin10 ||
|
||||
Aig_ObjRepr(p0, pFanin01) != pFanin11 )
|
||||
{
|
||||
Aig_ObjSetTravIdCurrent(p0, pObj0);
|
||||
CountNot++;
|
||||
}
|
||||
}
|
||||
else if ( Saig_ObjIsLo(p0, pObj0) )
|
||||
{
|
||||
assert( Saig_ObjIsLo(p1, pObj1) );
|
||||
pFanin00 = Aig_ObjFanin0( Saig_ObjLoToLi(p0, pObj0) );
|
||||
pFanin10 = Aig_ObjFanin0( Saig_ObjLoToLi(p1, pObj1) );
|
||||
if ( Aig_ObjRepr(p0, pFanin00) != pFanin10 )
|
||||
{
|
||||
Aig_ObjSetTravIdCurrent(p0, pObj0);
|
||||
CountNot++;
|
||||
}
|
||||
}
|
||||
}
|
||||
// remove irrelevant matches
|
||||
Aig_ManForEachObj( p0, pObj0, i )
|
||||
{
|
||||
pObj1 = Aig_ObjRepr( p0, pObj0 );
|
||||
if ( pObj1 == NULL )
|
||||
continue;
|
||||
assert( pObj0 == Aig_ObjRepr( p1, pObj1 ) );
|
||||
if ( Aig_ObjIsTravIdCurrent( p0, pObj0 ) )
|
||||
{
|
||||
Aig_ObjSetRepr( p0, pObj0, NULL );
|
||||
Aig_ObjSetRepr( p1, pObj1, NULL );
|
||||
}
|
||||
}
|
||||
printf( "Total matches = %6d. Wrong matches = %6d. Ratio = %5.2f %%\n",
|
||||
CountAll, CountNot, 100.0*CountNot/CountAll );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the number of dangling nodes removed.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Saig_StrSimSetContiguousMatching_rec( Aig_Man_t * p, Aig_Obj_t * pObj )
|
||||
{
|
||||
Aig_Obj_t * pFanout;
|
||||
int i, iFanout = -1;
|
||||
if ( Aig_ObjIsTravIdCurrent(p, pObj) )
|
||||
return;
|
||||
Aig_ObjSetTravIdCurrent(p, pObj);
|
||||
if ( Saig_ObjIsPo( p, pObj ) )
|
||||
return;
|
||||
if ( Saig_ObjIsLi( p, pObj ) )
|
||||
{
|
||||
Saig_StrSimSetContiguousMatching_rec( p, Saig_ObjLiToLo(p, pObj) );
|
||||
return;
|
||||
}
|
||||
assert( Aig_ObjIsPi(pObj) || Aig_ObjIsNode(pObj) );
|
||||
if ( Aig_ObjRepr(p, pObj) == NULL )
|
||||
return;
|
||||
// go through the fanouts
|
||||
Aig_ObjForEachFanout( p, pObj, pFanout, iFanout, i )
|
||||
Saig_StrSimSetContiguousMatching_rec( p, pFanout );
|
||||
// go through the fanins
|
||||
if ( !Aig_ObjIsPi( pObj ) )
|
||||
{
|
||||
Saig_StrSimSetContiguousMatching_rec( p, Aig_ObjFanin0(pObj) );
|
||||
Saig_StrSimSetContiguousMatching_rec( p, Aig_ObjFanin1(pObj) );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs structural matching of two AIGs using simulation.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Saig_StrSimSetContiguousMatching( Aig_Man_t * p0, Aig_Man_t * p1 )
|
||||
{
|
||||
Aig_Obj_t * pObj0, * pObj1;
|
||||
int i, CountAll = 0, CountNot = 0;
|
||||
// mark nodes reachable through the PIs
|
||||
Aig_ManIncrementTravId( p0 );
|
||||
Aig_ObjSetTravIdCurrent( p0, Aig_ManConst1(p0) );
|
||||
Saig_ManForEachPi( p0, pObj0, i )
|
||||
Saig_StrSimSetContiguousMatching_rec( p0, pObj0 );
|
||||
// remove irrelevant matches
|
||||
Aig_ManForEachObj( p0, pObj0, i )
|
||||
{
|
||||
pObj1 = Aig_ObjRepr( p0, pObj0 );
|
||||
if ( pObj1 == NULL )
|
||||
continue;
|
||||
CountAll++;
|
||||
assert( pObj0 == Aig_ObjRepr( p1, pObj1 ) );
|
||||
if ( !Aig_ObjIsTravIdCurrent( p0, pObj0 ) )
|
||||
{
|
||||
Aig_ObjSetRepr( p0, pObj0, NULL );
|
||||
Aig_ObjSetRepr( p1, pObj1, NULL );
|
||||
CountNot++;
|
||||
}
|
||||
}
|
||||
printf( "Total matches = %6d. Wrong matches = %6d. Ratio = %5.2f %%\n",
|
||||
CountAll, CountNot, 100.0*CountNot/CountAll );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Establishes relationship between nodes using pairing.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ssw_StrSimMatchingExtendOne( Aig_Man_t * p, Vec_Ptr_t * vNodes )
|
||||
{
|
||||
Aig_Obj_t * pNext, * pObj;
|
||||
int i, k, iFan;
|
||||
Vec_PtrClear( vNodes );
|
||||
Aig_ManIncrementTravId( p );
|
||||
Aig_ManForEachObj( p, pObj, i )
|
||||
{
|
||||
if ( !Aig_ObjIsNode(pObj) && !Aig_ObjIsPi(pObj) )
|
||||
continue;
|
||||
if ( Aig_ObjRepr( p, pObj ) != NULL )
|
||||
continue;
|
||||
if ( Saig_ObjIsLo(p, pObj) )
|
||||
{
|
||||
pNext = Saig_ObjLoToLi(p, pObj);
|
||||
pNext = Aig_ObjFanin0(pNext);
|
||||
if ( Aig_ObjRepr( p, pNext ) && !Aig_ObjIsTravIdCurrent(p, pNext) && !Aig_ObjIsConst1(pNext) )
|
||||
{
|
||||
Aig_ObjSetTravIdCurrent(p, pNext);
|
||||
Vec_PtrPush( vNodes, pNext );
|
||||
}
|
||||
}
|
||||
if ( Aig_ObjIsNode(pObj) )
|
||||
{
|
||||
pNext = Aig_ObjFanin0(pObj);
|
||||
if ( Aig_ObjRepr( p, pNext )&& !Aig_ObjIsTravIdCurrent(p, pNext) )
|
||||
{
|
||||
Aig_ObjSetTravIdCurrent(p, pNext);
|
||||
Vec_PtrPush( vNodes, pNext );
|
||||
}
|
||||
pNext = Aig_ObjFanin1(pObj);
|
||||
if ( Aig_ObjRepr( p, pNext ) && !Aig_ObjIsTravIdCurrent(p, pNext) )
|
||||
{
|
||||
Aig_ObjSetTravIdCurrent(p, pNext);
|
||||
Vec_PtrPush( vNodes, pNext );
|
||||
}
|
||||
}
|
||||
Aig_ObjForEachFanout( p, pObj, pNext, iFan, k )
|
||||
{
|
||||
if ( Saig_ObjIsPo(p, pNext) )
|
||||
continue;
|
||||
if ( Saig_ObjIsLi(p, pNext) )
|
||||
pNext = Saig_ObjLiToLo(p, pNext);
|
||||
if ( Aig_ObjRepr( p, pNext ) && !Aig_ObjIsTravIdCurrent(p, pNext) )
|
||||
{
|
||||
Aig_ObjSetTravIdCurrent(p, pNext);
|
||||
Vec_PtrPush( vNodes, pNext );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Establishes relationship between nodes using pairing.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ssw_StrSimMatchingCountUnmached( Aig_Man_t * p )
|
||||
{
|
||||
Aig_Obj_t * pObj;
|
||||
int i, Counter = 0;
|
||||
Aig_ManForEachObj( p, pObj, i )
|
||||
{
|
||||
if ( !Aig_ObjIsNode(pObj) && !Aig_ObjIsPi(pObj) )
|
||||
continue;
|
||||
if ( Aig_ObjRepr( p, pObj ) != NULL )
|
||||
continue;
|
||||
Counter++;
|
||||
}
|
||||
return Counter;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Establishes relationship between nodes using pairing.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ssw_StrSimMatchingExtend( Aig_Man_t * p0, Aig_Man_t * p1, int nDist, int fVerbose )
|
||||
{
|
||||
Vec_Ptr_t * vNodes0, * vNodes1;
|
||||
Aig_Obj_t * pNext0, * pNext1;
|
||||
int d, k;
|
||||
vNodes0 = Vec_PtrAlloc( 1000 );
|
||||
vNodes1 = Vec_PtrAlloc( 1000 );
|
||||
if ( fVerbose )
|
||||
{
|
||||
int nUnmached = Ssw_StrSimMatchingCountUnmached(p0);
|
||||
printf( "Extending islands by %d steps:\n", nDist );
|
||||
printf( "%2d : Total = %6d. Unmatched = %6d. Ratio = %6.2f %%\n",
|
||||
0, Aig_ManPiNum(p0) + Aig_ManNodeNum(p0),
|
||||
nUnmached, 100.0 * nUnmached/(Aig_ManPiNum(p0) + Aig_ManNodeNum(p0)) );
|
||||
}
|
||||
for ( d = 0; d < nDist; d++ )
|
||||
{
|
||||
Ssw_StrSimMatchingExtendOne( p0, vNodes0 );
|
||||
Ssw_StrSimMatchingExtendOne( p1, vNodes1 );
|
||||
Vec_PtrForEachEntry( vNodes0, pNext0, k )
|
||||
{
|
||||
pNext1 = Aig_ObjRepr( p0, pNext0 );
|
||||
if ( pNext1 == NULL )
|
||||
continue;
|
||||
assert( pNext0 == Aig_ObjRepr( p1, pNext1 ) );
|
||||
if ( Saig_ObjIsPi(p1, pNext1) )
|
||||
continue;
|
||||
Aig_ObjSetRepr( p0, pNext0, NULL );
|
||||
Aig_ObjSetRepr( p1, pNext1, NULL );
|
||||
}
|
||||
Vec_PtrForEachEntry( vNodes1, pNext1, k )
|
||||
{
|
||||
pNext0 = Aig_ObjRepr( p1, pNext1 );
|
||||
if ( pNext0 == NULL )
|
||||
continue;
|
||||
assert( pNext1 == Aig_ObjRepr( p0, pNext0 ) );
|
||||
if ( Saig_ObjIsPi(p0, pNext0) )
|
||||
continue;
|
||||
Aig_ObjSetRepr( p0, pNext0, NULL );
|
||||
Aig_ObjSetRepr( p1, pNext1, NULL );
|
||||
}
|
||||
if ( fVerbose )
|
||||
{
|
||||
int nUnmached = Ssw_StrSimMatchingCountUnmached(p0);
|
||||
printf( "%2d : Total = %6d. Unmatched = %6d. Ratio = %6.2f %%\n",
|
||||
d+1, Aig_ManPiNum(p0) + Aig_ManNodeNum(p0),
|
||||
nUnmached, 100.0 * nUnmached/(Aig_ManPiNum(p0) + Aig_ManNodeNum(p0)) );
|
||||
}
|
||||
}
|
||||
Vec_PtrFree( vNodes0 );
|
||||
Vec_PtrFree( vNodes1 );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs structural matching of two AIGs using simulation.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Saig_StrSimPerformMatching( Aig_Man_t * p0, Aig_Man_t * p1, int nDist, int fVerbose, Aig_Man_t ** ppMiter )
|
||||
{
|
||||
extern Aig_Man_t * Saig_ManWindowExtractMiter( Aig_Man_t * p0, Aig_Man_t * p1 );
|
||||
|
||||
Vec_Int_t * vPairs;
|
||||
Aig_Man_t * pPart0, * pPart1;
|
||||
Aig_Obj_t * pObj0, * pObj1;
|
||||
int i, nMatches, clk, clkTotal = clock();
|
||||
Aig_ManRandom( 1 );
|
||||
// consider the case when a miter is given
|
||||
if ( p1 == NULL )
|
||||
{
|
||||
if ( fVerbose )
|
||||
{
|
||||
Aig_ManPrintStats( p0 );
|
||||
}
|
||||
// demiter the miter
|
||||
if ( !Saig_ManDemiterSimpleDiff( p0, &pPart0, &pPart1 ) )
|
||||
{
|
||||
printf( "Demitering has failed.\n" );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pPart0 = Aig_ManDupSimple( p0 );
|
||||
pPart1 = Aig_ManDupSimple( p1 );
|
||||
}
|
||||
if ( fVerbose )
|
||||
{
|
||||
Aig_ManPrintStats( pPart0 );
|
||||
Aig_ManPrintStats( pPart1 );
|
||||
}
|
||||
// start simulation
|
||||
Saig_StrSimPrepareAig( pPart0 );
|
||||
Saig_StrSimPrepareAig( pPart1 );
|
||||
Saig_StrSimSetInitMatching( pPart0, pPart1 );
|
||||
if ( fVerbose )
|
||||
{
|
||||
printf( "Allocated %6.2f Mb to simulate the first AIG.\n",
|
||||
1.0 * Aig_ManObjNumMax(pPart0) * SAIG_WORDS * sizeof(unsigned) / (1<<20) );
|
||||
printf( "Allocated %6.2f Mb to simulate the second AIG.\n",
|
||||
1.0 * Aig_ManObjNumMax(pPart1) * SAIG_WORDS * sizeof(unsigned) / (1<<20) );
|
||||
}
|
||||
// iterate matching
|
||||
nMatches = 1;
|
||||
for ( i = 0; nMatches > 0; i++ )
|
||||
{
|
||||
clk = clock();
|
||||
Saig_StrSimulateRound( pPart0, pPart1 );
|
||||
nMatches = Saig_StrSimDetectUnique( pPart0, pPart1 );
|
||||
if ( fVerbose )
|
||||
{
|
||||
int nFlops = Saig_StrSimCountMatchedFlops(pPart0);
|
||||
int nNodes = Saig_StrSimCountMatchedNodes(pPart0);
|
||||
printf( "%3d : Match =%6d. FF =%6d. (%6.2f %%) Node =%6d. (%6.2f %%) ",
|
||||
i, nMatches,
|
||||
nFlops, 100.0*nFlops/Aig_ManRegNum(pPart0),
|
||||
nNodes, 100.0*nNodes/Aig_ManNodeNum(pPart0) );
|
||||
PRT( "Time", clock() - clk );
|
||||
}
|
||||
if ( i == 20 )
|
||||
break;
|
||||
}
|
||||
// cleanup
|
||||
Vec_PtrFree( pPart0->pData2 ); pPart0->pData2 = NULL;
|
||||
Vec_PtrFree( pPart1->pData2 ); pPart1->pData2 = NULL;
|
||||
// extend the islands
|
||||
Aig_ManFanoutStart( pPart0 );
|
||||
Aig_ManFanoutStart( pPart1 );
|
||||
if ( nDist )
|
||||
Ssw_StrSimMatchingExtend( pPart0, pPart1, nDist, fVerbose );
|
||||
Saig_StrSimSetFinalMatching( pPart0, pPart1 );
|
||||
// Saig_StrSimSetContiguousMatching( pPart0, pPart1 );
|
||||
// copy the results into array
|
||||
vPairs = Vec_IntAlloc( 2*Aig_ManObjNumMax(pPart0) );
|
||||
Aig_ManForEachObj( pPart0, pObj0, i )
|
||||
{
|
||||
pObj1 = Aig_ObjRepr(pPart0, pObj0);
|
||||
if ( pObj1 == NULL )
|
||||
continue;
|
||||
assert( pObj0 == Aig_ObjRepr(pPart1, pObj1) );
|
||||
Vec_IntPush( vPairs, pObj0->Id );
|
||||
Vec_IntPush( vPairs, pObj1->Id );
|
||||
}
|
||||
// this procedure adds matching of PO and LI
|
||||
if ( ppMiter )
|
||||
*ppMiter = Saig_ManWindowExtractMiter( pPart0, pPart1 );
|
||||
Aig_ManFanoutStop( pPart0 );
|
||||
Aig_ManFanoutStop( pPart1 );
|
||||
Aig_ManStop( pPart0 );
|
||||
Aig_ManStop( pPart1 );
|
||||
PRT( "Total runtime", clock() - clkTotal );
|
||||
return vPairs;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,582 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [saigSwitch.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Sequential AIG package.]
|
||||
|
||||
Synopsis [Returns switching propabilities.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: saigSwitch.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "saig.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct Saig_SimObj_t_ Saig_SimObj_t;
|
||||
struct Saig_SimObj_t_
|
||||
{
|
||||
int iFan0;
|
||||
int iFan1;
|
||||
unsigned Type : 8;
|
||||
unsigned Number : 24;
|
||||
unsigned pData[1];
|
||||
};
|
||||
|
||||
static inline int Saig_SimObjFaninC0( Saig_SimObj_t * pObj ) { return pObj->iFan0 & 1; }
|
||||
static inline int Saig_SimObjFaninC1( Saig_SimObj_t * pObj ) { return pObj->iFan1 & 1; }
|
||||
static inline int Saig_SimObjFanin0( Saig_SimObj_t * pObj ) { return pObj->iFan0 >> 1; }
|
||||
static inline int Saig_SimObjFanin1( Saig_SimObj_t * pObj ) { return pObj->iFan1 >> 1; }
|
||||
|
||||
//typedef struct Aig_CMan_t_ Aig_CMan_t;
|
||||
|
||||
//static Aig_CMan_t * Aig_CManCreate( Aig_Man_t * p );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates fast simulation manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Saig_SimObj_t * Saig_ManCreateMan( Aig_Man_t * p )
|
||||
{
|
||||
Saig_SimObj_t * pAig, * pEntry;
|
||||
Aig_Obj_t * pObj;
|
||||
int i;
|
||||
pAig = CALLOC( Saig_SimObj_t, Aig_ManObjNumMax(p)+1 );
|
||||
// printf( "Allocating %7.2f Mb.\n", 1.0 * sizeof(Saig_SimObj_t) * (Aig_ManObjNumMax(p)+1)/(1<<20) );
|
||||
Aig_ManForEachObj( p, pObj, i )
|
||||
{
|
||||
pEntry = pAig + i;
|
||||
pEntry->Type = pObj->Type;
|
||||
if ( Aig_ObjIsPi(pObj) || i == 0 )
|
||||
{
|
||||
if ( Saig_ObjIsLo(p, pObj) )
|
||||
{
|
||||
pEntry->iFan0 = (Saig_ObjLoToLi(p, pObj)->Id << 1);
|
||||
pEntry->iFan1 = -1;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
pEntry->iFan0 = (Aig_ObjFaninId0(pObj) << 1) | Aig_ObjFaninC0(pObj);
|
||||
if ( Aig_ObjIsPo(pObj) )
|
||||
continue;
|
||||
assert( Aig_ObjIsNode(pObj) );
|
||||
pEntry->iFan1 = (Aig_ObjFaninId1(pObj) << 1) | Aig_ObjFaninC1(pObj);
|
||||
}
|
||||
pEntry = pAig + Aig_ManObjNumMax(p);
|
||||
pEntry->Type = AIG_OBJ_VOID;
|
||||
return pAig;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Simulated one node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Saig_ManSimulateNode2( Saig_SimObj_t * pAig, Saig_SimObj_t * pObj )
|
||||
{
|
||||
Saig_SimObj_t * pObj0 = pAig + Saig_SimObjFanin0( pObj );
|
||||
Saig_SimObj_t * pObj1 = pAig + Saig_SimObjFanin1( pObj );
|
||||
if ( Saig_SimObjFaninC0(pObj) && Saig_SimObjFaninC1(pObj) )
|
||||
pObj->pData[0] = ~(pObj0->pData[0] | pObj1->pData[0]);
|
||||
else if ( Saig_SimObjFaninC0(pObj) && !Saig_SimObjFaninC1(pObj) )
|
||||
pObj->pData[0] = (~pObj0->pData[0] & pObj1->pData[0]);
|
||||
else if ( !Saig_SimObjFaninC0(pObj) && Saig_SimObjFaninC1(pObj) )
|
||||
pObj->pData[0] = (pObj0->pData[0] & ~pObj1->pData[0]);
|
||||
else // if ( !Saig_SimObjFaninC0(pObj) && !Saig_SimObjFaninC1(pObj) )
|
||||
pObj->pData[0] = (pObj0->pData[0] & pObj1->pData[0]);
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Simulated one node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Saig_ManSimulateNode( Saig_SimObj_t * pAig, Saig_SimObj_t * pObj )
|
||||
{
|
||||
Saig_SimObj_t * pObj0 = pAig + Saig_SimObjFanin0( pObj );
|
||||
Saig_SimObj_t * pObj1 = pAig + Saig_SimObjFanin1( pObj );
|
||||
pObj->pData[0] = (Saig_SimObjFaninC0(pObj)? ~pObj0->pData[0] : pObj0->pData[0])
|
||||
& (Saig_SimObjFaninC1(pObj)? ~pObj1->pData[0] : pObj1->pData[0]);
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Simulated buffer/inverter.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Saig_ManSimulateOneInput( Saig_SimObj_t * pAig, Saig_SimObj_t * pObj )
|
||||
{
|
||||
Saig_SimObj_t * pObj0 = pAig + Saig_SimObjFanin0( pObj );
|
||||
if ( Saig_SimObjFaninC0(pObj) )
|
||||
pObj->pData[0] = ~pObj0->pData[0];
|
||||
else // if ( !Saig_SimObjFaninC0(pObj) )
|
||||
pObj->pData[0] = pObj0->pData[0];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Simulates the timeframes.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Saig_ManSimulateFrames( Saig_SimObj_t * pAig, int nFrames, int nPref )
|
||||
{
|
||||
Saig_SimObj_t * pEntry;
|
||||
int f;
|
||||
for ( f = 0; f < nFrames; f++ )
|
||||
{
|
||||
for ( pEntry = pAig; pEntry->Type != AIG_OBJ_VOID; pEntry++ )
|
||||
{
|
||||
if ( pEntry->Type == AIG_OBJ_AND )
|
||||
Saig_ManSimulateNode( pAig, pEntry );
|
||||
else if ( pEntry->Type == AIG_OBJ_PO )
|
||||
Saig_ManSimulateOneInput( pAig, pEntry );
|
||||
else if ( pEntry->Type == AIG_OBJ_PI )
|
||||
{
|
||||
if ( pEntry->iFan0 == 0 ) // true PI
|
||||
pEntry->pData[0] = Aig_ManRandom( 0 );
|
||||
else if ( f > 0 ) // register output
|
||||
Saig_ManSimulateOneInput( pAig, pEntry );
|
||||
}
|
||||
else if ( pEntry->Type == AIG_OBJ_CONST1 )
|
||||
pEntry->pData[0] = ~0;
|
||||
else if ( pEntry->Type != AIG_OBJ_NONE )
|
||||
assert( 0 );
|
||||
if ( f >= nPref )
|
||||
pEntry->Number += Aig_WordCountOnes( pEntry->pData[0] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes switching activity of one node.]
|
||||
|
||||
Description [Uses the formula: Switching = 2 * nOnes * nZeros / (nTotal ^ 2) ]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
float Saig_ManComputeSwitching( int nOnes, int nSimWords )
|
||||
{
|
||||
int nTotal = 32 * nSimWords;
|
||||
return (float)2.0 * nOnes / nTotal * (nTotal - nOnes) / nTotal;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes switching activity of one node.]
|
||||
|
||||
Description [Uses the formula: Switching = 2 * nOnes * nZeros / (nTotal ^ 2) ]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
float Saig_ManComputeProbOne( int nOnes, int nSimWords )
|
||||
{
|
||||
int nTotal = 32 * nSimWords;
|
||||
return (float)nOnes / nTotal;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes switching activity of one node.]
|
||||
|
||||
Description [Uses the formula: Switching = 2 * nOnes * nZeros / (nTotal ^ 2) ]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
float Saig_ManComputeProbOnePlus( int nOnes, int nSimWords, int fCompl )
|
||||
{
|
||||
int nTotal = 32 * nSimWords;
|
||||
if ( fCompl )
|
||||
return (float)(nTotal-nOnes) / nTotal;
|
||||
else
|
||||
return (float)nOnes / nTotal;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Compute switching probabilities of all nodes.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Saig_ManComputeSwitchProbs_old( Aig_Man_t * p, int nFrames, int nPref, int fProbOne )
|
||||
{
|
||||
extern char * Abc_FrameReadFlag( char * pFlag );
|
||||
Saig_SimObj_t * pAig, * pEntry;
|
||||
Vec_Int_t * vSwitching;
|
||||
float * pSwitching;
|
||||
int nFramesReal, clk, clkTotal = clock();
|
||||
vSwitching = Vec_IntStart( Aig_ManObjNumMax(p) );
|
||||
pSwitching = (float *)vSwitching->pArray;
|
||||
clk = clock();
|
||||
pAig = Saig_ManCreateMan( p );
|
||||
//PRT( "\nCreation ", clock() - clk );
|
||||
|
||||
Aig_ManRandom( 1 );
|
||||
// get the number of frames to simulate
|
||||
// if the parameter "seqsimframes" is defined, use it
|
||||
// otherwise, use the given number of frames "nFrames"
|
||||
nFramesReal = nFrames;
|
||||
if ( Abc_FrameReadFlag("seqsimframes") )
|
||||
nFramesReal = atoi( Abc_FrameReadFlag("seqsimframes") );
|
||||
if ( nFramesReal <= nPref )
|
||||
{
|
||||
printf( "The total number of frames (%d) should exceed prefix (%d).\n", nFramesReal, nPref );\
|
||||
printf( "Setting the total number of frames to be %d.\n", nFrames );
|
||||
nFramesReal = nFrames;
|
||||
}
|
||||
//printf( "Simulating %d frames.\n", nFramesReal );
|
||||
clk = clock();
|
||||
Saig_ManSimulateFrames( pAig, nFramesReal, nPref );
|
||||
//PRT( "Simulation", clock() - clk );
|
||||
clk = clock();
|
||||
for ( pEntry = pAig; pEntry->Type != AIG_OBJ_VOID; pEntry++ )
|
||||
{
|
||||
/*
|
||||
if ( pEntry->Type == AIG_OBJ_AND )
|
||||
{
|
||||
Saig_SimObj_t * pObj0 = pAig + Saig_SimObjFanin0( pEntry );
|
||||
Saig_SimObj_t * pObj1 = pAig + Saig_SimObjFanin1( pEntry );
|
||||
printf( "%5.2f = %5.2f * %5.2f (%7.4f)\n",
|
||||
Saig_ManComputeProbOnePlus( pEntry->Number, nFrames - nPref, 0 ),
|
||||
Saig_ManComputeProbOnePlus( pObj0->Number, nFrames - nPref, Saig_SimObjFaninC0(pEntry) ),
|
||||
Saig_ManComputeProbOnePlus( pObj1->Number, nFrames - nPref, Saig_SimObjFaninC1(pEntry) ),
|
||||
Saig_ManComputeProbOnePlus( pEntry->Number, nFrames - nPref, 0 ) -
|
||||
Saig_ManComputeProbOnePlus( pObj0->Number, nFrames - nPref, Saig_SimObjFaninC0(pEntry) ) *
|
||||
Saig_ManComputeProbOnePlus( pObj1->Number, nFrames - nPref, Saig_SimObjFaninC1(pEntry) )
|
||||
);
|
||||
}
|
||||
*/
|
||||
if ( fProbOne )
|
||||
pSwitching[pEntry-pAig] = Saig_ManComputeProbOne( pEntry->Number, nFramesReal - nPref );
|
||||
else
|
||||
pSwitching[pEntry-pAig] = Saig_ManComputeSwitching( pEntry->Number, nFramesReal - nPref );
|
||||
//printf( "%3d : %7.2f\n", pEntry-pAig, pSwitching[pEntry-pAig] );
|
||||
}
|
||||
free( pAig );
|
||||
//PRT( "Switch ", clock() - clk );
|
||||
//PRT( "TOTAL ", clock() - clkTotal );
|
||||
|
||||
// Aig_CManCreate( p );
|
||||
return vSwitching;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
typedef struct Aig_CMan_t_ Aig_CMan_t;
|
||||
struct Aig_CMan_t_
|
||||
{
|
||||
// parameters
|
||||
int nIns;
|
||||
int nNodes;
|
||||
int nOuts;
|
||||
// current state
|
||||
int iNode;
|
||||
int iDiff0;
|
||||
int iDiff1;
|
||||
unsigned char * pCur;
|
||||
// stored data
|
||||
int iPrev;
|
||||
int nBytes;
|
||||
unsigned char Data[0];
|
||||
};
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_CMan_t * Aig_CManStart( int nIns, int nNodes, int nOuts )
|
||||
{
|
||||
Aig_CMan_t * p;
|
||||
p = (Aig_CMan_t *)ALLOC( char, sizeof(Aig_CMan_t) + 2*(2*nNodes + nOuts) );
|
||||
memset( p, 0, sizeof(Aig_CMan_t) );
|
||||
// set parameters
|
||||
p->nIns = nIns;
|
||||
p->nOuts = nOuts;
|
||||
p->nNodes = nNodes;
|
||||
p->nBytes = 2*(2*nNodes + nOuts);
|
||||
// prepare the manager
|
||||
p->iNode = 1 + p->nIns;
|
||||
p->iPrev = -1;
|
||||
p->pCur = p->Data;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Aig_CManStop( Aig_CMan_t * p )
|
||||
{
|
||||
free( p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Aig_CManRestart( Aig_CMan_t * p )
|
||||
{
|
||||
assert( p->iNode == 1 + p->nIns + p->nNodes + p->nOuts );
|
||||
p->iNode = 1 + p->nIns;
|
||||
p->iPrev = -1;
|
||||
p->pCur = p->Data;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Aig_CManStoreNum( Aig_CMan_t * p, unsigned x )
|
||||
{
|
||||
while ( x & ~0x7f )
|
||||
{
|
||||
*p->pCur++ = (x & 0x7f) | 0x80;
|
||||
x >>= 7;
|
||||
}
|
||||
*p->pCur++ = x;
|
||||
assert( p->pCur - p->Data < p->nBytes - 10 );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Aig_CManRestoreNum( Aig_CMan_t * p )
|
||||
{
|
||||
int ch, i, x = 0;
|
||||
for ( i = 0; (ch = *p->pCur++) & 0x80; i++ )
|
||||
x |= (ch & 0x7f) << (7 * i);
|
||||
return x | (ch << (7 * i));
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Aig_CManAddNode( Aig_CMan_t * p, int iFan0, int iFan1 )
|
||||
{
|
||||
assert( iFan0 < iFan1 );
|
||||
assert( iFan1 < (p->iNode << 1) );
|
||||
Aig_CManStoreNum( p, (p->iNode++ << 1) - iFan1 );
|
||||
Aig_CManStoreNum( p, iFan1 - iFan0 );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Aig_CManAddPo( Aig_CMan_t * p, int iFan0 )
|
||||
{
|
||||
if ( p->iPrev == -1 )
|
||||
Aig_CManStoreNum( p, p->iNode - iFan0 );
|
||||
else if ( p->iPrev <= iFan0 )
|
||||
Aig_CManStoreNum( p, (iFan0 - p->iPrev) << 1 );
|
||||
else
|
||||
Aig_CManStoreNum( p,((p->iPrev - iFan0) << 1) | 1 );
|
||||
p->iPrev = iFan0;
|
||||
p->iNode++;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Aig_CManGetNode( Aig_CMan_t * p, int * piFan0, int * piFan1 )
|
||||
{
|
||||
*piFan1 = (p->iNode++ << 1) - Aig_CManRestoreNum( p );
|
||||
*piFan0 = *piFan1 - Aig_CManRestoreNum( p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Aig_CManGetPo( Aig_CMan_t * p )
|
||||
{
|
||||
int Num = Aig_CManRestoreNum( p );
|
||||
if ( p->iPrev == -1 )
|
||||
p->iPrev = p->iNode;
|
||||
p->iNode++;
|
||||
if ( Num & 1 )
|
||||
return p->iPrev = p->iPrev + (Num >> 1);
|
||||
return p->iPrev = p->iPrev - (Num >> 1);
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Compute switching probabilities of all nodes.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_CMan_t * Aig_CManCreate( Aig_Man_t * p )
|
||||
{
|
||||
Aig_CMan_t * pCMan;
|
||||
Aig_Obj_t * pObj;
|
||||
int i;
|
||||
pCMan = Aig_CManStart( Aig_ManPiNum(p), Aig_ManNodeNum(p), Aig_ManPoNum(p) );
|
||||
Aig_ManForEachNode( p, pObj, i )
|
||||
Aig_CManAddNode( pCMan,
|
||||
(Aig_ObjFaninId0(pObj) << 1) | Aig_ObjFaninC0(pObj),
|
||||
(Aig_ObjFaninId1(pObj) << 1) | Aig_ObjFaninC1(pObj) );
|
||||
Aig_ManForEachPo( p, pObj, i )
|
||||
Aig_CManAddPo( pCMan,
|
||||
(Aig_ObjFaninId0(pObj) << 1) | Aig_ObjFaninC0(pObj) );
|
||||
printf( "\nBytes alloc = %5d. Bytes used = %7d. Ave per node = %4.2f. \n",
|
||||
pCMan->nBytes, pCMan->pCur - pCMan->Data,
|
||||
1.0 * (pCMan->pCur - pCMan->Data) / (pCMan->nNodes + pCMan->nOuts ) );
|
||||
// Aig_CManStop( pCMan );
|
||||
return pCMan;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Compute switching probabilities of all nodes.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Saig_ManComputeSwitchProbs2( Aig_Man_t * p, int nFrames, int nPref, int fProbOne )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,809 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [saigWnd.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Sequential AIG package.]
|
||||
|
||||
Synopsis [Sequential windowing.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: saigWnd.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "saig.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the array of PI/internal nodes.]
|
||||
|
||||
Description [Marks all the visited nodes with the current ID.
|
||||
Does not collect constant node and PO/LI nodes.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Saig_ManWindowOutline_rec( Aig_Man_t * p, Aig_Obj_t * pObj, int nDist, Vec_Ptr_t * vNodes, int * pDists )
|
||||
{
|
||||
Aig_Obj_t * pMatch, * pFanout;
|
||||
int fCollected, iFanout = -1, i;
|
||||
if ( nDist == 0 )
|
||||
return;
|
||||
if ( pDists[pObj->Id] >= nDist )
|
||||
return;
|
||||
pDists[pObj->Id] = nDist;
|
||||
fCollected = Aig_ObjIsTravIdCurrent( p, pObj );
|
||||
Aig_ObjSetTravIdCurrent( p, pObj );
|
||||
if ( Aig_ObjIsConst1(pObj) )
|
||||
return;
|
||||
if ( Saig_ObjIsPo(p, pObj) )
|
||||
return;
|
||||
if ( Saig_ObjIsLi(p, pObj) )
|
||||
{
|
||||
pMatch = Saig_ObjLiToLo( p, pObj );
|
||||
if ( !Aig_ObjIsTravIdCurrent( p, pMatch ) )
|
||||
Saig_ManWindowOutline_rec( p, pMatch, nDist, vNodes, pDists );
|
||||
Saig_ManWindowOutline_rec( p, Aig_ObjFanin0(pObj), nDist-1, vNodes, pDists );
|
||||
return;
|
||||
}
|
||||
if ( !fCollected )
|
||||
Vec_PtrPush( vNodes, pObj );
|
||||
if ( Saig_ObjIsPi(p, pObj) )
|
||||
return;
|
||||
if ( Saig_ObjIsLo(p, pObj) )
|
||||
{
|
||||
pMatch = Saig_ObjLoToLi( p, pObj );
|
||||
if ( !Aig_ObjIsTravIdCurrent( p, pMatch ) )
|
||||
Saig_ManWindowOutline_rec( p, pMatch, nDist, vNodes, pDists );
|
||||
Aig_ObjForEachFanout( p, pObj, pFanout, iFanout, i )
|
||||
Saig_ManWindowOutline_rec( p, pFanout, nDist-1, vNodes, pDists );
|
||||
return;
|
||||
}
|
||||
assert( Aig_ObjIsNode(pObj) );
|
||||
Saig_ManWindowOutline_rec( p, Aig_ObjFanin0(pObj), nDist-1, vNodes, pDists );
|
||||
Saig_ManWindowOutline_rec( p, Aig_ObjFanin1(pObj), nDist-1, vNodes, pDists );
|
||||
Aig_ObjForEachFanout( p, pObj, pFanout, iFanout, i )
|
||||
Saig_ManWindowOutline_rec( p, pFanout, nDist-1, vNodes, pDists );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the array of PI/internal nodes.]
|
||||
|
||||
Description [Marks all the visited nodes with the current ID.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Ptr_t * Saig_ManWindowOutline( Aig_Man_t * p, Aig_Obj_t * pObj, int nDist )
|
||||
{
|
||||
Vec_Ptr_t * vNodes;
|
||||
Aig_Obj_t * pObjLi, * pObjLo;
|
||||
int * pDists, i;
|
||||
pDists = CALLOC( int, Aig_ManObjNumMax(p) );
|
||||
vNodes = Vec_PtrAlloc( 1000 );
|
||||
Aig_ManIncrementTravId( p );
|
||||
Saig_ManWindowOutline_rec( p, pObj, nDist, vNodes, pDists );
|
||||
Vec_PtrSort( vNodes, Aig_ObjCompareIdIncrease );
|
||||
// make sure LI/LO are labeled/unlabeled mutually
|
||||
Saig_ManForEachLiLo( p, pObjLi, pObjLo, i )
|
||||
assert( Aig_ObjIsTravIdCurrent(p, pObjLi) ==
|
||||
Aig_ObjIsTravIdCurrent(p, pObjLo) );
|
||||
free( pDists );
|
||||
return vNodes;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns 1 if the node has unlabeled fanout.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Obj_t * Saig_ObjHasUnlabeledFanout( Aig_Man_t * p, Aig_Obj_t * pObj )
|
||||
{
|
||||
Aig_Obj_t * pFanout;
|
||||
int iFanout = -1, i;
|
||||
Aig_ObjForEachFanout( p, pObj, pFanout, iFanout, i )
|
||||
if ( Saig_ObjIsPo(p, pFanout) || !Aig_ObjIsTravIdCurrent(p, pFanout) )
|
||||
return pFanout;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Collects primary inputs.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Ptr_t * Saig_ManWindowCollectPis( Aig_Man_t * p, Vec_Ptr_t * vNodes )
|
||||
{
|
||||
Vec_Ptr_t * vNodesPi;
|
||||
Aig_Obj_t * pObj, * pMatch, * pFanin;
|
||||
int i;
|
||||
vNodesPi = Vec_PtrAlloc( 1000 );
|
||||
Vec_PtrForEachEntry( vNodes, pObj, i )
|
||||
{
|
||||
if ( Saig_ObjIsPi(p, pObj) )
|
||||
{
|
||||
assert( pObj->pData == NULL );
|
||||
Vec_PtrPush( vNodesPi, pObj );
|
||||
}
|
||||
else if ( Saig_ObjIsLo(p, pObj) )
|
||||
{
|
||||
pMatch = Saig_ObjLoToLi( p, pObj );
|
||||
pFanin = Aig_ObjFanin0(pMatch);
|
||||
if ( !Aig_ObjIsTravIdCurrent(p, pFanin) && pFanin->pData == NULL )
|
||||
Vec_PtrPush( vNodesPi, pFanin );
|
||||
}
|
||||
else
|
||||
{
|
||||
assert( Aig_ObjIsNode(pObj) );
|
||||
pFanin = Aig_ObjFanin0(pObj);
|
||||
if ( !Aig_ObjIsTravIdCurrent(p, pFanin) && pFanin->pData == NULL )
|
||||
Vec_PtrPush( vNodesPi, pFanin );
|
||||
pFanin = Aig_ObjFanin1(pObj);
|
||||
if ( !Aig_ObjIsTravIdCurrent(p, pFanin) && pFanin->pData == NULL )
|
||||
Vec_PtrPush( vNodesPi, pFanin );
|
||||
}
|
||||
}
|
||||
return vNodesPi;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Collects primary outputs.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Ptr_t * Saig_ManWindowCollectPos( Aig_Man_t * p, Vec_Ptr_t * vNodes, Vec_Ptr_t ** pvPointers )
|
||||
{
|
||||
Vec_Ptr_t * vNodesPo;
|
||||
Aig_Obj_t * pObj, * pPointer;
|
||||
int i;
|
||||
vNodesPo = Vec_PtrAlloc( 1000 );
|
||||
if ( pvPointers )
|
||||
*pvPointers = Vec_PtrAlloc( 1000 );
|
||||
Vec_PtrForEachEntry( vNodes, pObj, i )
|
||||
{
|
||||
if ( (pPointer = Saig_ObjHasUnlabeledFanout(p, pObj)) )
|
||||
{
|
||||
Vec_PtrPush( vNodesPo, pObj );
|
||||
if ( pvPointers )
|
||||
Vec_PtrPush( *pvPointers, pPointer );
|
||||
}
|
||||
}
|
||||
return vNodesPo;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Extracts the window AIG from the AIG manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Man_t * Saig_ManWindowExtractNodes( Aig_Man_t * p, Vec_Ptr_t * vNodes )
|
||||
{
|
||||
Aig_Man_t * pNew;
|
||||
Aig_Obj_t * pObj, * pMatch;
|
||||
Vec_Ptr_t * vNodesPi, * vNodesPo;
|
||||
int i, nRegCount;
|
||||
Aig_ManCleanData( p );
|
||||
// create the new manager
|
||||
pNew = Aig_ManStart( Vec_PtrSize(vNodes) );
|
||||
pNew->pName = Aig_UtilStrsav( "wnd" );
|
||||
pNew->pSpec = NULL;
|
||||
// map constant nodes
|
||||
pObj = Aig_ManConst1( p );
|
||||
pObj->pData = Aig_ManConst1( pNew );
|
||||
// create real PIs
|
||||
vNodesPi = Saig_ManWindowCollectPis( p, vNodes );
|
||||
Vec_PtrForEachEntry( vNodesPi, pObj, i )
|
||||
pObj->pData = Aig_ObjCreatePi(pNew);
|
||||
Vec_PtrFree( vNodesPi );
|
||||
// create register outputs
|
||||
Vec_PtrForEachEntry( vNodes, pObj, i )
|
||||
{
|
||||
if ( Saig_ObjIsLo(p, pObj) )
|
||||
pObj->pData = Aig_ObjCreatePi(pNew);
|
||||
}
|
||||
// create internal nodes
|
||||
Vec_PtrForEachEntry( vNodes, pObj, i )
|
||||
{
|
||||
if ( Aig_ObjIsNode(pObj) )
|
||||
pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
|
||||
}
|
||||
// create POs
|
||||
vNodesPo = Saig_ManWindowCollectPos( p, vNodes, NULL );
|
||||
Vec_PtrForEachEntry( vNodesPo, pObj, i )
|
||||
Aig_ObjCreatePo( pNew, pObj->pData );
|
||||
Vec_PtrFree( vNodesPo );
|
||||
// create register inputs
|
||||
nRegCount = 0;
|
||||
Vec_PtrForEachEntry( vNodes, pObj, i )
|
||||
{
|
||||
if ( Saig_ObjIsLo(p, pObj) )
|
||||
{
|
||||
pMatch = Saig_ObjLoToLi( p, pObj );
|
||||
Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pMatch) );
|
||||
nRegCount++;
|
||||
}
|
||||
}
|
||||
Aig_ManSetRegNum( pNew, nRegCount );
|
||||
Aig_ManCleanup( pNew );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
static void Saig_ManWindowInsertSmall_rec( Aig_Man_t * pNew, Aig_Obj_t * pObjSmall,
|
||||
Vec_Ptr_t * vBigNode2SmallPo, Vec_Ptr_t * vSmallPi2BigNode );
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Adds nodes for the big manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Saig_ManWindowInsertBig_rec( Aig_Man_t * pNew, Aig_Obj_t * pObjBig,
|
||||
Vec_Ptr_t * vBigNode2SmallPo, Vec_Ptr_t * vSmallPi2BigNode )
|
||||
{
|
||||
Aig_Obj_t * pMatch;
|
||||
if ( pObjBig->pData )
|
||||
return;
|
||||
if ( (pMatch = Vec_PtrEntry( vBigNode2SmallPo, pObjBig->Id )) )
|
||||
{
|
||||
Saig_ManWindowInsertSmall_rec( pNew, Aig_ObjFanin0(pMatch), vBigNode2SmallPo, vSmallPi2BigNode );
|
||||
pObjBig->pData = Aig_ObjChild0Copy(pMatch);
|
||||
return;
|
||||
}
|
||||
assert( Aig_ObjIsNode(pObjBig) );
|
||||
Saig_ManWindowInsertBig_rec( pNew, Aig_ObjFanin0(pObjBig), vBigNode2SmallPo, vSmallPi2BigNode );
|
||||
Saig_ManWindowInsertBig_rec( pNew, Aig_ObjFanin1(pObjBig), vBigNode2SmallPo, vSmallPi2BigNode );
|
||||
pObjBig->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObjBig), Aig_ObjChild1Copy(pObjBig) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Adds nodes for the small manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Saig_ManWindowInsertSmall_rec( Aig_Man_t * pNew, Aig_Obj_t * pObjSmall,
|
||||
Vec_Ptr_t * vBigNode2SmallPo, Vec_Ptr_t * vSmallPi2BigNode )
|
||||
{
|
||||
Aig_Obj_t * pMatch;
|
||||
if ( pObjSmall->pData )
|
||||
return;
|
||||
if ( (pMatch = Vec_PtrEntry( vSmallPi2BigNode, pObjSmall->Id )) )
|
||||
{
|
||||
Saig_ManWindowInsertBig_rec( pNew, pMatch, vBigNode2SmallPo, vSmallPi2BigNode );
|
||||
pObjSmall->pData = pMatch->pData;
|
||||
return;
|
||||
}
|
||||
assert( Aig_ObjIsNode(pObjSmall) );
|
||||
Saig_ManWindowInsertSmall_rec( pNew, Aig_ObjFanin0(pObjSmall), vBigNode2SmallPo, vSmallPi2BigNode );
|
||||
Saig_ManWindowInsertSmall_rec( pNew, Aig_ObjFanin1(pObjSmall), vBigNode2SmallPo, vSmallPi2BigNode );
|
||||
pObjSmall->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObjSmall), Aig_ObjChild1Copy(pObjSmall) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Extracts the network from the AIG manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Man_t * Saig_ManWindowInsertNodes( Aig_Man_t * p, Vec_Ptr_t * vNodes, Aig_Man_t * pWnd )
|
||||
{
|
||||
Aig_Man_t * pNew;
|
||||
Vec_Ptr_t * vBigNode2SmallPo, * vSmallPi2BigNode;
|
||||
Vec_Ptr_t * vNodesPi, * vNodesPo;
|
||||
Aig_Obj_t * pObj;
|
||||
int i;
|
||||
|
||||
// set mapping of small PIs into big nodes
|
||||
vSmallPi2BigNode = Vec_PtrStart( Aig_ManObjNumMax(pWnd) );
|
||||
vNodesPi = Saig_ManWindowCollectPis( p, vNodes );
|
||||
Vec_PtrForEachEntry( vNodesPi, pObj, i )
|
||||
Vec_PtrWriteEntry( vSmallPi2BigNode, Aig_ManPi(pWnd, i)->Id, pObj );
|
||||
assert( i == Saig_ManPiNum(pWnd) );
|
||||
Vec_PtrFree( vNodesPi );
|
||||
|
||||
// set mapping of big nodes into small POs
|
||||
vBigNode2SmallPo = Vec_PtrStart( Aig_ManObjNumMax(p) );
|
||||
vNodesPo = Saig_ManWindowCollectPos( p, vNodes, NULL );
|
||||
Vec_PtrForEachEntry( vNodesPo, pObj, i )
|
||||
Vec_PtrWriteEntry( vBigNode2SmallPo, pObj->Id, Aig_ManPo(pWnd, i) );
|
||||
assert( i == Saig_ManPoNum(pWnd) );
|
||||
Vec_PtrFree( vNodesPo );
|
||||
|
||||
// create the new manager
|
||||
Aig_ManCleanData( p );
|
||||
Aig_ManCleanData( pWnd );
|
||||
pNew = Aig_ManStart( Aig_ManObjNumMax(p) );
|
||||
pNew->pName = Aig_UtilStrsav( p->pName );
|
||||
pNew->pSpec = Aig_UtilStrsav( p->pSpec );
|
||||
// map constant nodes
|
||||
pObj = Aig_ManConst1( p );
|
||||
pObj->pData = Aig_ManConst1( pNew );
|
||||
pObj = Aig_ManConst1( pWnd );
|
||||
pObj->pData = Aig_ManConst1( pNew );
|
||||
|
||||
// create real PIs
|
||||
Aig_ManForEachPi( p, pObj, i )
|
||||
if ( Saig_ObjIsPi(p, pObj) || !Aig_ObjIsTravIdCurrent(p, pObj) )
|
||||
pObj->pData = Aig_ObjCreatePi(pNew);
|
||||
// create additional latch outputs
|
||||
Saig_ManForEachLo( pWnd, pObj, i )
|
||||
pObj->pData = Aig_ObjCreatePi(pNew);
|
||||
|
||||
// create internal nodes starting from the big
|
||||
Aig_ManForEachPo( p, pObj, i )
|
||||
if ( Saig_ObjIsPo(p, pObj) || !Aig_ObjIsTravIdCurrent(p, pObj) )
|
||||
{
|
||||
Saig_ManWindowInsertBig_rec( pNew, Aig_ObjFanin0(pObj), vBigNode2SmallPo, vSmallPi2BigNode );
|
||||
pObj->pData = Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) );
|
||||
}
|
||||
// create internal nodes starting from the small
|
||||
Saig_ManForEachLi( pWnd, pObj, i )
|
||||
{
|
||||
Saig_ManWindowInsertSmall_rec( pNew, Aig_ObjFanin0(pObj), vBigNode2SmallPo, vSmallPi2BigNode );
|
||||
pObj->pData = Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) );
|
||||
}
|
||||
Vec_PtrFree( vBigNode2SmallPo );
|
||||
Vec_PtrFree( vSmallPi2BigNode );
|
||||
// set the new number of registers
|
||||
assert( Aig_ManPiNum(pNew) - Aig_ManPiNum(p) == Aig_ManPoNum(pNew) - Aig_ManPoNum(p) );
|
||||
Aig_ManSetRegNum( pNew, Aig_ManRegNum(p) + (Aig_ManPiNum(pNew) - Aig_ManPiNum(p)) );
|
||||
Aig_ManCleanup( pNew );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Find a good object.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Obj_t * Saig_ManFindPivot( Aig_Man_t * p )
|
||||
{
|
||||
Aig_Obj_t * pObj;
|
||||
int i, Counter;
|
||||
if ( Aig_ManRegNum(p) > 0 )
|
||||
{
|
||||
if ( Aig_ManRegNum(p) == 1 )
|
||||
return Saig_ManLo( p, 0 );
|
||||
Saig_ManForEachLo( p, pObj, i )
|
||||
{
|
||||
if ( i == Aig_ManRegNum(p)/2 )
|
||||
return pObj;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Counter = 0;
|
||||
assert( Aig_ManNodeNum(p) > 1 );
|
||||
Aig_ManForEachNode( p, pObj, i )
|
||||
{
|
||||
if ( Counter++ == Aig_ManNodeNum(p)/2 )
|
||||
return pObj;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes sequential window of the node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Man_t * Saig_ManWindowExtract( Aig_Man_t * p, Aig_Obj_t * pObj, int nDist )
|
||||
{
|
||||
Aig_Man_t * pWnd;
|
||||
Vec_Ptr_t * vNodes;
|
||||
Aig_ManFanoutStart( p );
|
||||
vNodes = Saig_ManWindowOutline( p, pObj, nDist );
|
||||
pWnd = Saig_ManWindowExtractNodes( p, vNodes );
|
||||
Vec_PtrFree( vNodes );
|
||||
Aig_ManFanoutStop( p );
|
||||
return pWnd;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes sequential window of the node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Man_t * Saig_ManWindowInsert( Aig_Man_t * p, Aig_Obj_t * pObj, int nDist, Aig_Man_t * pWnd )
|
||||
{
|
||||
Aig_Man_t * pNew, * pWndTest;
|
||||
Vec_Ptr_t * vNodes;
|
||||
Aig_ManFanoutStart( p );
|
||||
|
||||
vNodes = Saig_ManWindowOutline( p, pObj, nDist );
|
||||
pWndTest = Saig_ManWindowExtractNodes( p, vNodes );
|
||||
if ( Saig_ManPiNum(pWndTest) != Saig_ManPiNum(pWnd) ||
|
||||
Saig_ManPoNum(pWndTest) != Saig_ManPoNum(pWnd) )
|
||||
{
|
||||
printf( "The window cannot be reinserted because PI/PO counts do not match.\n" );
|
||||
Aig_ManStop( pWndTest );
|
||||
Vec_PtrFree( vNodes );
|
||||
Aig_ManFanoutStop( p );
|
||||
return NULL;
|
||||
}
|
||||
Aig_ManStop( pWndTest );
|
||||
Vec_PtrFree( vNodes );
|
||||
|
||||
// insert the nodes
|
||||
Aig_ManCleanData( p );
|
||||
vNodes = Saig_ManWindowOutline( p, pObj, nDist );
|
||||
pNew = Saig_ManWindowInsertNodes( p, vNodes, pWnd );
|
||||
Vec_PtrFree( vNodes );
|
||||
Aig_ManFanoutStop( p );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Tests the above computation.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Man_t * Saig_ManWindowTest( Aig_Man_t * p )
|
||||
{
|
||||
int nDist = 3;
|
||||
Aig_Man_t * pWnd, * pNew;
|
||||
Aig_Obj_t * pPivot;
|
||||
pPivot = Saig_ManFindPivot( p );
|
||||
assert( pPivot != NULL );
|
||||
pWnd = Saig_ManWindowExtract( p, pPivot, nDist );
|
||||
pNew = Saig_ManWindowInsert( p, pPivot, nDist, pWnd );
|
||||
Aig_ManStop( pWnd );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Collects the nodes that are not linked to each other.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Ptr_t * Saig_ManCollectedDiffNodes( Aig_Man_t * p0, Aig_Man_t * p1 )
|
||||
{
|
||||
Vec_Ptr_t * vNodes;
|
||||
Aig_Obj_t * pObj0, * pObj1;
|
||||
int i;
|
||||
// collect nodes that are not linked
|
||||
Aig_ManIncrementTravId( p0 );
|
||||
vNodes = Vec_PtrAlloc( 1000 );
|
||||
Aig_ManForEachObj( p0, pObj0, i )
|
||||
{
|
||||
pObj1 = Aig_ObjRepr( p0, pObj0 );
|
||||
if ( pObj1 != NULL )
|
||||
{
|
||||
assert( pObj0 == Aig_ObjRepr( p1, pObj1 ) );
|
||||
continue;
|
||||
}
|
||||
// mark and collect unmatched objects
|
||||
Aig_ObjSetTravIdCurrent( p0, pObj0 );
|
||||
if ( Aig_ObjIsNode(pObj0) || Aig_ObjIsPi(pObj0) )
|
||||
Vec_PtrPush( vNodes, pObj0 );
|
||||
}
|
||||
// make sure LI/LO are labeled/unlabeled mutually
|
||||
Saig_ManForEachLiLo( p0, pObj0, pObj1, i )
|
||||
assert( Aig_ObjIsTravIdCurrent(p0, pObj0) ==
|
||||
Aig_ObjIsTravIdCurrent(p0, pObj1) );
|
||||
return vNodes;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates PIs of the miter.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Saig_ManWindowCreatePis( Aig_Man_t * pNew, Aig_Man_t * p0, Aig_Man_t * p1, Vec_Ptr_t * vNodes0 )
|
||||
{
|
||||
Aig_Obj_t * pObj, * pMatch, * pFanin;
|
||||
int i, Counter = 0;
|
||||
Vec_PtrForEachEntry( vNodes0, pObj, i )
|
||||
{
|
||||
if ( Saig_ObjIsLo(p0, pObj) )
|
||||
{
|
||||
pMatch = Saig_ObjLoToLi( p0, pObj );
|
||||
pFanin = Aig_ObjFanin0(pMatch);
|
||||
if ( !Aig_ObjIsTravIdCurrent(p0, pFanin) && pFanin->pData == NULL )
|
||||
{
|
||||
pFanin->pData = Aig_ObjCreatePi(pNew);
|
||||
pMatch = Aig_ObjRepr( p0, pFanin );
|
||||
assert( pFanin == Aig_ObjRepr( p1, pMatch ) );
|
||||
assert( pMatch != NULL );
|
||||
pMatch->pData = pFanin->pData;
|
||||
Counter++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
assert( Aig_ObjIsNode(pObj) );
|
||||
pFanin = Aig_ObjFanin0(pObj);
|
||||
if ( !Aig_ObjIsTravIdCurrent(p0, pFanin) && pFanin->pData == NULL )
|
||||
{
|
||||
pFanin->pData = Aig_ObjCreatePi(pNew);
|
||||
pMatch = Aig_ObjRepr( p0, pFanin );
|
||||
assert( pFanin == Aig_ObjRepr( p1, pMatch ) );
|
||||
assert( pMatch != NULL );
|
||||
pMatch->pData = pFanin->pData;
|
||||
Counter++;
|
||||
}
|
||||
pFanin = Aig_ObjFanin1(pObj);
|
||||
if ( !Aig_ObjIsTravIdCurrent(p0, pFanin) && pFanin->pData == NULL )
|
||||
{
|
||||
pFanin->pData = Aig_ObjCreatePi(pNew);
|
||||
pMatch = Aig_ObjRepr( p0, pFanin );
|
||||
assert( pFanin == Aig_ObjRepr( p1, pMatch ) );
|
||||
assert( pMatch != NULL );
|
||||
pMatch->pData = pFanin->pData;
|
||||
Counter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
// printf( "Added %d primary inputs.\n", Counter );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates POs of the miter.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Saig_ManWindowCreatePos( Aig_Man_t * pNew, Aig_Man_t * p0, Aig_Man_t * p1 )
|
||||
{
|
||||
Aig_Obj_t * pObj0, * pObj1, * pMiter;
|
||||
Aig_Obj_t * pFanin0, * pFanin1;
|
||||
int i;
|
||||
Aig_ManForEachObj( p0, pObj0, i )
|
||||
{
|
||||
if ( Aig_ObjIsTravIdCurrent(p0, pObj0) )
|
||||
continue;
|
||||
if ( Aig_ObjIsConst1(pObj0) )
|
||||
continue;
|
||||
if ( Aig_ObjIsPi(pObj0) )
|
||||
continue;
|
||||
pObj1 = Aig_ObjRepr( p0, pObj0 );
|
||||
assert( pObj0 == Aig_ObjRepr( p1, pObj1 ) );
|
||||
if ( Aig_ObjIsPo(pObj0) )
|
||||
{
|
||||
pFanin0 = Aig_ObjFanin0(pObj0);
|
||||
pFanin1 = Aig_ObjFanin0(pObj1);
|
||||
assert( Aig_ObjIsTravIdCurrent(p0, pFanin0) ==
|
||||
Aig_ObjIsTravIdCurrent(p1, pFanin1) );
|
||||
if ( Aig_ObjIsTravIdCurrent(p0, pFanin0) )
|
||||
{
|
||||
pMiter = Aig_Exor( pNew, pFanin0->pData, pFanin1->pData );
|
||||
Aig_ObjCreatePo( pNew, pMiter );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
assert( Aig_ObjIsNode(pObj0) );
|
||||
|
||||
pFanin0 = Aig_ObjFanin0(pObj0);
|
||||
pFanin1 = Aig_ObjFanin0(pObj1);
|
||||
assert( Aig_ObjIsTravIdCurrent(p0, pFanin0) ==
|
||||
Aig_ObjIsTravIdCurrent(p1, pFanin1) );
|
||||
if ( Aig_ObjIsTravIdCurrent(p0, pFanin0) )
|
||||
{
|
||||
pMiter = Aig_Exor( pNew, pFanin0->pData, pFanin1->pData );
|
||||
Aig_ObjCreatePo( pNew, pMiter );
|
||||
}
|
||||
|
||||
pFanin0 = Aig_ObjFanin1(pObj0);
|
||||
pFanin1 = Aig_ObjFanin1(pObj1);
|
||||
assert( Aig_ObjIsTravIdCurrent(p0, pFanin0) ==
|
||||
Aig_ObjIsTravIdCurrent(p1, pFanin1) );
|
||||
if ( Aig_ObjIsTravIdCurrent(p0, pFanin0) )
|
||||
{
|
||||
pMiter = Aig_Exor( pNew, pFanin0->pData, pFanin1->pData );
|
||||
Aig_ObjCreatePo( pNew, pMiter );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Extracts the window AIG from the AIG manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Man_t * Saig_ManWindowExtractMiter( Aig_Man_t * p0, Aig_Man_t * p1 )
|
||||
{
|
||||
Aig_Man_t * pNew;
|
||||
Aig_Obj_t * pObj0, * pObj1, * pMatch0, * pMatch1;
|
||||
Vec_Ptr_t * vNodes0, * vNodes1;
|
||||
int i, nRegCount;
|
||||
// add matching of POs and LIs
|
||||
Saig_ManForEachPo( p0, pObj0, i )
|
||||
{
|
||||
pObj1 = Aig_ManPo( p1, i );
|
||||
Aig_ObjSetRepr( p0, pObj0, pObj1 );
|
||||
Aig_ObjSetRepr( p1, pObj1, pObj0 );
|
||||
}
|
||||
Saig_ManForEachLi( p0, pObj0, i )
|
||||
{
|
||||
pMatch0 = Saig_ObjLiToLo( p0, pObj0 );
|
||||
pMatch1 = Aig_ObjRepr( p0, pMatch0 );
|
||||
if ( pMatch1 == NULL )
|
||||
continue;
|
||||
assert( pMatch0 == Aig_ObjRepr( p1, pMatch1 ) );
|
||||
pObj1 = Saig_ObjLoToLi( p1, pMatch1 );
|
||||
Aig_ObjSetRepr( p0, pObj0, pObj1 );
|
||||
Aig_ObjSetRepr( p1, pObj1, pObj0 );
|
||||
}
|
||||
// clean the markings
|
||||
Aig_ManCleanData( p0 );
|
||||
Aig_ManCleanData( p1 );
|
||||
// collect nodes that are not linked
|
||||
vNodes0 = Saig_ManCollectedDiffNodes( p0, p1 );
|
||||
vNodes1 = Saig_ManCollectedDiffNodes( p1, p0 );
|
||||
// create the new manager
|
||||
pNew = Aig_ManStart( Vec_PtrSize(vNodes0) + Vec_PtrSize(vNodes1) );
|
||||
pNew->pName = Aig_UtilStrsav( "wnd" );
|
||||
pNew->pSpec = NULL;
|
||||
// map constant nodes
|
||||
pObj0 = Aig_ManConst1( p0 );
|
||||
pObj0->pData = Aig_ManConst1( pNew );
|
||||
pObj1 = Aig_ManConst1( p1 );
|
||||
pObj1->pData = Aig_ManConst1( pNew );
|
||||
// create real PIs
|
||||
Saig_ManWindowCreatePis( pNew, p0, p1, vNodes0 );
|
||||
Saig_ManWindowCreatePis( pNew, p1, p0, vNodes1 );
|
||||
// create register outputs
|
||||
Vec_PtrForEachEntry( vNodes0, pObj0, i )
|
||||
{
|
||||
if ( Saig_ObjIsLo(p0, pObj0) )
|
||||
pObj0->pData = Aig_ObjCreatePi(pNew);
|
||||
}
|
||||
Vec_PtrForEachEntry( vNodes1, pObj1, i )
|
||||
{
|
||||
if ( Saig_ObjIsLo(p1, pObj1) )
|
||||
pObj1->pData = Aig_ObjCreatePi(pNew);
|
||||
}
|
||||
// create internal nodes
|
||||
Vec_PtrForEachEntry( vNodes0, pObj0, i )
|
||||
{
|
||||
if ( Aig_ObjIsNode(pObj0) )
|
||||
pObj0->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj0), Aig_ObjChild1Copy(pObj0) );
|
||||
}
|
||||
Vec_PtrForEachEntry( vNodes1, pObj1, i )
|
||||
{
|
||||
if ( Aig_ObjIsNode(pObj1) )
|
||||
pObj1->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj1), Aig_ObjChild1Copy(pObj1) );
|
||||
}
|
||||
// create POs
|
||||
Saig_ManWindowCreatePos( pNew, p0, p1 );
|
||||
// Saig_ManWindowCreatePos( pNew, p1, p0 );
|
||||
// create register inputs
|
||||
nRegCount = 0;
|
||||
Vec_PtrForEachEntry( vNodes0, pObj0, i )
|
||||
{
|
||||
if ( Saig_ObjIsLo(p0, pObj0) )
|
||||
{
|
||||
pMatch0 = Saig_ObjLoToLi( p0, pObj0 );
|
||||
Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pMatch0) );
|
||||
nRegCount++;
|
||||
}
|
||||
}
|
||||
Vec_PtrForEachEntry( vNodes1, pObj1, i )
|
||||
{
|
||||
if ( Saig_ObjIsLo(p1, pObj1) )
|
||||
{
|
||||
pMatch1 = Saig_ObjLoToLi( p1, pObj1 );
|
||||
Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pMatch1) );
|
||||
nRegCount++;
|
||||
}
|
||||
}
|
||||
Aig_ManSetRegNum( pNew, nRegCount );
|
||||
Aig_ManCleanup( pNew );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -51,11 +51,16 @@ struct Ssw_Pars_t_
|
|||
int nBTLimitGlobal;// conflict limit for multiple runs
|
||||
int nMinDomSize; // min clock domain considered for optimization
|
||||
int nItersStop; // stop after the given number of iterations
|
||||
int fDumpSRInit; // dumps speculative reduction
|
||||
int nResimDelta; // the number of nodes to resimulate
|
||||
int fPolarFlip; // uses polarity adjustment
|
||||
int fLatchCorr; // perform register correspondence
|
||||
int fSemiFormal; // enable semiformal filtering
|
||||
int fUniqueness; // enable uniqueness constraints
|
||||
int fDynamic; // enable dynamic addition of constraints
|
||||
int fLocalSim; // enable local simulation simulation
|
||||
int fPartSigCorr; // uses partial signal correspondence
|
||||
int nIsleDist; // extends islands by the given distance
|
||||
int fVerbose; // verbose stats
|
||||
int fFlopVerbose; // verbose printout of redundant flops
|
||||
// optimized latch correspondence
|
||||
|
|
@ -82,6 +87,8 @@ struct Ssw_Cex_t_
|
|||
unsigned pData[0]; // the cex bit data (the number of bits: nRegs + (iFrame+1) * nPis)
|
||||
};
|
||||
|
||||
typedef struct Ssw_Sml_t_ Ssw_Sml_t; // sequential simulation manager
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// MACRO DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -97,8 +104,11 @@ extern void Ssw_ManSetDefaultParams( Ssw_Pars_t * p );
|
|||
extern void Ssw_ManSetDefaultParamsLcorr( Ssw_Pars_t * p );
|
||||
extern Aig_Man_t * Ssw_SignalCorrespondence( Aig_Man_t * pAig, Ssw_Pars_t * pPars );
|
||||
extern Aig_Man_t * Ssw_LatchCorrespondence( Aig_Man_t * pAig, Ssw_Pars_t * pPars );
|
||||
/*=== sswIslands.c ==========================================================*/
|
||||
extern int Ssw_SecWithSimilarityPairs( Aig_Man_t * p0, Aig_Man_t * p1, Vec_Int_t * vPairs, Ssw_Pars_t * pPars );
|
||||
extern int Ssw_SecWithSimilarity( Aig_Man_t * p0, Aig_Man_t * p1, Ssw_Pars_t * pPars );
|
||||
/*=== sswMiter.c ===================================================*/
|
||||
extern int Ssw_SecSpecialMiter( Aig_Man_t * pMiter, int fVerbose );
|
||||
extern int Ssw_SecSpecialMiter( Aig_Man_t * p0, Aig_Man_t * p1, int nFrames, int fVerbose );
|
||||
/*=== sswPart.c ==========================================================*/
|
||||
extern Aig_Man_t * Ssw_SignalCorrespondencePart( Aig_Man_t * pAig, Ssw_Pars_t * pPars );
|
||||
/*=== sswPairs.c ===================================================*/
|
||||
|
|
@ -107,6 +117,14 @@ extern int Ssw_SecWithPairs( Aig_Man_t * pAig1, Aig_Man_t * pAig2, Vec
|
|||
extern int Ssw_SecGeneral( Aig_Man_t * pAig1, Aig_Man_t * pAig2, Ssw_Pars_t * pPars );
|
||||
extern int Ssw_SecGeneralMiter( Aig_Man_t * pMiter, Ssw_Pars_t * pPars );
|
||||
/*=== sswSim.c ===================================================*/
|
||||
extern Ssw_Sml_t * Ssw_SmlSimulateComb( Aig_Man_t * pAig, int nWords );
|
||||
extern Ssw_Sml_t * Ssw_SmlSimulateSeq( Aig_Man_t * pAig, int nPref, int nFrames, int nWords );
|
||||
extern void Ssw_SmlUnnormalize( Ssw_Sml_t * p );
|
||||
extern void Ssw_SmlStop( Ssw_Sml_t * p );
|
||||
extern int Ssw_SmlNumFrames( Ssw_Sml_t * p );
|
||||
extern int Ssw_SmlNumWordsTotal( Ssw_Sml_t * p );
|
||||
extern unsigned * Ssw_SmlSimInfo( Ssw_Sml_t * p, Aig_Obj_t * pObj );
|
||||
extern int Ssw_SmlObjsAreEqualWord( Ssw_Sml_t * p, Aig_Obj_t * pObj0, Aig_Obj_t * pObj1 );
|
||||
extern Ssw_Cex_t * Ssw_SmlAllocCounterExample( int nRegs, int nRealPis, int nFrames );
|
||||
extern void Ssw_SmlFreeCounterExample( Ssw_Cex_t * pCex );
|
||||
extern int Ssw_SmlRunCounterExample( Aig_Man_t * pAig, Ssw_Cex_t * p );
|
||||
|
|
|
|||
|
|
@ -211,6 +211,7 @@ Aig_Man_t * Ssw_SpeculativeReduction( Ssw_Man_t * p )
|
|||
|
||||
// start the fraig package
|
||||
pFrames = Aig_ManStart( Aig_ManObjNumMax(p->pAig) * p->nFrames );
|
||||
pFrames->pName = Aig_UtilStrsav( p->pAig->pName );
|
||||
// map constants and PIs
|
||||
Ssw_ObjSetFrame( p, Aig_ManConst1(p->pAig), 0, Aig_ManConst1(pFrames) );
|
||||
Saig_ManForEachPi( p->pAig, pObj, i )
|
||||
|
|
|
|||
|
|
@ -585,7 +585,7 @@ int Ssw_ClassesPrepareRehash( Ssw_Cla_t * p, Vec_Ptr_t * vCands )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ssw_Cla_t * Ssw_ClassesPrepare( Aig_Man_t * pAig, int fLatchCorr, int nMaxLevs, int fVerbose )
|
||||
Ssw_Cla_t * Ssw_ClassesPrepare( Aig_Man_t * pAig, int nFramesK, int fLatchCorr, int nMaxLevs, int fVerbose )
|
||||
{
|
||||
// int nFrames = 4;
|
||||
// int nWords = 1;
|
||||
|
|
@ -595,7 +595,7 @@ Ssw_Cla_t * Ssw_ClassesPrepare( Aig_Man_t * pAig, int fLatchCorr, int nMaxLevs,
|
|||
// int nWords = 4;
|
||||
// int nIters = 0;
|
||||
|
||||
int nFrames = 4;
|
||||
int nFrames = AIG_MAX( nFramesK, 4 );
|
||||
int nWords = 2;
|
||||
int nIters = 16;
|
||||
Ssw_Cla_t * p;
|
||||
|
|
@ -836,7 +836,7 @@ Ssw_Cla_t * Ssw_ClassesPreparePairs( Aig_Man_t * pAig, Vec_Int_t ** pvClasses )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ssw_Cla_t * Ssw_ClassesFromIslands( Aig_Man_t * pMiter, Vec_Int_t * vPairs )
|
||||
Ssw_Cla_t * Ssw_ClassesPreparePairsSimple( Aig_Man_t * pMiter, Vec_Int_t * vPairs )
|
||||
{
|
||||
Ssw_Cla_t * p;
|
||||
Aig_Obj_t ** ppClassNew;
|
||||
|
|
|
|||
|
|
@ -51,10 +51,13 @@ void Ssw_ManSetDefaultParams( Ssw_Pars_t * p )
|
|||
p->nBTLimitGlobal = 5000000; // conflict limit for all runs
|
||||
p->nMinDomSize = 100; // min clock domain considered for optimization
|
||||
p->nItersStop = 0; // stop after the given number of iterations
|
||||
p->nResimDelta = 1000; // the internal of nodes to resimulate
|
||||
p->fPolarFlip = 0; // uses polarity adjustment
|
||||
p->fLatchCorr = 0; // performs register correspondence
|
||||
p->fSemiFormal = 0; // enable semiformal filtering
|
||||
p->fUniqueness = 0; // enable uniqueness constraints
|
||||
p->fDynamic = 0; // dynamic partitioning
|
||||
p->fLocalSim = 0; // local simulation
|
||||
p->fVerbose = 0; // verbose stats
|
||||
// latch correspondence
|
||||
p->fLatchCorrOpt = 0; // performs optimized register correspondence
|
||||
|
|
@ -260,6 +263,9 @@ Aig_Man_t * Ssw_SignalCorrespondence( Aig_Man_t * pAig, Ssw_Pars_t * pPars )
|
|||
if ( pPars->fLatchCorrOpt )
|
||||
{
|
||||
pPars->fLatchCorr = 1;
|
||||
pPars->nFramesAddSim = 0;
|
||||
if ( (pAig->vClockDoms && Vec_VecSize(pAig->vClockDoms) > 0) )
|
||||
return Ssw_SignalCorrespondencePart( pAig, pPars );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -276,7 +282,7 @@ Aig_Man_t * Ssw_SignalCorrespondence( Aig_Man_t * pAig, Ssw_Pars_t * pPars )
|
|||
if ( p->pPars->nConstrs == 0 )
|
||||
{
|
||||
// perform one round of seq simulation and generate candidate equivalence classes
|
||||
p->ppClasses = Ssw_ClassesPrepare( pAig, pPars->fLatchCorr, pPars->nMaxLevs, pPars->fVerbose );
|
||||
p->ppClasses = Ssw_ClassesPrepare( pAig, pPars->nFramesK, pPars->fLatchCorr, pPars->nMaxLevs, pPars->fVerbose );
|
||||
// p->ppClasses = Ssw_ClassesPrepareTargets( pAig );
|
||||
if ( pPars->fLatchCorrOpt )
|
||||
p->pSml = Ssw_SmlStart( pAig, 0, 2, 1 );
|
||||
|
|
@ -292,6 +298,8 @@ Aig_Man_t * Ssw_SignalCorrespondence( Aig_Man_t * pAig, Ssw_Pars_t * pPars )
|
|||
p->ppClasses = Ssw_ClassesPrepareSimple( pAig, pPars->fLatchCorr, pPars->nMaxLevs );
|
||||
Ssw_ClassesSetData( p->ppClasses, NULL, NULL, Ssw_SmlObjIsConstBit, Ssw_SmlObjsAreEqualBit );
|
||||
}
|
||||
if ( p->pPars->fLocalSim )
|
||||
p->pVisited = CALLOC( int, Ssw_SmlNumFrames( p->pSml ) * Aig_ManObjNumMax(p->pAig) );
|
||||
// perform refinement of classes
|
||||
pAigNew = Ssw_SignalCorrespondenceRefine( p );
|
||||
if ( pPars->fUniqueness )
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue