Version abc90118

This commit is contained in:
Alan Mishchenko 2009-01-18 08:01:00 -08:00
parent c9ad5880cc
commit f936cc0680
189 changed files with 24544 additions and 1349 deletions

View File

@ -12,12 +12,12 @@ MODULES := \
src/bdd/cudd src/bdd/dsd src/bdd/epd src/bdd/mtr \ src/bdd/cudd src/bdd/dsd src/bdd/epd src/bdd/mtr \
src/bdd/parse src/bdd/reo src/bdd/cas \ src/bdd/parse src/bdd/reo src/bdd/cas \
src/map/fpga src/map/mapper src/map/mio src/map/super \ 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/extra src/misc/mvc src/misc/st src/misc/util \
src/misc/nm src/misc/vec src/misc/hash \ src/misc/nm src/misc/vec src/misc/hash \
src/misc/bzlib src/misc/zlib \ src/misc/bzlib src/misc/zlib \
src/opt/cut src/opt/dec src/opt/fxu src/opt/rwr src/opt/mfs \ 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/bsat src/sat/csat src/sat/msat src/sat/fraig \
src/sat/psat \ src/sat/psat \
src/aig/ivy src/aig/hop src/aig/rwt src/aig/deco \ 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/csw src/aig/ioa src/aig/aig src/aig/kit \
src/aig/bdc src/aig/bar src/aig/ntl src/aig/nwk \ 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/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) default: $(PROG)

276
abc.dsp
View File

@ -42,7 +42,7 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 0 # PROP Ignore_Export_Lib 0
# PROP Target_Dir "" # PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c # 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 BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe BSC32=bscmake.exe
@ -50,7 +50,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo # ADD BSC32 /nologo
LINK32=link.exe 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 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" !ELSEIF "$(CFG)" == "abc - Win32 Debug"
@ -66,7 +66,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0 # PROP Ignore_Export_Lib 0
# PROP Target_Dir "" # 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 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 # SUBTRACT CPP /X
# ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG"
@ -75,7 +75,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo # ADD BSC32 /nologo
LINK32=link.exe 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 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 !ENDIF
@ -290,6 +290,10 @@ SOURCE=.\src\base\abci\abcMeasure.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\src\base\abci\abcMerge.c
# End Source File
# Begin Source File
SOURCE=.\src\base\abci\abcMini.c SOURCE=.\src\base\abci\abcMini.c
# End Source File # End Source File
# Begin Source File # Begin Source File
@ -538,6 +542,10 @@ SOURCE=.\src\base\io\ioWriteBlifMv.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\src\base\io\ioWriteBook.c
# End Source File
# Begin Source File
SOURCE=.\src\base\io\ioWriteCnf.c SOURCE=.\src\base\io\ioWriteCnf.c
# End Source File # End Source File
# Begin Source File # Begin Source File
@ -1640,26 +1648,6 @@ SOURCE=.\src\opt\lpk\lpkSets.c
# Begin Group "fret" # Begin Group "fret"
# PROP Default_Filter "" # 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 # End Group
# Begin Group "mfs" # Begin Group "mfs"
@ -1961,96 +1949,72 @@ SOURCE=.\src\map\if\ifTruth.c
SOURCE=.\src\map\if\ifUtil.c SOURCE=.\src\map\if\ifUtil.c
# End Source File # End Source File
# End Group # 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" # Begin Group "ply"
# PROP Default_Filter ""
# End Group
# Begin Group "pcm"
# PROP Default_Filter ""
# End Group
# Begin Group "amap"
# PROP Default_Filter "" # PROP Default_Filter ""
# Begin Source File # Begin Source File
SOURCE=.\src\map\ply\ply.h SOURCE=.\src\map\amap\amap.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\src\map\ply\plyAbc.c SOURCE=.\src\map\amap\amapCore.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\src\map\ply\plyAig.c SOURCE=.\src\map\amap\amapGraph.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\src\map\ply\plyFake.c SOURCE=.\src\map\amap\amapInt.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\src\map\ply\plyInt.h SOURCE=.\src\map\amap\amapLib.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\src\map\ply\plyIter.c SOURCE=.\src\map\amap\amapMan.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\src\map\ply\plyLib.c SOURCE=.\src\map\amap\amapMatch.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\src\map\ply\plyMan.c SOURCE=.\src\map\amap\amapMerge.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\src\map\ply\plyMap.c SOURCE=.\src\map\amap\amapOutput.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\src\map\ply\plyNtk.c SOURCE=.\src\map\amap\amapParse.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\src\map\ply\plyPair.c SOURCE=.\src\map\amap\amapPerm.c
# End Source File # End Source File
# Begin 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 Source File
# End Group # End Group
# End Group # End Group
@ -2934,6 +2898,10 @@ SOURCE=.\src\aig\aig\aig.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\src\aig\aig\aigCanon.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\aig\aigCheck.c SOURCE=.\src\aig\aig\aigCheck.c
# End Source File # End Source File
# Begin Source File # Begin Source File
@ -3310,10 +3278,6 @@ SOURCE=.\src\aig\saig\saigIoa.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\src\aig\saig\saigLoc.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\saig\saigMiter.c SOURCE=.\src\aig\saig\saigMiter.c
# End Source File # End Source File
# Begin Source File # Begin Source File
@ -3338,12 +3302,40 @@ SOURCE=.\src\aig\saig\saigScl.c
# End Source File # End Source File
# Begin 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 SOURCE=.\src\aig\saig\saigSynch.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\src\aig\saig\saigTrans.c SOURCE=.\src\aig\saig\saigTrans.c
# End Source File # End Source File
# Begin Source File
SOURCE=.\src\aig\saig\saigWnd.c
# End Source File
# End Group # End Group
# Begin Group "int" # Begin Group "int"
@ -3532,6 +3524,46 @@ SOURCE=.\src\aig\ssw\sswUnique.c
# Begin Group "cec" # Begin Group "cec"
# PROP Default_Filter "" # 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 # End Group
# Begin Group "cgt" # Begin Group "cgt"
@ -3565,6 +3597,90 @@ SOURCE=.\src\aig\cgt\cgtMan.c
SOURCE=.\src\aig\cgt\cgtSat.c SOURCE=.\src\aig\cgt\cgtSat.c
# End Source File # End Source File
# End Group # 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
# End Group # End Group
# Begin Group "Header Files" # Begin Group "Header Files"

6
abc.rc
View File

@ -22,10 +22,10 @@ set gnuplotunix gnuplot
# standard aliases # standard aliases
alias b balance alias b balance
alias cg clockgate
alias cl cleanup alias cl cleanup
alias clp collapse alias clp collapse
alias cs care_set alias cs care_set
alias dc2 dcompress2
alias esd ext_seq_dcs alias esd ext_seq_dcs
alias f fraig alias f fraig
alias fs fraig_sweep alias fs fraig_sweep
@ -40,6 +40,7 @@ alias pd print_dsd
alias pex print_exdc -d alias pex print_exdc -d
alias pf print_factor alias pf print_factor
alias pfan print_fanio alias pfan print_fanio
alias pg print_gates
alias pl print_level alias pl print_level
alias plat print_latch alias plat print_latch
alias pio print_io 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 c\s\0\000.aig; int"
#alias t "r test/interpol.blif; st; int" #alias t "r test/interpol.blif; st; int"
#read_library at\syn\brdcm.genlib

View File

@ -144,6 +144,7 @@ struct Aig_Man_t_
void * pImpData; // implication checking data void * pImpData; // implication checking data
void * pManTime; // the timing manager void * pManTime; // the timing manager
void * pManCuts; void * pManCuts;
int * pFastSim;
Vec_Ptr_t * vMapped; Vec_Ptr_t * vMapped;
Vec_Int_t * vFlopNums; Vec_Int_t * vFlopNums;
Vec_Int_t * vFlopReprs; Vec_Int_t * vFlopReprs;
@ -154,6 +155,7 @@ struct Aig_Man_t_
int fCreatePios; int fCreatePios;
Vec_Int_t * vEquPairs; Vec_Int_t * vEquPairs;
Vec_Vec_t * vClockDoms; Vec_Vec_t * vClockDoms;
Vec_Int_t * vProbs; // probability of node being 1
// timing statistics // timing statistics
int time1; int time1;
int time2; int time2;
@ -195,14 +197,14 @@ struct Aig_ManCut_t_
}; };
#ifdef WIN32 #ifdef WIN32
#define DLLEXPORT __declspec(dllexport) #define ABC_DLLEXPORT __declspec(dllexport)
#define DLLIMPORT __declspec(dllimport) #define ABC_DLLIMPORT __declspec(dllimport)
#else /* defined(WIN32) */ #else /* defined(WIN32) */
#define DLLIMPORT #define ABC_DLLIMPORT
#endif /* defined(WIN32) */ #endif /* defined(WIN32) */
#ifndef ABC_DLL #ifndef ABC_DLL
#define ABC_DLL DLLIMPORT #define ABC_DLL ABC_DLLIMPORT
#endif #endif
static inline Aig_Cut_t * Aig_ObjCuts( Aig_ManCut_t * p, Aig_Obj_t * pObj ) { return p->pCuts[pObj->Id]; } 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 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_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 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 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 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) ); } 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 ); extern void Aig_ManStopMemory( Aig_Man_t * p );
/*=== aigMffc.c ==========================================================*/ /*=== aigMffc.c ==========================================================*/
extern int Aig_NodeRef_rec( Aig_Obj_t * pNode, unsigned LevelMin ); 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_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_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 ); extern int Aig_NodeMffsExtendCut( Aig_Man_t * p, Aig_Obj_t * pNode, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vResult );
/*=== aigObj.c ==========================================================*/ /*=== aigObj.c ==========================================================*/

694
src/aig/aig/aigCanon.c Normal file
View File

@ -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 ///
////////////////////////////////////////////////////////////////////////

View File

@ -978,6 +978,7 @@ Aig_Man_t * Aig_ManDupOneOutput( Aig_Man_t * p, int iPoNum, int fAddRegs )
return pNew; return pNew;
} }
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/// END OF FILE /// /// END OF FILE ///
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////

View File

@ -206,10 +206,12 @@ void Aig_ManStop( Aig_Man_t * p )
if ( p->vLevelR ) Vec_IntFree( p->vLevelR ); if ( p->vLevelR ) Vec_IntFree( p->vLevelR );
if ( p->vLevels ) Vec_VecFree( p->vLevels ); if ( p->vLevels ) Vec_VecFree( p->vLevels );
if ( p->vFlopNums) Vec_IntFree( p->vFlopNums ); if ( p->vFlopNums) Vec_IntFree( p->vFlopNums );
if ( p->vFlopReprs)Vec_IntFree( p->vFlopReprs ); if ( p->vFlopReprs) Vec_IntFree( p->vFlopReprs );
if ( p->pManExdc ) Aig_ManStop( p->pManExdc ); if ( p->pManExdc ) Aig_ManStop( p->pManExdc );
if ( p->vOnehots ) Vec_VecFree( (Vec_Vec_t *)p->vOnehots ); if ( p->vOnehots ) Vec_VecFree( (Vec_Vec_t *)p->vOnehots );
if ( p->vClockDoms)Vec_VecFree( p->vClockDoms ); if ( p->vClockDoms) Vec_VecFree( p->vClockDoms );
if ( p->vProbs ) Vec_IntFree( p->vProbs );
FREE( p->pFastSim );
FREE( p->pData ); FREE( p->pData );
FREE( p->pSeqModel ); FREE( p->pSeqModel );
FREE( p->pName ); FREE( p->pName );

View File

@ -39,17 +39,22 @@
SeeAlso [] 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; Aig_Obj_t * pFanin;
int Counter = 0; int Counter = 0;
if ( pProbs )
*pPower = 0.0;
if ( Aig_ObjIsPi(pNode) ) if ( Aig_ObjIsPi(pNode) )
return 0; return 0;
// consider the first fanin // consider the first fanin
pFanin = Aig_ObjFanin0(pNode); pFanin = Aig_ObjFanin0(pNode);
assert( pFanin->nRefs > 0 ); assert( pFanin->nRefs > 0 );
if ( --pFanin->nRefs == 0 && (!LevelMin || pFanin->Level > LevelMin) ) 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 // skip the buffer
if ( Aig_ObjIsBuf(pNode) ) if ( Aig_ObjIsBuf(pNode) )
return Counter; return Counter;
@ -58,7 +63,9 @@ int Aig_NodeDeref_rec( Aig_Obj_t * pNode, unsigned LevelMin )
pFanin = Aig_ObjFanin1(pNode); pFanin = Aig_ObjFanin1(pNode);
assert( pFanin->nRefs > 0 ); assert( pFanin->nRefs > 0 );
if ( --pFanin->nRefs == 0 && (!LevelMin || pFanin->Level > LevelMin) ) 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; 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) ); assert( Aig_ObjIsNode(pNode) );
if ( vSupp ) Vec_PtrClear( vSupp ); if ( vSupp ) Vec_PtrClear( vSupp );
Aig_ManIncrementTravId( p ); 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 ); Aig_NodeMffsSupp_rec( p, pNode, LevelMin, vSupp, 1, NULL );
ConeSize2 = Aig_NodeRef_rec( pNode, LevelMin ); ConeSize2 = Aig_NodeRef_rec( pNode, LevelMin );
assert( ConeSize1 == ConeSize2 ); assert( ConeSize1 == ConeSize2 );
@ -192,13 +199,14 @@ int Aig_NodeMffsSupp( Aig_Man_t * p, Aig_Obj_t * pNode, int LevelMin, Vec_Ptr_t
SeeAlso [] 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; int ConeSize1, ConeSize2;
assert( (pPower != NULL) == (p->vProbs != NULL) );
assert( !Aig_IsComplement(pNode) ); assert( !Aig_IsComplement(pNode) );
assert( Aig_ObjIsNode(pNode) ); assert( Aig_ObjIsNode(pNode) );
Aig_ManIncrementTravId( p ); 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 ); ConeSize2 = Aig_NodeRefLabel_rec( p, pNode, 0 );
assert( ConeSize1 == ConeSize2 ); assert( ConeSize1 == ConeSize2 );
assert( ConeSize1 > 0 ); 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 ); Aig_ManIncrementTravId( p );
Vec_PtrForEachEntry( vLeaves, pObj, i ) Vec_PtrForEachEntry( vLeaves, pObj, i )
pObj->nRefs++; pObj->nRefs++;
ConeSize1 = Aig_NodeDeref_rec( pNode, 0 ); ConeSize1 = Aig_NodeDeref_rec( pNode, 0, NULL, NULL );
ConeSize2 = Aig_NodeRefLabel_rec( p, pNode, 0 ); ConeSize2 = Aig_NodeRefLabel_rec( p, pNode, 0 );
Vec_PtrForEachEntry( vLeaves, pObj, i ) Vec_PtrForEachEntry( vLeaves, pObj, i )
pObj->nRefs--; pObj->nRefs--;
@ -256,7 +264,7 @@ int Aig_NodeMffsExtendCut( Aig_Man_t * p, Aig_Obj_t * pNode, Vec_Ptr_t * vLeaves
if ( LevelMax == 0 ) if ( LevelMax == 0 )
return 0; return 0;
// dereference the cut // dereference the cut
ConeSize1 = Aig_NodeDeref_rec( pNode, 0 ); ConeSize1 = Aig_NodeDeref_rec( pNode, 0, NULL, NULL );
// try expanding each node in the boundary // try expanding each node in the boundary
ConeBest = AIG_INFINITY; ConeBest = AIG_INFINITY;
pLeafBest = NULL; 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 ) if ( (int)pObj->Level != LevelMax )
continue; continue;
ConeCur1 = Aig_NodeDeref_rec( pObj, 0 ); ConeCur1 = Aig_NodeDeref_rec( pObj, 0, NULL, NULL );
if ( ConeBest > ConeCur1 ) if ( ConeBest > ConeCur1 )
{ {
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( pLeafBest != NULL );
assert( Aig_ObjIsNode(pLeafBest) ); assert( Aig_ObjIsNode(pLeafBest) );
// deref the best leaf // deref the best leaf
ConeCur1 = Aig_NodeDeref_rec( pLeafBest, 0 ); ConeCur1 = Aig_NodeDeref_rec( pLeafBest, 0, NULL, NULL );
// collect the cut nodes // collect the cut nodes
Vec_PtrClear( vResult ); Vec_PtrClear( vResult );
Aig_ManIncrementTravId( p ); Aig_ManIncrementTravId( p );

View File

@ -116,6 +116,15 @@ Aig_Obj_t * Aig_ObjCreate( Aig_Man_t * p, Aig_Obj_t * pGhost )
assert( !Aig_IsComplement(pObj->pHaig) ); assert( !Aig_IsComplement(pObj->pHaig) );
// printf( "Creating HAIG node %d equivalent to node %d.\n", pObj->pHaig->Id, pObj->Id ); // 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; return pObj;
} }

View File

@ -232,6 +232,7 @@ int Aig_ManSeqCleanup( Aig_Man_t * p )
Vec_PtrFree( vNodes ); Vec_PtrFree( vNodes );
p->nTruePis = Aig_ManPiNum(p) - Aig_ManRegNum(p); p->nTruePis = Aig_ManPiNum(p) - Aig_ManRegNum(p);
p->nTruePos = Aig_ManPoNum(p) - Aig_ManRegNum(p); p->nTruePos = Aig_ManPoNum(p) - Aig_ManRegNum(p);
Aig_ManSetPioNumbers( p );
// remove dangling nodes // remove dangling nodes
return Aig_ManCleanup( p ); return Aig_ManCleanup( p );
} }
@ -577,6 +578,58 @@ void Aig_ManComputeSccs( Aig_Man_t * p )
Vec_VecFree( (Vec_Vec_t *)vSupports ); 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************************************************************* /**Function*************************************************************
Synopsis [Gives the current ABC network to AIG manager for processing.] 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_Man_t * pAigInit, * pAigNew;
Aig_Obj_t * pFlop1, * pFlop2; Aig_Obj_t * pFlop1, * pFlop2;
int i, Entry1, Entry2, nTruePis;//, nRegs; 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 // store the original AIG
assert( pAig->vFlopNums == NULL ); assert( pAig->vFlopNums == NULL );
pAigInit = pAig; pAigInit = pAig;

View File

@ -44,10 +44,10 @@ static inline int Aig_XsimInv( int Value )
} }
static inline int Aig_XsimAnd( int Value0, int Value1 ) 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 ) if ( Value0 == AIG_XVSX || Value1 == AIG_XVSX )
return AIG_XVSX; return AIG_XVSX;
if ( Value0 == AIG_XVS0 || Value1 == AIG_XVS0 )
return AIG_XVS0;
assert( Value0 == AIG_XVS1 && Value1 == AIG_XVS1 ); assert( Value0 == AIG_XVS1 && Value1 == AIG_XVS1 );
return 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) ); // printf( "%d ", Aig_TsiStateCount(pTsi, pState) );
// Aig_TsiStatePrint( pTsi, pState ); //Aig_TsiStatePrint( pTsi, pState );
// check if this state exists // check if this state exists
if ( Aig_TsiStateLookup( pTsi, pState, pTsi->nWords ) ) if ( Aig_TsiStateLookup( pTsi, pState, pTsi->nWords ) )
break; break;

View File

@ -1,4 +1,5 @@
SRC += src/aig/aig/aigCheck.c \ SRC += src/aig/aig/aigCheck.c \
src/aig/aig/aigCanon.c \
src/aig/aig/aigCuts.c \ src/aig/aig/aigCuts.c \
src/aig/aig/aigDfs.c \ src/aig/aig/aigDfs.c \
src/aig/aig/aigDup.c \ src/aig/aig/aigDup.c \

View File

@ -721,7 +721,7 @@ int Bbr_BuildTreeNode( DdManager * dd,
Bbr_ImageNode_t * pNode1, * pNode2; Bbr_ImageNode_t * pNode1, * pNode2;
Bbr_ImageVar_t * pVar; Bbr_ImageVar_t * pVar;
Bbr_ImageNode_t * pNode; Bbr_ImageNode_t * pNode;
DdNode * bCube, * bTemp, * bSuppTemp, * bParts; DdNode * bCube, * bTemp, * bSuppTemp;//, * bParts;
int iNode1, iNode2; int iNode1, iNode2;
int iVarBest, nSupp, v; int iVarBest, nSupp, v;
@ -773,7 +773,7 @@ int Bbr_BuildTreeNode( DdManager * dd,
Bbr_FindBestPartitions( dd, pVar->bParts, nNodes, pNodes, &iNode1, &iNode2 ); Bbr_FindBestPartitions( dd, pVar->bParts, nNodes, pNodes, &iNode1, &iNode2 );
pNode1 = pNodes[iNode1]; pNode1 = pNodes[iNode1];
pNode2 = pNodes[iNode2]; pNode2 = pNodes[iNode2];
/*
// it is not possible that a var appears only in these two // it is not possible that a var appears only in these two
// otherwise, it would have a different cost // otherwise, it would have a different cost
bParts = Cudd_bddAnd( dd, dd->vars[iNode1], dd->vars[iNode2] ); Cudd_Ref( bParts ); 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 ) if ( pVars[v] && pVars[v]->bParts == bParts )
assert( 0 ); assert( 0 );
Cudd_RecursiveDeref( dd, bParts ); Cudd_RecursiveDeref( dd, bParts );
*/
// combines two nodes // combines two nodes
pNode = Bbr_CombineTwoNodes( dd, b1, pNode1, pNode2 ); pNode = Bbr_CombineTwoNodes( dd, b1, pNode1, pNode2 );
} }

View File

@ -72,7 +72,8 @@ Bdc_Man_t * Bdc_ManAlloc( Bdc_Par_t * pPars )
p->nNodesAlloc = 512; p->nNodesAlloc = 512;
p->pNodes = ALLOC( Bdc_Fun_t, p->nNodesAlloc ); p->pNodes = ALLOC( Bdc_Fun_t, p->nNodesAlloc );
// memory // 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 // set up hash table
p->nTableSize = (1 << p->pPars->nVarsMax); p->nTableSize = (1 << p->pPars->nVarsMax);
p->pTable = ALLOC( Bdc_Fun_t *, p->nTableSize ); p->pTable = ALLOC( Bdc_Fun_t *, p->nTableSize );

View File

@ -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_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 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 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_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_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; } static inline void Bdc_IsfNot( Bdc_Isf_t * p ) { unsigned * puT = p->puOn; p->puOn = p->puOff; p->puOff = puT; }

100
src/aig/cec/cec.h Normal file
View File

@ -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 ///
////////////////////////////////////////////////////////////////////////

151
src/aig/cec/cecAig.c Normal file
View 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 ///
////////////////////////////////////////////////////////////////////////

569
src/aig/cec/cecClass.c Normal file
View 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 ///
////////////////////////////////////////////////////////////////////////

328
src/aig/cec/cecCnf.c Normal file
View 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 ///
////////////////////////////////////////////////////////////////////////

233
src/aig/cec/cecCore.c Normal file
View 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 ///
////////////////////////////////////////////////////////////////////////

220
src/aig/cec/cecInt.h Normal file
View 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 ///
////////////////////////////////////////////////////////////////////////

View File

@ -1,12 +1,12 @@
/**CFile**************************************************************** /**CFile****************************************************************
FileName [saigLoc.c] FileName [cecMan.c]
SystemName [ABC: Logic synthesis and verification system.] SystemName [ABC: Logic synthesis and verification system.]
PackageName [Sequential AIG package.] PackageName [Combinatinoal equivalence checking.]
Synopsis [Localization.] Synopsis [Manager pcocures.]
Author [Alan Mishchenko] Author [Alan Mishchenko]
@ -14,11 +14,11 @@
Date [Ver. 1.0. Started - June 20, 2005.] 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 /// /// DECLARATIONS ///
@ -40,6 +40,17 @@
***********************************************************************/ ***********************************************************************/
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/// END OF FILE /// /// END OF FILE ///

View File

@ -4,23 +4,21 @@
SystemName [ABC: Logic synthesis and verification system.] 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] Author [Alan Mishchenko]
Affiliation [UC Berkeley] 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 "cecInt.h"
#include "cnf.h"
#include "solver.h"
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/// DECLARATIONS /// /// DECLARATIONS ///
@ -32,7 +30,7 @@
/**Function************************************************************* /**Function*************************************************************
Synopsis [Writes CNF into a file.] Synopsis [Creates the manager.]
Description [] Description []
@ -41,33 +39,25 @@
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
solver * Cnf_WriteIntoSolverNew( Cnf_Dat_t * p ) Cec_ManSat_t * Cec_ManCreate( Aig_Man_t * pAig, Cec_ParSat_t * pPars )
{ {
solver * pSat; Cec_ManSat_t * p;
int i, status; // create interpolation manager
pSat = solver_new(); p = ALLOC( Cec_ManSat_t, 1 );
for ( i = 0; i < p->nVars; i++ ) memset( p, 0, sizeof(Cec_ManSat_t) );
solver_newVar( pSat ); p->pPars = pPars;
for ( i = 0; i < p->nClauses; i++ ) p->pAig = pAig;
{ // SAT solving
if ( !solver_addClause( pSat, p->pClauses[i+1]-p->pClauses[i], p->pClauses[i] ) ) p->nSatVars = 1;
{ p->pSatVars = CALLOC( int, Aig_ManObjNumMax(pAig) );
solver_delete( pSat ); p->vUsedNodes = Vec_PtrAlloc( 1000 );
return NULL; p->vFanins = Vec_PtrAlloc( 100 );
} return p;
}
status = solver_simplify(pSat);
if ( status == 0 )
{
solver_delete( pSat );
return NULL;
}
return pSat;
} }
/**Function************************************************************* /**Function*************************************************************
Synopsis [Adds the OR-clause.] Synopsis [Frees the manager.]
Description [] Description []
@ -76,90 +66,127 @@ solver * Cnf_WriteIntoSolverNew( Cnf_Dat_t * p )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
int Cnf_DataWriteAndClausesNew( void * p, Cnf_Dat_t * pCnf ) void Cec_ManStop( Cec_ManSat_t * p )
{ {
/* if ( p->pSat )
sat_solver * pSat = p; sat_solver_delete( p->pSat );
Vec_PtrFree( p->vUsedNodes );
Vec_PtrFree( p->vFanins );
FREE( p->pSatVars );
free( p );
}
/**Function*************************************************************
Synopsis [Recycles the SAT solver.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Cec_ManSatSolverRecycle( Cec_ManSat_t * p )
{
int Lit;
if ( p->pSat )
{
Aig_Obj_t * pObj; 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;
}
/**Function*************************************************************
Synopsis [Adds the OR-clause.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Cnf_DataWriteOrClauseNew( solver * pSat, Cnf_Dat_t * pCnf )
{
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 ) )
{
free( pLits );
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; int i;
pModel = ALLOC( int, nVars+1 ); Vec_PtrForEachEntry( p->vUsedNodes, pObj, i )
for ( i = 0; i < nVars; i++ ) Cec_ObjSetSatNum( p, pObj, 0 );
{ Vec_PtrClear( p->vUsedNodes );
assert( pVars[i] >= 0 && pVars[i] < solver_num_vars(pSat) ); // memset( p->pSatVars, 0, sizeof(int) * Aig_ManObjNumMax(p->pAigTotal) );
pModel[i] = (int)(solver_modelValue_Var( pSat, pVars[i] ) == solver_l_True); 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;
}
else // if ( RetValue == l_Undef )
{
p->timeSatUndec += clock() - clk;
p->timeSatUndec++;
return -1;
} }
return pModel;
} }
/**Function************************************************************* /**Function*************************************************************
@ -173,112 +200,51 @@ int * Sat_SolverGetModelNew( solver * pSat, int * pVars, int nVars )
SeeAlso [] 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; Bar_Progress_t * pProgress = NULL;
Cnf_Dat_t * pCnf; Cec_MtrStatus_t Status;
int status, RetValue, clk = clock(); Cec_ManSat_t * p;
Vec_Int_t * vCiIds; Aig_Obj_t * pObj;
int i, status;
assert( Aig_ManRegNum(pMan) == 0 ); Status = Cec_MiterStatus( pAig );
pMan->pData = NULL; p = Cec_ManCreate( pAig, pPars );
pProgress = Bar_ProgressStart( stdout, Aig_ManPoNum(pAig) );
// derive CNF Aig_ManForEachPo( pAig, pObj, i )
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 )
{ {
Cnf_DataFree( pCnf ); Bar_ProgressUpdate( pProgress, i, "SAT..." );
return 1; if ( Cec_OutputStatus(pAig, pObj) )
} continue;
status = Cec_ManSatCheckNode( p, Aig_ObjFanin0(pObj) );
if ( status == 1 )
if ( fAndOuts )
{ {
assert( 0 ); Status.nUndec--, Status.nUnsat++;
// assert each output independently Aig_ObjPatchFanin0( pAig, pObj, Aig_ManConst0(pAig) );
if ( !Cnf_DataWriteAndClausesNew( pSat, pCnf ) )
{
solver_delete( pSat );
Cnf_DataFree( pCnf );
return 1;
} }
}
else
{
// add the OR clause for the outputs
if ( !Cnf_DataWriteOrClauseNew( pSat, pCnf ) )
{
solver_delete( pSat );
Cnf_DataFree( pCnf );
return 1;
}
}
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 ) if ( status == 0 )
{ {
Vec_IntFree( vCiIds ); Status.nUndec--, Status.nSat++;
solver_delete( pSat ); Aig_ObjPatchFanin0( pAig, pObj, Aig_ManConst1(pAig) );
// printf( "The problem is UNSATISFIABLE after simplification.\n" );
return 1;
} }
if ( status == -1 )
// solve the miter continue;
clk = clock(); // save the pattern (if it is first)
if ( fVerbose ) if ( Status.iOut == -1 )
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 ) // quit if at least one of them is solved
{ if ( status == 0 && pPars->fFirstStop )
// printf( "The problem is SATISFIABLE.\n" ); break;
RetValue = 0;
} }
else if ( status == solver_l_False ) Aig_ManCleanup( pAig );
{ Bar_ProgressStop( pProgress );
// printf( "The problem is UNSATISFIABLE.\n" ); printf( " Confs = %8d. Recycles = %6d.\n", p->pPars->nBTLimit, p->nRecycles );
RetValue = 1; Cec_ManStop( p );
} return Status;
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;
} }
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/// END OF FILE /// /// END OF FILE ///
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////

459
src/aig/cec/cecSim.c Normal file
View 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 ///
////////////////////////////////////////////////////////////////////////

187
src/aig/cec/cecStatus.c Normal file
View 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 ///
////////////////////////////////////////////////////////////////////////

8
src/aig/cec/module.make Normal file
View 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

View File

@ -52,8 +52,9 @@ struct Cgt_Par_t_
int nConfMax; // the max number of conflicts at a node int nConfMax; // the max number of conflicts at a node
int nVarsMin; // the min number of variables to recycle the SAT solver 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 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 fVerbose; // verbosity flag
int fVeryVerbose; // verbosity flag
}; };
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////

View File

@ -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 ) void Cgt_ManDetectCandidates( Aig_Man_t * pAig, Aig_Obj_t * pObj, int nLevelMax, Vec_Ptr_t * vCands )
{ {
Vec_PtrClear( vCands ); Vec_PtrClear( vCands );
if ( !Aig_ObjIsNode(Aig_ObjFanin0(pObj)) ) if ( !Aig_ObjIsNode(pObj) )
return; return;
Aig_ManIncrementTravId( pAig ); Aig_ManIncrementTravId( pAig );
Cgt_ManDetectCandidates_rec( pAig, pObj, nLevelMax, vCands ); 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 ); 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************************************************************* /**Function*************************************************************
Synopsis [Derives miter for clock-gating.] 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 [] 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; int i;
assert( Aig_ObjIsPi(pObjLo) ); assert( Aig_ObjIsPi(pObjLo) );
pMiter = Aig_ManConst0( pNew ); // detect nodes and their cone
Cgt_ManDetectFanout( p->pAig, pObjLo, p->pPars->nOdcMax, p->vFanout ); Cgt_ManDetectFanout( p->pAig, pObjLo, p->pPars->nOdcMax, p->vFanout );
Vec_PtrForEachEntry( p->vFanout, pRoot, i ) Cgt_ManCollectVisited( p->pAig, p->vFanout, p->vVisited );
pMiter = Aig_Or( pNew, pMiter, Aig_Exor(pNew, pRoot->pData, pRoot->pNext) ); // 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; 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 * Cgt_ManDeriveAigForGating( Cgt_Man_t * p )
{ {
Aig_Man_t * pNew; 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; int i;
assert( Aig_ManRegNum(p->pAig) ); assert( Aig_ManRegNum(p->pAig) );
Aig_ManCleanNext( p->pAig );
pNew = Aig_ManStart( Aig_ManObjNumMax(p->pAig) ); pNew = Aig_ManStart( Aig_ManObjNumMax(p->pAig) );
pNew->pName = Aig_UtilStrsav( "CG_miter" );
// build the first frame // build the first frame
Aig_ManConst1(p->pAig)->pData = Aig_ManConst1(pNew); Aig_ManConst1(p->pAig)->pData = Aig_ManConst1(pNew);
Aig_ManForEachPi( p->pAig, pObj, i ) 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) ); pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
// Saig_ManForEachPo( p->pAig, pObj, i ) // Saig_ManForEachPo( p->pAig, pObj, i )
// pObj->pData = Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) ); // pObj->pData = Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) );
// build the second frame if ( p->pPars->nOdcMax > 0 )
Aig_ManConst1(p->pAig)->pNext = Aig_ManConst1(pNew); {
Saig_ManForEachPi( p->pAig, pObj, i ) // create storage for observability conditions
pObj->pNext = Aig_ObjCreatePi( pNew ); vCopy0 = Vec_PtrStart( Aig_ManObjNumMax(p->pAig) );
vCopy1 = Vec_PtrStart( Aig_ManObjNumMax(p->pAig) );
// initialize register outputs
Saig_ManForEachLiLo( p->pAig, pObjLi, pObjLo, i ) Saig_ManForEachLiLo( p->pAig, pObjLi, pObjLo, i )
pObjLo->pNext = Aig_ObjChild0Copy(pObjLi); {
Aig_ManForEachNode( p->pAig, pObj, i ) Vec_PtrWriteEntry( vCopy0, Aig_ObjId(pObjLo), Aig_ObjChild0Copy(pObjLi) );
if ( Aig_ObjLevel(pObj) <= p->pPars->nOdcMax ) Vec_PtrWriteEntry( vCopy1, Aig_ObjId(pObjLo), Aig_ObjChild0Copy(pObjLi) );
pObj->pNext = Aig_And( pNew, Aig_ObjChild0Next(pObj), Aig_ObjChild1Next(pObj) ); }
// 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 // construct clock-gating miters for each register input
Saig_ManForEachLiLo( p->pAig, pObjLi, pObjLo, i ) Saig_ManForEachLiLo( p->pAig, pObjLi, pObjLo, i )
pObjLi->pData = Aig_ObjCreatePo( pNew, Cgt_ManConstructMiter(p, pNew, pObjLo) ); {
Aig_ManCleanNext( p->pAig ); pMiter = Aig_Exor( pNew, pObjLo->pData, Aig_ObjChild0Copy(pObjLi) );
Aig_ManSetPioNumbers( p->pAig ); pObjLi->pData = Aig_ObjCreatePo( pNew, pMiter );
}
}
Aig_ManCleanup( pNew ); Aig_ManCleanup( pNew );
Aig_ManSetPioNumbers( pNew );
return 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************************************************************* /**Function*************************************************************
Synopsis [Duplicates the AIG recursively.] Synopsis [Duplicates the AIG recursively.]
@ -213,15 +408,19 @@ Aig_Man_t * Cgt_ManDeriveAigForGating( Cgt_Man_t * p )
SeeAlso [] 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) ) if ( Aig_ObjIsTravIdCurrent(pAig, pObj) )
return pObj->pData; return pObj->pData;
Aig_ObjSetTravIdCurrent(pAig, pObj); Aig_ObjSetTravIdCurrent(pAig, pObj);
if ( Aig_ObjIsPi(pObj) ) if ( Aig_ObjIsPi(pObj) )
return pObj->pData = Aig_ObjCreatePi( pNew ); {
Cgt_ManDupPartition_rec( pNew, pAig, Aig_ObjFanin0(pObj) ); pObj->pData = Aig_ObjCreatePi( pNew );
Cgt_ManDupPartition_rec( pNew, pAig, Aig_ObjFanin1(pObj) ); 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) ); 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 [] 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_Man_t * pNew;
Aig_Obj_t * pObj; Aig_Obj_t * pObj;
int i; 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 ); pNew = Aig_ManStart( nVarsMin );
Aig_ManIncrementTravId( pAig ); pNew->pName = Aig_UtilStrsav( "partition" );
Aig_ManConst1(pAig)->pData = Aig_ManConst1(pNew); Aig_ManIncrementTravId( pFrame );
Aig_ObjSetTravIdCurrent( pAig, Aig_ManConst1(pAig) ); Aig_ManConst1(pFrame)->pData = Aig_ManConst1(pNew);
for ( i = iStart; i < iStart + nFlopsMin && i < Aig_ManPoNum(pAig); i++ ) Aig_ObjSetTravIdCurrent( pFrame, Aig_ManConst1(pFrame) );
for ( i = iStart; i < iStart + nFlopsMin && i < Aig_ManPoNum(pFrame); i++ )
{ {
pObj = Aig_ManPo( pAig, i ); pObj = Aig_ManPo( pFrame, i );
Cgt_ManDupPartition_rec( pNew, pAig, Aig_ObjFanin0(pObj) ); Cgt_ManDupPartition_rec( pNew, pFrame, Aig_ObjFanin0(pObj), vLeaves );
pObj->pData = Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) ); 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 ); pObj = Aig_ManPo( pFrame, i );
Cgt_ManDupPartition_rec( pNew, pAig, Aig_ObjFanin0(pObj) ); Cgt_ManDupPartition_rec( pNew, pFrame, Aig_ObjFanin0(pObj), vLeaves );
pObj->pData = Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) ); 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; 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************************************************************* /**Function*************************************************************
Synopsis [Derives AIG after clock-gating.] Synopsis [Derives AIG after clock-gating.]
@ -273,34 +518,74 @@ Aig_Man_t * Cgt_ManDupPartition( Aig_Man_t * pAig, int nVarsMin, int nFlopsMin,
SeeAlso [] 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_Man_t * pNew;
Aig_Obj_t * pObj, * pObjNew, * pObjLi, * pObjLo, * pGate, * pGateNew; Aig_Obj_t * pObj, * pObjNew, * pObjLi, * pObjLo, * pGateNew;
int i; 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) ); assert( Aig_ManRegNum(pAig) );
pNew = Aig_ManStart( Aig_ManObjNumMax(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_ManConst1(pAig)->pData = Aig_ManConst1(pNew);
Aig_ManForEachPi( pAig, pObj, i ) Aig_ManForEachPi( pAig, pObj, i )
pObj->pData = Aig_ObjCreatePi( pNew ); pObj->pData = Aig_ObjCreatePi( pNew );
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 ) Aig_ManForEachNode( pAig, pObj, i )
pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
}
if ( pnUsedNodes != NULL )
*pnUsedNodes = Aig_ManNodeNum(pNew);
Saig_ManForEachPo( pAig, pObj, i ) Saig_ManForEachPo( pAig, pObj, i )
pObj->pData = Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) ); pObj->pData = Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) );
Saig_ManForEachLiLo( pAig, pObjLi, pObjLo, i ) Saig_ManForEachLiLo( pAig, pObjLi, pObjLo, i )
{ {
pGate = Vec_PtrEntry( vGates, i ); vOne = Vec_VecEntry( vGates, i );
if ( pGate == NULL ) if ( Vec_PtrSize(vOne) == 0 )
pObjNew = Aig_ObjChild0Copy(pObjLi); pObjNew = Aig_ObjChild0Copy(pObjLi);
else 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) ); pObjNew = Aig_Mux( pNew, pGateNew, pObjLo->pData, Aig_ObjChild0Copy(pObjLi) );
} }
pObjLi->pData = Aig_ObjCreatePo( pNew, pObjNew ); pObjLi->pData = Aig_ObjCreatePo( pNew, pObjNew );
} }
Aig_ManCleanup( pNew ); Aig_ManCleanup( pNew );
Aig_ManSetRegNum( pNew, Aig_ManRegNum(pAig) ); Aig_ManSetRegNum( pNew, Aig_ManRegNum(pAig) );
// unlabel nodes
Aig_ManCleanMarkAB( pAig );
Aig_ManCleanNext( pAig );
return pNew; return pNew;
} }

View File

@ -19,6 +19,7 @@
***********************************************************************/ ***********************************************************************/
#include "cgtInt.h" #include "cgtInt.h"
#include "bar.h"
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/// DECLARATIONS /// /// DECLARATIONS ///
@ -42,13 +43,14 @@
void Cgt_SetDefaultParams( Cgt_Par_t * p ) void Cgt_SetDefaultParams( Cgt_Par_t * p )
{ {
memset( p, 0, sizeof(Cgt_Par_t) ); 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->nCandMax = 1000; // the max number of candidates at each node
p->nOdcMax = 0; // the max number of ODC levels to consider p->nOdcMax = 0; // the max number of ODC levels to consider
p->nConfMax = 1000; // the max number of conflicts at a node p->nConfMax = 10; // the max number of conflicts at a node
p->nVarsMin = 5000; // the min number of vars to recycle the SAT solver p->nVarsMin = 1000; // the min number of vars to recycle the SAT solver
p->nFlopsMin = 25; // the min number of flops to recycle the SAT solver p->nFlopsMin = 5; // the min number of flops to recycle the SAT solver
p->fVerbose = 0; // verbosity flag p->fAreaOnly = 0; // derive clock-gating to minimize area
p->fVerbose = 1; // verbosity flag
} }
/**Function************************************************************* /**Function*************************************************************
@ -62,14 +64,14 @@ void Cgt_SetDefaultParams( Cgt_Par_t * p )
SeeAlso [] 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; unsigned * pInfoCand, * pInfoMiter;
int w, nWords = Aig_BitWordNum( p->nPatts ); int w, nWords = Aig_BitWordNum( p->nPatts );
pInfoCand = Vec_PtrEntry( p->vPatts, Aig_ObjId(Aig_Regular(pCandFrame)) ); pInfoCand = Vec_PtrEntry( p->vPatts, Aig_ObjId(Aig_Regular(pCandPart)) );
pInfoMiter = Vec_PtrEntry( p->vPatts, Aig_ObjId(pMiterFrame) ); pInfoMiter = Vec_PtrEntry( p->vPatts, Aig_ObjId(pMiterPart) );
// C => !M -- true is the same as C & M -- false // C => !M -- true is the same as C & M -- false
if ( !Aig_IsComplement(pCandFrame) ) if ( !Aig_IsComplement(pCandPart) )
{ {
for ( w = 0; w < nWords; w++ ) for ( w = 0; w < nWords; w++ )
if ( pInfoCand[w] & pInfoMiter[w] ) if ( pInfoCand[w] & pInfoMiter[w] )
@ -106,6 +108,7 @@ void Cgt_SimulationRecord( Cgt_Man_t * p )
if ( p->nPatts == 32 * p->nPattWords ) if ( p->nPatts == 32 * p->nPattWords )
{ {
Vec_PtrReallocSimInfo( p->vPatts ); Vec_PtrReallocSimInfo( p->vPatts );
Vec_PtrCleanSimInfo( p->vPatts, p->nPattWords, 2 * p->nPattWords );
p->nPattWords *= 2; p->nPattWords *= 2;
} }
} }
@ -121,15 +124,16 @@ void Cgt_SimulationRecord( Cgt_Man_t * p )
SeeAlso [] 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; Vec_Ptr_t * vNodes = p->vFanout;
Aig_Obj_t * pMiter, * pCand, * pMiterFrame, * pCandFrame, * pMiterPart, * pCandPart; 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) ); assert( Vec_VecSize(p->vGatesAll) == Aig_ManPoNum(p->pFrame) );
// go through all the registers inputs of this range // 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 ); pMiter = Saig_ManLi( p->pAig, i );
Cgt_ManDetectCandidates( p->pAig, Aig_ObjFanin0(pMiter), p->pPars->nLevelMax, vNodes ); Cgt_ManDetectCandidates( p->pAig, Aig_ObjFanin0(pMiter), p->pPars->nLevelMax, vNodes );
// go through the candidates of this PO // go through the candidates of this PO
@ -153,6 +157,8 @@ void Cgt_ClockGatingRangeCheck( Cgt_Man_t * p, int iStart )
if ( RetValue == 0 ) if ( RetValue == 0 )
Cgt_SimulationRecord( p ); Cgt_SimulationRecord( p );
} }
else
p->nCallsFiltered++;
// try reverse polarity // try reverse polarity
if ( Cgt_SimulationFilter( p, Aig_Not(pCandPart), pMiterPart ) ) if ( Cgt_SimulationFilter( p, Aig_Not(pCandPart), pMiterPart ) )
{ {
@ -165,7 +171,16 @@ void Cgt_ClockGatingRangeCheck( Cgt_Man_t * p, int iStart )
if ( RetValue == 0 ) if ( RetValue == 0 )
Cgt_SimulationRecord( p ); 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 );
}
} }
} }
@ -182,16 +197,33 @@ void Cgt_ClockGatingRangeCheck( Cgt_Man_t * p, int iStart )
***********************************************************************/ ***********************************************************************/
int Cgt_ClockGatingRange( Cgt_Man_t * p, int iStart ) int Cgt_ClockGatingRange( Cgt_Man_t * p, int iStart )
{ {
int iStop; int nOutputs, iStop, clk, clkTotal = clock();
p->pPart = Cgt_ManDupPartition( p->pFrame, p->pPars->nVarsMin, p->pPars->nFlopsMin, iStart ); int nCallsUnsat = p->nCallsUnsat;
p->pCnf = Cnf_DeriveSimple( p->pPart, Aig_ManPoNum(p->pPart) ); 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 ); p->pSat = Cnf_DataWriteIntoSolver( p->pCnf, 1, 0 );
sat_solver_compress( p->pSat ); 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 ); Vec_PtrCleanSimInfo( p->vPatts, 0, p->nPattWords );
Cgt_ClockGatingRangeCheck( p, iStart ); p->timePrepare += clock() - clk;
iStop = iStart + Aig_ManPoNum(p->pPart); 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 ); Cgt_ManClean( p );
p->nRecycles++;
return iStop; 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 ) Vec_Vec_t * Cgt_ClockGatingCandidates( Aig_Man_t * pAig, Aig_Man_t * pCare, Cgt_Par_t * pPars )
{ {
Bar_Progress_t * pProgress = NULL;
Cgt_Par_t Pars; Cgt_Par_t Pars;
Cgt_Man_t * p; Cgt_Man_t * p;
Vec_Vec_t * vGatesAll; Vec_Vec_t * vGatesAll;
int iStart; int iStart, clk = clock(), clkTotal = clock();
// reset random numbers
Aig_ManRandom( 1 );
if ( pPars == NULL ) if ( pPars == NULL )
Cgt_SetDefaultParams( pPars = &Pars ); Cgt_SetDefaultParams( pPars = &Pars );
p = Cgt_ManCreate( pAig, pCare, pPars ); p = Cgt_ManCreate( pAig, pCare, pPars );
p->pFrame = Cgt_ManDeriveAigForGating( p ); p->pFrame = Cgt_ManDeriveAigForGating( p );
p->timeAig += clock() - clk;
assert( Aig_ManPoNum(p->pFrame) == Saig_ManRegNum(p->pAig) ); 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); ) for ( iStart = 0; iStart < Aig_ManPoNum(p->pFrame); )
{
Bar_ProgressUpdate( pProgress, iStart, NULL );
iStart = Cgt_ClockGatingRange( p, iStart ); iStart = Cgt_ClockGatingRange( p, iStart );
}
Bar_ProgressStop( pProgress );
vGatesAll = p->vGatesAll; vGatesAll = p->vGatesAll;
p->vGatesAll = NULL;
p->timeTotal = clock() - clkTotal;
Cgt_ManStop( p );
return vGatesAll; 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; Aig_Man_t * pGated;
Vec_Vec_t * vGatesAll; Vec_Vec_t * vGatesAll;
Vec_Ptr_t * vGates; Vec_Vec_t * vGates;
int nNodesUsed, clk = clock();
vGatesAll = Cgt_ClockGatingCandidates( pAig, pCare, pPars ); vGatesAll = Cgt_ClockGatingCandidates( pAig, pCare, pPars );
vGates = Cgt_ManDecideSimple( pAig, vGatesAll ); if ( pPars->fAreaOnly )
pGated = Cgt_ManDeriveGatedAig( pAig, vGates ); vGates = Cgt_ManDecideArea( pAig, vGatesAll, pPars->nOdcMax, pPars->fVerbose );
Vec_PtrFree( vGates ); 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 ); Vec_VecFree( vGatesAll );
return pGated; return pGated;
} }

View File

@ -25,8 +25,11 @@
/// DECLARATIONS /// /// 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_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 /// /// FUNCTION DEFINITIONS ///
@ -34,7 +37,7 @@ extern int Ssw_SmlCheckXorImplication( Ssw_Sml_t * p, Aig_Obj_t * pObjLi, Aig_Ob
/**Function************************************************************* /**Function*************************************************************
Synopsis [Chooses what clock-gate to use for each register.] Synopsis [Collects POs in the transitive fanout.]
Description [] Description []
@ -43,11 +46,127 @@ extern int Ssw_SmlCheckXorImplication( Ssw_Sml_t * p, Aig_Obj_t * pObjLi, Aig_Ob
SeeAlso [] 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; Vec_Ptr_t * vGates;
vGates = Vec_PtrStart( Saig_ManRegNum(pAig) ); Aig_Obj_t * pObj;
return vGates; 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************************************************************* /**Function*************************************************************
@ -62,14 +181,18 @@ Vec_Ptr_t * Cgt_ManDecide( Aig_Man_t * pAig, Vec_Vec_t * vGatesAll )
SeeAlso [] 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; Ssw_Sml_t * pSml;
Vec_Ptr_t * vGates, * vCands; Vec_Vec_t * vGates;
Vec_Ptr_t * vCands;
Aig_Obj_t * pObjLi, * pObjLo, * pCand, * pCandBest; Aig_Obj_t * pObjLi, * pObjLo, * pCand, * pCandBest;
int i, k, nHitsCur, nHitsMax; int i, k, nHitsCur, nHitsMax, Counter = 0, clk = clock();
vGates = Vec_PtrStart( Saig_ManRegNum(pAig) ); int nTransTotal = 0, nTransSaved = 0;
pSml = Ssw_SmlSimulateSeq( pAig, 0, 32, 1 ); vGates = Vec_VecStart( Saig_ManRegNum(pAig) );
pSml = Ssw_SmlSimulateSeq( pAig, 0, nFrames, nWords );
Saig_ManForEachLiLo( pAig, pObjLi, pObjLo, i ) Saig_ManForEachLiLo( pAig, pObjLi, pObjLo, i )
{ {
nHitsMax = 0; nHitsMax = 0;
@ -78,10 +201,10 @@ Vec_Ptr_t * Cgt_ManDecideSimple( Aig_Man_t * pAig, Vec_Vec_t * vGatesAll )
Vec_PtrForEachEntry( vCands, pCand, k ) Vec_PtrForEachEntry( vCands, pCand, k )
{ {
// check if this is indeed a clock-gate // 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" ); printf( "Clock gate candidate is invalid!\n" );
// find its characteristic number // find its characteristic number
nHitsCur = Ssw_SmlCountXorImplication( pSml, pObjLi, pObjLo, pCand ); nHitsCur = Ssw_SmlNodeCountOnesReal( pSml, pCand );
if ( nHitsMax < nHitsCur ) if ( nHitsMax < nHitsCur )
{ {
nHitsMax = nHitsCur; nHitsMax = nHitsCur;
@ -89,9 +212,80 @@ Vec_Ptr_t * Cgt_ManDecideSimple( Aig_Man_t * pAig, Vec_Vec_t * vGatesAll )
} }
} }
if ( pCandBest != NULL ) if ( pCandBest != NULL )
Vec_PtrWriteEntry( vGates, i, pCandBest ); {
Vec_VecPush( vGates, i, pCandBest );
Counter++;
nTransSaved += nHitsMax;
}
nTransTotal += 32 * nFrames * nWords;
} }
Ssw_SmlStop( pSml ); 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; return vGates;
} }

View File

@ -48,12 +48,16 @@ struct Cgt_Man_t_
// user's data // user's data
Cgt_Par_t * pPars; // user's parameters Cgt_Par_t * pPars; // user's parameters
Aig_Man_t * pAig; // user's AIG manager 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_Vec_t * vGatesAll; // the computed clock-gates
Vec_Ptr_t * vGates; // the selected clock-gates Vec_Ptr_t * vGates; // the selected clock-gates
// internal data // internal data
Aig_Man_t * pFrame; // clock gate AIG manager Aig_Man_t * pFrame; // clock gate AIG manager
Vec_Ptr_t * vFanout; // temporary storage for fanouts Vec_Ptr_t * vFanout; // temporary storage for fanouts
Vec_Ptr_t * vVisited; // temporary storage for visited nodes
// SAT solving // SAT solving
Aig_Man_t * pPart; // partition Aig_Man_t * pPart; // partition
Cnf_Dat_t * pCnf; // CNF of the 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 nPatts; // the number of patterns accumulated
int nPattWords; // the number of pattern words int nPattWords; // the number of pattern words
// statistics // statistics
int nRecycles; // recycles
int nCalls; // total calls int nCalls; // total calls
int nCallsSat; // satisfiable calls int nCallsSat; // satisfiable calls
int nCallsUnsat; // unsatisfiable calls int nCallsUnsat; // unsatisfiable calls
int nCallsUndec; // undecided 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 timeSat; // total runtime
int timeSatSat; // satisfiable runtime int timeSatSat; // satisfiable runtime
int timeSatUnsat; // unsatisfiable runtime int timeSatUnsat; // unsatisfiable runtime
int timeSatUndec; // undecided 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 ==========================================================*/ /*=== cgtAig.c ==========================================================*/
extern void Cgt_ManDetectCandidates( Aig_Man_t * pAig, Aig_Obj_t * pObj, int nLevelMax, Vec_Ptr_t * vCands ); 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_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_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_Ptr_t * vGates ); extern Aig_Man_t * Cgt_ManDeriveGatedAig( Aig_Man_t * pAig, Vec_Vec_t * vGates, int fReduce, int * pnUsedNodes );
/*=== cgtDecide.c ==========================================================*/ /*=== cgtDecide.c ==========================================================*/
extern Vec_Ptr_t * Cgt_ManDecide( 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_Ptr_t * Cgt_ManDecideSimple( Aig_Man_t * pAig, Vec_Vec_t * vGatesAll ); extern Vec_Vec_t * Cgt_ManDecideArea( Aig_Man_t * pAig, Vec_Vec_t * vGatesAll, int nOdcMax, int fVerbose );
/*=== cgtMan.c ==========================================================*/ /*=== cgtMan.c ==========================================================*/
extern Cgt_Man_t * Cgt_ManCreate( Aig_Man_t * pAig, Aig_Man_t * pCare, Cgt_Par_t * pPars ); 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 ); extern void Cgt_ManClean( Cgt_Man_t * p );

View File

@ -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->pAig = pAig;
p->vGatesAll = Vec_VecStart( Saig_ManRegNum(pAig) ); p->vGatesAll = Vec_VecStart( Saig_ManRegNum(pAig) );
p->vFanout = Vec_PtrAlloc( 1000 ); p->vFanout = Vec_PtrAlloc( 1000 );
p->vVisited = Vec_PtrAlloc( 1000 );
p->nPattWords = 16; 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; return p;
} }
@ -106,27 +118,16 @@ void Cgt_ManClean( Cgt_Man_t * p )
***********************************************************************/ ***********************************************************************/
void Cgt_ManPrintStats( 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); p->timeOther = p->timeTotal-p->timeAig-p->timePrepare-p->timeSat-p->timeDecision;
PRTP( "AIG ", p->timeAig, p->timeTotal );
printf( "Parameters: F = %d. AddF = %d. C-lim = %d. Constr = %d. MaxLev = %d. Mem = %0.2f Mb.\n", PRTP( "Prepare ", p->timePrepare, p->timeTotal );
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 );
PRTP( "SAT solving", p->timeSat, p->timeTotal ); PRTP( "SAT solving", p->timeSat, p->timeTotal );
PRTP( " unsat ", p->timeSatUnsat, p->timeTotal ); PRTP( " unsat ", p->timeSatUnsat, p->timeTotal );
PRTP( " sat ", p->timeSatSat, p->timeTotal ); PRTP( " sat ", p->timeSatSat, p->timeTotal );
@ -155,8 +156,13 @@ void Cgt_ManStop( Cgt_Man_t * p )
Aig_ManStop( p->pFrame ); Aig_ManStop( p->pFrame );
Cgt_ManClean( p ); Cgt_ManClean( p );
Vec_PtrFree( p->vFanout ); Vec_PtrFree( p->vFanout );
Vec_PtrFree( p->vVisited );
if ( p->vGates )
Vec_PtrFree( p->vGates ); Vec_PtrFree( p->vGates );
if ( p->vGatesAll )
Vec_VecFree( p->vGatesAll ); Vec_VecFree( p->vGatesAll );
if ( p->vSuppsInv )
Vec_VecFree( p->vSuppsInv );
free( p ); free( p );
} }

View File

@ -47,6 +47,7 @@ struct Dar_RwrPar_t_
int fFanout; // support fanout representation int fFanout; // support fanout representation
int fUpdateLevel; // update level int fUpdateLevel; // update level
int fUseZeros; // performs zero-cost replacement int fUseZeros; // performs zero-cost replacement
int fPower; // enables power-aware rewriting
int fVerbose; // enables verbose output int fVerbose; // enables verbose output
int fVeryVerbose; // enables very 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 ========================================================*/ /*=== darScript.c ========================================================*/
extern Aig_Man_t * Dar_ManRewriteDefault( Aig_Man_t * pAig ); 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_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_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 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 ); extern Aig_Man_t * Dar_ManChoice( Aig_Man_t * pAig, int fBalance, int fUpdateLevel, int fConstruct, int nConfMax, int nLevelMax, int fVerbose );
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -47,6 +47,7 @@ void Dar_ManDefaultRwrParams( Dar_RwrPar_t * pPars )
pPars->fFanout = 1; pPars->fFanout = 1;
pPars->fUpdateLevel = 0; pPars->fUpdateLevel = 0;
pPars->fUseZeros = 0; pPars->fUseZeros = 0;
pPars->fPower = 0;
pPars->fVerbose = 0; pPars->fVerbose = 0;
pPars->fVeryVerbose = 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 ) 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; Dar_Man_t * p;
// Bar_Progress_t * pProgress; // Bar_Progress_t * pProgress;
Dar_Cut_t * pCut; Dar_Cut_t * pCut;
@ -74,6 +76,8 @@ int Dar_ManRewrite( Aig_Man_t * pAig, Dar_RwrPar_t * pPars )
Dar_LibPrepare( pPars->nSubgMax ); Dar_LibPrepare( pPars->nSubgMax );
// create rewriting manager // create rewriting manager
p = Dar_ManStart( pAig, pPars ); p = Dar_ManStart( pAig, pPars );
if ( pPars->fPower )
pAig->vProbs = Saig_ManComputeSwitchProbs( pAig, 48, 16, 1 );
// remove dangling nodes // remove dangling nodes
Aig_ManCleanup( pAig ); Aig_ManCleanup( pAig );
// if updating levels is requested, start fanout and timing // 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_ManVerifyReverseLevel( pAig );
Aig_ManStopReverseLevels( pAig ); Aig_ManStopReverseLevels( pAig );
} }
if ( pAig->vProbs )
{
Vec_IntFree( pAig->vProbs );
pAig->vProbs = NULL;
}
// stop the rewriting manager // stop the rewriting manager
Dar_ManStop( p ); Dar_ManStop( p );
Aig_ManCheckPhase( pAig ); Aig_ManCheckPhase( pAig );

View File

@ -44,6 +44,7 @@ struct Dar_LibDat_t_ // library object data
Aig_Obj_t * pFunc; // the corresponding AIG node if it exists Aig_Obj_t * pFunc; // the corresponding AIG node if it exists
int Level; // level of this node after it is constructured int Level; // level of this node after it is constructured
int TravId; // traversal ID of the library object data 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 fMffc; // set to one if node is part of MFFC
unsigned char nLats[3]; // the number of latches on the input/output stem 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) ); pFanin = Aig_NotCond(pFanin, ((uPhase >> i) & 1) );
s_DarLib->pDatas[i].pFunc = pFanin; s_DarLib->pDatas[i].pFunc = pFanin;
s_DarLib->pDatas[i].Level = Aig_Regular(pFanin)->Level; 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++; p->nCutsGood++;
return 1; return 1;
@ -716,14 +723,14 @@ int Dar_LibCutMatch( Dar_Man_t * p, Dar_Cut_t * pCut )
SeeAlso [] 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; int i, nNodes;
// mark the cut leaves // mark the cut leaves
for ( i = 0; i < nLeaves; i++ ) for ( i = 0; i < nLeaves; i++ )
Aig_Regular(s_DarLib->pDatas[i].pFunc)->nRefs++; Aig_Regular(s_DarLib->pDatas[i].pFunc)->nRefs++;
// label MFFC with current ID // label MFFC with current ID
nNodes = Aig_NodeMffsLabel( p, pRoot ); nNodes = Aig_NodeMffsLabel( p, pRoot, pPower );
// unmark the cut leaves // unmark the cut leaves
for ( i = 0; i < nLeaves; i++ ) for ( i = 0; i < nLeaves; i++ )
Aig_Regular(s_DarLib->pDatas[i].pFunc)->nRefs--; 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 [] 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; Dar_LibDat_t * pData;
int Area; int Area;
if ( pPower )
*pPower = (float)0.0;
if ( pObj->fTerm ) if ( pObj->fTerm )
return 0; return 0;
assert( pObj->Num > 3 ); 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; pData->TravId = Out;
// this is a new node - get a bound on the area of its branches // this is a new node - get a bound on the area of its branches
nNodesSaved--; 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 ) if ( Area > nNodesSaved )
return 0xff; 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 ) if ( Area > nNodesSaved )
return 0xff; 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; 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 ) void Dar_LibEval( Dar_Man_t * p, Aig_Obj_t * pRoot, Dar_Cut_t * pCut, int Required )
{ {
int fTraining = 0; int fTraining = 0;
float PowerSaved, PowerAdded;
Dar_LibObj_t * pObj; Dar_LibObj_t * pObj;
int Out, k, Class, nNodesSaved, nNodesAdded, nNodesGained, clk; int Out, k, Class, nNodesSaved, nNodesAdded, nNodesGained, clk;
clk = clock(); 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) ) if ( !Dar_LibCutMatch(p, pCut) )
return; return;
// mark MFFC of the node // 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 // evaluate the cut
Class = s_DarLib->pMap[pCut->uTruth]; Class = s_DarLib->pMap[pCut->uTruth];
Dar_LibEvalAssignNums( p, Class, pRoot ); 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]); pObj = Dar_LibObj(s_DarLib, s_DarLib->pSubgr0[Class][Out]);
if ( Aig_Regular(s_DarLib->pDatas[pObj->Num].pFunc) == pRoot ) if ( Aig_Regular(s_DarLib->pDatas[pObj->Num].pFunc) == pRoot )
continue; 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; nNodesGained = nNodesSaved - nNodesAdded;
if ( p->pPars->fPower && PowerSaved < PowerAdded )
continue;
if ( fTraining && nNodesGained >= 0 ) if ( fTraining && nNodesGained >= 0 )
Dar_LibIncrementScore( Class, Out, nNodesGained + 1 ); Dar_LibIncrementScore( Class, Out, nNodesGained + 1 );
if ( nNodesGained < 0 || (nNodesGained == 0 && !p->pPars->fUseZeros) ) if ( nNodesGained < 0 || (nNodesGained == 0 && !p->pPars->fUseZeros) )

View File

@ -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->pFunc = Vec_PtrEntry(vCut, i);
pNode->Level = Aig_Regular(pNode->pFunc)->Level; 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" ); //printf( "Trying:\n" );
// compute the AIG size after adding the internal nodes // compute the AIG size after adding the internal nodes

View File

@ -153,7 +153,7 @@ void Dar_ManHaigPrintStats( Aig_Man_t * pAig )
SeeAlso [] 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" //alias compress2 "b -l; rw -l; rwz -l; b -l; rwz -l; b -l"
{ {
Aig_Man_t * pTemp; 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; pParsRwr->fUpdateLevel = fUpdateLevel;
pParsRef->fUpdateLevel = fUpdateLevel; pParsRef->fUpdateLevel = fUpdateLevel;
pParsRwr->fPower = fPower;
pParsRwr->fVerbose = 0;//fVerbose; pParsRwr->fVerbose = 0;//fVerbose;
pParsRef->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 [] 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" //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; Aig_Man_t * pTemp;
@ -238,6 +240,7 @@ Aig_Man_t * Dar_ManCompress2( Aig_Man_t * pAig, int fBalance, int fUpdateLevel,
pParsRwr->fUpdateLevel = fUpdateLevel; pParsRwr->fUpdateLevel = fUpdateLevel;
pParsRef->fUpdateLevel = fUpdateLevel; pParsRef->fUpdateLevel = fUpdateLevel;
pParsRwr->fFanout = fFanout; pParsRwr->fFanout = fFanout;
pParsRwr->fPower = fPower;
pParsRwr->fVerbose = 0;//fVerbose; pParsRwr->fVerbose = 0;//fVerbose;
pParsRef->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 [] 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 resyn "b; rw; rwz; b; rwz; b"
//alias resyn2 "b; rw; rf; b; rw; rwz; b; rfz; 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 ) Aig_ManForEachObj( pAig, pObj, i )
pObj->pHaig = pObj; pObj->pHaig = pObj;
pAig = Dar_ManCompress (pAig, fBalance, fUpdateLevel, fVerbose); pAig = Dar_ManCompress(pAig, fBalance, fUpdateLevel, fPower, fVerbose);
Vec_PtrPush( vAigs, pAig ); Vec_PtrPush( vAigs, pAig );
//Aig_ManPrintStats( pAig ); //Aig_ManPrintStats( pAig );
@ -354,7 +357,7 @@ Vec_Ptr_t * Dar_ManChoiceSynthesis( Aig_Man_t * pAig, int fBalance, int fUpdateL
pObj->pHaig = pObj; pObj->pHaig = pObj;
} }
pAig = Dar_ManCompress2(pAig, fBalance, fUpdateLevel, 1, fVerbose); pAig = Dar_ManCompress2(pAig, fBalance, fUpdateLevel, 1, fPower, fVerbose);
Vec_PtrPush( vAigs, pAig ); Vec_PtrPush( vAigs, pAig );
//Aig_ManPrintStats( pAig ); //Aig_ManPrintStats( pAig );
@ -384,7 +387,7 @@ Aig_Man_t * Dar_ManChoice( Aig_Man_t * pAig, int fBalance, int fUpdateLevel, int
clk = clock(); clk = clock();
// vAigs = Dar_ManChoiceSynthesisExt(); // vAigs = Dar_ManChoiceSynthesisExt();
vAigs = Dar_ManChoiceSynthesis( pAig, fBalance, fUpdateLevel, fVerbose ); vAigs = Dar_ManChoiceSynthesis( pAig, fBalance, fUpdateLevel, 0, fVerbose );
// swap the first and last network // swap the first and last network
// this should lead to the primary choice being "better" because of synthesis // 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(); clk = clock();
// vAigs = Dar_ManChoiceSynthesisExt(); // 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 // swap the first and last network
// this should lead to the primary choice being "better" because of synthesis // this should lead to the primary choice being "better" because of synthesis

View File

@ -47,6 +47,7 @@ struct Dch_Pars_t_
int fSynthesis; // set to 1 to perform synthesis int fSynthesis; // set to 1 to perform synthesis
int fPolarFlip; // uses polarity adjustment int fPolarFlip; // uses polarity adjustment
int fSimulateTfo; // uses simulatin of TFO classes int fSimulateTfo; // uses simulatin of TFO classes
int fPower; // uses power-aware rewriting
int fVerbose; // verbose stats int fVerbose; // verbose stats
int timeSynth; // synthesis runtime int timeSynth; // synthesis runtime
int nNodesAhead; // the lookahead in terms of nodes int nNodesAhead; // the lookahead in terms of nodes

View File

@ -48,6 +48,7 @@ void Dch_ManSetDefaultParams( Dch_Pars_t * p )
p->fSynthesis = 1; // derives three snapshots p->fSynthesis = 1; // derives three snapshots
p->fPolarFlip = 1; // uses polarity adjustment p->fPolarFlip = 1; // uses polarity adjustment
p->fSimulateTfo = 1; // simulate TFO p->fSimulateTfo = 1; // simulate TFO
p->fPower = 0; // power-aware rewriting
p->fVerbose = 0; // verbose stats p->fVerbose = 0; // verbose stats
p->nNodesAhead = 1000; // the lookahead in terms of nodes p->nNodesAhead = 1000; // the lookahead in terms of nodes
p->nCallsRecycle = 100; // calls to perform before recycling SAT solver p->nCallsRecycle = 100; // calls to perform before recycling SAT solver

View File

@ -404,7 +404,7 @@ clk = clock();
pNew = Aig_ManDupOrdered( pTemp = pNew ); pNew = Aig_ManDupOrdered( pTemp = pNew );
Aig_ManStop( pTemp ); Aig_ManStop( pTemp );
// pNew = Dar_ManRewriteDefault( pTemp = pNew ); // 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 ); Aig_ManStop( pTemp );
if ( pParSec->fVerbose ) if ( pParSec->fVerbose )
{ {

97
src/aig/fsim/fsim.h Normal file
View File

@ -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 ///
////////////////////////////////////////////////////////////////////////

83
src/aig/fsim/fsimCore.c Normal file
View 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 ///
////////////////////////////////////////////////////////////////////////

364
src/aig/fsim/fsimFront.c Normal file
View 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 ///
////////////////////////////////////////////////////////////////////////

134
src/aig/fsim/fsimInt.h Normal file
View 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 ///
////////////////////////////////////////////////////////////////////////

207
src/aig/fsim/fsimMan.c Normal file
View 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 ///
////////////////////////////////////////////////////////////////////////

560
src/aig/fsim/fsimSim.c Normal file
View 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 ///
////////////////////////////////////////////////////////////////////////

588
src/aig/fsim/fsimSwitch.c Normal file
View 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 ///
////////////////////////////////////////////////////////////////////////

410
src/aig/fsim/fsimTsim.c Normal file
View 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 ///
////////////////////////////////////////////////////////////////////////

6
src/aig/fsim/module.make Normal file
View 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

View File

@ -64,7 +64,10 @@ typedef enum {
struct Hop_Obj_t_ // 6 words struct Hop_Obj_t_ // 6 words
{ {
void * pData; // misc void * pData; // misc
union {
Hop_Obj_t * pNext; // strashing table Hop_Obj_t * pNext; // strashing table
int PioNum; // the number of PI/PO
};
Hop_Obj_t * pFanin0; // fanin Hop_Obj_t * pFanin0; // fanin
Hop_Obj_t * pFanin1; // fanin Hop_Obj_t * pFanin1; // fanin
unsigned int Type : 3; // object type unsigned int Type : 3; // object type

View File

@ -44,6 +44,7 @@ Hop_Obj_t * Hop_ObjCreatePi( Hop_Man_t * p )
Hop_Obj_t * pObj; Hop_Obj_t * pObj;
pObj = Hop_ManFetchMemory( p ); pObj = Hop_ManFetchMemory( p );
pObj->Type = AIG_PI; pObj->Type = AIG_PI;
pObj->PioNum = Vec_PtrSize( p->vPis );
Vec_PtrPush( p->vPis, pObj ); Vec_PtrPush( p->vPis, pObj );
p->nObjs[AIG_PI]++; p->nObjs[AIG_PI]++;
return pObj; return pObj;

View File

@ -44,6 +44,12 @@ static inline void Hop_ManTruthFill( unsigned * pOut, int nVars )
for ( w = Hop_ManTruthWordNum(nVars)-1; w >= 0; w-- ) for ( w = Hop_ManTruthWordNum(nVars)-1; w >= 0; w-- )
pOut[w] = ~(unsigned)0; 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 /// /// FUNCTION DEFINITIONS ///
@ -155,7 +161,7 @@ unsigned * Hop_ManConvertAigToTruth( Hop_Man_t * p, Hop_Obj_t * pRoot, int nVars
vTtElems = NULL; vTtElems = NULL;
// clear the data fields and set marks // clear the data fields and set marks
nNodes = Hop_ManConvertAigToTruth_rec1( pRoot ); nNodes = Hop_ManConvertAigToTruth_rec1( Hop_Regular(pRoot) );
// prepare memory // prepare memory
nWords = Hop_TruthWordNum( nVars ); nWords = Hop_TruthWordNum( nVars );
Vec_IntClear( vTruth ); 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 // 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 // copy the result
Hop_ManTruthCopy( pTruth, pTruth2, nVars ); Hop_ManTruthCopy( pTruth, pTruth2, nVars );
if ( Hop_IsComplement(pRoot) )
Hop_ManTruthNot( pTruth, pTruth, nVars );
if ( vTtElems ) if ( vTtElems )
Vec_PtrFree( vTtElems ); Vec_PtrFree( vTtElems );
return pTruth; return pTruth;

View File

@ -258,6 +258,12 @@ void Ioa_WriteAiger( Aig_Man_t * pMan, char * pFileName, int fWriteSymbols, int
unsigned char * pBuffer; unsigned char * pBuffer;
unsigned uLit0, uLit1, uLit; 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) ); // assert( Aig_ManIsStrash(pMan) );
// start the output stream // start the output stream
pFile = fopen( pFileName, "wb" ); pFile = fopen( pFileName, "wb" );

View File

@ -141,14 +141,14 @@ struct Kit_DsdMan_t_
}; };
#ifdef WIN32 #ifdef WIN32
#define DLLEXPORT __declspec(dllexport) #define ABC_DLLEXPORT __declspec(dllexport)
#define DLLIMPORT __declspec(dllimport) #define ABC_DLLIMPORT __declspec(dllimport)
#else /* defined(WIN32) */ #else /* defined(WIN32) */
#define DLLIMPORT #define ABC_DLLIMPORT
#endif /* defined(WIN32) */ #endif /* defined(WIN32) */
#ifndef ABC_DLL #ifndef ABC_DLL
#define ABC_DLL DLLIMPORT #define ABC_DLL ABC_DLLIMPORT
#endif #endif
static inline int Kit_DsdVar2Lit( int Var, int fCompl ) { return Var + Var + fCompl; } 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 ) \ #define Kit_DsdNtkForEachObj( pNtk, pObj, i ) \
for ( i = 0; (i < (pNtk)->nNodes) && ((pObj) = (pNtk)->pNodes[i]); i++ ) for ( i = 0; (i < (pNtk)->nNodes) && ((pObj) = (pNtk)->pNodes[i]); i++ )
#define Kit_DsdObjForEachFanin( pNtk, pObj, iLit, 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 ) \ #define Kit_PlaForEachCube( pSop, nFanins, pCube ) \
for ( pCube = (pSop); *pCube; pCube += (nFanins) + 3 ) 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_DsdVerify( Kit_DsdNtk_t * pNtk, unsigned * pTruth, int nVars );
extern void Kit_DsdNtkFree( Kit_DsdNtk_t * pNtk ); extern void Kit_DsdNtkFree( Kit_DsdNtk_t * pNtk );
extern int Kit_DsdNonDsdSizeMax( 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_DsdNonDsdSupports( Kit_DsdNtk_t * pNtk );
extern unsigned Kit_DsdGetSupports( Kit_DsdNtk_t * p ); extern unsigned Kit_DsdGetSupports( Kit_DsdNtk_t * p );
extern Kit_DsdNtk_t * Kit_DsdExpand( 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 ==========================================================*/ /*=== kitTruth.c ==========================================================*/
extern void Kit_TruthSwapAdjacentVars( unsigned * pOut, unsigned * pIn, int nVars, int Start ); 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_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 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_TruthVarInSupport( unsigned * pTruth, int nVars, int iVar );
extern int Kit_TruthSupportSize( unsigned * pTruth, int nVars ); 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_TruthMinCofSuppOverlap( unsigned * pTruth, int nVars, int * pVarMin );
extern int Kit_TruthBestCofVar( unsigned * pTruth, int nVars, unsigned * pCof0, unsigned * pCof1 ); 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_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 void Kit_TruthCountOnesInCofsSlow( unsigned * pTruth, int nVars, short * pStore, unsigned * pAux );
extern unsigned Kit_TruthHash( unsigned * pIn, int nWords ); extern unsigned Kit_TruthHash( unsigned * pIn, int nWords );
extern unsigned Kit_TruthSemiCanonicize( unsigned * pInOut, unsigned * pAux, int nVars, char * pCanonPerm, short * pStore ); extern unsigned Kit_TruthSemiCanonicize( unsigned * pInOut, unsigned * pAux, int nVars, char * pCanonPerm, short * pStore );

View File

@ -139,9 +139,9 @@ Kit_DsdNtk_t * Kit_DsdNtkAlloc( int nVars )
Kit_DsdNtk_t * pNtk; Kit_DsdNtk_t * pNtk;
pNtk = ALLOC( Kit_DsdNtk_t, 1 ); pNtk = ALLOC( Kit_DsdNtk_t, 1 );
memset( pNtk, 0, sizeof(Kit_DsdNtk_t) ); 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->nVars = nVars;
pNtk->nNodesAlloc = nVars; pNtk->nNodesAlloc = nVars+1;
pNtk->pMem = ALLOC( unsigned, 6 * Kit_TruthWordNum(nVars) ); pNtk->pMem = ALLOC( unsigned, 6 * Kit_TruthWordNum(nVars) );
return pNtk; return pNtk;
} }
@ -303,10 +303,13 @@ void Kit_DsdPrintExpanded( Kit_DsdNtk_t * pNtk )
***********************************************************************/ ***********************************************************************/
void Kit_DsdPrintFromTruth( unsigned * pTruth, int nVars ) void Kit_DsdPrintFromTruth( unsigned * pTruth, int nVars )
{ {
Kit_DsdNtk_t * pTemp; Kit_DsdNtk_t * pTemp, * pTemp2;
pTemp = Kit_DsdDecomposeMux( pTruth, nVars, 5 ); 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 ); Kit_DsdNtkFree( pTemp );
} }
@ -392,7 +395,6 @@ unsigned * Kit_DsdTruthComputeNode_rec( Kit_DsdMan_t * p, Kit_DsdNtk_t * pNtk, i
pTruthPrime = Kit_DsdObjTruth( pObj ); pTruthPrime = Kit_DsdObjTruth( pObj );
// get storage for the temporary minterm // get storage for the temporary minterm
pTruthMint = Vec_PtrEntry(p->vTtNodes, pNtk->nVars + pNtk->nNodes); pTruthMint = Vec_PtrEntry(p->vTtNodes, pNtk->nVars + pNtk->nNodes);
// go through the minterms // go through the minterms
nMints = (1 << pObj->nFans); nMints = (1 << pObj->nFans);
Kit_TruthClear( pTruthRes, pNtk->nVars ); 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_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 ); pTruthTemp = Kit_TruthCompose( p->dd, Kit_DsdObjTruth(pObj), pObj->nFans, pTruthFans, pNtk->nVars, p->vTtBdds, p->vNodes );
Kit_TruthCopy( pTruthRes, pTruthTemp, pNtk->nVars ); Kit_TruthCopy( pTruthRes, pTruthTemp, pNtk->nVars );
return pTruthRes; return pTruthRes;
@ -550,7 +555,6 @@ unsigned * Kit_DsdTruthComputeNodeOne_rec( Kit_DsdMan_t * p, Kit_DsdNtk_t * pNtk
pTruthPrime = Kit_DsdObjTruth( pObj ); pTruthPrime = Kit_DsdObjTruth( pObj );
// get storage for the temporary minterm // get storage for the temporary minterm
pTruthMint = Vec_PtrEntry(p->vTtNodes, pNtk->nVars + pNtk->nNodes); pTruthMint = Vec_PtrEntry(p->vTtNodes, pNtk->nVars + pNtk->nNodes);
// go through the minterms // go through the minterms
nMints = (1 << pObj->nFans); nMints = (1 << pObj->nFans);
Kit_TruthClear( pTruthRes, pNtk->nVars ); 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_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 ); pTruthTemp = Kit_TruthCompose( p->dd, Kit_DsdObjTruth(pObj), pObj->nFans, pTruthFans, pNtk->nVars, p->vTtBdds, p->vNodes );
Kit_TruthCopy( pTruthRes, pTruthTemp, pNtk->nVars ); Kit_TruthCopy( pTruthRes, pTruthTemp, pNtk->nVars );
return pTruthRes; return pTruthRes;
@ -747,7 +754,6 @@ unsigned * Kit_DsdTruthComputeNodeTwo_rec( Kit_DsdMan_t * p, Kit_DsdNtk_t * pNtk
pTruthPrime = Kit_DsdObjTruth( pObj ); pTruthPrime = Kit_DsdObjTruth( pObj );
// get storage for the temporary minterm // get storage for the temporary minterm
pTruthMint = Vec_PtrEntry(p->vTtNodes, pNtk->nVars + pNtk->nNodes); pTruthMint = Vec_PtrEntry(p->vTtNodes, pNtk->nVars + pNtk->nNodes);
// go through the minterms // go through the minterms
nMints = (1 << pObj->nFans); nMints = (1 << pObj->nFans);
Kit_TruthClear( pTruthRes, pNtk->nVars ); 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_TruthOr( pTruthRes, pTruthRes, pTruthMint, pNtk->nVars );
} }
*/ */
// Kit_DsdObjForEachFanin( pNtk, pObj, iLit, i )
// assert( !Kit_DsdLitIsCompl(iLit) );
Kit_DsdObjForEachFanin( pNtk, pObj, iLit, i ) 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 ); pTruthTemp = Kit_TruthCompose( p->dd, Kit_DsdObjTruth(pObj), pObj->nFans, pTruthFans, pNtk->nVars, p->vTtBdds, p->vNodes );
Kit_TruthCopy( pTruthRes, pTruthTemp, pNtk->nVars ); Kit_TruthCopy( pTruthRes, pTruthTemp, pNtk->nVars );
return pTruthRes; return pTruthRes;
@ -957,7 +966,7 @@ int Kit_DsdCountLuts( Kit_DsdNtk_t * pNtk, int nLutSize )
/**Function************************************************************* /**Function*************************************************************
Synopsis [Counts the number of blocks of the given number of inputs.] Synopsis [Returns the size of the largest non-DSD block.]
Description [] Description []
@ -980,6 +989,34 @@ int Kit_DsdNonDsdSizeMax( Kit_DsdNtk_t * pNtk )
return nSizeMax; 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************************************************************* /**Function*************************************************************
Synopsis [Finds the union of supports of the non-DSD blocks.] 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 ); Kit_TruthChangePhase( pTruthNew, pObjNew->nFans, i );
} }
} }
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 the incoming phase is complemented, absorb it into the prime node
if ( Kit_DsdLitIsCompl(iLit) ) if ( Kit_DsdLitIsCompl(iLit) )
Kit_TruthNot( pTruthNew, pTruthNew, pObj->nFans ); Kit_TruthNot( pTruthNew, pTruthNew, pObj->nFans );
return Kit_DsdVar2Lit( pObjNew->Id, 0 ); return Kit_DsdVar2Lit( pObjNew->Id, 0 );
}
} }
/**Function************************************************************* /**Function*************************************************************
@ -1834,7 +1907,7 @@ void Kit_DsdDecompose_rec( Kit_DsdNtk_t * pNtk, Kit_DsdObj_t * pObj, unsigned uS
return; return;
} }
} }
/*
// if all decomposition methods failed and we are still above the limit, perform MUX-decomposition // if all decomposition methods failed and we are still above the limit, perform MUX-decomposition
if ( nDecMux > 0 && (int)pObj->nFans > nDecMux ) 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 ); assert( pObj->Type == KIT_DSD_PRIME );
pTruth[0] = 0xCACACACA; pTruth[0] = 0xCACACACA;
pObj->nFans = 3; pObj->nFans = 3;
pObj->pFans[2] = pObj->pFans[iBestVar];
pObj->pFans[0] = 2*pRes0->Id; pRes0->nRefs++; pObj->pFans[0] = 2*pRes0->Id; pRes0->nRefs++;
pObj->pFans[1] = 2*pRes1->Id; pRes1->nRefs++; pObj->pFans[1] = 2*pRes1->Id; pRes1->nRefs++;
pObj->pFans[2] = pObj->pFans[iBestVar];
// call recursively // call recursively
Kit_DsdDecompose_rec( pNtk, pRes0, uSupp0, pObj->pFans + 0, nDecMux ); Kit_DsdDecompose_rec( pNtk, pRes0, uSupp0, pObj->pFans + 0, nDecMux );
Kit_DsdDecompose_rec( pNtk, pRes1, uSupp1, pObj->pFans + 1, nDecMux ); Kit_DsdDecompose_rec( pNtk, pRes1, uSupp1, pObj->pFans + 1, nDecMux );
} }
*/
} }
/**Function************************************************************* /**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 * 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 ); return Kit_DsdDecomposeInt( pTruth, nVars, nDecMux );
} }

View File

@ -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 of variables is nVars. The total number of variables in nVarsAll. The last argument
(Phase) contains shows where the variables should go.] (Phase) contains shows where the variables should go.]
SideEffects [] SideEffects [The input truth table is modified.]
SeeAlso [] 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 of variables is nVars. The total number of variables in nVarsAll. The last argument
(Phase) contains shows what variables should remain.] (Phase) contains shows what variables should remain.]
SideEffects [] SideEffects [The input truth table is modified.]
SeeAlso [] SeeAlso []
@ -215,6 +215,43 @@ void Kit_TruthShrink( unsigned * pOut, unsigned * pIn, int nVars, int nVarsAll,
Kit_TruthCopy( pOut, pIn, 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************************************************************* /**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************************************************************* /**Function*************************************************************
Synopsis [Counts the number of 1's in each cofactor.] 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 // collect the minterm counts
Kit_TruthCountOnesInCofs( pIn, nVars, pStore ); Kit_TruthCountOnesInCofs( pIn, nVars, pStore );
// Kit_TruthCountOnesInCofsSlow( pIn, nVars, pStore2, pAux ); /*
// for ( i = 0; i < 2*nVars; i++ ) Kit_TruthCountOnesInCofsSlow( pIn, nVars, pStore2, pAux );
// { for ( i = 0; i < 2*nVars; i++ )
// assert( pStore[i] == pStore2[i] ); {
// } assert( pStore[i] == pStore2[i] );
}
*/
// canonicize phase // canonicize phase
for ( i = 0; i < nVars; i++ ) 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; continue;
uCanonPhase |= (1 << i); uCanonPhase |= (1 << i);
Temp = pStore[2*i+0]; Temp = pStore[2*i+0];
@ -1463,11 +1555,12 @@ unsigned Kit_TruthSemiCanonicize( unsigned * pInOut, unsigned * pAux, int nVars,
// permute // permute
Counter = 0; Counter = 0;
do { do {
fChange = 0; fChange = 0;
for ( i = 0; i < nVars-1; i++ ) for ( i = 0; i < nVars-1; i++ )
{ {
if ( pStore[2*i] >= pStore[2*(i+1)] ) if ( pStore[2*i] <= pStore[2*(i+1)] )
continue; continue;
Counter++; Counter++;
fChange = 1; fChange = 1;
@ -1485,17 +1578,18 @@ unsigned Kit_TruthSemiCanonicize( unsigned * pInOut, unsigned * pAux, int nVars,
pStore[2*(i+1)+1] = Temp; pStore[2*(i+1)+1] = Temp;
// if the polarity of variables is different, swap them // if the polarity of variables is different, swap them
if ( ((uCanonPhase & (1 << i)) > 0) != ((uCanonPhase & (1 << (i+1))) > 0) ) // if ( ((uCanonPhase & (1 << i)) > 0) != ((uCanonPhase & (1 << (i+1))) > 0) )
{ // {
uCanonPhase ^= (1 << i); // uCanonPhase ^= (1 << i);
uCanonPhase ^= (1 << (i+1)); // uCanonPhase ^= (1 << (i+1));
} // }
Kit_TruthSwapAdjacentVars( pOut, pIn, nVars, i ); Kit_TruthSwapAdjacentVars( pOut, pIn, nVars, i );
pTemp = pIn; pIn = pOut; pOut = pTemp; pTemp = pIn; pIn = pOut; pOut = pTemp;
} }
} while ( fChange ); } while ( fChange );
/* /*
Extra_PrintBinary( stdout, &uCanonPhase, nVars+1 ); printf( " : " ); Extra_PrintBinary( stdout, &uCanonPhase, nVars+1 ); printf( " : " );
for ( i = 0; i < nVars; i++ ) for ( i = 0; i < nVars; i++ )

View File

@ -53,6 +53,7 @@ struct Mfx_Par_t_
int fMoreEffort; // performs high-affort minimization int fMoreEffort; // performs high-affort minimization
int fSwapEdge; // performs edge swapping int fSwapEdge; // performs edge swapping
int fDelay; // performs optimization for delay int fDelay; // performs optimization for delay
int fPower; // performs power-aware optimization
int fVerbose; // enable basic stats int fVerbose; // enable basic stats
int fVeryVerbose; // enable detailed stats int fVeryVerbose; // enable detailed stats
}; };

View File

@ -53,6 +53,7 @@ void Mfx_ParsDefault( Mfx_Par_t * pPars )
pPars->fArea = 0; pPars->fArea = 0;
pPars->fMoreEffort = 0; pPars->fMoreEffort = 0;
pPars->fSwapEdge = 0; pPars->fSwapEdge = 0;
pPars->fPower = 0;
pPars->fVerbose = 0; pPars->fVerbose = 0;
pPars->fVeryVerbose = 0; pPars->fVeryVerbose = 0;
} }
@ -105,7 +106,9 @@ clk = clock();
return 1; return 1;
} }
// solve the SAT problem // 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 ); Mfx_EdgeSwapEval( p, pNode );
else else
{ {
@ -132,7 +135,7 @@ int Mfx_Node( Mfx_Man_t * p, Nwk_Obj_t * pNode )
{ {
Hop_Obj_t * pObj; Hop_Obj_t * pObj;
int RetValue; int RetValue;
float dProb;
int nGain, clk; int nGain, clk;
p->nNodesTried++; p->nNodesTried++;
// prepare data structure for this node // prepare data structure for this node
@ -170,7 +173,8 @@ p->timeSat += clock() - clk;
} }
// minimize the local function of the node using bi-decomposition // minimize the local function of the node using bi-decomposition
assert( p->nFanins == Nwk_ObjFaninNum(pNode) ); 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); nGain = Hop_DagSize(pNode->pFunc) - Hop_DagSize(pObj);
if ( nGain >= 0 ) if ( nGain >= 0 )
{ {
@ -182,6 +186,45 @@ p->timeSat += clock() - clk;
return 1; 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************************************************************* /**Function*************************************************************
Synopsis [] 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 ); 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 // compute don't-cares for each node
nNodes = 0; nNodes = 0;
p->nTotalNodesBeg = nTotalNodesBeg; 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) ); pProgress = Bar_ProgressStart( stdout, Nwk_ManNodeNum(pNtk) );
vLevels = Nwk_ManLevelize( pNtk ); vLevels = Nwk_ManLevelize( pNtk );
Vec_VecForEachLevelStart( vLevels, vNodes, k, 1 ) Vec_VecForEachLevelStart( vLevels, vNodes, k, 1 )
{ {
if ( !p->pPars->fVeryVerbose ) 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 ); PRT( "Time", clock() - clk2 );
} }
} }
Bar_ProgressStop( pProgress ); Bar_ProgressStop( pProgress );
Vec_VecFree( vLevels ); 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_ManVerifyLevel( pNtk ) );
assert( Nwk_ManVerifyTiming( pNtk ) ); assert( Nwk_ManVerifyTiming( pNtk ) );
if ( pPars->fPower )
printf( "Total switching after = %7.2f.\n", Nwl_ManComputeTotalSwitching(pNtk) );
// free the manager // free the manager
p->timeTotal = clock() - clk; p->timeTotal = clock() - clk;
Mfx_ManStop( p ); Mfx_ManStop( p );

View File

@ -81,6 +81,8 @@ struct Mfx_Man_t_
Vec_Ptr_t * vFanins; // the new set of fanins Vec_Ptr_t * vFanins; // the new set of fanins
int nTotConfLim; // total conflict limit int nTotConfLim; // total conflict limit
int nTotConfLevel; // total conflicts on this level int nTotConfLevel; // total conflicts on this level
// switching activity
Vec_Int_t * vProbs;
// the result of solving // the result of solving
int nFanins; // the number of fanins int nFanins; // the number of fanins
int nWords; // the number of words 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 ); extern void Mfx_ManClean( Mfx_Man_t * p );
/*=== mfxResub.c ==========================================================*/ /*=== mfxResub.c ==========================================================*/
extern void Mfx_PrintResubStats( Mfx_Man_t * p ); 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_EdgeSwapEval( Mfx_Man_t * p, Nwk_Obj_t * pNode );
extern int Mfx_ResubNode( 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 ); extern int Mfx_ResubNode2( Mfx_Man_t * p, Nwk_Obj_t * pNode );

View File

@ -168,6 +168,8 @@ void Mfx_ManStop( Mfx_Man_t * p )
Aig_ManStop( p->pCare ); Aig_ManStop( p->pCare );
if ( p->vSuppsInv ) if ( p->vSuppsInv )
Vec_VecFree( (Vec_Vec_t *)p->vSuppsInv ); Vec_VecFree( (Vec_Vec_t *)p->vSuppsInv );
if ( p->vProbs )
Vec_IntFree( p->vProbs );
Mfx_ManClean( p ); Mfx_ManClean( p );
Int_ManFree( p->pMan ); Int_ManFree( p->pMan );
Vec_IntFree( p->vMem ); Vec_IntFree( p->vMem );

View File

@ -206,6 +206,8 @@ p->timeInt += clock() - clk;
iVar = -1; iVar = -1;
while ( 1 ) while ( 1 )
{ {
float * pProbab = (float *)(p->vProbs? p->vProbs->pArray : NULL);
assert( (pProbab != NULL) == p->pPars->fPower );
if ( fVeryVerbose ) if ( fVeryVerbose )
{ {
printf( "%3d: %2d ", p->nCexes, iVar ); printf( "%3d: %2d ", p->nCexes, iVar );
@ -222,6 +224,13 @@ p->timeInt += clock() - clk;
assert( nWords <= p->nDivWords ); assert( nWords <= p->nDivWords );
for ( iVar = 0; iVar < Vec_PtrSize(p->vDivs)-Nwk_ObjFaninNum(pNode); iVar++ ) 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 ); pData = Vec_PtrEntry( p->vDivCexes, iVar );
for ( w = 0; w < nWords; w++ ) for ( w = 0; w < nWords; w++ )
if ( pData[w] != ~0 ) if ( pData[w] != ~0 )
@ -429,6 +438,33 @@ int Mfx_EdgeSwapEval( Mfx_Man_t * p, Nwk_Obj_t * pNode )
return 0; 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************************************************************* /**Function*************************************************************
Synopsis [Performs resubstitution for the node.] Synopsis [Performs resubstitution for the node.]

View File

@ -79,6 +79,10 @@ struct Ntl_Man_t_
Aig_Man_t * pAig; // the extracted AIG Aig_Man_t * pAig; // the extracted AIG
Tim_Man_t * pManTime; // the timing manager Tim_Man_t * pManTime; // the timing manager
int iLastCi; // the last true CI 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 // hashing names into models
Ntl_Mod_t ** pModTable; // the hash table of names into models Ntl_Mod_t ** pModTable; // the hash table of names into models
int nModTableSize; // the allocated table size 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 * vObjs; // the array of all objects
Vec_Ptr_t * vPis; // the array of PI objects Vec_Ptr_t * vPis; // the array of PI objects
Vec_Ptr_t * vPos; // the array of PO 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 int nObjs[NTL_OBJ_VOID]; // counter of objects of each type
// box attributes // box attributes
unsigned int attrWhite :1; // box has known logic 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 Ntl_Net_t ** pTable; // the hash table of names into nets
int nTableSize; // the allocated table size int nTableSize; // the allocated table size
int nEntries; // the number of entries in the hash table 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 // delay information
Vec_Int_t * vDelays; Vec_Int_t * vDelays;
Vec_Int_t * vTimeInputs; Vec_Int_t * vTimeInputs;
@ -154,6 +162,7 @@ struct Ntl_Net_t_
int iTemp; // other data int iTemp; // other data
}; };
Ntl_Obj_t * pDriver; // driver of the net 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 nVisits; // the number of times the net is visited
char fMark; // temporary mark char fMark; // temporary mark
char pName[0]; // the name of this net char pName[0]; // the name of this net
@ -175,15 +184,16 @@ struct Ntl_Lut_t_
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/// INLINED FUNCTIONS /// /// INLINED FUNCTIONS ///
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
#ifdef WIN32 #ifdef WIN32
#define DLLEXPORT __declspec(dllexport) #define ABC_DLLEXPORT __declspec(dllexport)
#define DLLIMPORT __declspec(dllimport) #define ABC_DLLIMPORT __declspec(dllimport)
#else /* defined(WIN32) */ #else /* defined(WIN32) */
#define DLLIMPORT #define ABC_DLLIMPORT
#endif /* defined(WIN32) */ #endif /* defined(WIN32) */
#ifndef ABC_DLL #ifndef ABC_DLL
#define ABC_DLL DLLIMPORT #define ABC_DLL ABC_DLLIMPORT
#endif #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 ); }
@ -197,6 +207,8 @@ static inline int Ntl_ModelBoxNum( Ntl_Mod_t * p ) { return p->nO
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_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_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_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; } 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 ) \ #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++ ) 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 ) \ #define Ntl_ModelForEachNet( pNwk, pNet, i ) \
for ( i = 0; i < pNwk->nTableSize; i++ ) \ Vec_PtrForEachEntry( pNwk->vNets, pNet, i ) \
for ( pNet = pNwk->pTable[i]; pNet; pNet = pNet->pNext ) if ( pNet == NULL ) {} else
#define Ntl_ModelForEachObj( pNwk, pObj, i ) \ #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++ ) \ for ( i = 0; (i < Vec_PtrSize(pNwk->vObjs)) && (((pObj) = (Ntl_Obj_t*)Vec_PtrEntry(pNwk->vObjs, i)), 1); i++ ) \
if ( pObj == NULL ) {} else 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_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 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_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_ModelCountNets( Ntl_Mod_t * p );
extern ABC_DLL int Ntl_ManAddModel( Ntl_Man_t * p, Ntl_Mod_t * pModel ); 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 ); extern ABC_DLL Ntl_Mod_t * Ntl_ManFindModel( Ntl_Man_t * p, const char * pName );

View File

@ -206,11 +206,13 @@ checkobjs:
printf( "Net in bin %d does not have a name\n", i ); printf( "Net in bin %d does not have a name\n", i );
fStatus = 0; fStatus = 0;
} }
/*
if ( pNet->pDriver == NULL ) if ( pNet->pDriver == NULL )
{ {
printf( "Net %s does not have a driver\n", pNet->pName ); printf( "Net %s does not have a driver\n", pNet->pName );
fStatus = 0; fStatus = 0;
} }
*/
} }
// check objects // check objects

View File

@ -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 ) 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_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 ); 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; Aig_Man_t * pTemp;
// perform synthesis // perform synthesis
//printf( "Pre-synthesis AIG: " ); //printf( "Pre-synthesis AIG: " );
//Aig_ManPrintStats( pAig ); //Aig_ManPrintStats( pAig );
// pTemp = Dar_ManBalance( pAig, 1 ); // 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 ); pTemp = Dar_ManChoice( pAig, fBalance, fUpdateLevel, fConstruct, nConfMax, nLevelMax, fVerbose );
//printf( "Post-synthesis AIG: " ); //printf( "Post-synthesis AIG: " );
//Aig_ManPrintStats( pTemp ); //Aig_ManPrintStats( pTemp );

View File

@ -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->pCopy = Aig_Not(pNet->pCopy);
pNet->nVisits = 2; pNet->nVisits = 2;
// remember the class of this register // 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 // compute AIG for the internal nodes
Ntl_ModelForEachPo( pModel, pObj, i ) Ntl_ModelForEachPo( pModel, pObj, i )

View File

@ -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 ) void Ntl_ManReduce( Ntl_Man_t * p, Aig_Man_t * pAig )
{ {
Aig_Obj_t * pObj, * pObjRepr; Aig_Obj_t * pObj, * pObjRepr;
Ntl_Net_t * pNet, * pNetRepr; Ntl_Net_t * pNet, * pNetRepr, * pNetNew;
Ntl_Mod_t * pRoot; Ntl_Mod_t * pRoot;
Ntl_Obj_t * pNode; Ntl_Obj_t * pNode, * pNodeOld;
int i, fCompl, Counter = 0; int i, fCompl, Counter = 0;
assert( pAig->pReprs ); assert( pAig->pReprs );
pRoot = Ntl_ManRootModel( p ); 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" ); pNode->pSop = fCompl? Ntl_ManStoreSop( p->pMemSops, "0 1\n" ) : Ntl_ManStoreSop( p->pMemSops, "1 1\n" );
Ntl_ObjSetFanin( pNode, pNetRepr, 0 ); Ntl_ObjSetFanin( pNode, pNetRepr, 0 );
// make the new node drive the equivalent net (pNet) // make the new node drive the equivalent net (pNet)
pNodeOld = pNet->pDriver;
if ( !Ntl_ModelClearNetDriver( pNet->pDriver, pNet ) ) if ( !Ntl_ModelClearNetDriver( pNet->pDriver, pNet ) )
printf( "Ntl_ManReduce(): Internal error! Net already has no driver.\n" ); printf( "Ntl_ManReduce(): Internal error! Net already has no driver.\n" );
if ( !Ntl_ModelSetNetDriver( pNode, pNet ) ) if ( !Ntl_ModelSetNetDriver( pNode, pNet ) )
printf( "Ntl_ManReduce(): Internal error! Net already has a driver.\n" ); 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++; Counter++;
} }
} }
@ -372,6 +385,11 @@ Ntl_Man_t * Ntl_ManFraig( Ntl_Man_t * p, int nPartSize, int nConfLimit, int nLev
pAig = Ntl_ManExtract( p ); pAig = Ntl_ManExtract( p );
pNew = Ntl_ManInsertAig( p, pAig ); pNew = Ntl_ManInsertAig( p, pAig );
pAigCol = Ntl_ManCollapseComb( pNew ); pAigCol = Ntl_ManCollapseComb( pNew );
if ( pAigCol == NULL )
{
Aig_ManStop( pAig );
return pNew;
}
// perform fraiging for the given design // perform fraiging for the given design
nPartSize = nPartSize? nPartSize : Aig_ManPoNum(pAigCol); 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 ); pAig = Ntl_ManExtract( p );
pNew = Ntl_ManInsertAig( p, pAig ); pNew = Ntl_ManInsertAig( p, pAig );
pAigCol = Ntl_ManCollapseSeq( pNew, 0 ); pAigCol = Ntl_ManCollapseSeq( pNew, 0 );
//Saig_ManDumpBlif( pAigCol, "1s.blif" ); if ( pAigCol == NULL )
{
Aig_ManStop( pAig );
return pNew;
}
// perform SCL for the given design // perform SCL for the given design
pTemp = Aig_ManScl( pAigCol, fLatchConst, fLatchEqual, fVerbose ); pTemp = Aig_ManScl( pAigCol, fLatchConst, fLatchEqual, fVerbose );
Aig_ManStop( pTemp ); Aig_ManStop( pTemp );
if ( pNew->vRegClasses && Vec_IntSize(pNew->vRegClasses) && pAigCol->pReprs )
Ntl_ManFilterRegisterClasses( pAigCol, pNew->vRegClasses, fVerbose );
// finalize the transformation // finalize the transformation
pNew = Ntl_ManFinalize( pAux = pNew, pAig, pAigCol, fVerbose ); 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 ) Ntl_Man_t * Ntl_ManLcorr( Ntl_Man_t * p, int nConfMax, int fVerbose )
{ {
Ssw_Pars_t Pars, * pPars = &Pars;
Ntl_Man_t * pNew, * pAux; Ntl_Man_t * pNew, * pAux;
Aig_Man_t * pAig, * pAigCol, * pTemp; Aig_Man_t * pAig, * pAigCol, * pTemp;
Ssw_Pars_t Pars, * pPars = &Pars;
Ssw_ManSetDefaultParamsLcorr( pPars );
pPars->nBTLimit = nConfMax;
pPars->fVerbose = fVerbose;
// collapse the AIG // collapse the AIG
pAig = Ntl_ManExtract( p ); pAig = Ntl_ManExtract( p );
pNew = Ntl_ManInsertAig( p, pAig ); 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 // perform LCORR for the given design
// pTemp = Fra_FraigLatchCorrespondence( pAigCol, 0, nConfMax, 0, fVerbose, NULL, 0 );
Ssw_ManSetDefaultParamsLcorr( pPars );
pPars->nBTLimit = nConfMax;
pPars->fVerbose = fVerbose;
pTemp = Ssw_LatchCorrespondence( pAigCol, pPars ); pTemp = Ssw_LatchCorrespondence( pAigCol, pPars );
Aig_ManStop( pTemp ); Aig_ManStop( pTemp );
if ( p->vRegClasses && Vec_IntSize(p->vRegClasses) && pAigCol->pReprs )
Ntl_ManFilterRegisterClasses( pAigCol, p->vRegClasses, fVerbose );
// finalize the transformation // finalize the transformation
pNew = Ntl_ManFinalize( pAux = pNew, pAig, pAigCol, fVerbose ); pNew = Ntl_ManFinalize( pAux = pNew, pAig, pAigCol, fVerbose );

View File

@ -42,7 +42,7 @@
***********************************************************************/ ***********************************************************************/
Ntl_Man_t * Ntl_ManInsertMapping( Ntl_Man_t * p, Vec_Ptr_t * vMapping, Aig_Man_t * pAig ) 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_Ptr_t * vCopies;
Vec_Int_t * vCover; Vec_Int_t * vCover;
Ntl_Mod_t * pRoot; 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 ) Ntl_Man_t * Ntl_ManInsertAig( Ntl_Man_t * p, Aig_Man_t * pAig )
{ {
char Buffer[100]; char Buffer[1000];
Ntl_Mod_t * pRoot; Ntl_Mod_t * pRoot;
Ntl_Obj_t * pNode; Ntl_Obj_t * pNode;
Ntl_Net_t * pNet, * pNetCo; Ntl_Net_t * pNet, * pNetCo;
@ -243,7 +243,6 @@ Ntl_Man_t * Ntl_ManInsertAig( Ntl_Man_t * p, Aig_Man_t * pAig )
return p; return p;
} }
/**Function************************************************************* /**Function*************************************************************
Synopsis [Inserts the given mapping into the netlist.] 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 ) Ntl_Man_t * Ntl_ManInsertNtk( Ntl_Man_t * p, Nwk_Man_t * pNtk )
{ {
char Buffer[100]; char Buffer[1000];
Vec_Ptr_t * vObjs; Vec_Ptr_t * vObjs;
Vec_Int_t * vTruth; Vec_Int_t * vTruth;
Vec_Int_t * vCover; Vec_Int_t * vCover;
@ -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 ); pTruth = Hop_ManConvertAigToTruth( pNtk->pManHop, Hop_Regular(pObj->pFunc), Nwk_ObjFaninNum(pObj), vTruth, 0 );
if ( Hop_IsComplement(pObj->pFunc) ) if ( Hop_IsComplement(pObj->pFunc) )
Kit_TruthNot( pTruth, pTruth, Nwk_ObjFaninNum(pObj) ); 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)) ) if ( !Kit_TruthIsConst0(pTruth, Nwk_ObjFaninNum(pObj)) && !Kit_TruthIsConst1(pTruth, Nwk_ObjFaninNum(pObj)) )
{ {
Nwk_ObjForEachFanin( pObj, pFanin, k ) 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 ); Ntl_ObjSetFanin( pNode, pNet, k );
} }
} }
else else if ( Kit_TruthIsConst0(pTruth, Nwk_ObjFaninNum(pObj)) )
{
pObj->pFunc = Hop_ManConst0(pNtk->pManHop);
pNode->nFanins = 0; 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 ); sprintf( Buffer, "lut%0*d", nDigits, i );
if ( (pNet = Ntl_ModelFindNet( pRoot, Buffer )) ) 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 // get the corresponding PO and its driver
pObj = Nwk_ManCo( pNtk, i ); pObj = Nwk_ManCo( pNtk, i );
pFanin = Nwk_ObjFanin0( pObj ); pFanin = Nwk_ObjFanin0( pObj );
// get the net driving the driver // get the net driving this PO
pNet = pFanin->pCopy; 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 = Ntl_ModelCreateNode( pRoot, 1 );
pNode->pSop = pObj->fInvert? Ntl_ManStoreSop( p->pMemSops, "0 1\n" ) : Ntl_ManStoreSop( p->pMemSops, "1 1\n" ); pNode->pSop = pObj->fInvert? Ntl_ManStoreSop( p->pMemSops, "0 1\n" ) : Ntl_ManStoreSop( p->pMemSops, "1 1\n" );
Ntl_ObjSetFanin( pNode, pNet, 0 ); Ntl_ObjSetFanin( pNode, pNet, 0 );
}
// update the CO driver net // update the CO driver net
assert( pNetCo->pDriver == NULL ); assert( pNetCo->pDriver == NULL );
if ( !Ntl_ModelSetNetDriver( pNode, pNetCo ) ) if ( !Ntl_ModelSetNetDriver( pNode, pNetCo ) )

View File

@ -108,6 +108,7 @@ Ntl_Man_t * Ntl_ManStartFrom( Ntl_Man_t * pOld )
pNew->pName = Ntl_ManStoreFileName( pNew, pOld->pName ); pNew->pName = Ntl_ManStoreFileName( pNew, pOld->pName );
pNew->pSpec = Ntl_ManStoreName( pNew, pOld->pName ); pNew->pSpec = Ntl_ManStoreName( pNew, pOld->pName );
Vec_PtrForEachEntry( pOld->vModels, pModel, i ) Vec_PtrForEachEntry( pOld->vModels, pModel, i )
{
if ( i == 0 ) if ( i == 0 )
{ {
Ntl_ManMarkCiCoNets( pOld ); Ntl_ManMarkCiCoNets( pOld );
@ -116,15 +117,21 @@ Ntl_Man_t * Ntl_ManStartFrom( Ntl_Man_t * pOld )
} }
else else
pModel->pCopy = Ntl_ModelDup( pNew, pModel ); pModel->pCopy = Ntl_ModelDup( pNew, pModel );
}
Vec_PtrForEachEntry( pOld->vModels, pModel, i ) Vec_PtrForEachEntry( pOld->vModels, pModel, i )
Ntl_ModelForEachBox( pModel, pBox, k ) Ntl_ModelForEachBox( pModel, pBox, k )
{
((Ntl_Obj_t *)pBox->pCopy)->pImplem = pBox->pImplem->pCopy; ((Ntl_Obj_t *)pBox->pCopy)->pImplem = pBox->pImplem->pCopy;
((Ntl_Obj_t *)pBox->pCopy)->iTemp = pBox->iTemp;
}
Ntl_ManForEachCiNet( pOld, pNet, i ) Ntl_ManForEachCiNet( pOld, pNet, i )
Vec_PtrPush( pNew->vCis, pNet->pCopy ); Vec_PtrPush( pNew->vCis, pNet->pCopy );
Ntl_ManForEachCoNet( pOld, pNet, i ) Ntl_ManForEachCoNet( pOld, pNet, i )
Vec_PtrPush( pNew->vCos, pNet->pCopy ); Vec_PtrPush( pNew->vCos, pNet->pCopy );
if ( pOld->pManTime ) if ( pOld->pManTime )
pNew->pManTime = Tim_ManDup( pOld->pManTime, 0 ); pNew->pManTime = Tim_ManDup( pOld->pManTime, 0 );
if ( pOld->pNal )
pOld->pNalD( pOld, pNew );
return pNew; return pNew;
} }
@ -195,13 +202,14 @@ void Ntl_ManFree( Ntl_Man_t * p )
if ( p->pMemSops ) Aig_MmFlexStop( p->pMemSops, 0 ); if ( p->pMemSops ) Aig_MmFlexStop( p->pMemSops, 0 );
if ( p->pAig ) Aig_ManStop( p->pAig ); if ( p->pAig ) Aig_ManStop( p->pAig );
if ( p->pManTime ) Tim_ManStop( p->pManTime ); if ( p->pManTime ) Tim_ManStop( p->pManTime );
if ( p->pNal ) p->pNalF( p->pNal );
FREE( p->pModTable ); FREE( p->pModTable );
free( p ); free( p );
} }
/**Function************************************************************* /**Function*************************************************************
Synopsis [Deallocates the netlist manager.] Synopsis []
Description [] Description []
@ -219,6 +227,7 @@ void Ntl_ManPrintStats( Ntl_Man_t * p )
printf( "po = %5d ", Ntl_ModelPoNum(pRoot) ); printf( "po = %5d ", Ntl_ModelPoNum(pRoot) );
printf( "lat = %5d ", Ntl_ModelLatchNum(pRoot) ); printf( "lat = %5d ", Ntl_ModelLatchNum(pRoot) );
printf( "node = %5d ", Ntl_ModelNodeNum(pRoot) ); printf( "node = %5d ", Ntl_ModelNodeNum(pRoot) );
printf( "\n " );
printf( "inv/buf = %5d ", Ntl_ModelLut1Num(pRoot) ); printf( "inv/buf = %5d ", Ntl_ModelLut1Num(pRoot) );
printf( "box = %4d ", Ntl_ModelBoxNum(pRoot) ); printf( "box = %4d ", Ntl_ModelBoxNum(pRoot) );
printf( "mod = %3d ", Vec_PtrSize(p->vModels) ); printf( "mod = %3d ", Vec_PtrSize(p->vModels) );
@ -230,6 +239,50 @@ void Ntl_ManPrintStats( Ntl_Man_t * p )
fflush( stdout ); 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************************************************************* /**Function*************************************************************
Synopsis [Deallocates the netlist manager.] Synopsis [Deallocates the netlist manager.]
@ -283,6 +336,8 @@ void Ntl_ManSaveBoxType( Ntl_Obj_t * pObj )
***********************************************************************/ ***********************************************************************/
void Ntl_ManPrintTypes( Ntl_Man_t * p ) void Ntl_ManPrintTypes( Ntl_Man_t * p )
{ {
Vec_Ptr_t * vFlops;
Ntl_Net_t * pNet;
Ntl_Mod_t * pModel; Ntl_Mod_t * pModel;
Ntl_Obj_t * pObj; Ntl_Obj_t * pObj;
int i; int i;
@ -296,7 +351,7 @@ void Ntl_ManPrintTypes( Ntl_Man_t * p )
{ {
if ( !p->BoxTypes[i] ) if ( !p->BoxTypes[i] )
continue; 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 & 1) > 0)? "white ": "black " );
printf( " %s", ((i & 2) > 0)? "box ": "logic " ); printf( " %s", ((i & 2) > 0)? "box ": "logic " );
printf( " %s", ((i & 4) > 0)? "comb ": "seq " ); 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( " %s", ((i & 16) > 0)? "no_merge": "merge " );
printf( "\n" ); 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++ ) for ( i = 0; i < 32; i++ )
p->BoxTypes[i] = 0; 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************************************************************* /**Function*************************************************************
@ -336,6 +404,7 @@ Ntl_Mod_t * Ntl_ModelAlloc( Ntl_Man_t * pMan, char * pName )
p->vObjs = Vec_PtrAlloc( 100 ); p->vObjs = Vec_PtrAlloc( 100 );
p->vPis = Vec_PtrAlloc( 10 ); p->vPis = Vec_PtrAlloc( 10 );
p->vPos = Vec_PtrAlloc( 10 ); p->vPos = Vec_PtrAlloc( 10 );
p->vNets = Vec_PtrAlloc( 100 );
// start the table // start the table
p->nTableSize = Aig_PrimeCudd( 100 ); p->nTableSize = Aig_PrimeCudd( 100 );
p->pTable = ALLOC( Ntl_Net_t *, p->nTableSize ); 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 ) 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 ); pNet->pCopy = Ntl_ModelFindOrCreateNet( pModelNew, pNet->pName );
((Ntl_Net_t *)pNet->pCopy)->pDriver = pNet->pDriver->pCopy; ((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->vTimeOutputs ) Vec_IntFree( p->vTimeOutputs );
if ( p->vTimeInputs ) Vec_IntFree( p->vTimeInputs ); if ( p->vTimeInputs ) Vec_IntFree( p->vTimeInputs );
if ( p->vDelays ) Vec_IntFree( p->vDelays ); 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->vObjs );
Vec_PtrFree( p->vPis ); Vec_PtrFree( p->vPis );
Vec_PtrFree( p->vPos ); Vec_PtrFree( p->vPos );

View File

@ -1322,6 +1322,7 @@ static char * Ioa_ReadParseTableBlif( Ioa_ReadMod_t * p, char * pTable, int nFan
char * pProduct, * pOutput; char * pProduct, * pOutput;
int i, Polarity = -1; int i, Polarity = -1;
p->pMan->nTablesRead++; p->pMan->nTablesRead++;
// get the tokens // get the tokens
Ioa_ReadSplitIntoTokens( vTokens, pTable, '.' ); 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 ) if ( Vec_PtrSize(vTokens) == 1 )
{ {
pOutput = Vec_PtrEntry( vTokens, 0 ); pOutput = Vec_PtrEntry( vTokens, 0 );
if ( *pOutput == '\"' )
return Ntl_ManStoreSop( p->pMan->pDesign->pMemSops, pOutput );
if ( ((pOutput[0] - '0') & 0x8E) || pOutput[1] ) 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 ); sprintf( p->pMan->sError, "Line %d: Constant table has wrong output value \"%s\".", Ioa_ReadGetLine(p->pMan, pOutput), pOutput );

View File

@ -139,8 +139,11 @@ int Ntl_ManSweep( Ntl_Man_t * p, int fVerbose )
} }
// remove the fanout nets // remove the fanout nets
Ntl_ObjForEachFanout( pObj, pNet, k ) Ntl_ObjForEachFanout( pObj, pNet, k )
if ( pNet != NULL ) if ( pNet != NULL && pNet->pName[0] != 0 )
{
Ntl_ModelDeleteNet( pRoot, pNet ); Ntl_ModelDeleteNet( pRoot, pNet );
Vec_PtrWriteEntry( pRoot->vNets, pNet->NetId, NULL );
}
// remove the object // remove the object
if ( Ntl_ObjIsNode(pObj) && Ntl_ObjFaninNum(pObj) == 1 ) if ( Ntl_ObjIsNode(pObj) && Ntl_ObjFaninNum(pObj) == 1 )
pRoot->nObjs[NTL_OBJ_LUT1]--; pRoot->nObjs[NTL_OBJ_LUT1]--;
@ -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 ) ) if ( !Ntl_ManCheck( p ) )

View File

@ -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 ); pNet = (Ntl_Net_t *)Aig_MmFlexEntryFetch( p->pMan->pMemObjs, sizeof(Ntl_Net_t) + strlen(pName) + 1 );
memset( pNet, 0, sizeof(Ntl_Net_t) ); memset( pNet, 0, sizeof(Ntl_Net_t) );
strcpy( pNet->pName, pName ); strcpy( pNet->pName, pName );
pNet->NetId = Vec_PtrSize( p->vNets );
Vec_PtrPush( p->vNets, pNet );
return pNet; return pNet;
} }
@ -104,7 +106,7 @@ clk = clock();
/**Function************************************************************* /**Function*************************************************************
Synopsis [Finds or creates the net.] Synopsis [Finds net.]
Description [] Description []
@ -125,7 +127,7 @@ Ntl_Net_t * Ntl_ModelFindNet( Ntl_Mod_t * p, const char * pName )
/**Function************************************************************* /**Function*************************************************************
Synopsis [Finds or creates the net.] Synopsis [Deletes net from the hash table.]
Description [] Description []
@ -150,6 +152,26 @@ void Ntl_ModelDeleteNet( Ntl_Mod_t * p, Ntl_Net_t * pNet )
p->pTable[Key] = pEnt->pNext; p->pTable[Key] = pEnt->pNext;
else else
pPrev->pNext = pEnt->pNext; 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************************************************************* /**Function*************************************************************
@ -178,6 +200,17 @@ Ntl_Net_t * Ntl_ModelFindOrCreateNet( Ntl_Mod_t * p, const char * pName )
return pEnt; 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 * Ntl_ModelDontFindCreateNet( Ntl_Mod_t * p, const char * pName )
{ {
Ntl_Net_t * pEnt; Ntl_Net_t * pEnt;

View File

@ -424,7 +424,7 @@ Vec_Vec_t * Ntl_ManTransformRegClasses( Ntl_Man_t * pMan, int nSizeMax, int fVer
vParts = Vec_PtrAlloc( 100 ); vParts = Vec_PtrAlloc( 100 );
for ( i = 0; i <= ClassMax; i++ ) for ( i = 0; i <= ClassMax; i++ )
{ {
if ( pClassNums[i] < nSizeMax ) if ( pClassNums[i] == 0 || pClassNums[i] < nSizeMax )
continue; continue;
vPart = Vec_IntAlloc( pClassNums[i] ); vPart = Vec_IntAlloc( pClassNums[i] );
Vec_IntForEachEntry( pMan->vRegClasses, Class, k ) Vec_IntForEachEntry( pMan->vRegClasses, Class, k )

View File

@ -140,6 +140,8 @@ void Ioa_WriteBlifModel( FILE * pFile, Ntl_Mod_t * pModel, int fMain )
fprintf( pFile, " %s", pNet->pName ); fprintf( pFile, " %s", pNet->pName );
fprintf( pFile, " %s\n", Ntl_ObjFanout0(pObj)->pName ); fprintf( pFile, " %s\n", Ntl_ObjFanout0(pObj)->pName );
fprintf( pFile, "%s", pObj->pSop ); fprintf( pFile, "%s", pObj->pSop );
if ( *pObj->pSop == '\"' )
fprintf( pFile, "\n" );
} }
else if ( Ntl_ObjIsLatch(pObj) ) 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", pNet->pName );
gzprintf( pFile, " %s\n", Ntl_ObjFanout0(pObj)->pName ); gzprintf( pFile, " %s\n", Ntl_ObjFanout0(pObj)->pName );
gzprintf( pFile, "%s", pObj->pSop ); gzprintf( pFile, "%s", pObj->pSop );
if ( *pObj->pSop == '\"' )
gzprintf( pFile, "\n" );
} }
else if ( Ntl_ObjIsLatch(pObj) ) 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", pNet->pName );
fprintfBz2( b, " %s\n", Ntl_ObjFanout0(pObj)->pName ); fprintfBz2( b, " %s\n", Ntl_ObjFanout0(pObj)->pName );
fprintfBz2( b, "%s", pObj->pSop ); fprintfBz2( b, "%s", pObj->pSop );
if ( *pObj->pSop == '\"' )
fprintfBz2( b, "\n" );
} }
else if ( Ntl_ObjIsLatch(pObj) ) else if ( Ntl_ObjIsLatch(pObj) )
{ {
@ -625,7 +631,11 @@ void Ioa_WriteBlif( Ntl_Man_t * p, char * pFileName )
Ntl_Mod_t * pModel; Ntl_Mod_t * pModel;
int i, bzError; int i, bzError;
bz2file b; bz2file b;
if ( p->pNal )
{
p->pNalW( p, pFileName );
return;
}
// write the GZ file // write the GZ file
if (!strncmp(pFileName+strlen(pFileName)-3,".gz",3)) if (!strncmp(pFileName+strlen(pFileName)-3,".gz",3))
{ {

View File

@ -123,14 +123,14 @@ struct Nwk_Obj_t_
//#pragma warning( disable : 4273 ) //#pragma warning( disable : 4273 )
#ifdef WIN32 #ifdef WIN32
#define DLLEXPORT __declspec(dllexport) #define ABC_DLLEXPORT __declspec(dllexport)
#define DLLIMPORT __declspec(dllimport) #define ABC_DLLIMPORT __declspec(dllimport)
#else /* defined(WIN32) */ #else /* defined(WIN32) */
#define DLLIMPORT #define ABC_DLLIMPORT
#endif /* defined(WIN32) */ #endif /* defined(WIN32) */
#ifndef ABC_DLL #ifndef ABC_DLL
#define ABC_DLL DLLIMPORT #define ABC_DLL ABC_DLLIMPORT
#endif #endif
static inline int Nwk_ManCiNum( Nwk_Man_t * p ) { return p->nObjs[NWK_OBJ_CI]; } 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 ); extern ABC_DLL Vec_Ptr_t * Nwk_ManDeriveRetimingCut( Aig_Man_t * p, int fForward, int fVerbose );
/*=== nwkBidec.c ==========================================================*/ /*=== nwkBidec.c ==========================================================*/
extern ABC_DLL void Nwk_ManBidecResyn( Nwk_Man_t * pNtk, int fVerbose ); 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 ==========================================================*/ /*=== nwkCheck.c ==========================================================*/
extern ABC_DLL int Nwk_ManCheck( Nwk_Man_t * p ); extern ABC_DLL int Nwk_ManCheck( Nwk_Man_t * p );
/*=== nwkDfs.c ==========================================================*/ /*=== nwkDfs.c ==========================================================*/
@ -265,7 +265,8 @@ extern ABC_DLL Vec_Ptr_t * Nwk_ManRetimeCutBackward( Nwk_Man_t * pMan, int n
/*=== nwkMan.c ============================================================*/ /*=== nwkMan.c ============================================================*/
extern ABC_DLL Nwk_Man_t * Nwk_ManAlloc(); extern ABC_DLL Nwk_Man_t * Nwk_ManAlloc();
extern ABC_DLL void Nwk_ManFree( Nwk_Man_t * p ); 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 ============================================================*/ /*=== nwkMap.c ============================================================*/
extern ABC_DLL Nwk_Man_t * Nwk_MappingIf( Aig_Man_t * p, Tim_Man_t * pManTime, If_Par_t * pPars ); extern ABC_DLL Nwk_Man_t * Nwk_MappingIf( Aig_Man_t * p, Tim_Man_t * pManTime, If_Par_t * pPars );
/*=== nwkObj.c ============================================================*/ /*=== nwkObj.c ============================================================*/

View File

@ -24,6 +24,26 @@
/// DECLARATIONS /// /// 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) ); } 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 [] 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; unsigned * pTruth;
Bdc_Fun_t * pFunc; 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) ) if ( Hop_IsComplement(pRoot) )
for ( i = Aig_TruthWordNum(nVars)-1; i >= 0; i-- ) for ( i = Aig_TruthWordNum(nVars)-1; i >= 0; i-- )
pTruth[i] = ~pTruth[i]; pTruth[i] = ~pTruth[i];
// 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 // decompose truth table
Bdc_ManDecompose( p, pTruth, puCare, nVars, NULL, 1000 ); Bdc_ManDecompose( p, pTruth, puCare, nVars, NULL, 1000 );
}
}
else
{
// decompose truth table
Bdc_ManDecompose( p, pTruth, puCare, nVars, NULL, 1000 );
}
// convert back into HOP // convert back into HOP
Bdc_FuncSetCopy( Bdc_ManFunc( p, 0 ), Hop_ManConst1( pHop ) ); Bdc_FuncSetCopy( Bdc_ManFunc( p, 0 ), Hop_ManConst1( pHop ) );
for ( i = 0; i < nVars; i++ ) for ( i = 0; i < nVars; i++ )
@ -106,7 +151,7 @@ void Nwk_ManBidecResyn( Nwk_Man_t * pNtk, int fVerbose )
if ( Nwk_ObjFaninNum(pObj) > 15 ) if ( Nwk_ObjFaninNum(pObj) > 15 )
continue; continue;
nNodes1 = Hop_DagSize(pObj->pFunc); 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); nNodes2 = Hop_DagSize(pObj->pFunc);
nGainTotal += nNodes1 - nNodes2; nGainTotal += nNodes1 - nNodes2;
} }

View File

@ -181,6 +181,42 @@ char * Nwk_FileNameGeneric( char * FileName )
return pRes; 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************************************************************* /**Function*************************************************************
Synopsis [Prints stats of the manager.] Synopsis [Prints stats of the manager.]
@ -192,7 +228,7 @@ char * Nwk_FileNameGeneric( char * FileName )
SeeAlso [] 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 int Ntl_ManLatchNum( void * p );
extern void Ioa_WriteBlifLogic( Nwk_Man_t * pNtk, void * pNtl, char * pFileName ); extern void Ioa_WriteBlifLogic( Nwk_Man_t * pNtk, void * pNtl, char * pFileName );
@ -222,6 +258,8 @@ void Nwk_ManPrintStats( Nwk_Man_t * pNtk, If_Lib_t * pLutLib, int fSaveBest, int
printf( "lev = %3d ", Nwk_ManLevel(pNtk) ); printf( "lev = %3d ", Nwk_ManLevel(pNtk) );
// printf( "lev2 = %3d ", Nwk_ManLevelBackup(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 ); Nwk_ManPrintLutSizes( pNtk, pLutLib );
printf( "\n" ); printf( "\n" );
// Nwk_ManDelayTracePrint( pNtk, pLutLib ); // Nwk_ManDelayTracePrint( pNtk, pLutLib );

View File

@ -59,6 +59,7 @@ void Nwk_ManSetIfParsDefault( If_Par_t * pPars )
pPars->fExpRed = 1; //// pPars->fExpRed = 1; ////
pPars->fLatchPaths = 0; pPars->fLatchPaths = 0;
pPars->fEdge = 1; pPars->fEdge = 1;
pPars->fPower = 0;
pPars->fCutMin = 0; pPars->fCutMin = 0;
pPars->fSeqMap = 0; pPars->fSeqMap = 0;
pPars->fVerbose = 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 ) 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_Man_t * pIfMan;
If_Obj_t * pIfObj; If_Obj_t * pIfObj;
Aig_Obj_t * pNode, * pFanin, * pPrev; 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 // start the mapping manager and set its parameters
pIfMan = If_ManStart( pPars ); pIfMan = If_ManStart( pPars );
pIfMan->vSwitching = vSwitching2;
// load the AIG into the mapper // load the AIG into the mapper
Aig_ManForEachObj( p, pNode, i ) 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 ); pIfObj = If_ManCreateCi( pIfMan );
If_ObjSetLevel( pIfObj, Aig_ObjLevel(pNode) ); If_ObjSetLevel( pIfObj, Aig_ObjLevel(pNode) );
// printf( "pi=%d ", pIfObj->Level ); // printf( "pi=%d ", pIfObj->Level );
if ( pIfMan->nLevelMax < (int)pIfObj->Level )
pIfMan->nLevelMax = (int)pIfObj->Level;
} }
else if ( Aig_ObjIsPo(pNode) ) 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 ); assert( Vec_PtrEntry(vAigToIf, i) == NULL );
Vec_PtrWriteEntry( vAigToIf, i, pIfObj ); Vec_PtrWriteEntry( vAigToIf, i, pIfObj );
pNode->pData = pIfObj; pNode->pData = pIfObj;
if ( vSwitching2 )
pSwitching2[pIfObj->Id] = pSwitching[pNode->Id];
// set up the choice node // set up the choice node
if ( Aig_ObjIsChoice( p, pNode ) ) 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) ); // assert( If_ObjLevel(pIfObj) == Aig_ObjLevel(pNode) );
} }
if ( vSwitching )
Vec_IntFree( vSwitching );
return pIfMan; return pIfMan;
} }

View File

@ -913,7 +913,7 @@ int Nwk_ManCountTotalFanins( Nwk_Obj_t * pLut, Nwk_Obj_t * pCand )
SeeAlso [] 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; Nwk_Obj_t * pFanin, * pObj;
int i, k; 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 ) if ( Nwk_ObjFaninNum(pLut) > pPars->nMaxLutSize )
continue; continue;
Nwl_ManCollectOverlapCands( pLut, vCands1, pPars ); Nwk_ManCollectOverlapCands( pLut, vCands1, pPars );
if ( pPars->fUseDiffSupp ) if ( pPars->fUseDiffSupp )
Nwk_ManCollectNonOverlapCands( pLut, vStart, vNext, vCands2, pPars ); Nwk_ManCollectNonOverlapCands( pLut, vStart, vNext, vCands2, pPars );
if ( Vec_PtrSize(vCands1) == 0 && Vec_PtrSize(vCands2) == 0 ) 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 ); Nwk_ManGraphReportMemoryUsage( p );
} }
vResult = p->vPairs; p->vPairs = NULL; vResult = p->vPairs; p->vPairs = NULL;
/*
for ( i = 0; i < vResult->nSize; i += 2 ) for ( i = 0; i < vResult->nSize; i += 2 )
printf( "(%d,%d) ", vResult->pArray[i], vResult->pArray[i+1] ); printf( "(%d,%d) ", vResult->pArray[i], vResult->pArray[i+1] );
printf( "\n" ); printf( "\n" );
*/
Nwk_ManGraphFree( p ); Nwk_ManGraphFree( p );
return vResult; return vResult;
} }

View File

@ -133,6 +133,7 @@ Aig_Man_t * Nwk_ManStrash( Nwk_Man_t * pNtk )
} }
Vec_PtrFree( vObjs ); Vec_PtrFree( vObjs );
Aig_ManCleanup( pMan ); Aig_ManCleanup( pMan );
Aig_ManSetRegNum( pMan, 0 );
return pMan; return pMan;
} }

View File

@ -242,7 +242,7 @@ extern void Nwk_ObjReplace( Nwk_Obj_t * pNodeOld, Nwk_Obj_t * pNodeNe
/*=== nwkMan.c ============================================================*/ /*=== nwkMan.c ============================================================*/
extern Nwk_Man_t * Nwk_ManAlloc(); extern Nwk_Man_t * Nwk_ManAlloc();
extern void Nwk_ManFree( Nwk_Man_t * p ); 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 ============================================================*/ /*=== nwkObj.c ============================================================*/
extern Nwk_Obj_t * Nwk_ManCreateCi( Nwk_Man_t * pMan, int nFanouts ); extern Nwk_Obj_t * Nwk_ManCreateCi( Nwk_Man_t * pMan, int nFanouts );
extern Nwk_Obj_t * Nwk_ManCreateCo( Nwk_Man_t * pMan ); extern Nwk_Obj_t * Nwk_ManCreateCo( Nwk_Man_t * pMan );

View File

@ -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 int Ntl_ManLatchNum( void * p );
extern void Ioa_WriteBlifLogic( Nwk_Man_t * pNtk, void * pNtl, char * pFileName ); extern void Ioa_WriteBlifLogic( Nwk_Man_t * pNtk, void * pNtl, char * pFileName );

View File

@ -6,12 +6,18 @@ SRC += src/aig/saig/saigAbs.c \
src/aig/saig/saigHaig.c \ src/aig/saig/saigHaig.c \
src/aig/saig/saigInd.c \ src/aig/saig/saigInd.c \
src/aig/saig/saigIoa.c \ src/aig/saig/saigIoa.c \
src/aig/saig/saigLoc.c \
src/aig/saig/saigMiter.c \ src/aig/saig/saigMiter.c \
src/aig/saig/saigPhase.c \ src/aig/saig/saigPhase.c \
src/aig/saig/saigRetFwd.c \ src/aig/saig/saigRetFwd.c \
src/aig/saig/saigRetMin.c \ src/aig/saig/saigRetMin.c \
src/aig/saig/saigRetStep.c \ src/aig/saig/saigRetStep.c \
src/aig/saig/saigScl.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/saigSynch.c \
src/aig/saig/saigTrans.c src/aig/saig/saigTrans.c \
src/aig/saig/saigWnd.c

View File

@ -30,7 +30,6 @@ extern "C" {
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
#include "aig.h" #include "aig.h"
#include "int.h"
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/// PARAMETERS /// /// PARAMETERS ///
@ -40,6 +39,18 @@ extern "C" {
/// BASIC TYPES /// /// 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 /// /// MACRO DEFINITIONS ///
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
@ -79,7 +90,7 @@ static inline Aig_Obj_t * Saig_ObjLiToLo( Aig_Man_t * p, Aig_Obj_t * pObj ) {
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/*=== sswAbs.c ==========================================================*/ /*=== 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 ==========================================================*/ /*=== saigBmc.c ==========================================================*/
extern int Saig_ManBmcSimple( Aig_Man_t * pAig, int nFrames, int nSizeMax, int nBTLimit, int fRewrite, int fVerbose, int * piFrame ); 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 ); 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 ==========================================================*/ /*=== saigIoa.c ==========================================================*/
extern void Saig_ManDumpBlif( Aig_Man_t * p, char * pFileName ); extern void Saig_ManDumpBlif( Aig_Man_t * p, char * pFileName );
extern Aig_Man_t * Saig_ManReadBlif( 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 ==========================================================*/ /*=== 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_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_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 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_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 ); 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 ); extern int Saig_ManRetimeSteps( Aig_Man_t * p, int nSteps, int fForward, int fAddBugs );
/*=== saigScl.c ==========================================================*/ /*=== saigScl.c ==========================================================*/
extern void Saig_ManReportUselessRegisters( Aig_Man_t * pAig ); 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 ==========================================================*/ /*=== saigSynch.c ==========================================================*/
extern Aig_Man_t * Saig_ManDupInitZero( Aig_Man_t * p ); extern Aig_Man_t * Saig_ManDupInitZero( Aig_Man_t * p );
/*=== saigTrans.c ==========================================================*/ /*=== saigTrans.c ==========================================================*/
extern Aig_Man_t * Saig_ManTimeframeSimplify( Aig_Man_t * pAig, int nFrames, int nFramesMax, int fInit, int fVerbose ); 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 #ifdef __cplusplus
} }

View File

@ -23,6 +23,7 @@
#include "cnf.h" #include "cnf.h"
#include "satSolver.h" #include "satSolver.h"
#include "satStore.h" #include "satStore.h"
#include "ssw.h"
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/// DECLARATIONS /// /// 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 ) ) if ( Saig_ObjIsPi( p, pObj ) )
return 1; return 1;
if ( Saig_ObjIsLo( p, pObj ) ) if ( Saig_ObjIsLo( p, pObj ) )
{
if ( i == 0 )
return 1;
return Saig_AbsMarkVisited_rec( p, vObj2Visit, Saig_ObjLoToLi(p, pObj), i-1 ); return Saig_AbsMarkVisited_rec( p, vObj2Visit, Saig_ObjLoToLi(p, pObj), i-1 );
}
if ( Aig_ObjIsPo( pObj ) ) if ( Aig_ObjIsPo( pObj ) )
return Saig_AbsMarkVisited_rec( p, vObj2Visit, Aig_ObjFanin0(pObj), i ); return Saig_AbsMarkVisited_rec( p, vObj2Visit, Aig_ObjFanin0(pObj), i );
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; Aig_Obj_t * pObj;
int i, f; int i, f;
vObj2Visit = Vec_StrStart( Aig_ManObjNumMax(p) * nFramesMax ); vObj2Visit = Vec_StrStart( Aig_ManObjNumMax(p) * nFramesMax );
Saig_ManForEachLo( p, pObj, i ) // Saig_ManForEachLo( p, pObj, i )
Saig_AbsSetVisited( vObj2Visit, Aig_ManObjNumMax(p), pObj, 0 ); // Saig_AbsSetVisited( vObj2Visit, Aig_ManObjNumMax(p), pObj, 0 );
for ( f = 0; f < nFramesMax; f++ ) for ( f = 0; f < nFramesMax; f++ )
{ {
Saig_AbsSetVisited( vObj2Visit, Aig_ManObjNumMax(p), Aig_ManConst1(p), f ); Saig_AbsSetVisited( vObj2Visit, Aig_ManObjNumMax(p), Aig_ManConst1(p), f );
@ -205,6 +210,7 @@ Vec_Ptr_t * Saig_AbsCreateFrames( Aig_Man_t * p, int nFramesMax, int fVerbose )
pFrame->nAsserts = Vec_PtrSize(vLoObjs); pFrame->nAsserts = Vec_PtrSize(vLoObjs);
// create POs // create POs
Aig_ManForEachPo( p, pObj, i ) Aig_ManForEachPo( p, pObj, i )
{
if ( Saig_AbsVisited( vObj2Visit, Aig_ManObjNumMax(p), pObj, f ) ) if ( Saig_AbsVisited( vObj2Visit, Aig_ManObjNumMax(p), pObj, f ) )
{ {
Saig_AbsCreateFrames_rec( pFrame, Aig_ObjFanin0(pObj) ); 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) ) if ( i >= Saig_ManPoNum(p) )
Vec_PtrPush( vLiObjs, pObj ); 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 ); Aig_ManCleanData( pFrame );
Vec_PtrForEachEntry( vLoObjs, pObj, i ) Vec_PtrForEachEntry( vLoObjs, pObj, i )
((Aig_Obj_t *)pObj->pData)->pData = pObj; ((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 auxiliary clauses (output, connectors, initial)
// add output clause // add output clause
if ( !sat_solver_addclause( pSat, Vec_IntArray(vPoLits), Vec_IntArray(vPoLits) + Vec_IntSize(vPoLits) ) ) if ( !sat_solver_addclause( pSat, Vec_IntArray(vPoLits), Vec_IntArray(vPoLits) + Vec_IntSize(vPoLits) ) )
{
printf( "SAT solver is not created correctly.\n" );
assert( 0 ); assert( 0 );
}
Vec_IntFree( vPoLits ); Vec_IntFree( vPoLits );
// add connecting clauses // 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************************************************************* /**Function*************************************************************
Synopsis [Performs proof-based abstraction using BMC of the given depth.] Synopsis [Performs proof-based abstraction using BMC of the given depth.]
@ -636,17 +693,100 @@ void Saig_AbsExtendOneStep( Aig_Man_t * p, Vec_Int_t * vFlops )
SeeAlso [] 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; Cnf_Dat_t * pCnf;
Vec_Ptr_t * vFrames; Vec_Ptr_t * vFrames;
sat_solver * pSat; sat_solver * pSat;
Vec_Int_t * vCore; Vec_Int_t * vCore;
Vec_Int_t * vFlops; Vec_Int_t * vFlops;
int clk = clock(), clk2 = clock(); int Iter, clk = clock(), clk2 = clock();
assert( Aig_ManRegNum(p) > 0 ); assert( Aig_ManRegNum(p) > 0 );
Aig_ManSetPioNumbers( p ); Aig_ManSetPioNumbers( p );
if ( fSkipProof )
{
assert( 0 );
if ( fVerbose )
printf( "Performing counter-example-based refinement.\n" );
// vFlops = Vec_IntStartNatural( 100 );
// Vec_IntPush( vFlops, 0 );
}
else
{
if ( fVerbose ) if ( fVerbose )
printf( "Performing proof-based abstraction with %d frames and %d max conflicts.\n", nFrames, nConfMax ); printf( "Performing proof-based abstraction with %d frames and %d max conflicts.\n", nFrames, nConfMax );
if ( fDynamic ) if ( fDynamic )
@ -693,6 +833,8 @@ Aig_Man_t * Saig_ManProofAbstraction( Aig_Man_t * p, int nFrames, int nConfMax,
printf( "The number of relevant registers is %d (out of %d). ", Vec_IntSize(vFlops), Aig_ManRegNum(p) ); printf( "The number of relevant registers is %d (out of %d). ", Vec_IntSize(vFlops), Aig_ManRegNum(p) );
PRT( "Time", clock() - clk ); PRT( "Time", clock() - clk );
} }
}
/*
// extend the abstraction // extend the abstraction
if ( fExtend ) if ( fExtend )
{ {
@ -702,8 +844,33 @@ Aig_Man_t * Saig_ManProofAbstraction( Aig_Man_t * p, int nFrames, int nConfMax,
if ( fVerbose ) if ( fVerbose )
printf( " %d flops.\n", Vec_IntSize(vFlops) ); printf( " %d flops.\n", Vec_IntSize(vFlops) );
} }
*/
// create the resulting AIG // create the resulting AIG
pResult = Saig_ManAbstraction( p, vFlops ); 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 ); Vec_IntFree( vFlops );
return pResult; return pResult;
} }

View File

@ -207,7 +207,7 @@ Aig_Obj_t * Saig_BmcIntervalExplore_rec( Saig_Bmc_t * p, Aig_Obj_t * pObj, int i
SeeAlso [] 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; Aig_Obj_t * pRes;
pRes = Saig_BmcObjFrame( p, pObj, i ); 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 ) ) if ( Saig_ObjIsPi( p->pAig, pObj ) )
pRes = Aig_ObjCreatePi(p->pFrm); pRes = Aig_ObjCreatePi(p->pFrm);
else if ( Saig_ObjIsLo( p->pAig, pObj ) ) 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 ) ) 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 ); pRes = Saig_BmcObjChild0( p, pObj, i );
} }
else else
{ {
Saig_BmcIntervalConstruct_rec( p, Aig_ObjFanin0(pObj), i ); Saig_BmcIntervalConstruct_rec_OLD( p, Aig_ObjFanin0(pObj), i );
Saig_BmcIntervalConstruct_rec( p, Aig_ObjFanin1(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) ); pRes = Aig_And( p->pFrm, Saig_BmcObjChild0(p, pObj, i), Saig_BmcObjChild1(p, pObj, i) );
} }
assert( pRes != AIG_VISITED ); 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; 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************************************************************* /**Function*************************************************************
Synopsis [Adds new AIG nodes to the frames.] 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 ) void Saig_BmcInterval( Saig_Bmc_t * p )
{ {
Aig_Obj_t * pTarget; Aig_Obj_t * pTarget;
// Aig_Obj_t * pObj; Aig_Obj_t * pObj, * pRes;
// int i; int i, iFrame;
int nNodes = Aig_ManObjNum( p->pFrm ); int nNodes = Aig_ManObjNum( p->pFrm );
Vec_PtrClear( p->vTargets ); Vec_PtrClear( p->vTargets );
p->iFramePrev = p->iFrameLast; p->iFramePrev = p->iFrameLast;
@ -258,21 +297,25 @@ void Saig_BmcInterval( Saig_Bmc_t * p )
if ( p->iOutputLast == 0 ) if ( p->iOutputLast == 0 )
{ {
Saig_BmcObjSetFrame( p, Aig_ManConst1(p->pAig), p->iFrameLast, Aig_ManConst1(p->pFrm) ); 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++ ) for ( ; p->iOutputLast < Saig_ManPoNum(p->pAig); p->iOutputLast++ )
{ {
if ( Aig_ManObjNum(p->pFrm) >= nNodes + p->nNodesMax ) if ( Aig_ManObjNum(p->pFrm) >= nNodes + p->nNodesMax )
return; return;
Saig_BmcIntervalExplore_rec( p, Aig_ManPo(p->pAig, p->iOutputLast), p->iFrameLast ); // 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 ); Vec_PtrClear( p->vVisited );
pTarget = Saig_BmcIntervalConstruct_rec( p, Aig_ManPo(p->pAig, p->iOutputLast), p->iFrameLast, p->vVisited );
/////////
// if ( Aig_ObjIsConst1(Aig_Regular(pTarget)) )
// continue;
Vec_PtrPush( p->vTargets, pTarget ); 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 // generate counter-example
Saig_BmcDeriveFailed( p, i ); Saig_BmcDeriveFailed( p, i );
p->pAig->pSeqModel = Saig_BmcGenerateCounterExample( p ); 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_True;
} }
return l_False; return l_False;
@ -564,7 +612,7 @@ void Saig_BmcPerform( Aig_Man_t * pAig, int nFramesMax, int nNodesMax, int nConf
RetValue = Saig_BmcSolveTargets( p ); RetValue = Saig_BmcSolveTargets( p );
if ( fVerbose ) 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 ); Iter, p->iFrameLast, p->iOutputLast, Aig_ManNodeNum(p->pFrm), p->nSatVars, (int)p->pSat->stats.conflicts );
PRT( "Time", clock() - clk2 ); PRT( "Time", clock() - clk2 );
} }

View File

@ -46,6 +46,7 @@ Aig_Man_t * Said_ManDupOrpos( Aig_Man_t * pAig )
int i; int i;
// start the new manager // start the new manager
pAigNew = Aig_ManStart( Aig_ManNodeNum(pAig) ); pAigNew = Aig_ManStart( Aig_ManNodeNum(pAig) );
pAigNew->pName = Aig_UtilStrsav( pAig->pName );
// map the constant node // map the constant node
Aig_ManConst1(pAig)->pData = Aig_ManConst1( pAigNew ); Aig_ManConst1(pAig)->pData = Aig_ManConst1( pAigNew );
// create variables for PIs // 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 * 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; Aig_Obj_t * pObj, * pObjLi, * pObjLo;
int i, Entry; int i, Entry;
// start the new manager // start the new manager
pAigNew = Aig_ManStart( Aig_ManNodeNum(pAig) ); pAigNew = Aig_ManStart( Aig_ManNodeNum(pAig) );
pAigNew->pName = Aig_UtilStrsav( pAig->pName );
// map the constant node // map the constant node
Aig_ManConst1(pAig)->pData = Aig_ManConst1( pAigNew ); Aig_ManConst1(pAig)->pData = Aig_ManConst1( pAigNew );
// label included flops // 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_ManSetRegNum( pAigNew, Vec_IntSize(vFlops) );
Aig_ManSeqCleanup( pAigNew ); Aig_ManSeqCleanup( pAigNew );
// pAigNew = Aig_ManDupSimpleDfs( pTemp = pAigNew );
// Aig_ManStop( pTemp );
return pAigNew; return pAigNew;
} }

View File

@ -28,6 +28,60 @@
/// FUNCTION DEFINITIONS /// /// 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************************************************************* /**Function*************************************************************
Synopsis [Creates sequential miter.] 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; 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************************************************************* /**Function*************************************************************
Synopsis [Create combinational timeframes by unrolling sequential circuits.] 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; Vec_Ptr_t * vSet0, * vSet1;
Aig_Obj_t * pObj, * pFanin, * pObj0, * pObj1; Aig_Obj_t * pObj, * pFanin, * pObj0, * pObj1;
int i, Counter = 0; int i, Counter = 0;
assert( Saig_ManRegNum(p) % 2 == 0 ); // assert( Saig_ManRegNum(p) % 2 == 0 );
vSet0 = Vec_PtrAlloc( Saig_ManPoNum(p) ); vSet0 = Vec_PtrAlloc( Saig_ManPoNum(p) );
vSet1 = Vec_PtrAlloc( Saig_ManPoNum(p) ); vSet1 = Vec_PtrAlloc( Saig_ManPoNum(p) );
Saig_ManForEachPo( p, pObj, i ) Saig_ManForEachPo( p, pObj, i )
@ -773,27 +937,47 @@ PRT( "Time", clock() - clkTotal );
SeeAlso [] 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; Aig_Man_t * pPart0, * pPart1;
int RetValue; int RetValue;
if ( fVerbose ) if ( fVerbose )
Aig_ManPrintStats( pMiter ); printf( "Performing sequential verification combinational A/B miter.\n" );
// consider the case when a miter is given
if ( p1 == NULL )
{
if ( fVerbose )
{
Aig_ManPrintStats( p0 );
}
// demiter the miter // demiter the miter
if ( !Saig_ManDemiterSimple( pMiter, &pPart0, &pPart1 ) ) if ( !Saig_ManDemiterSimpleDiff( p0, &pPart0, &pPart1 ) )
{ {
printf( "Demitering has failed.\n" ); printf( "Demitering has failed.\n" );
return -1; return -1;
} }
}
else
{
pPart0 = Aig_ManDupSimple( p0 );
pPart1 = Aig_ManDupSimple( p1 );
}
if ( fVerbose ) if ( fVerbose )
{ {
Aig_ManPrintStats( pPart0 ); // Aig_ManPrintStats( pPart0 );
Aig_ManPrintStats( pPart1 ); // Aig_ManPrintStats( pPart1 );
Aig_ManDumpBlif( pPart0, "part0.blif", NULL, NULL ); if ( p1 == 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_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 ); RetValue = Ssw_SecSpecial( pPart0, pPart1, nFrames, fVerbose );
Aig_ManStop( pPart0 ); Aig_ManStop( pPart0 );
Aig_ManStop( pPart1 ); Aig_ManStop( pPart1 );

View File

@ -468,7 +468,7 @@ void Saig_TsiStateOrAll( Saig_Tsim_t * pTsi, unsigned * pState )
SeeAlso [] 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; Saig_Tsim_t * pTsi;
Aig_Obj_t * pObj, * pObjLi, * pObjLo; 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 ); // Saig_TsiStatePrint( pTsi, pState );
// check if this state exists // check if this state exists
if ( Saig_TsiStateLookup( pTsi, pState, pTsi->nWords ) ) if ( Saig_TsiStateLookup( pTsi, pState, pTsi->nWords ) )
{
if ( fVerbose )
printf( "Ternary simulation converged after %d iterations.\n", f );
return pTsi; return pTsi;
}
// insert this state // insert this state
Saig_TsiStateInsert( pTsi, pState, pTsi->nWords ); Saig_TsiStateInsert( pTsi, pState, pTsi->nWords );
// simulate internal nodes // 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_ManPiNum(p) );
assert( Saig_ManPoNum(p) ); assert( Saig_ManPoNum(p) );
// perform terminary simulation // perform terminary simulation
pTsi = Saig_ManReachableTernary( p, vInits ); pTsi = Saig_ManReachableTernary( p, vInits, fVerbose );
if ( pTsi == NULL ) if ( pTsi == NULL )
return NULL; return NULL;
// derive information // derive information
@ -837,7 +841,7 @@ Aig_Man_t * Saig_ManPhaseAbstractAuto( Aig_Man_t * p, int fVerbose )
assert( Saig_ManPiNum(p) ); assert( Saig_ManPiNum(p) );
assert( Saig_ManPoNum(p) ); assert( Saig_ManPoNum(p) );
// perform terminary simulation // perform terminary simulation
pTsi = Saig_ManReachableTernary( p, NULL ); pTsi = Saig_ManReachableTernary( p, NULL, fVerbose );
if ( pTsi == NULL ) if ( pTsi == NULL )
return NULL; return NULL;
// derive information // derive information

325
src/aig/saig/saigSimExt.c Normal file
View File

@ -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 ///
////////////////////////////////////////////////////////////////////////

443
src/aig/saig/saigSimFast.c Normal file
View 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 ///
////////////////////////////////////////////////////////////////////////

726
src/aig/saig/saigSimMv.c Normal file
View 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 ///
////////////////////////////////////////////////////////////////////////

513
src/aig/saig/saigSimSeq.c Normal file
View 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 ///
////////////////////////////////////////////////////////////////////////

971
src/aig/saig/saigStrSim.c Normal file
View 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 ///
////////////////////////////////////////////////////////////////////////

582
src/aig/saig/saigSwitch.c Normal file
View 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 ///
////////////////////////////////////////////////////////////////////////

809
src/aig/saig/saigWnd.c Normal file
View 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 ///
////////////////////////////////////////////////////////////////////////

View File

@ -51,11 +51,16 @@ struct Ssw_Pars_t_
int nBTLimitGlobal;// conflict limit for multiple runs int nBTLimitGlobal;// conflict limit for multiple runs
int nMinDomSize; // min clock domain considered for optimization int nMinDomSize; // min clock domain considered for optimization
int nItersStop; // stop after the given number of iterations 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 fPolarFlip; // uses polarity adjustment
int fLatchCorr; // perform register correspondence int fLatchCorr; // perform register correspondence
int fSemiFormal; // enable semiformal filtering int fSemiFormal; // enable semiformal filtering
int fUniqueness; // enable uniqueness constraints int fUniqueness; // enable uniqueness constraints
int fDynamic; // enable dynamic addition of 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 fVerbose; // verbose stats
int fFlopVerbose; // verbose printout of redundant flops int fFlopVerbose; // verbose printout of redundant flops
// optimized latch correspondence // 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) 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 /// /// MACRO DEFINITIONS ///
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
@ -97,8 +104,11 @@ extern void Ssw_ManSetDefaultParams( Ssw_Pars_t * p );
extern void Ssw_ManSetDefaultParamsLcorr( 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_SignalCorrespondence( Aig_Man_t * pAig, Ssw_Pars_t * pPars );
extern Aig_Man_t * Ssw_LatchCorrespondence( 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 ===================================================*/ /*=== 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 ==========================================================*/ /*=== sswPart.c ==========================================================*/
extern Aig_Man_t * Ssw_SignalCorrespondencePart( Aig_Man_t * pAig, Ssw_Pars_t * pPars ); extern Aig_Man_t * Ssw_SignalCorrespondencePart( Aig_Man_t * pAig, Ssw_Pars_t * pPars );
/*=== sswPairs.c ===================================================*/ /*=== 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_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 ); extern int Ssw_SecGeneralMiter( Aig_Man_t * pMiter, Ssw_Pars_t * pPars );
/*=== sswSim.c ===================================================*/ /*=== 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 Ssw_Cex_t * Ssw_SmlAllocCounterExample( int nRegs, int nRealPis, int nFrames );
extern void Ssw_SmlFreeCounterExample( Ssw_Cex_t * pCex ); extern void Ssw_SmlFreeCounterExample( Ssw_Cex_t * pCex );
extern int Ssw_SmlRunCounterExample( Aig_Man_t * pAig, Ssw_Cex_t * p ); extern int Ssw_SmlRunCounterExample( Aig_Man_t * pAig, Ssw_Cex_t * p );

View File

@ -211,6 +211,7 @@ Aig_Man_t * Ssw_SpeculativeReduction( Ssw_Man_t * p )
// start the fraig package // start the fraig package
pFrames = Aig_ManStart( Aig_ManObjNumMax(p->pAig) * p->nFrames ); pFrames = Aig_ManStart( Aig_ManObjNumMax(p->pAig) * p->nFrames );
pFrames->pName = Aig_UtilStrsav( p->pAig->pName );
// map constants and PIs // map constants and PIs
Ssw_ObjSetFrame( p, Aig_ManConst1(p->pAig), 0, Aig_ManConst1(pFrames) ); Ssw_ObjSetFrame( p, Aig_ManConst1(p->pAig), 0, Aig_ManConst1(pFrames) );
Saig_ManForEachPi( p->pAig, pObj, i ) Saig_ManForEachPi( p->pAig, pObj, i )

View File

@ -585,7 +585,7 @@ int Ssw_ClassesPrepareRehash( Ssw_Cla_t * p, Vec_Ptr_t * vCands )
SeeAlso [] 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 nFrames = 4;
// int nWords = 1; // int nWords = 1;
@ -595,7 +595,7 @@ Ssw_Cla_t * Ssw_ClassesPrepare( Aig_Man_t * pAig, int fLatchCorr, int nMaxLevs,
// int nWords = 4; // int nWords = 4;
// int nIters = 0; // int nIters = 0;
int nFrames = 4; int nFrames = AIG_MAX( nFramesK, 4 );
int nWords = 2; int nWords = 2;
int nIters = 16; int nIters = 16;
Ssw_Cla_t * p; Ssw_Cla_t * p;
@ -836,7 +836,7 @@ Ssw_Cla_t * Ssw_ClassesPreparePairs( Aig_Man_t * pAig, Vec_Int_t ** pvClasses )
SeeAlso [] 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; Ssw_Cla_t * p;
Aig_Obj_t ** ppClassNew; Aig_Obj_t ** ppClassNew;

View File

@ -51,10 +51,13 @@ void Ssw_ManSetDefaultParams( Ssw_Pars_t * p )
p->nBTLimitGlobal = 5000000; // conflict limit for all runs p->nBTLimitGlobal = 5000000; // conflict limit for all runs
p->nMinDomSize = 100; // min clock domain considered for optimization p->nMinDomSize = 100; // min clock domain considered for optimization
p->nItersStop = 0; // stop after the given number of iterations 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->fPolarFlip = 0; // uses polarity adjustment
p->fLatchCorr = 0; // performs register correspondence p->fLatchCorr = 0; // performs register correspondence
p->fSemiFormal = 0; // enable semiformal filtering p->fSemiFormal = 0; // enable semiformal filtering
p->fUniqueness = 0; // enable uniqueness constraints p->fUniqueness = 0; // enable uniqueness constraints
p->fDynamic = 0; // dynamic partitioning
p->fLocalSim = 0; // local simulation
p->fVerbose = 0; // verbose stats p->fVerbose = 0; // verbose stats
// latch correspondence // latch correspondence
p->fLatchCorrOpt = 0; // performs optimized register 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 ) if ( pPars->fLatchCorrOpt )
{ {
pPars->fLatchCorr = 1; pPars->fLatchCorr = 1;
pPars->nFramesAddSim = 0;
if ( (pAig->vClockDoms && Vec_VecSize(pAig->vClockDoms) > 0) )
return Ssw_SignalCorrespondencePart( pAig, pPars );
} }
else else
{ {
@ -276,7 +282,7 @@ Aig_Man_t * Ssw_SignalCorrespondence( Aig_Man_t * pAig, Ssw_Pars_t * pPars )
if ( p->pPars->nConstrs == 0 ) if ( p->pPars->nConstrs == 0 )
{ {
// perform one round of seq simulation and generate candidate equivalence classes // 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 ); // p->ppClasses = Ssw_ClassesPrepareTargets( pAig );
if ( pPars->fLatchCorrOpt ) if ( pPars->fLatchCorrOpt )
p->pSml = Ssw_SmlStart( pAig, 0, 2, 1 ); 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 ); p->ppClasses = Ssw_ClassesPrepareSimple( pAig, pPars->fLatchCorr, pPars->nMaxLevs );
Ssw_ClassesSetData( p->ppClasses, NULL, NULL, Ssw_SmlObjIsConstBit, Ssw_SmlObjsAreEqualBit ); 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 // perform refinement of classes
pAigNew = Ssw_SignalCorrespondenceRefine( p ); pAigNew = Ssw_SignalCorrespondenceRefine( p );
if ( pPars->fUniqueness ) if ( pPars->fUniqueness )

View File

@ -277,6 +277,83 @@ p->timeSimSat += clock() - clk;
return RetValue1 > 0 || RetValue2 > 0; return RetValue1 > 0 || RetValue2 > 0;
} }
/**Function*************************************************************
Synopsis [Performs one round of simulation with counter-examples.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ssw_ManSweepResimulateDynLocal( Ssw_Man_t * p, int f )
{
Aig_Obj_t * pObj, * pRepr, ** ppClass;
int i, k, nSize, RetValue1, RetValue2, clk = clock();
p->nSimRounds++;
// transfer PI simulation information from storage
// Ssw_SmlAssignDist1Plus( p->pSml, p->pPatWords );
Ssw_ManSweepTransferDyn( p );
// determine const1 cands and classes to be simulated
Vec_PtrClear( p->vResimConsts );
Vec_PtrClear( p->vResimClasses );
Aig_ManIncrementTravId( p->pAig );
for ( i = p->iNodeStart; i < p->iNodeLast + p->pPars->nResimDelta; i++ )
{
if ( i >= Aig_ManObjNumMax( p->pAig ) )
break;
pObj = Aig_ManObj( p->pAig, i );
if ( pObj == NULL )
continue;
if ( Ssw_ObjIsConst1Cand(p->pAig, pObj) )
{
Vec_PtrPush( p->vResimConsts, pObj );
continue;
}
pRepr = Aig_ObjRepr(p->pAig, pObj);
if ( pRepr == NULL )
continue;
if ( Aig_ObjIsTravIdCurrent(p->pAig, pRepr) )
continue;
Aig_ObjSetTravIdCurrent(p->pAig, pRepr);
Vec_PtrPush( p->vResimClasses, pRepr );
}
// simulate internal nodes
// Ssw_SmlSimulateOneFrame( p->pSml );
// Ssw_SmlSimulateOne( p->pSml );
// resimulate dynamically
// Aig_ManIncrementTravId( p->pAig );
// Aig_ObjIsTravIdCurrent( p->pAig, Aig_ManConst1(p->pAig) );
p->nVisCounter++;
Vec_PtrForEachEntry( p->vResimConsts, pObj, i )
Ssw_SmlSimulateOneDyn_rec( p->pSml, pObj, p->nFrames-1, p->pVisited, p->nVisCounter );
// resimulate the cone of influence of the cand classes
Vec_PtrForEachEntry( p->vResimClasses, pRepr, i )
{
ppClass = Ssw_ClassesReadClass( p->ppClasses, pRepr, &nSize );
for ( k = 0; k < nSize; k++ )
Ssw_SmlSimulateOneDyn_rec( p->pSml, ppClass[k], p->nFrames-1, p->pVisited, p->nVisCounter );
}
// check equivalence classes
// RetValue1 = Ssw_ClassesRefineConst1( p->ppClasses, 1 );
// RetValue2 = Ssw_ClassesRefine( p->ppClasses, 1 );
// refine these nodes
RetValue1 = Ssw_ClassesRefineConst1Group( p->ppClasses, p->vResimConsts, 1 );
RetValue2 = 0;
Vec_PtrForEachEntry( p->vResimClasses, pRepr, i )
RetValue2 += Ssw_ClassesRefineOneClass( p->ppClasses, pRepr, 1 );
// prepare simulation info for the next round
Vec_PtrCleanSimInfo( p->vSimInfo, 0, 1 );
p->nPatterns = 0;
p->nSimRounds++;
p->timeSimSat += clock() - clk;
return RetValue1 > 0 || RetValue2 > 0;
}
/**Function************************************************************* /**Function*************************************************************
Synopsis [Performs fraiging for the internal nodes.] Synopsis [Performs fraiging for the internal nodes.]
@ -321,8 +398,11 @@ p->timeReduce += clock() - clk;
Ssw_ClassesClearRefined( p->ppClasses ); Ssw_ClassesClearRefined( p->ppClasses );
if ( p->pPars->fVerbose ) if ( p->pPars->fVerbose )
pProgress = Bar_ProgressStart( stdout, Aig_ManObjNumMax(p->pAig) ); pProgress = Bar_ProgressStart( stdout, Aig_ManObjNumMax(p->pAig) );
p->iNodeStart = 0;
Aig_ManForEachObj( p->pAig, pObj, i ) Aig_ManForEachObj( p->pAig, pObj, i )
{ {
if ( p->iNodeStart == 0 )
p->iNodeStart = i;
if ( p->pPars->fVerbose ) if ( p->pPars->fVerbose )
Bar_ProgressUpdate( pProgress, i, NULL ); Bar_ProgressUpdate( pProgress, i, NULL );
if ( Saig_ObjIsLo(p->pAig, pObj) ) if ( Saig_ObjIsLo(p->pAig, pObj) )
@ -341,7 +421,14 @@ p->timeReduce += clock() - clk;
{ {
// resimulate // resimulate
if ( p->nPatterns > 0 ) if ( p->nPatterns > 0 )
{
p->iNodeLast = i;
if ( p->pPars->fLocalSim )
Ssw_ManSweepResimulateDynLocal( p, f );
else
Ssw_ManSweepResimulateDyn( p, f ); Ssw_ManSweepResimulateDyn( p, f );
p->iNodeStart = i+1;
}
// printf( "Recycling SAT solver with %d vars and %d calls.\n", // printf( "Recycling SAT solver with %d vars and %d calls.\n",
// p->pMSat->nSatVars, p->nRecycleCalls ); // p->pMSat->nSatVars, p->nRecycleCalls );
// Aig_ManCleanMarkAB( p->pAig ); // Aig_ManCleanMarkAB( p->pAig );
@ -363,11 +450,24 @@ p->timeReduce += clock() - clk;
} }
// resimulate // resimulate
if ( p->nPatterns == 32 ) if ( p->nPatterns == 32 )
{
p->iNodeLast = i;
if ( p->pPars->fLocalSim )
Ssw_ManSweepResimulateDynLocal( p, f );
else
Ssw_ManSweepResimulateDyn( p, f ); Ssw_ManSweepResimulateDyn( p, f );
p->iNodeStart = i+1;
}
} }
// resimulate // resimulate
if ( p->nPatterns > 0 ) if ( p->nPatterns > 0 )
{
p->iNodeLast = i;
if ( p->pPars->fLocalSim )
Ssw_ManSweepResimulateDynLocal( p, f );
else
Ssw_ManSweepResimulateDyn( p, f ); Ssw_ManSweepResimulateDyn( p, f );
}
// collect stats // collect stats
if ( p->pPars->fVerbose ) if ( p->pPars->fVerbose )
Bar_ProgressStop( pProgress ); Bar_ProgressStop( pProgress );

Some files were not shown because too many files have changed in this diff Show More