mirror of https://github.com/YosysHQ/abc.git
Merge remote-tracking branch 'upstream/master' into yosys-experimental
This commit is contained in:
commit
43b9a4defe
|
|
@ -31,6 +31,7 @@ src/aig/ddb/
|
|||
*.plg
|
||||
|
||||
*.zip
|
||||
*.DS_Store
|
||||
|
||||
abcspaceext.dsw
|
||||
abcext.dsp
|
||||
|
|
|
|||
4
Makefile
4
Makefile
|
|
@ -26,9 +26,9 @@ MODULES := \
|
|||
src/misc/vec src/misc/hash src/misc/tim src/misc/bzlib src/misc/zlib \
|
||||
src/misc/mem src/misc/bar src/misc/bbl src/misc/parse \
|
||||
src/opt/cut src/opt/fxu src/opt/fxch src/opt/rwr src/opt/mfs src/opt/sim \
|
||||
src/opt/ret src/opt/fret src/opt/res src/opt/lpk src/opt/nwk src/opt/rwt \
|
||||
src/opt/ret src/opt/fret src/opt/res src/opt/lpk src/opt/nwk src/opt/rwt src/opt/rar \
|
||||
src/opt/cgt src/opt/csw src/opt/dar src/opt/dau src/opt/dsc src/opt/sfm src/opt/sbd \
|
||||
src/sat/bsat src/sat/xsat src/sat/satoko src/sat/csat src/sat/msat src/sat/psat src/sat/cnf src/sat/bmc src/sat/glucose src/sat/glucose2 \
|
||||
src/sat/bsat src/sat/xsat src/sat/satoko src/sat/csat src/sat/msat src/sat/psat src/sat/cnf src/sat/bmc src/sat/glucose src/sat/glucose2 src/sat/kissat src/sat/cadical \
|
||||
src/bool/bdc src/bool/deco src/bool/dec src/bool/kit src/bool/lucky \
|
||||
src/bool/rsb src/bool/rpo \
|
||||
src/proof/pdr src/proof/abs src/proof/live src/proof/ssc src/proof/int \
|
||||
|
|
|
|||
796
abclib.dsp
796
abclib.dsp
|
|
@ -691,6 +691,10 @@ SOURCE=.\src\base\io\ioWriteGml.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\base\io\ioWriteHMetis.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\base\io\ioWriteList.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
@ -2514,6 +2518,742 @@ SOURCE=.\src\sat\glucose2\Vec.h
|
|||
SOURCE=.\src\sat\glucose2\XAlloc.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "kissat"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\allocate.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\analyze.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\ands.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\arena.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\assign.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\averages.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\backbone.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\backtrack.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\build.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\bump.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\check.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\classify.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\clause.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\collect.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\colors.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\compact.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\config.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\congruence.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\decide.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\deduce.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\definition.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\dense.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\dump.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\eliminate.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\equivalences.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\error.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\extend.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\factor.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\fastel.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\file.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\flags.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\format.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\forward.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\gates.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\heap.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\ifthenelse.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\import.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\internal.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\kimits.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\kissatSolver.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\kissatTest.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\kitten.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\kptions.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\krite.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\kucky.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\learn.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\logging.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\minimize.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\mode.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\phases.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\preprocess.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\print.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\probe.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\profile.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\promote.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\proof.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\propbeyond.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\propdense.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\propinitially.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\proprobe.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\propsearch.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\queue.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\reduce.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\reluctant.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\reorder.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\rephase.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\report.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\resize.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\resolve.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\resources.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\restart.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\search.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\shrink.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\smooth.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\sort.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\stack.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\statistics.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\strengthen.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\substitute.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\sweep.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\terminate.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\tiers.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\trail.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\transitive.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\utilities.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\vector.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\vivify.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\walk.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\warmup.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\watch.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\kissat\weaken.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "cadical"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_kitten.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_analyze.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_arena.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_assume.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_averages.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_backtrack.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_backward.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_bins.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_block.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_ccadical.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_checker.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_clause.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_collect.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_compact.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_condition.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_config.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_congruence.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_constrain.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_contract.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_cover.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_decide.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_decompose.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_deduplicate.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_definition.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_drattracer.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_elim.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_elimfast.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_ema.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_extend.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_external.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_external_propagate.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_factor.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_file.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_flags.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_flip.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_format.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_frattracer.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_gates.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_idruptracer.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_instantiate.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_internal.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_ipasir.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_lidruptracer.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_limit.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_logging.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_lookahead.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_lratchecker.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_lrattracer.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_lucky.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_message.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_minimize.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_occs.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_options.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_parse.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_phases.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_probe.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_profile.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_proof.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_propagate.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_queue.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_random.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_reap.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_reduce.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_rephase.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_report.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_resources.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_restart.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_restore.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_score.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_shrink.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_signal.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_solution.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_solver.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_stable.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_stats.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_subsume.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_sweep.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_terminal.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_ternary.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_tier.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_transred.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_unstable.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_util.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_var.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_veripbtracer.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_version.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_vivify.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_walk.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadical_watch.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadicalSolver.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\cadical\cadicalTest.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Group
|
||||
# Begin Group "opt"
|
||||
|
||||
|
|
@ -2578,6 +3318,54 @@ SOURCE=.\src\opt\fxu\fxuSingle.c
|
|||
SOURCE=.\src\opt\fxu\fxuUpdate.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "rar"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\opt\rar\rewire_map.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\opt\rar\rewire_miaig.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\opt\rar\rewire_rar.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\opt\rar\rewire_rng.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\opt\rar\rewire_time.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\opt\rar\rewire_tt.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\opt\rar\rewire_vec.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\opt\rar\rewire_map.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\opt\rar\rewire_miaig.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\opt\rar\rewire_rar.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\opt\rar\rewire_rng.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "rwr"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
|
|
@ -4111,6 +4899,10 @@ SOURCE=.\src\misc\util\utilBridge.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\misc\util\utilBSet.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\misc\util\utilCex.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
@ -5207,6 +5999,10 @@ SOURCE=.\src\aig\gia\giaRex.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\gia\giaRrr.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\gia\giaSat3.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
|
|||
|
|
@ -249,6 +249,11 @@ struct Gia_Man_t_
|
|||
int iFirstPoId;
|
||||
int iFirstAndObj;
|
||||
int iFirstPoObj;
|
||||
Vec_Str_t * vTTISOPs; // truth tables from ISOP computation
|
||||
Vec_Int_t * vTTLut; // truth tables from ISOP computation
|
||||
Vec_Int_t * vMFFCsInfo; // MFFC information
|
||||
Vec_Int_t * vMFFCsLuts; // MFFCs for each lut
|
||||
Vec_Ptr_t * vLutsRankings; // LUTs rankings of inputs
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -1431,6 +1436,7 @@ extern void Gia_ManEquivFixOutputPairs( Gia_Man_t * p );
|
|||
extern int Gia_ManCheckTopoOrder( Gia_Man_t * p );
|
||||
extern int * Gia_ManDeriveNexts( Gia_Man_t * p );
|
||||
extern void Gia_ManDeriveReprs( Gia_Man_t * p );
|
||||
extern void Gia_ManDeriveReprsFromSibls( Gia_Man_t *p );
|
||||
extern int Gia_ManEquivCountLits( Gia_Man_t * p );
|
||||
extern int Gia_ManEquivCountLitsAll( Gia_Man_t * p );
|
||||
extern int Gia_ManEquivCountClasses( Gia_Man_t * p );
|
||||
|
|
@ -1801,6 +1807,9 @@ extern Gia_Man_t * Gia_ManTtoptCare( Gia_Man_t * p, int nIns, int nOuts,
|
|||
extern Gia_Man_t * Gia_ManTransductionBdd( Gia_Man_t * pGia, int nType, int fMspf, int nRandom, int nSortType, int nPiShuffle, int nParameter, int fLevel, Gia_Man_t * pExdc, int fNewLine, int nVerbose );
|
||||
extern Gia_Man_t * Gia_ManTransductionTt( Gia_Man_t * pGia, int nType, int fMspf, int nRandom, int nSortType, int nPiShuffle, int nParameter, int fLevel, Gia_Man_t * pExdc, int fNewLine, int nVerbose );
|
||||
|
||||
/*=== giaRrr.cpp ===========================================================*/
|
||||
extern Gia_Man_t * Gia_ManRrr( Gia_Man_t *pGia, int iSeed, int nWords, int nTimeout, int nSchedulerVerbose, int nPartitionerVerbose, int nOptimizerVerbose, int nAnalyzerVerbose, int nSimulatorVerbose, int nSatSolverVerbose, int fUseBddCspf, int fUseBddMspf, int nConflictLimit, int nSortType, int nOptimizerFlow, int nSchedulerFlow, int nDistance, int nRestarts, int nThreads, int nWindowSize, int fDeterministic );
|
||||
|
||||
/*=== giaCTas.c ===========================================================*/
|
||||
typedef struct Tas_Man_t_ Tas_Man_t;
|
||||
extern Tas_Man_t * Tas_ManAlloc( Gia_Man_t * pAig, int nBTLimit );
|
||||
|
|
@ -1843,6 +1852,8 @@ extern void Bnd_ManPrintStats();
|
|||
// util
|
||||
extern Gia_Man_t* Bnd_ManCutBoundary( Gia_Man_t *p, Vec_Int_t* vEI, Vec_Int_t* vEO, Vec_Bit_t* vEI_phase, Vec_Bit_t* vEO_phase );
|
||||
|
||||
extern int Gia_ObjCheckMffc( Gia_Man_t * p, Gia_Obj_t * pRoot, int Limit, Vec_Int_t * vNodes, Vec_Int_t * vLeaves, Vec_Int_t * vInners );
|
||||
|
||||
ABC_NAMESPACE_HEADER_END
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -19,10 +19,12 @@
|
|||
***********************************************************************/
|
||||
|
||||
#include "giaAig.h"
|
||||
#include "aig/gia/gia.h"
|
||||
#include "proof/fra/fra.h"
|
||||
#include "proof/dch/dch.h"
|
||||
#include "opt/dar/dar.h"
|
||||
#include "opt/dau/dau.h"
|
||||
#include <assert.h>
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
|
@ -191,6 +193,8 @@ Gia_Man_t * Gia_ManFromAigChoices( Aig_Man_t * p )
|
|||
Gia_ManSetRegNum( pNew, Aig_ManRegNum(p) );
|
||||
//assert( Gia_ManObjNum(pNew) == Aig_ManObjNum(p) );
|
||||
//Gia_ManCheckChoices( pNew );
|
||||
if ( pNew->pSibls )
|
||||
Gia_ManDeriveReprsFromSibls( pNew );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -314,7 +314,7 @@ int Gia_AigerWriteCellMappingInstance( Gia_Man_t * p, unsigned char * pBuffer, i
|
|||
Vec_Str_t * Gia_AigerWriteCellMappingDoc( Gia_Man_t * p )
|
||||
{
|
||||
unsigned char * pBuffer;
|
||||
int i, iFan, nCells = 0, nInstances = 0, nSize = 8, nSize2 = 0;
|
||||
int i, nCells = 0, nInstances = 0, nSize = 8, nSize2 = 0;
|
||||
Mio_Cell2_t * pCells = Mio_CollectRootsNewDefault2( 6, &nCells, 0 );
|
||||
assert( pCells );
|
||||
|
||||
|
|
|
|||
|
|
@ -162,6 +162,65 @@ Gia_Man_t * Gia_ManDeepSyn( Gia_Man_t * pGia, int nIters, int nNoImpr, int TimeO
|
|||
return pBest;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Generating one AIG by applying a randomized script.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Gia_Man_t * Gia_ManRandSyn( Gia_Man_t * p, unsigned random_seed )
|
||||
{
|
||||
char * pCompress2rs = "balance -l; resub -K 6 -l; rewrite -l; resub -K 6 -N 2 -l; refactor -l; resub -K 8 -l; balance -l; resub -K 8 -N 2 -l; rewrite -l; resub -K 10 -l; rewrite -z -l; resub -K 10 -N 2 -l; balance -l; resub -K 12 -l; refactor -z -l; resub -K 12 -N 2 -l; rewrite -z -l; balance -l";
|
||||
unsigned Rand = random_seed;
|
||||
int fDch = Rand & 1;
|
||||
//int fCom = (Rand >> 1) & 3;
|
||||
int fCom = (Rand >> 1) & 1;
|
||||
int fFx = (Rand >> 2) & 1;
|
||||
int fUseTwo = 0;
|
||||
int KLut = fUseTwo ? 2 + (Rand % 5) : 3 + (Rand % 4);
|
||||
//int fChange = 0;
|
||||
char Command[2000];
|
||||
char pComp[1000];
|
||||
if ( fCom == 3 )
|
||||
sprintf( pComp, "; &put; %s; %s; %s; &get", pCompress2rs, pCompress2rs, pCompress2rs );
|
||||
else if ( fCom == 2 )
|
||||
sprintf( pComp, "; &put; %s; %s; &get", pCompress2rs, pCompress2rs );
|
||||
else if ( fCom == 1 )
|
||||
sprintf( pComp, "; &put; %s; &get", pCompress2rs );
|
||||
else if ( fCom == 0 )
|
||||
sprintf( pComp, "; &dc2" );
|
||||
sprintf( Command, "&dch%s; &if -a -K %d; &mfs -e -W 20 -L 20%s%s",
|
||||
fDch ? " -f" : "", KLut, fFx ? "; &fx; &st" : "", pComp );
|
||||
Gia_Man_t * pOld = Abc_FrameGetGia(Abc_FrameGetGlobalFrame());
|
||||
Abc_FrameUpdateGia( Abc_FrameGetGlobalFrame(), Gia_ManDup(p) );
|
||||
if ( Abc_FrameIsBatchMode() )
|
||||
{
|
||||
if ( Cmd_CommandExecute(Abc_FrameGetGlobalFrame(), Command) )
|
||||
{
|
||||
Abc_Print( 1, "Something did not work out with the command \"%s\".\n", Command );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Abc_FrameSetBatchMode( 1 );
|
||||
if ( Cmd_CommandExecute(Abc_FrameGetGlobalFrame(), Command) )
|
||||
{
|
||||
Abc_Print( 1, "Something did not work out with the command \"%s\".\n", Command );
|
||||
return NULL;
|
||||
}
|
||||
Abc_FrameSetBatchMode( 0 );
|
||||
}
|
||||
Gia_Man_t * pRes = Abc_FrameGetGia(Abc_FrameGetGlobalFrame());
|
||||
Abc_FrameUpdateGia( Abc_FrameGetGlobalFrame(), pOld );
|
||||
return pRes;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -310,6 +310,39 @@ void Gia_ManDeriveReprs( Gia_Man_t * p )
|
|||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Given pSibls, derives original representitives and nexts.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
void Gia_ManDeriveReprsFromSibls( Gia_Man_t *p )
|
||||
{
|
||||
|
||||
int i, iObj;
|
||||
assert( !p->pReprs && p->pSibls );
|
||||
p->pReprs = ABC_CALLOC( Gia_Rpr_t, Gia_ManObjNum(p) );
|
||||
for ( i = 0; i < Gia_ManObjNum(p); i++ )
|
||||
Gia_ObjSetRepr( p, i, GIA_VOID );
|
||||
for ( i = 0; i < Gia_ManObjNum(p); i++ )
|
||||
{
|
||||
if ( p->pSibls[i] == 0 )
|
||||
continue;
|
||||
if ( p->pReprs[i].iRepr != GIA_VOID )
|
||||
continue;
|
||||
for ( iObj = p->pSibls[i]; iObj; iObj = p->pSibls[iObj] )
|
||||
p->pReprs[iObj].iRepr = i;
|
||||
}
|
||||
ABC_FREE( p->pNexts );
|
||||
p->pNexts = Gia_ManDeriveNexts( p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
|
@ -2770,7 +2803,10 @@ void Gia_ManTransferEquivs2( Gia_Man_t * p, Gia_Man_t * pOld )
|
|||
{
|
||||
Vec_IntClear( vClass );
|
||||
Gia_ClassForEachObj( p, i, k )
|
||||
Vec_IntPushUnique( vClass, Abc_Lit2Var(Gia_ManObj(p, k)->Value) );
|
||||
if ( (int)Gia_ManObj(p, k)->Value >= 0 )
|
||||
Vec_IntPushUnique( vClass, Abc_Lit2Var(Gia_ManObj(p, k)->Value) );
|
||||
if ( Vec_IntSize( vClass ) <= 1 )
|
||||
continue;
|
||||
assert( Vec_IntSize( vClass ) > 1 );
|
||||
Vec_IntSort( vClass, 0 );
|
||||
iRepr = Vec_IntEntry( vClass, 0 );
|
||||
|
|
|
|||
|
|
@ -217,7 +217,9 @@ Vec_Wec_t * Gia_ManFxRetrieve( Gia_Man_t * p, Vec_Str_t ** pvCompl, int fReverse
|
|||
int nVars = Gia_ObjLutSize( p, i );
|
||||
int * pVars = Gia_ObjLutFanins( p, i );
|
||||
word * pTruth = Vec_WrdEntryP( vTruths, Counter++ * nWords );
|
||||
Abc_TtFlipVar5( pTruth, nVars );
|
||||
int Status = Kit_TruthIsop( (unsigned *)pTruth, nVars, vCover, 1 );
|
||||
Abc_TtFlipVar5( pTruth, nVars );
|
||||
if ( Vec_IntSize(vCover) == 0 || (Vec_IntSize(vCover) == 1 && Vec_IntEntry(vCover,0) == 0) )
|
||||
{
|
||||
Vec_StrWriteEntry( *pvCompl, pObj->Value, (char)(Vec_IntSize(vCover) == 0) );
|
||||
|
|
|
|||
|
|
@ -1302,6 +1302,65 @@ Gia_Man_t * Gia_ManGenMux( int nIns, char * pNums )
|
|||
return p;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Generates N-bit sorter using pair-wise sorting algorithm.]
|
||||
|
||||
Description [https://en.wikipedia.org/wiki/Pairwise_sorting_network]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Gia_ManGenSorterOne( Gia_Man_t * p, int * pLits, int i, int k )
|
||||
{
|
||||
int Lit1 = Gia_ManAppendAnd( p, pLits[i], pLits[k] );
|
||||
int Lit2 = Gia_ManAppendOr ( p, pLits[i], pLits[k] );
|
||||
pLits[i] = Lit1;
|
||||
pLits[k] = Lit2;
|
||||
}
|
||||
static inline void Gia_ManGenSorterConstrMerge( Gia_Man_t * p, int * pLits, int lo, int hi, int r )
|
||||
{
|
||||
int i, step = r * 2;
|
||||
if ( step < hi - lo )
|
||||
{
|
||||
Gia_ManGenSorterConstrMerge( p, pLits, lo, hi-r, step );
|
||||
Gia_ManGenSorterConstrMerge( p, pLits, lo+r, hi, step );
|
||||
for ( i = lo+r; i < hi-r; i += step )
|
||||
Gia_ManGenSorterOne( p, pLits, i, i+r );
|
||||
}
|
||||
}
|
||||
static inline void Gia_ManGenSorterConstrRange( Gia_Man_t * p, int * pLits, int lo, int hi )
|
||||
{
|
||||
if ( hi - lo >= 1 )
|
||||
{
|
||||
int i, mid = lo + (hi - lo) / 2;
|
||||
for ( i = lo; i <= mid; i++ )
|
||||
Gia_ManGenSorterOne( p, pLits, i, i + (hi - lo + 1) / 2 );
|
||||
Gia_ManGenSorterConstrRange( p, pLits, lo, mid );
|
||||
Gia_ManGenSorterConstrRange( p, pLits, mid+1, hi );
|
||||
Gia_ManGenSorterConstrMerge( p, pLits, lo, hi, 1 );
|
||||
}
|
||||
}
|
||||
Gia_Man_t * Gia_ManGenSorter( int LogN )
|
||||
{
|
||||
int i, nVars = 1 << LogN;
|
||||
int nVarsAlloc = nVars + 2 * (nVars * LogN * (LogN-1) / 4 + nVars - 1);
|
||||
Vec_Int_t * vLits = Vec_IntAlloc( nVars );
|
||||
Gia_Man_t * p = Gia_ManStart( 1 + 2*nVars + nVarsAlloc );
|
||||
p->pName = Abc_UtilStrsav( "sorter" );
|
||||
for ( i = 0; i < nVars; i++ )
|
||||
Vec_IntPush( vLits, Gia_ManAppendCi(p) );
|
||||
Gia_ManGenSorterConstrRange( p, Vec_IntArray(vLits), 0, nVars - 1 );
|
||||
for ( i = 0; i < nVars; i++ )
|
||||
Gia_ManAppendCo( p, Vec_IntEntry(vLits, i) );
|
||||
Vec_IntFree( vLits );
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -807,7 +807,7 @@ void Gia_ManPrintNpnClasses( Gia_Man_t * p )
|
|||
int i, k, iFan, Class, OtherClasses, OtherClasses2, nTotal, Counter, Counter2;
|
||||
unsigned * pTruth; int nLutSize = 0;
|
||||
assert( Gia_ManHasMapping(p) );
|
||||
assert( Gia_ManLutSizeMax( p ) <= 4 );
|
||||
//assert( Gia_ManLutSizeMax( p ) <= 4 );
|
||||
vLeaves = Vec_IntAlloc( 100 );
|
||||
vVisited = Vec_IntAlloc( 100 );
|
||||
vTruth = Vec_IntAlloc( (1<<16) );
|
||||
|
|
|
|||
|
|
@ -422,7 +422,9 @@ Gia_Man_t * Gia_ManInsertMfs( Gia_Man_t * p, Sfm_Ntk_t * pNtk, int fAllBoxes )
|
|||
int nVarsNew;
|
||||
Abc_TtSimplify( pTruth, Vec_IntArray(vLeaves), Vec_IntSize(vLeaves), &nVarsNew );
|
||||
Vec_IntShrink( vLeaves, nVarsNew );
|
||||
Abc_TtFlipVar5( pTruth, Vec_IntSize(vLeaves) );
|
||||
iLitNew = Gia_ManFromIfLogicCreateLut( pNew, pTruth, vLeaves, vCover, vMapping, vMapping2 );
|
||||
Abc_TtFlipVar5( pTruth, Vec_IntSize(vLeaves) );
|
||||
if ( MapSize < Vec_IntSize(vMapping2) )
|
||||
{
|
||||
assert( Vec_IntEntryLast(vMapping2) == Abc_Lit2Var(iLitNew) );
|
||||
|
|
@ -430,7 +432,11 @@ Gia_Man_t * Gia_ManInsertMfs( Gia_Man_t * p, Sfm_Ntk_t * pNtk, int fAllBoxes )
|
|||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Abc_TtFlipVar5( pTruth, Vec_IntSize(vLeaves) );
|
||||
iLitNew = Gia_ManFromIfLogicCreateLut( pNew, pTruth, vLeaves, vCover, vMapping, vMapping2 );
|
||||
Abc_TtFlipVar5( pTruth, Vec_IntSize(vLeaves) );
|
||||
}
|
||||
}
|
||||
else // internal CO
|
||||
{
|
||||
|
|
|
|||
|
|
@ -555,6 +555,23 @@ char * Abc_FrameGiaOutputMiniLutAttr( Abc_Frame_t * pAbc, void * pMiniLut )
|
|||
printf( "Current network in ABC framework is not defined.\n" );
|
||||
return Gia_ManToMiniLutAttr( pGia, pMiniLut );
|
||||
}
|
||||
int * Abc_FrameGiaOutputMiniLutObj( Abc_Frame_t * pAbc )
|
||||
{
|
||||
int * pRes = NULL;
|
||||
if ( pAbc == NULL )
|
||||
printf( "ABC framework is not initialized by calling Abc_Start()\n" );
|
||||
if ( pAbc->vMiniLutObjs == NULL )
|
||||
printf( "MiniLut objects are not defined.\n" );
|
||||
pRes = Vec_IntReleaseArray( pAbc->vMiniLutObjs );
|
||||
Vec_IntFreeP( &pAbc->vMiniLutObjs );
|
||||
return pRes;
|
||||
}
|
||||
void Abc_FrameSetObjDelays( Abc_Frame_t * pAbc, int * pDelays, int nDelays )
|
||||
{
|
||||
Vec_IntFreeP( &pAbc->vObjDelays );
|
||||
pAbc->vObjDelays = Vec_IntAllocArrayCopy( pDelays, nDelays );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
|
|
|
|||
|
|
@ -1172,7 +1172,10 @@ void Nf_ManCutMatchOne( Nf_Man_t * p, int iObj, int * pCut, int * pCutSet )
|
|||
if ( ArrivalA + pC->iDelays[k] <= Required && Required != SCL_INFINITY )
|
||||
{
|
||||
Delay = Abc_MaxInt( Delay, ArrivalA + pC->iDelays[k] );
|
||||
AreaF += pBestF[iFanin]->M[fComplF][1].F;
|
||||
if ( AreaF >= (float)1e32 || pBestF[iFanin]->M[fComplF][1].F >= (float)1e32 )
|
||||
AreaF = (float)1e32;
|
||||
else
|
||||
AreaF += pBestF[iFanin]->M[fComplF][1].F;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1617,8 +1620,7 @@ int Nf_ManSetMapRefs( Nf_Man_t * p )
|
|||
p->pPars->Area++;
|
||||
p->nInvs++;
|
||||
}
|
||||
reqTime = Abc_MinInt( Nf_ObjRequired(p, i, 0), Nf_ObjRequired(p, i, 1) );
|
||||
Tim_ManSetCiRequired( p->pManTim, Gia_ObjCioId(pObj), reqTime );
|
||||
Tim_ManSetCiRequired( p->pManTim, Gia_ObjCioId(pObj), Nf_ObjRequired(p, i, 0) );
|
||||
continue;
|
||||
}
|
||||
if ( Gia_ObjIsCo(pObj) )
|
||||
|
|
@ -1930,7 +1932,9 @@ void Nf_ManResetMatches( Nf_Man_t * p, int Round )
|
|||
Nf_Mat_t * pDc, * pAc, * pMfan, * pM[2];
|
||||
int i, c, Arrival;
|
||||
// go through matches in the topo order
|
||||
Gia_ManForEachAnd( p->pGia, pObj, i )
|
||||
if ( p->pManTim )
|
||||
Tim_ManIncrementTravId( p->pManTim );
|
||||
Gia_ManForEachObjWithBoxes( p->pGia, pObj, i )
|
||||
{
|
||||
if ( Gia_ObjIsBuf(pObj) )
|
||||
{
|
||||
|
|
@ -1947,6 +1951,18 @@ void Nf_ManResetMatches( Nf_Man_t * p, int Round )
|
|||
}
|
||||
continue;
|
||||
}
|
||||
if ( Gia_ObjIsCi(pObj) )
|
||||
{
|
||||
Arrival = Tim_ManGetCiArrival( p->pManTim, Gia_ObjCioId(pObj) );
|
||||
Nf_ObjPrepareCi( p, i, Arrival );
|
||||
continue;
|
||||
}
|
||||
if ( Gia_ObjIsCo(pObj) )
|
||||
{
|
||||
Arrival = Nf_ObjMatchD( p, Gia_ObjFaninId0(pObj, i), Gia_ObjFaninC0(pObj) )->D;
|
||||
Tim_ManSetCoArrival( p->pManTim, Gia_ObjCioId(pObj), Arrival );
|
||||
continue;
|
||||
}
|
||||
// select the best match for each phase
|
||||
for ( c = 0; c < 2; c++ )
|
||||
{
|
||||
|
|
@ -2019,29 +2035,38 @@ void Nf_ManComputeMappingEla( Nf_Man_t * p )
|
|||
Mio_Cell2_t * pCell;
|
||||
Nf_Mat_t Mb, * pMb = &Mb, * pM;
|
||||
word AreaBef, AreaAft, Gain = 0;
|
||||
int i, c, iVar, Id, fCompl, k, * pCut, reqTime;
|
||||
int Required;
|
||||
Nf_ManSetOutputRequireds( p, 1 );
|
||||
int i, c, iVar, Id, fCompl, k, * pCut, Required;
|
||||
Nf_ManResetMatches( p, p->Iter - p->pPars->nRounds );
|
||||
Nf_ManSetOutputRequireds( p, 1 );
|
||||
Gia_ManForEachObjReverseWithBoxes( p->pGia, pObj, i )
|
||||
{
|
||||
if ( Gia_ObjIsBuf(pObj) )
|
||||
{
|
||||
if ( Nf_ObjMapRefNum(p, i, 1) )
|
||||
Nf_ObjUpdateRequired( p, i, 0, Nf_ObjRequired(p, i, 1) - p->InvDelayI );
|
||||
Nf_ObjUpdateRequired( p, Gia_ObjFaninId0(pObj, i), Gia_ObjFaninC0(pObj), Nf_ObjRequired(p, i, 0) );
|
||||
int reqTime = Nf_ObjRequired(p, i, 0);
|
||||
int iObj = Gia_ObjFaninId0p(p->pGia, pObj);
|
||||
int fCompl = Gia_ObjFaninC0(pObj);
|
||||
Nf_ObjUpdateRequired( p, iObj, fCompl, reqTime );
|
||||
if ( iObj > 0 && Nf_ObjMatchBest(p, iObj, fCompl)->fCompl )
|
||||
Nf_ObjUpdateRequired( p, iObj, !fCompl, reqTime - p->InvDelayI );
|
||||
continue;
|
||||
}
|
||||
if ( Gia_ObjIsCi(pObj) )
|
||||
{
|
||||
reqTime = Abc_MinInt( Nf_ObjRequired(p, i, 0), Nf_ObjRequired(p, i, 1) );
|
||||
Tim_ManSetCiRequired( p->pManTim, Gia_ObjCioId(pObj), reqTime );
|
||||
if ( Nf_ObjMapRefNum(p, i, 1) )
|
||||
Nf_ObjUpdateRequired( p, i, 0, Nf_ObjRequired(p, i, 1) - p->InvDelayI );
|
||||
Tim_ManSetCiRequired( p->pManTim, Gia_ObjCioId(pObj), Nf_ObjRequired(p, i, 0) );
|
||||
continue;
|
||||
}
|
||||
if ( Gia_ObjIsCo(pObj) )
|
||||
{
|
||||
reqTime = Tim_ManGetCoRequired( p->pManTim, Gia_ObjCioId(pObj) );
|
||||
Nf_ObjUpdateRequired( p, Gia_ObjFaninId0(pObj, i), Gia_ObjFaninC0(pObj), reqTime );
|
||||
int reqTime = Tim_ManGetCoRequired( p->pManTim, Gia_ObjCioId(pObj) );
|
||||
int iObj = Gia_ObjFaninId0p(p->pGia, pObj);
|
||||
int fCompl = Gia_ObjFaninC0(pObj);
|
||||
Nf_ObjUpdateRequired( p, iObj, fCompl, reqTime );
|
||||
if ( iObj > 0 && Nf_ObjMatchBest(p, iObj, fCompl)->fCompl )
|
||||
Nf_ObjUpdateRequired( p, iObj, !fCompl, reqTime - p->InvDelayI );
|
||||
continue;
|
||||
}
|
||||
for ( c = 0; c < 2; c++ )
|
||||
|
|
|
|||
|
|
@ -965,6 +965,12 @@ Vec_Wec_t * Min_ManComputeCexes( Gia_Man_t * p, Vec_Int_t * vOuts0, int nMaxTrie
|
|||
if ( Vec_IntEntry(vStats[2], i) >= nMinCexes || Vec_IntEntry(vStats[1], i) > 10*Vec_IntEntry(vStats[2], i) )
|
||||
continue;
|
||||
{
|
||||
assert( Gia_ObjIsCo(pObj) );
|
||||
if ( Gia_ObjFaninId0p(p, pObj) == 0 ) {
|
||||
if ( fVerbose )
|
||||
printf( "Output %d is driven by constant %d.\n", Gia_ObjCioId(pObj), Gia_ObjFaninC0(pObj) );
|
||||
continue;
|
||||
}
|
||||
abctime clk = Abc_Clock();
|
||||
int iObj = Min_ManCo(pNew, i);
|
||||
int Index = Gia_ObjCioId(pObj);
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ int Gia_ObjCheckMffc_rec( Gia_Man_t * p,Gia_Obj_t * pObj, int Limit, Vec_Int_t *
|
|||
return 0;
|
||||
return 1;
|
||||
}
|
||||
static inline int Gia_ObjCheckMffc( Gia_Man_t * p, Gia_Obj_t * pRoot, int Limit, Vec_Int_t * vNodes, Vec_Int_t * vLeaves, Vec_Int_t * vInners )
|
||||
int Gia_ObjCheckMffc( Gia_Man_t * p, Gia_Obj_t * pRoot, int Limit, Vec_Int_t * vNodes, Vec_Int_t * vLeaves, Vec_Int_t * vInners )
|
||||
{
|
||||
int RetValue, iObj, i;
|
||||
Vec_IntClear( vNodes );
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
#include "aig/gia/gia.h"
|
||||
|
||||
#include "opt/rrr/rrr.h"
|
||||
#include "opt/rrr/rrrAbc.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
Gia_Man_t *Gia_ManRrr(Gia_Man_t *pGia, int iSeed, int nWords, int nTimeout, int nSchedulerVerbose, int nPartitionerVerbose, int nOptimizerVerbose, int nAnalyzerVerbose, int nSimulatorVerbose, int nSatSolverVerbose, int fUseBddCspf, int fUseBddMspf, int nConflictLimit, int nSortType, int nOptimizerFlow, int nSchedulerFlow, int nDistance, int nRestarts, int nThreads, int nWindowSize, int fDeterministic) {
|
||||
rrr::AndNetwork ntk;
|
||||
ntk.Read(pGia, rrr::GiaReader<rrr::AndNetwork>);
|
||||
rrr::Parameter Par;
|
||||
Par.iSeed = iSeed;
|
||||
Par.nWords = nWords;
|
||||
Par.nTimeout = nTimeout;
|
||||
Par.nSchedulerVerbose = nSchedulerVerbose;
|
||||
Par.nPartitionerVerbose = nPartitionerVerbose;
|
||||
Par.nOptimizerVerbose = nOptimizerVerbose;
|
||||
Par.nAnalyzerVerbose = nAnalyzerVerbose;
|
||||
Par.nSimulatorVerbose = nSimulatorVerbose;
|
||||
Par.nSatSolverVerbose = nSatSolverVerbose;
|
||||
Par.fUseBddCspf = fUseBddCspf;
|
||||
Par.fUseBddMspf = fUseBddMspf;
|
||||
Par.nConflictLimit = nConflictLimit;
|
||||
Par.nSortType = nSortType;
|
||||
Par.nOptimizerFlow = nOptimizerFlow;
|
||||
Par.nSchedulerFlow = nSchedulerFlow;
|
||||
Par.nDistance = nDistance;
|
||||
Par.nRestarts = nRestarts;
|
||||
Par.nThreads = nThreads;
|
||||
Par.nWindowSize = nWindowSize;
|
||||
Par.fDeterministic = fDeterministic;
|
||||
rrr::Perform(&ntk, &Par);
|
||||
Gia_Man_t *pNew = rrr::CreateGia(&ntk);
|
||||
return pNew;
|
||||
}
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
|
@ -25,6 +25,12 @@
|
|||
#include "map/scl/sclCon.h"
|
||||
#include "misc/vec/vecHsh.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define unlink _unlink
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
||||
|
|
@ -1216,6 +1222,351 @@ void Gia_ManLutSat( Gia_Man_t * pGia, int LutSize, int nNumber, int nImproves, i
|
|||
Vec_IntFreeP( &pGia->vPacking );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Gia_RunKadical( char * pFileNameIn, char * pFileNameOut, int nBTLimit, int TimeOut, int fVerbose )
|
||||
{
|
||||
extern Vec_Int_t * Exa4_ManParse( char *pFileName );
|
||||
int fVerboseSolver = 0;
|
||||
abctime clkTotal = Abc_Clock();
|
||||
Vec_Int_t * vRes = NULL;
|
||||
#ifdef _WIN32
|
||||
char * pKadical = "kadical.exe";
|
||||
#else
|
||||
char * pKadical = "kadical";
|
||||
#endif
|
||||
char Command[1000], * pCommand = (char *)&Command;
|
||||
if ( nBTLimit ) {
|
||||
if ( TimeOut )
|
||||
sprintf( pCommand, "%s -c %d -t %d %s %s > %s", pKadical, nBTLimit, TimeOut, fVerboseSolver ? "": "-q", pFileNameIn, pFileNameOut );
|
||||
else
|
||||
sprintf( pCommand, "%s -c %d %s %s > %s", pKadical, nBTLimit, fVerboseSolver ? "": "-q", pFileNameIn, pFileNameOut );
|
||||
}
|
||||
else {
|
||||
if ( TimeOut )
|
||||
sprintf( pCommand, "%s -t %d %s %s > %s", pKadical, TimeOut, fVerboseSolver ? "": "-q", pFileNameIn, pFileNameOut );
|
||||
else
|
||||
sprintf( pCommand, "%s %s %s > %s", pKadical, fVerboseSolver ? "": "-q", pFileNameIn, pFileNameOut );
|
||||
}
|
||||
#ifdef __wasm
|
||||
if ( 1 )
|
||||
#else
|
||||
if ( system( pCommand ) == -1 )
|
||||
#endif
|
||||
{
|
||||
fprintf( stdout, "Command \"%s\" did not succeed.\n", pCommand );
|
||||
return 0;
|
||||
}
|
||||
vRes = Exa4_ManParse( pFileNameOut );
|
||||
if ( fVerbose )
|
||||
{
|
||||
if ( vRes )
|
||||
printf( "The problem has a solution. " );
|
||||
else if ( vRes == NULL && TimeOut == 0 )
|
||||
printf( "The problem has no solution. " );
|
||||
else if ( vRes == NULL )
|
||||
printf( "The problem has no solution or reached a resource limit after %d sec. ", TimeOut );
|
||||
Abc_PrintTime( 1, "SAT solver time", Abc_Clock() - clkTotal );
|
||||
}
|
||||
return vRes;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Gia_SatVarReqPos( int i ) { return i*7+0; } // p
|
||||
int Gia_SatVarReqNeg( int i ) { return i*7+1; } // n
|
||||
int Gia_SatVarAckPos( int i ) { return i*7+2; } // P
|
||||
int Gia_SatVarAckNeg( int i ) { return i*7+3; } // N
|
||||
int Gia_SatVarInv ( int i ) { return i*7+4; } // i
|
||||
int Gia_SatVarFan0 ( int i ) { return i*7+5; } // 0
|
||||
int Gia_SatVarFan1 ( int i ) { return i*7+6; } // 1
|
||||
|
||||
int Gia_SatValReqPos( Vec_Int_t * p, int i ) { return Vec_IntEntry(p, i*7+0); } // p
|
||||
int Gia_SatValReqNeg( Vec_Int_t * p, int i ) { return Vec_IntEntry(p, i*7+1); } // n
|
||||
int Gia_SatValAckPos( Vec_Int_t * p, int i ) { return Vec_IntEntry(p, i*7+2); } // P
|
||||
int Gia_SatValAckNeg( Vec_Int_t * p, int i ) { return Vec_IntEntry(p, i*7+3); } // N
|
||||
int Gia_SatValInv ( Vec_Int_t * p, int i ) { return Vec_IntEntry(p, i*7+4); } // i
|
||||
int Gia_SatValFan0 ( Vec_Int_t * p, int i ) { return Vec_IntEntry(p, i*7+5); } // 0
|
||||
int Gia_SatValFan1 ( Vec_Int_t * p, int i ) { return Vec_IntEntry(p, i*7+6); } // 1
|
||||
|
||||
void Gia_SatDumpClause( Vec_Str_t * vStr, int * pLits, int nLits )
|
||||
{
|
||||
for ( int i = 0; i < nLits; i++ )
|
||||
Vec_StrPrintF( vStr, "%d ", Abc_LitIsCompl(pLits[i]) ? -Abc_Lit2Var(pLits[i])-1 : Abc_Lit2Var(pLits[i])+1 );
|
||||
Vec_StrPrintF( vStr, "0\n" );
|
||||
}
|
||||
void Gia_SatDumpLiteral( Vec_Str_t * vStr, int Lit )
|
||||
{
|
||||
Gia_SatDumpClause( vStr, &Lit, 1 );
|
||||
}
|
||||
void Gia_SatDumpKlause( Vec_Str_t * vStr, int nIns, int nAnds, int nBound )
|
||||
{
|
||||
int i, nVars = nIns + 7*nAnds;
|
||||
Vec_StrPrintF( vStr, "k %d ", nVars - nBound );
|
||||
// counting primary inputs: n
|
||||
for ( i = 0; i < nIns; i++ )
|
||||
Vec_StrPrintF( vStr, "-%d ", Gia_SatVarReqNeg(1+i)+1 );
|
||||
// counting internal nodes: p, n, P, N, i, 0, 1
|
||||
for ( i = 0; i < 7*nAnds; i++ )
|
||||
Vec_StrPrintF( vStr, "-%d ", (1+nIns)*7+i+1 );
|
||||
Vec_StrPrintF( vStr, "0\n" );
|
||||
}
|
||||
|
||||
Vec_Str_t * Gia_ManSimpleCnf( Gia_Man_t * p, int nBound )
|
||||
{
|
||||
Vec_Str_t * vStr = Vec_StrAlloc( 10000 );
|
||||
Gia_SatDumpKlause( vStr, Gia_ManCiNum(p), Gia_ManAndNum(p), nBound );
|
||||
int i, n, m, Id, pLits[4]; Gia_Obj_t * pObj;
|
||||
for ( n = 0; n < 7; n++ )
|
||||
Gia_SatDumpLiteral( vStr, Abc_Var2Lit(n, 1) );
|
||||
// acknowledge positive PI literals
|
||||
Gia_ManForEachCiId( p, Id, i )
|
||||
for ( n = 0; n < 7; n++ ) if ( n != 1 )
|
||||
Gia_SatDumpLiteral( vStr, Abc_Var2Lit(Gia_SatVarReqPos(Id)+n, n>0) );
|
||||
// require driving PO literals
|
||||
Gia_ManForEachCo( p, pObj, i )
|
||||
Gia_SatDumpLiteral( vStr, Abc_Var2Lit( Gia_SatVarReqPos(Gia_ObjFaninId0p(p, pObj)) + Gia_ObjFaninC0(pObj), 0 ) );
|
||||
// internal nodes
|
||||
Gia_ManForEachAnd( p, pObj, i ) {
|
||||
int fCompl[2] = { Gia_ObjFaninC0(pObj), Gia_ObjFaninC1(pObj) };
|
||||
int iFans[2] = { Gia_ObjFaninId0(pObj, i), Gia_ObjFaninId1(pObj, i) };
|
||||
Gia_Obj_t * pFans[2] = { Gia_ObjFanin0(pObj), Gia_ObjFanin1(pObj) };
|
||||
// require inverter: p & !n & N -> i, n & !p & P -> i
|
||||
for ( n = 0; n < 2; n++ ) {
|
||||
pLits[0] = Abc_Var2Lit( Gia_SatVarReqPos(i)+n, 1 );
|
||||
pLits[1] = Abc_Var2Lit( Gia_SatVarReqNeg(i)-n, 0 );
|
||||
pLits[2] = Abc_Var2Lit( Gia_SatVarAckNeg(i)-n, 1 );
|
||||
pLits[3] = Abc_Var2Lit( Gia_SatVarInv (i), 0 );
|
||||
Gia_SatDumpClause( vStr, pLits, 4 );
|
||||
}
|
||||
// exclusive acknowledge: !P + !N
|
||||
pLits[0] = Abc_Var2Lit( Gia_SatVarAckPos(i), 1 );
|
||||
pLits[1] = Abc_Var2Lit( Gia_SatVarAckNeg(i), 1 );
|
||||
Gia_SatDumpClause( vStr, pLits, 2 );
|
||||
// required acknowledge: p -> P + N, n -> P + N
|
||||
pLits[1] = Abc_Var2Lit( Gia_SatVarAckPos(i), 0 );
|
||||
pLits[2] = Abc_Var2Lit( Gia_SatVarAckNeg(i), 0 );
|
||||
pLits[0] = Abc_Var2Lit( Gia_SatVarReqPos(i), 1 );
|
||||
Gia_SatDumpClause( vStr, pLits, 3 );
|
||||
pLits[0] = Abc_Var2Lit( Gia_SatVarReqNeg(i), 1 );
|
||||
Gia_SatDumpClause( vStr, pLits, 3 );
|
||||
// forbid acknowledge: !p & !n -> !P, !p & !n -> !N
|
||||
pLits[0] = Abc_Var2Lit( Gia_SatVarReqPos(i), 0 );
|
||||
pLits[1] = Abc_Var2Lit( Gia_SatVarReqNeg(i), 0 );
|
||||
pLits[2] = Abc_Var2Lit( Gia_SatVarAckPos(i), 1 );
|
||||
Gia_SatDumpClause( vStr, pLits, 3 );
|
||||
pLits[2] = Abc_Var2Lit( Gia_SatVarAckNeg(i), 1 );
|
||||
Gia_SatDumpClause( vStr, pLits, 3 );
|
||||
// when fanins can be used: !N & !P -> !0, !N & !P -> !1
|
||||
pLits[0] = Abc_Var2Lit( Gia_SatVarAckPos(i), 0 );
|
||||
pLits[1] = Abc_Var2Lit( Gia_SatVarAckNeg(i), 0 );
|
||||
pLits[2] = Abc_Var2Lit( Gia_SatVarFan0(i), 1 );
|
||||
Gia_SatDumpClause( vStr, pLits, 3 );
|
||||
pLits[2] = Abc_Var2Lit( Gia_SatVarFan1(i), 1 );
|
||||
Gia_SatDumpClause( vStr, pLits, 3 );
|
||||
// when fanins are not used: 0 -> !N, 0 -> !P, 1 -> !N, 1 -> !P
|
||||
for ( m = 0; m < 2; m++ )
|
||||
for ( n = 0; n < 2; n++ ) {
|
||||
pLits[0] = Abc_Var2Lit( Gia_SatVarFan0(i)+n, 1 );
|
||||
pLits[1] = Abc_Var2Lit( Gia_SatVarReqPos(iFans[n])+m, 1 );
|
||||
Gia_SatDumpClause( vStr, pLits, 2 );
|
||||
}
|
||||
// can only extend both when both complemented: !(C0 & C1) -> !0 + !1
|
||||
pLits[0] = Abc_Var2Lit( Gia_SatVarFan0(i), 1 );
|
||||
pLits[1] = Abc_Var2Lit( Gia_SatVarFan1(i), 1 );
|
||||
if ( !fCompl[0] || !fCompl[1] )
|
||||
Gia_SatDumpClause( vStr, pLits, 2 );
|
||||
// if fanin is a primary input, cannot extend it (pi -> !0 or pi -> !1)
|
||||
for ( n = 0; n < 2; n++ )
|
||||
if ( Gia_ObjIsCi(pFans[n]) )
|
||||
Gia_SatDumpLiteral( vStr, Abc_Var2Lit( Gia_SatVarFan0(i)+n, 1 ) );
|
||||
// propagating assignments when fanin is not used
|
||||
// P & !0 -> C0 ? P0 : N0
|
||||
// N & !0 -> C0 ? N0 : P0
|
||||
// P & !1 -> C1 ? P1 : N1
|
||||
// N & !1 -> C1 ? N1 : P1
|
||||
for ( m = 0; m < 2; m++ )
|
||||
for ( n = 0; n < 2; n++ ) {
|
||||
pLits[0] = Abc_Var2Lit( Gia_SatVarAckPos(i)+m, 1 );
|
||||
pLits[1] = Abc_Var2Lit( Gia_SatVarFan0(i)+n, 0 );
|
||||
pLits[2] = Abc_Var2Lit( Gia_SatVarReqPos(iFans[n]) + !(m ^ fCompl[n]), 0 );
|
||||
Gia_SatDumpClause( vStr, pLits, 3 );
|
||||
}
|
||||
// propagating assignments when fanins are used
|
||||
// P & 0 -> (C0 ^ C00) ? P00 : N00
|
||||
// P & 0 -> (C0 ^ C01) ? P01 : N01
|
||||
// N & 0 -> (C0 ^ C00) ? N00 : P00
|
||||
// N & 0 -> (C0 ^ C01) ? N01 : P01
|
||||
// P & 1 -> (C1 ^ C10) ? P10 : N10
|
||||
// P & 1 -> (C1 ^ C11) ? P11 : N11
|
||||
// N & 1 -> (C1 ^ C10) ? N10 : P10
|
||||
// N & 1 -> (C1 ^ C11) ? N11 : P11
|
||||
for ( m = 0; m < 2; m++ )
|
||||
for ( n = 0; n < 2; n++ )
|
||||
if ( Gia_ObjIsAnd(pFans[n]) ) {
|
||||
pLits[0] = Abc_Var2Lit( Gia_SatVarAckPos(i)+m, 1 );
|
||||
pLits[1] = Abc_Var2Lit( Gia_SatVarFan0(i)+n, 1 );
|
||||
pLits[2] = Abc_Var2Lit( Gia_SatVarReqPos(Gia_ObjFaninId0p(p, pFans[n])) + !(m ^ fCompl[n] ^ Gia_ObjFaninC0(pFans[n])), 0 );
|
||||
Gia_SatDumpClause( vStr, pLits, 3 );
|
||||
pLits[2] = Abc_Var2Lit( Gia_SatVarReqPos(Gia_ObjFaninId1p(p, pFans[n])) + !(m ^ fCompl[n] ^ Gia_ObjFaninC1(pFans[n])), 0 );
|
||||
Gia_SatDumpClause( vStr, pLits, 3 );
|
||||
}
|
||||
}
|
||||
Vec_StrPush( vStr, '\0' );
|
||||
return vStr;
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
GIA_GATE_ZERO, // 0:
|
||||
GIA_GATE_ONE, // 1:
|
||||
GIA_GATE_BUF, // 2:
|
||||
GIA_GATE_INV, // 3:
|
||||
GIA_GATE_NAN2, // 4:
|
||||
GIA_GATE_NOR2, // 5:
|
||||
GIA_GATE_AOI21, // 6:
|
||||
GIA_GATE_NAN3, // 7:
|
||||
GIA_GATE_NOR3, // 8:
|
||||
GIA_GATE_OAI21, // 9:
|
||||
GIA_GATE_AOI22, // 10:
|
||||
GIA_GATE_OAI22, // 11:
|
||||
RTM_VAL_VOID // 12: unused value
|
||||
} Gia_ManGate_t;
|
||||
|
||||
Vec_Int_t * Gia_ManDeriveSimpleMapping( Gia_Man_t * p, Vec_Int_t * vRes )
|
||||
{
|
||||
Vec_Int_t * vMapping = Vec_IntStart( 2*Gia_ManObjNum(p) );
|
||||
int i, Id; Gia_Obj_t * pObj;
|
||||
Gia_ManForEachCiId( p, Id, i )
|
||||
if ( Gia_SatValReqNeg(vRes, Id) )
|
||||
Vec_IntWriteEntry( vMapping, Abc_Var2Lit(Id, 1), -1 );
|
||||
Gia_ManForEachAnd( p, pObj, i )
|
||||
{
|
||||
if ( Gia_SatValAckPos(vRes, i) + Gia_SatValAckNeg(vRes, i) == 0 )
|
||||
continue;
|
||||
assert( Gia_SatValAckPos(vRes, i) != Gia_SatValAckNeg(vRes, i) );
|
||||
if ( (Gia_SatValReqPos(vRes, i) && Gia_SatValReqNeg(vRes, i)) || Gia_SatValInv(vRes, i) )
|
||||
Vec_IntWriteEntry( vMapping, Abc_Var2Lit(i, Gia_SatValAckPos(vRes, i)), -1 );
|
||||
int fComp = Gia_SatValAckNeg(vRes, i);
|
||||
int fFan0 = Gia_SatValFan0(vRes, i);
|
||||
int fFan1 = Gia_SatValFan1(vRes, i);
|
||||
Gia_Obj_t * pFans[2] = { Gia_ObjFanin0(pObj), Gia_ObjFanin1(pObj) };
|
||||
Vec_IntWriteEntry( vMapping, Abc_Var2Lit(i, fComp), Vec_IntSize(vMapping) );
|
||||
if ( fFan0 && fFan1 ) {
|
||||
assert( Gia_ObjFaninC0(pObj) && Gia_ObjFaninC1(pObj) );
|
||||
Vec_IntPush( vMapping, 4 );
|
||||
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId0p(p, pFans[0]), !(fComp ^ Gia_ObjFaninC0(pObj) ^ Gia_ObjFaninC0(pFans[0]))) );
|
||||
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId1p(p, pFans[0]), !(fComp ^ Gia_ObjFaninC0(pObj) ^ Gia_ObjFaninC1(pFans[0]))) );
|
||||
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId0p(p, pFans[1]), !(fComp ^ Gia_ObjFaninC1(pObj) ^ Gia_ObjFaninC0(pFans[1]))) );
|
||||
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId1p(p, pFans[1]), !(fComp ^ Gia_ObjFaninC1(pObj) ^ Gia_ObjFaninC1(pFans[1]))) );
|
||||
Vec_IntPush( vMapping, fComp ? GIA_GATE_OAI22 : GIA_GATE_AOI22 );
|
||||
} else if ( fFan0 ) {
|
||||
Vec_IntPush( vMapping, 3 );
|
||||
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId0p(p, pFans[0]), !(fComp ^ Gia_ObjFaninC0(pObj) ^ Gia_ObjFaninC0(pFans[0]))) );
|
||||
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId1p(p, pFans[0]), !(fComp ^ Gia_ObjFaninC0(pObj) ^ Gia_ObjFaninC1(pFans[0]))) );
|
||||
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId1p(p, pObj), !(fComp ^ Gia_ObjFaninC1(pObj))) );
|
||||
if ( Gia_ObjFaninC0(pObj) )
|
||||
Vec_IntPush( vMapping, fComp ? GIA_GATE_OAI21 : GIA_GATE_AOI21 );
|
||||
else
|
||||
Vec_IntPush( vMapping, fComp ? GIA_GATE_NAN3 : GIA_GATE_NOR3 );
|
||||
} else if ( fFan1 ) {
|
||||
Vec_IntPush( vMapping, 3 );
|
||||
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId0p(p, pFans[1]), !(fComp ^ Gia_ObjFaninC1(pObj) ^ Gia_ObjFaninC0(pFans[1]))) );
|
||||
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId1p(p, pFans[1]), !(fComp ^ Gia_ObjFaninC1(pObj) ^ Gia_ObjFaninC1(pFans[1]))) );
|
||||
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId0p(p, pObj), !(fComp ^ Gia_ObjFaninC0(pObj))) );
|
||||
if ( Gia_ObjFaninC1(pObj) )
|
||||
Vec_IntPush( vMapping, fComp ? GIA_GATE_OAI21 : GIA_GATE_AOI21 );
|
||||
else
|
||||
Vec_IntPush( vMapping, fComp ? GIA_GATE_NAN3 : GIA_GATE_NOR3 );
|
||||
} else {
|
||||
Vec_IntPush( vMapping, 2 );
|
||||
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId0p(p, pObj), !(fComp ^ Gia_ObjFaninC0(pObj))) );
|
||||
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId1p(p, pObj), !(fComp ^ Gia_ObjFaninC1(pObj))) );
|
||||
Vec_IntPush( vMapping, fComp ? GIA_GATE_NAN2 : GIA_GATE_NOR2 );
|
||||
}
|
||||
}
|
||||
return vMapping;
|
||||
}
|
||||
void Gia_ManSimplePrintMapping( Vec_Int_t * vRes, int nIns )
|
||||
{
|
||||
int i, k, nObjs = Vec_IntSize(vRes)/7, nSteps = Abc_Base10Log(nObjs);
|
||||
int nCard = Vec_IntSum(vRes) - nIns; char NumStr[10];
|
||||
printf( "Solution with cardinality %d:\n", nCard );
|
||||
for ( k = 0; k < nSteps; k++ ) {
|
||||
printf( " " );
|
||||
for ( i = 0; i < nObjs; i++ ) {
|
||||
sprintf( NumStr, "%02d", i );
|
||||
printf( "%c", NumStr[k] );
|
||||
}
|
||||
printf( "\n" );
|
||||
}
|
||||
for ( k = 0; k < 7; k++ ) {
|
||||
printf( "%c ", "pnPNi01"[k] );
|
||||
for ( i = 0; i < nObjs; i++ )
|
||||
if ( Vec_IntEntry( vRes, i*7+k ) == 0 )
|
||||
printf( " " );
|
||||
else
|
||||
printf( "1" );
|
||||
printf( "\n" );
|
||||
}
|
||||
}
|
||||
int Gia_ManDumpCnf( char * pFileName, Vec_Str_t * vStr, int nVars )
|
||||
{
|
||||
FILE * pFile = fopen( pFileName, "wb" );
|
||||
if ( pFile == NULL ) { printf( "Cannot open input file \"%s\".\n", pFileName ); return 0; }
|
||||
fprintf( pFile, "p knf %d %d\n%s\n", nVars, Vec_StrCountEntry(vStr, '\n'), Vec_StrArray(vStr) );
|
||||
fclose( pFile );
|
||||
return 1;
|
||||
}
|
||||
int Gia_ManSimpleMapping( Gia_Man_t * p, int nBound, int nBTLimit, int nTimeout, int fVerbose )
|
||||
{
|
||||
char * pFileNameI = (char *)"__temp__.cnf";
|
||||
char * pFileNameO = (char *)"__temp__.out";
|
||||
if ( nBound == 0 )
|
||||
nBound = 5 * Gia_ManAndNum(p);
|
||||
Vec_Str_t * vStr = Gia_ManSimpleCnf( p, nBound/2 );
|
||||
int nVars = 7*(Gia_ManObjNum(p)-Gia_ManCoNum(p));
|
||||
if ( !Gia_ManDumpCnf(pFileNameI, vStr, nVars) ) {
|
||||
Vec_StrFree( vStr );
|
||||
return 0;
|
||||
}
|
||||
if ( fVerbose )
|
||||
printf( "SAT variables = %d. SAT clauses = %d. Cardinality bound = %d. Conflict limit = %d. Timeout = %d.\n",
|
||||
nVars, Vec_StrCountEntry(vStr, '\n'), nBound, nBTLimit, nTimeout );
|
||||
//char pFileName[100]; sprintf( pFileName, "temp%02d.cnf", nBound/2 );
|
||||
//Gia_ManDumpCnf( pFileName, vStr, nVars );
|
||||
Vec_StrFree( vStr );
|
||||
Vec_Int_t * vRes = Gia_RunKadical( pFileNameI, pFileNameO, nBTLimit, nTimeout, 1 );
|
||||
unlink( pFileNameI );
|
||||
//unlink( pFileNameO );
|
||||
if ( vRes == NULL )
|
||||
return 0;
|
||||
Vec_IntFreeP( &p->vCellMapping );
|
||||
assert( p->vCellMapping == NULL );
|
||||
Vec_IntDrop( vRes, 0 );
|
||||
if ( fVerbose ) Gia_ManSimplePrintMapping( vRes, Gia_ManCiNum(p) );
|
||||
p->vCellMapping = Gia_ManDeriveSimpleMapping( p, vRes );
|
||||
Vec_IntFree( vRes );
|
||||
return 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -645,6 +645,25 @@ Gia_Man_t * Gia_ManSifPerform( Gia_Man_t * p, int nLutSize, int fEvalOnly, int f
|
|||
pNew = Gia_ManSifTransform( p, vCuts, vTimes, nLutSize, Upper, fVerbose );
|
||||
Vec_IntFree( vCuts );
|
||||
Vec_IntFree( vTimes );
|
||||
//Gia_ManTransferTiming( pNew, p );
|
||||
if ( p->vNamesIn ) {
|
||||
char * pName; int i;
|
||||
pNew->vNamesIn = p->vNamesIn; p->vNamesIn = NULL;
|
||||
Vec_PtrForEachEntryStart( char *, pNew->vNamesIn, pName, i, Gia_ManPiNum(pNew) )
|
||||
ABC_FREE( pName );
|
||||
Vec_PtrShrink( pNew->vNamesIn, Gia_ManPiNum(pNew) );
|
||||
for ( i = 0; i < Gia_ManRegNum(pNew); i++ )
|
||||
Vec_PtrPush( pNew->vNamesIn, Abc_UtilStrsavNum("_fo", i) );
|
||||
}
|
||||
if ( p->vNamesOut ) {
|
||||
char * pName; int i;
|
||||
pNew->vNamesOut = p->vNamesOut; p->vNamesOut = NULL;
|
||||
Vec_PtrForEachEntryStart( char *, pNew->vNamesOut, pName, i, Gia_ManPoNum(pNew) )
|
||||
ABC_FREE( pName );
|
||||
Vec_PtrShrink( pNew->vNamesOut, Gia_ManPoNum(pNew) );
|
||||
for ( i = 0; i < Gia_ManRegNum(pNew); i++ )
|
||||
Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsavNum("_fi", i) );
|
||||
}
|
||||
return pNew;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -612,7 +612,7 @@ Vec_Int_t * Gia_ManSwiSimulate( Gia_Man_t * pAig, Gia_ParSwi_t * pPars )
|
|||
else if ( pPars->fProbTrans )
|
||||
{
|
||||
Gia_ManForEachObj( pAig, pObj, i )
|
||||
pSwitching[i] = Gia_ManSwiComputeProbOne( p->pData1[i], pPars->nWords*(pPars->nIters-pPars->nPref) );
|
||||
pSwitching[i] = Gia_ManSwiComputeSwitching( p->pData1[i], pPars->nWords*(pPars->nIters-pPars->nPref) );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -559,6 +559,11 @@ void Gia_ObjComputeTruthTableStart( Gia_Man_t * p, int nVarsMax )
|
|||
p->vTtMemory = Vec_WrdStart( p->nTtWords * 64 );
|
||||
p->vTtNums = Vec_IntAlloc( Gia_ManObjNum(p) + 1000 );
|
||||
Vec_IntFill( p->vTtNums, Vec_IntCap(p->vTtNums), -ABC_INFINITY );
|
||||
if ( nVarsMax >= 6 ) {
|
||||
word * pTruth; int i;
|
||||
Vec_PtrForEachEntry( word *, p->vTtInputs, pTruth, i )
|
||||
Abc_TtFlipVar5( pTruth, nVarsMax );
|
||||
}
|
||||
}
|
||||
void Gia_ObjComputeTruthTableStop( Gia_Man_t * p )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -3453,6 +3453,117 @@ Gia_Man_t * Gia_ManDupInsertWindows( Gia_Man_t * p, Vec_Ptr_t * vvIns, Vec_Ptr_t
|
|||
return pNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computing equivalent nodes across the two AIGs.]
|
||||
|
||||
Description [Assumes that both AIGs are structurally hashed without dandling nodes.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Gia_Man_t * Gia_ManCreateDualOutputMiter( Gia_Man_t * p0, Gia_Man_t * p1 )
|
||||
{
|
||||
Gia_Man_t * pNew; Gia_Obj_t * pObj; int i;
|
||||
assert( Gia_ManCiNum(p0) == Gia_ManCiNum(p1) );
|
||||
assert( Gia_ManCoNum(p0) == Gia_ManCoNum(p1) );
|
||||
// start the manager
|
||||
pNew = Gia_ManStart( Gia_ManObjNum(p0) + Gia_ManObjNum(p1) );
|
||||
pNew->pName = Abc_UtilStrsav( "miter" );
|
||||
Gia_ManFillValue( p0 );
|
||||
Gia_ManFillValue( p1 );
|
||||
// map combinational inputs
|
||||
Gia_ManConst0(p0)->Value = 0;
|
||||
Gia_ManConst0(p1)->Value = 0;
|
||||
Gia_ManForEachCi( p0, pObj, i )
|
||||
Gia_ManCi(p1, i)->Value = pObj->Value = Gia_ManAppendCi( pNew );
|
||||
// map internal nodes and outputs
|
||||
Gia_ManHashAlloc( pNew );
|
||||
Gia_ManForEachAnd( p0, pObj, i )
|
||||
pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
|
||||
assert( Gia_ManAndNum(pNew) == Gia_ManAndNum(p0) ); // the input AIG p0 is structurally hashed
|
||||
Gia_ManForEachAnd( p1, pObj, i )
|
||||
pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
|
||||
// add the outputs
|
||||
Gia_ManForEachCo( p0, pObj, i )
|
||||
pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
|
||||
Gia_ManForEachCo( p1, pObj, i )
|
||||
pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
|
||||
printf( "The two AIGs have %d structurally equivalent nodes.\n", Gia_ManAndNum(p0) + Gia_ManAndNum(p1) - Gia_ManAndNum(pNew) );
|
||||
// there should be no dangling nodes (otherwise, the second AIG may not be structurally hashed)
|
||||
int nDangling = Gia_ManMarkDangling(pNew);
|
||||
assert( nDangling == 0 );
|
||||
Gia_ManCleanMark01(pNew);
|
||||
return pNew;
|
||||
}
|
||||
Vec_Int_t * Gia_ManFindMutualEquivs( Gia_Man_t * p0, Gia_Man_t * p1, int nConflictLimit, int fVerbose )
|
||||
{
|
||||
Vec_Int_t * vPairs = Vec_IntAlloc( 100 );
|
||||
// derive the miter
|
||||
Gia_Man_t * pMiter = Gia_ManCreateDualOutputMiter( p0, p1 );
|
||||
//Gia_ManPrintStats( pMiter, NULL );
|
||||
//Gia_AigerWrite( pMiter, "out.aig", 0, 0, 0 );
|
||||
// perform SAT sweeping
|
||||
extern Gia_Man_t * Cec4_ManSimulateTest3( Gia_Man_t * p, int nBTLimit, int fVerbose );
|
||||
Gia_Man_t * pNew = Cec4_ManSimulateTest3( pMiter, nConflictLimit, fVerbose );
|
||||
Gia_ManStop( pNew );
|
||||
// now, pMiter is annotated with the equiv class info
|
||||
|
||||
// here we collect AIG node pairs with the following properties:
|
||||
// - the first node belongs to p0; the second node belongs to p1
|
||||
// - both nodes are internal nodes of p0 and p1 (not primary inputs/outputs)
|
||||
// - these nodes are combinationally equivalent (possibly up to the complement)
|
||||
// - these nodes are "singleton" equivalences (no other nodes in p0 and p1 are equivalent to them)
|
||||
// - these nodes are not structurally equivalent (that is, they have structurally different TFI logic cones)
|
||||
|
||||
// count the number of nodes in each equivalence class
|
||||
Vec_Int_t * vCounts = Vec_IntStart( Gia_ManObjNum(pMiter) );
|
||||
Gia_Obj_t * pObj; int i, k;
|
||||
Gia_ManForEachClass( pMiter, i )
|
||||
Gia_ClassForEachObj( pMiter, i, k )
|
||||
Vec_IntAddToEntry( vCounts, i, 1 );
|
||||
|
||||
// map each miter node coming from p1 into the corresponding node in p1
|
||||
Vec_Int_t * vMap = Vec_IntStartFull( Gia_ManObjNum(pMiter) );
|
||||
int iStartP1 = 1 + Gia_ManPiNum(p0) + Gia_ManAndNum(p0);
|
||||
Gia_ManForEachAnd( p1, pObj, i )
|
||||
if ( Abc_Lit2Var(pObj->Value) >= iStartP1 ) // node from p1 (not from p0)
|
||||
Vec_IntWriteEntry( vMap, Abc_Lit2Var(pObj->Value), i );
|
||||
|
||||
// go through functionally (not structurally!) equivalent nodes in the second AIG
|
||||
// and collect those node pairs from p0 and p1 whose equivalence class contains exactly two nodes
|
||||
for ( i = iStartP1; i < Gia_ManObjNum(pMiter) - Gia_ManCoNum(pMiter); i++ ) {
|
||||
assert( Gia_ObjIsAnd(Gia_ManObj(pMiter, i)) );
|
||||
int Repr = Gia_ObjRepr(pMiter, i);
|
||||
if ( Repr == GIA_VOID || Repr >= iStartP1 || Vec_IntEntry(vCounts, Repr) != 2 )
|
||||
continue;
|
||||
assert( Repr < iStartP1 ); // node in p0
|
||||
assert( Vec_IntEntry(vMap, i) > 0 ); // node in p1
|
||||
Vec_IntPushTwo( vPairs, Repr, Vec_IntEntry(vMap, i) );
|
||||
}
|
||||
// cleanup
|
||||
Vec_IntFree( vMap );
|
||||
Vec_IntFree( vCounts );
|
||||
Gia_ManStop( pMiter );
|
||||
return vPairs;
|
||||
}
|
||||
void Gia_ManFindMutualEquivsTest()
|
||||
{
|
||||
Gia_Man_t * p0 = Gia_AigerRead( "p0.aig", 0, 0, 0 );
|
||||
Gia_Man_t * p1 = Gia_AigerRead( "p1.aig", 0, 0, 0 );
|
||||
Vec_Int_t * vPairs = Gia_ManFindMutualEquivs( p0, p1, 0, 0 );
|
||||
printf( "Pair Aig0 node Aig1 node\n" );
|
||||
int i, Obj0, Obj1;
|
||||
Vec_IntForEachEntryDouble( vPairs, Obj0, Obj1, i )
|
||||
printf( "%3d %6d %6d\n", i/2, Obj0, Obj1 );
|
||||
Gia_ManStop( p0 );
|
||||
Gia_ManStop( p1 );
|
||||
Vec_IntFree( vPairs );
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ SRC += src/aig/gia/giaAig.c \
|
|||
src/aig/gia/giaResub6.c \
|
||||
src/aig/gia/giaRetime.c \
|
||||
src/aig/gia/giaRex.c \
|
||||
src/aig/gia/giaRrr.cpp \
|
||||
src/aig/gia/giaSatEdge.c \
|
||||
src/aig/gia/giaSatLE.c \
|
||||
src/aig/gia/giaSatLut.c \
|
||||
|
|
@ -111,4 +112,4 @@ SRC += src/aig/gia/giaAig.c \
|
|||
src/aig/gia/giaTtopt.cpp \
|
||||
src/aig/gia/giaUnate.c \
|
||||
src/aig/gia/giaUtil.c \
|
||||
src/aig/gia/giaBound.c
|
||||
src/aig/gia/giaBound.c
|
||||
|
|
|
|||
|
|
@ -219,7 +219,8 @@ static inline void Ndr_DataPushString( Ndr_Data_t * p, int ObjType, int Type, ch
|
|||
{
|
||||
//word Truth = (word)pFunc;
|
||||
//Ndr_DataPushArray( p, Type, 2, (int *)&Truth );
|
||||
Ndr_DataPushArray( p, Type, 2, (int *)&pFunc );
|
||||
int nInts = (strlen(pFunc) + 1 + sizeof(int) - 1) / sizeof(int);
|
||||
Ndr_DataPushArray( p, Type, nInts, (int *)&pFunc );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -640,6 +640,7 @@ extern ABC_DLL Vec_Ptr_t * Abc_AigDfsMap( Abc_Ntk_t * pNtk );
|
|||
extern ABC_DLL Vec_Vec_t * Abc_DfsLevelized( Abc_Obj_t * pNode, int fTfi );
|
||||
extern ABC_DLL Vec_Vec_t * Abc_NtkLevelize( Abc_Ntk_t * pNtk );
|
||||
extern ABC_DLL int Abc_NtkLevel( Abc_Ntk_t * pNtk );
|
||||
extern ABC_DLL int Abc_NtkLevelR( Abc_Ntk_t * pNtk );
|
||||
extern ABC_DLL int Abc_NtkLevelReverse( Abc_Ntk_t * pNtk );
|
||||
extern ABC_DLL int Abc_NtkIsAcyclic( Abc_Ntk_t * pNtk );
|
||||
extern ABC_DLL int Abc_NtkIsAcyclicWithBoxes( Abc_Ntk_t * pNtk );
|
||||
|
|
|
|||
|
|
@ -1514,6 +1514,14 @@ int Abc_NtkLevelReverse( Abc_Ntk_t * pNtk )
|
|||
}
|
||||
return LevelsMax;
|
||||
}
|
||||
int Abc_NtkLevelR( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
int i, LevelMax = Abc_NtkLevelReverse( pNtk );
|
||||
Abc_Obj_t * pNode;
|
||||
Abc_NtkForEachObj( pNtk, pNode, i )
|
||||
pNode->Level = (int)(LevelMax - pNode->Level + 1);
|
||||
return LevelMax;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
|
|||
|
|
@ -1344,10 +1344,11 @@ Abc_Ntk_t * Abc_NtkCreateWithNodes( Vec_Ptr_t * vSop )
|
|||
Abc_NodeFreeNames( vNames );
|
||||
// create the node, add PIs as fanins, set the function
|
||||
Vec_PtrForEachEntry( char *, vSop, pSop, i )
|
||||
{
|
||||
{
|
||||
pNode = Abc_NtkCreateNode( pNtkNew );
|
||||
Abc_NtkForEachPi( pNtkNew, pFanin, k )
|
||||
Abc_ObjAddFanin( pNode, pFanin );
|
||||
if ( Abc_SopGetVarNum(pSop) > 0 )
|
||||
Abc_NtkForEachPi( pNtkNew, pFanin, k )
|
||||
Abc_ObjAddFanin( pNode, pFanin );
|
||||
pNode->pData = Abc_SopRegister( (Mem_Flex_t *)pNtkNew->pManFunc, pSop );
|
||||
// create the only PO
|
||||
pNodePo = Abc_NtkCreatePo(pNtkNew);
|
||||
|
|
|
|||
1531
src/base/abci/abc.c
1531
src/base/abci/abc.c
File diff suppressed because it is too large
Load Diff
|
|
@ -21,10 +21,11 @@
|
|||
#include "base/abc/abc.h"
|
||||
#include "bool/kit/kit.h"
|
||||
#include "aig/miniaig/miniaig.h"
|
||||
#include "misc/util/utilTruth.h"
|
||||
|
||||
#ifdef ABC_USE_CUDD
|
||||
#include "bdd/extrab/extraBdd.h"
|
||||
#include "bdd/extrab/extraLutCas.h"
|
||||
//#include "bdd/extrab/extraLutCas.h"
|
||||
#endif
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
|
@ -119,7 +120,7 @@ Abc_Ntk_t * Abc_NtkCascade( Abc_Ntk_t * pNtk, int nLutSize, int fCheck, int fVer
|
|||
#else
|
||||
|
||||
Abc_Ntk_t * Abc_NtkCascade( Abc_Ntk_t * pNtk, int nLutSize, int fCheck, int fVerbose ) { return NULL; }
|
||||
word * Abc_LutCascade( Mini_Aig_t * p, int nLutSize, int fVerbose ) { return NULL; }
|
||||
word * Abc_LutCascade( Mini_Aig_t * p, int nLutSize, int nLuts, int nRails, int nIters, int fVerbose ) { return NULL; }
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -131,7 +132,7 @@ word * Abc_LutCascade( Mini_Aig_t * p, int nLutSize, int fVerbose ) { return NUL
|
|||
- the number of words in this block
|
||||
- the number of fanins
|
||||
- the list of fanins
|
||||
- the variable ID of the output (can be one of the fanin variables)
|
||||
- the variable ID of the output (should be a LUT counter starting with the number of variables)
|
||||
- truth tables (one word for 6 vars or less; more words as needed for more than 6 vars)
|
||||
For a 6-input node, the LUT info block takes 10 words (block size, fanin count, 6 fanins, output ID, truth table).
|
||||
For a 4-input node, the LUT info block takes 8 words (block size, fanin count, 4 fanins, output ID, truth table).
|
||||
|
|
@ -159,37 +160,157 @@ word * Abc_LutCascadeGenTest()
|
|||
pLuts[1+1] = 6;
|
||||
for ( i = 0; i < 6; i++ )
|
||||
pLuts[1+2+i] = i;
|
||||
pLuts[1+8] = 0;
|
||||
pLuts[1+8] = 9;
|
||||
pLuts[1+9] = ABC_CONST(0x8000000000000000);
|
||||
// second node
|
||||
pLuts[11+0] = 8;
|
||||
pLuts[11+1] = 4;
|
||||
for ( i = 0; i < 4; i++ )
|
||||
pLuts[11+2+i] = i ? i + 5 : 0;
|
||||
pLuts[11+6] = 1;
|
||||
pLuts[11+2+i] = i ? i + 5 : 9;
|
||||
pLuts[11+6] = 10;
|
||||
pLuts[11+7] = ABC_CONST(0xFFFEFFFEFFFEFFFE);
|
||||
return pLuts;
|
||||
}
|
||||
void Abc_LutCascadePrintLut( word * pLuts, int n, int i )
|
||||
{
|
||||
word nIns = pLuts[i+1];
|
||||
word * pIns = pLuts+i+2;
|
||||
word * pT = pLuts+i+2+nIns+1;
|
||||
printf( "LUT%d : ", n );
|
||||
printf( "%c = F( ", 'a'+(int)pIns[nIns] );
|
||||
for ( int k = 0; k < nIns; k++ )
|
||||
printf( "%c ", 'a'+(int)pIns[k] );
|
||||
printf( ") " );
|
||||
Abc_TtPrintHexRev( stdout, pT, nIns );
|
||||
printf( "\n" );
|
||||
}
|
||||
void Abc_LutCascadePrint( word * pLuts )
|
||||
{
|
||||
int n, i, k;
|
||||
printf( "Single-rail LUT cascade has %d nodes:\n", (int)pLuts[0] );
|
||||
int n, i;
|
||||
printf( "The LUT cascade contains %d LUTs:\n", (int)pLuts[0] );
|
||||
for ( n = 0, i = 1; n < pLuts[0]; n++, i += pLuts[i] )
|
||||
Abc_LutCascadePrintLut( pLuts, n, i );
|
||||
}
|
||||
void Abc_LutCascadeGenOne( Vec_Wrd_t * vRes, int nIns, int * pIns, int Out, word * p )
|
||||
{
|
||||
int w, nWords = Abc_TtWordNum(nIns);
|
||||
//int iStart = Vec_WrdSize(vRes);
|
||||
Vec_WrdAddToEntry(vRes, 0, 1);
|
||||
Vec_WrdPush( vRes, 3+nIns+nWords );
|
||||
Vec_WrdPush( vRes, nIns );
|
||||
for ( w = 0; w < nIns; w++ )
|
||||
Vec_WrdPush( vRes, pIns[w] );
|
||||
Vec_WrdPush( vRes, Out );
|
||||
if ( nIns < 6 )
|
||||
Vec_WrdPush( vRes, p ? p[0] : Abc_Tt6Stretch(Abc_Random(0), nIns) );
|
||||
else
|
||||
for ( w = 0; w < nWords; w++ )
|
||||
Vec_WrdPush( vRes, p ? p[w] : Abc_RandomW(0) );
|
||||
//printf("Adding LUT: "); Abc_LutCascadePrintLut( Vec_WrdArray(vRes), 0, iStart );
|
||||
}
|
||||
word * Abc_LutCascadeGen( int nVars, int nLutSize, int nRails, int nShared )
|
||||
{
|
||||
assert( nLutSize - nRails - nShared > 0 );
|
||||
Vec_Wrd_t * vRes = Vec_WrdStart( 1 );
|
||||
Vec_Int_t * vFanins = Vec_IntAlloc( nLutSize );
|
||||
Vec_Int_t * vVars = Vec_IntStartNatural( nVars );
|
||||
Vec_Str_t * vGuide = Vec_StrAlloc( 100 );
|
||||
Abc_Random(1);
|
||||
int i, c = 0, Obj, iVarNext = nVars, iVarPrev = -1;
|
||||
while ( Vec_IntSize(vVars) > nLutSize ) {
|
||||
if ( Vec_WrdSize(vRes) > 1 )
|
||||
for ( i = 0; i < nRails; i++ )
|
||||
Vec_IntPop( vVars );
|
||||
Vec_StrPush( vGuide, '0'+c++ );
|
||||
Vec_IntClear( vFanins );
|
||||
for ( i = 0; i < nShared; i++ ) {
|
||||
int Index = -1;
|
||||
do Index = Abc_Random(0) % Vec_IntSize(vVars);
|
||||
while ( Vec_IntFind(vFanins, Vec_IntEntry(vVars, Index)) >= 0 );
|
||||
Vec_IntPush( vFanins, Vec_IntEntry(vVars, Index) );
|
||||
Vec_StrPush( vGuide, 'A'+Vec_IntEntry(vVars, Index) );
|
||||
}
|
||||
for ( i = 0; i < nLutSize - nRails - nShared; i++ ) {
|
||||
int Index = -1;
|
||||
do Index = Abc_Random(0) % Vec_IntSize(vVars);
|
||||
while ( Vec_IntFind(vFanins, Vec_IntEntry(vVars, Index)) >= 0 );
|
||||
Vec_IntPush( vFanins, Vec_IntEntry(vVars, Index) );
|
||||
Vec_StrPush( vGuide, 'a'+Vec_IntEntry(vVars, Index) );
|
||||
Vec_IntDrop( vVars, Index );
|
||||
}
|
||||
if ( Vec_WrdSize(vRes) == 1 ) {
|
||||
for ( i = 0; i < nRails; i++ ) {
|
||||
int Index = -1;
|
||||
do Index = Abc_Random(0) % Vec_IntSize(vVars);
|
||||
while ( Vec_IntFind(vFanins, Vec_IntEntry(vVars, Index)) >= 0 );
|
||||
Vec_IntPush( vFanins, Vec_IntEntry(vVars, Index) );
|
||||
Vec_StrPush( vGuide, 'a'+Vec_IntEntry(vVars, Index) );
|
||||
Vec_IntDrop( vVars, Index );
|
||||
}
|
||||
}
|
||||
else {
|
||||
assert( iVarPrev > 0 );
|
||||
for ( i = 0; i < nRails; i++ ) {
|
||||
Vec_IntPush( vFanins, iVarPrev+i );
|
||||
Vec_StrPush( vGuide, 'a'+iVarPrev+i );
|
||||
}
|
||||
}
|
||||
iVarPrev = iVarNext;
|
||||
assert( Vec_IntSize(vFanins) == nLutSize );
|
||||
for ( i = 0; i < nRails; i++ ) {
|
||||
Abc_LutCascadeGenOne( vRes, Vec_IntSize(vFanins), Vec_IntArray(vFanins), iVarNext++, NULL );
|
||||
Vec_IntPush( vVars, iVarPrev+i );
|
||||
}
|
||||
}
|
||||
assert( Vec_IntSize(vVars) <= nLutSize );
|
||||
Abc_LutCascadeGenOne( vRes, Vec_IntSize(vVars), Vec_IntArray(vVars), iVarNext, NULL );
|
||||
Vec_StrPush( vGuide, '0'+c++ );
|
||||
Vec_IntForEachEntry( vVars, Obj, i )
|
||||
Vec_StrPush( vGuide, 'a'+Obj );
|
||||
Vec_StrPush( vGuide, '\0' );
|
||||
|
||||
printf( "Generated %d-LUT cascade for a %d-var function with %d rails and %d shared vars (node = %d, level = %d).\n",
|
||||
nLutSize, nVars, nRails, nShared, (int)Vec_WrdEntry(vRes, 0), c );
|
||||
printf( "Structural info: %s\n", Vec_StrArray(vGuide) );
|
||||
Vec_StrFree( vGuide );
|
||||
|
||||
word * pRes = Vec_WrdReleaseArray(vRes);
|
||||
Vec_WrdFree( vRes );
|
||||
return pRes;
|
||||
}
|
||||
word * Abc_LutCascadeTruth( word * pLuts, int nVars )
|
||||
{
|
||||
int nWords = Abc_TtWordNum(nVars);
|
||||
Vec_Wrd_t * vFuncs = Vec_WrdStartTruthTables6( nVars );
|
||||
Vec_WrdFillExtra( vFuncs, nWords*(nVars+pLuts[0]+1), (word)0 );
|
||||
word * pCube = Vec_WrdEntryP( vFuncs, nWords*(nVars+pLuts[0]) );
|
||||
int n, i, m, v, iLastLut = -1;
|
||||
for ( n = 0, i = 1; n < pLuts[0]; n++, i += pLuts[i] )
|
||||
{
|
||||
word nIns = pLuts[i+1];
|
||||
word nIns = pLuts[i+1];
|
||||
word * pIns = pLuts+i+2;
|
||||
word * pT = pLuts+i+2+nIns+1;
|
||||
printf( "LUT%d : ", n );
|
||||
printf( "%02d = F( ", (int)pIns[nIns] );
|
||||
for ( k = 0; k < nIns; k++ )
|
||||
printf( "%02d ", (int)pIns[k] );
|
||||
for ( ; k < 8; k++ )
|
||||
printf( " " );
|
||||
printf( ") " );
|
||||
Extra_PrintHex2( stdout, (unsigned *)pT, nIns );
|
||||
printf( "\n" );
|
||||
}
|
||||
assert( pLuts[i] == 3+nIns+Abc_TtWordNum(nIns) );
|
||||
assert( pIns[nIns] < nVars+pLuts[0] );
|
||||
word * pIn[30], * pOut = Vec_WrdEntryP( vFuncs, nWords*pIns[nIns] );
|
||||
for ( v = 0; v < nIns; v++ )
|
||||
pIn[v] = Vec_WrdEntryP( vFuncs, nWords*pIns[v] );
|
||||
for ( m = 0; m < (1<<nIns); m++ ) {
|
||||
if ( !Abc_TtGetBit(pT, m) )
|
||||
continue;
|
||||
Abc_TtFill(pCube, nWords);
|
||||
for ( v = 0; v < nIns; v++ )
|
||||
Abc_TtAndCompl(pCube, pCube, 0, pIn[v], !((m>>v)&1), nWords);
|
||||
Abc_TtOr(pOut, pOut, pCube, nWords);
|
||||
}
|
||||
iLastLut = pIns[nIns];
|
||||
}
|
||||
word * pRes = Vec_WrdReleaseArray(vFuncs);
|
||||
Abc_TtCopy( pRes, pRes + nWords*iLastLut, nWords, 0 );
|
||||
Vec_WrdFree( vFuncs );
|
||||
return pRes;
|
||||
}
|
||||
|
||||
word * Abc_LutCascadeTest( Mini_Aig_t * p, int nLutSize, int fVerbose )
|
||||
{
|
||||
word * pLuts = Abc_LutCascadeGenTest();
|
||||
|
|
@ -198,6 +319,207 @@ word * Abc_LutCascadeTest( Mini_Aig_t * p, int nLutSize, int fVerbose )
|
|||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [LUT cascade decomposition.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
// computes permutation masks for the current stage
|
||||
int Abc_TtGetGuide( char * pGuide, int Iter, Vec_Int_t * vVarIDs, int fShared )
|
||||
{
|
||||
int i, Res = 0, Count = 0;
|
||||
for ( i = 0; pGuide[i]; i++ )
|
||||
if ( pGuide[i] >= '0' && pGuide[i] <= '9' ) {
|
||||
if ( Count++ == Iter )
|
||||
break;
|
||||
}
|
||||
assert( i < strlen(pGuide) );
|
||||
assert( pGuide[i] == '0'+Iter );
|
||||
for ( i++; pGuide[i]; i++ )
|
||||
{
|
||||
char Char = pGuide[i];
|
||||
if ( Char >= '0' && Char <= '9' )
|
||||
break;
|
||||
if ( fShared && Char >= 'a' && Char <= 'z' )
|
||||
continue;
|
||||
int Value = -1;
|
||||
if ( Char >= 'a' && Char <= 'z' )
|
||||
Value = Char - 'a';
|
||||
else if ( Char >= 'A' && Char <= 'Z' )
|
||||
Value = Char - 'A';
|
||||
else assert( 0 );
|
||||
int iPlace = Vec_IntFind(vVarIDs, Value);
|
||||
assert( iPlace >= 0 );
|
||||
assert( ((Res >> iPlace) & 1) == 0 );
|
||||
Res |= 1 << iPlace;
|
||||
}
|
||||
return Res;
|
||||
}
|
||||
|
||||
// moves variables in the mask to be the last ones in the order
|
||||
void Abc_TtPermuteMask( word * p, int nVars, int Mask, Vec_Int_t * vPerm )
|
||||
{
|
||||
assert( !vPerm || nVars == Vec_IntSize(vPerm) );
|
||||
int v, i, iLast = nVars-1, nWords = Abc_TtWordNum(nVars);
|
||||
int * pPerm = vPerm ? Vec_IntArray(vPerm) : NULL;
|
||||
if ( 0 && vPerm ) {
|
||||
printf( "Beg: " );
|
||||
for ( v = 0; v < nVars; v++ )
|
||||
printf( "%c ", 'a'+Vec_IntEntry(vPerm, v) );
|
||||
printf( "\n" );
|
||||
printf( "Bit: " );
|
||||
for ( v = 0; v < nVars; v++ )
|
||||
printf( "%c ", (Mask >> v) & 1 ? '1' : '-' );
|
||||
printf( "\n" );
|
||||
}
|
||||
for ( v = nVars-1; v >= 0; v-- ) {
|
||||
if ( ((Mask >> v) & 1) == 0 )
|
||||
continue;
|
||||
if ( v == iLast ) {
|
||||
iLast--;
|
||||
continue;
|
||||
}
|
||||
assert( v < iLast );
|
||||
for ( i = v; i < iLast; i++ ) {
|
||||
Abc_TtSwapAdjacent( p, nWords, i );
|
||||
if ( pPerm ) ABC_SWAP( int, pPerm[i], pPerm[i+1] )
|
||||
}
|
||||
iLast--;
|
||||
}
|
||||
if ( 0 && vPerm ) {
|
||||
printf( "End: " );
|
||||
for ( v = 0; v < nVars; v++ )
|
||||
printf( "%c ", 'a'+Vec_IntEntry(vPerm, v) );
|
||||
printf( "\n" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// checks if the given function exists in storage
|
||||
// if the function does not exist, adds it to storage
|
||||
// returns the number of the function in storage
|
||||
int Abc_LutCascadeLookup( word * pStore, int nFuncs, word * pFunc, int nWords )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < nFuncs; i++ )
|
||||
if ( Abc_TtEqual( pStore+i*nWords, pFunc, nWords ) )
|
||||
return i;
|
||||
Abc_TtCopy( pStore+i*nWords, pFunc, nWords, 0 );
|
||||
assert( i == nFuncs );
|
||||
return i;
|
||||
}
|
||||
void Abc_LutCascadeDerive( word * p, int nVars, int nBVars, int Myu, word * pRem, word * pDec, int nStep )
|
||||
{
|
||||
int nFVars = nVars-nBVars; assert( nFVars >= 6 );
|
||||
int nEVars = Abc_Base2Log(Myu);
|
||||
int nFWords = Abc_TtWordNum(nFVars);
|
||||
int m, e, iFunc, nFuncs = 0;
|
||||
//printf( "Decomposition pattern with %d BS vars and %d FS vars: ", nBVars, nFVars );
|
||||
for ( m = 0; m < (1 << nBVars); m++ ) {
|
||||
iFunc = Abc_LutCascadeLookup( pRem, nFuncs, p+m*nFWords, nFWords );
|
||||
//printf( "%x", iFunc );
|
||||
nFuncs = Abc_MaxInt( nFuncs, iFunc+1 );
|
||||
for ( e = 0; e < nEVars; e++ )
|
||||
if ( (iFunc >> e) & 1 )
|
||||
Abc_TtSetBit(pDec+e*nStep, m);
|
||||
}
|
||||
//printf( "\n" );
|
||||
assert( nFuncs <= Myu );
|
||||
iFunc = nFuncs-1;
|
||||
for ( m = nFuncs; m < (1 << nEVars); m++ )
|
||||
Abc_TtCopy( pRem+m*nFWords, pRem+iFunc*nFWords, nFWords, 0 );
|
||||
if ( nBVars < 6 )
|
||||
for ( e = 0; e < nEVars; e++ )
|
||||
pDec[e*nStep] = Abc_Tt6Stretch( pDec[e*nStep], nBVars );
|
||||
}
|
||||
|
||||
// performs decomposition of one stage
|
||||
static inline int Abc_LutCascadeDecStage( char * pGuide, int Iter, Vec_Wrd_t * vFuncs[3], Vec_Int_t * vVarIDs, int nRVars, int nRails, int nLutSize, int fVerbose, Vec_Wrd_t * vCas )
|
||||
{
|
||||
extern word Abc_TtFindBVarsSVars( word * p, int nVars, int nRVars, int nRails, int nLutSize, int fVerbose );
|
||||
assert( Vec_IntSize(vVarIDs) > nLutSize );
|
||||
assert( Vec_IntSize(vVarIDs) <= 24 );
|
||||
word Guide = pGuide ? 0 : Abc_TtFindBVarsSVars( Vec_WrdArray(vFuncs[0]), Vec_IntSize(vVarIDs), nRVars, nRails, nLutSize, fVerbose );
|
||||
int m, Myu = pGuide ? 1 << nRails : (Guide >> 48) & 0xFF;
|
||||
int nEVars = Abc_Base2Log(Myu);
|
||||
if ( nEVars > nRails ) {
|
||||
printf( "Best Myu (%d) requires %d rails that is more than available (%d).\n", Myu, nEVars, nRails );
|
||||
Vec_IntClear( vVarIDs );
|
||||
return 0;
|
||||
}
|
||||
int nVars = Vec_IntSize(vVarIDs);
|
||||
int mBVars = pGuide ? Abc_TtGetGuide(pGuide, Iter, vVarIDs, 0) : Guide & 0xFFFFFF;
|
||||
int nBVars = __builtin_popcount(mBVars);
|
||||
assert( nBVars <= nLutSize );
|
||||
Abc_TtPermuteMask( Vec_WrdArray(vFuncs[0]), nVars, mBVars, vVarIDs );
|
||||
int mSVars = pGuide ? Abc_TtGetGuide(pGuide, Iter, vVarIDs, 1) : (Guide >> 24) & 0xFFFFFF;
|
||||
int nSVars = __builtin_popcount(mSVars);
|
||||
Abc_TtPermuteMask( Vec_WrdArray(vFuncs[0]), nVars, mSVars, vVarIDs );
|
||||
// prepare function (nVars -> nAVars+nVars)
|
||||
int nFVars = nVars - nBVars;
|
||||
int nAVars = nFVars >= 6 ? 0 : 6-nFVars;
|
||||
int nWordsNew = Abc_TtWordNum(nVars+nAVars);
|
||||
Vec_WrdFillExtra( vFuncs[0], nWordsNew, 0 );
|
||||
word * pFunc = Vec_WrdArray(vFuncs[0]);
|
||||
Abc_TtStretch6( pFunc, nVars, nVars+nAVars );
|
||||
Abc_TtPermuteMask( pFunc, nVars+nAVars, (1 << nVars)-1, NULL );
|
||||
// prepare remainder function (nAVars+nFVars+nEVars+nSVars)
|
||||
int nWordsRem = Abc_TtWordNum(nAVars+nFVars+nEVars+nSVars);
|
||||
Vec_WrdFill( vFuncs[1], nWordsRem, 0 );
|
||||
word * pRem = Vec_WrdArray(vFuncs[1]);
|
||||
// prepare decomposed functions (nBVars+nZVars) * nEVars
|
||||
int nUVars = nBVars - nSVars;
|
||||
int nZVars = nUVars >= 6 ? 0 : 6-nUVars;
|
||||
int nWordsDec = Abc_TtWordNum(nBVars+nZVars);
|
||||
int nWordsStep = Abc_TtWordNum(nUVars+nZVars);
|
||||
Vec_WrdFill( vFuncs[2], nWordsDec*nEVars, 0 );
|
||||
word * pDec = Vec_WrdArray(vFuncs[2]);
|
||||
int nSMints = 1 << nSVars;
|
||||
for ( m = 0; m < nSMints; m++ )
|
||||
Abc_LutCascadeDerive(pFunc+m*nWordsNew/nSMints, nVars+nAVars-nSVars, nBVars-nSVars, Myu,
|
||||
pRem+m*nWordsRem/nSMints, pDec+m*nWordsStep, nWordsDec );
|
||||
Abc_TtPermuteMask( pRem, nAVars+nFVars+nEVars+nSVars, (1 << nAVars)-1, NULL );
|
||||
Abc_TtPermuteMask( pRem, nFVars+nEVars+nSVars, ((1 << nEVars)-1) << nFVars, NULL );
|
||||
for ( m = 0; m < nEVars; m++ )
|
||||
Abc_TtPermuteMask( pDec+m*nWordsDec, nUVars+nZVars+nSVars, ((1 << nZVars)-1) << nUVars, NULL );
|
||||
for ( m = 0; m < nEVars; m++ )
|
||||
Abc_LutCascadeGenOne( vCas, nBVars, Vec_IntArray(vVarIDs)+nVars-nBVars, Vec_WrdEntry(vCas,0), pDec+m*nWordsDec );
|
||||
Abc_TtCopy( pFunc, pRem, Abc_TtWordNum(nFVars+nSVars+nEVars), 0 );
|
||||
assert( nEVars < nUVars );
|
||||
for ( m = 0; m < nSVars; m++ )
|
||||
Vec_IntWriteEntry(vVarIDs, nFVars+m, Vec_IntEntry(vVarIDs, nVars-nSVars+m) );
|
||||
for ( m = 0; m < nEVars; m++ )
|
||||
Vec_IntWriteEntry(vVarIDs, nFVars+nSVars+m, Vec_WrdEntry(vCas,0)-nEVars+m );
|
||||
Vec_IntShrink( vVarIDs, nFVars+nSVars+nEVars );
|
||||
return nEVars;
|
||||
}
|
||||
static inline word * Abc_LutCascadeDec( char * pGuide, word * pTruth, Vec_Int_t * vVarIDs, int nRails, int nLutSize, int fVerbose )
|
||||
{
|
||||
word * pRes = NULL; int i, nRVars = 0, nVars = Vec_IntSize(vVarIDs);
|
||||
Vec_Wrd_t * vFuncs[3] = { Vec_WrdStart(Abc_TtWordNum(nVars)), Vec_WrdAlloc(0), Vec_WrdAlloc(0) };
|
||||
Abc_TtCopy( Vec_WrdArray(vFuncs[0]), pTruth, Abc_TtWordNum(nVars), 0 );
|
||||
Vec_Wrd_t * vCas = Vec_WrdAlloc( 100 ); Vec_WrdPush( vCas, nVars );
|
||||
for ( i = 0; Vec_IntSize(vVarIDs) > nLutSize; i++ )
|
||||
nRVars = Abc_LutCascadeDecStage( pGuide, i, vFuncs, vVarIDs, nRVars, nRails, nLutSize, fVerbose, vCas );
|
||||
if ( Vec_IntSize(vVarIDs) > 0 ) {
|
||||
Abc_LutCascadeGenOne( vCas, Vec_IntSize(vVarIDs), Vec_IntArray(vVarIDs), Vec_WrdEntry(vCas, 0), Vec_WrdArray(vFuncs[0]) );
|
||||
Vec_WrdAddToEntry( vCas, 0, -nVars );
|
||||
pRes = Vec_WrdReleaseArray(vCas);
|
||||
}
|
||||
Vec_WrdFree( vCas );
|
||||
for ( i = 0; i < 3; i++ )
|
||||
Vec_WrdFree( vFuncs[i] );
|
||||
return pRes;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
|
@ -225,11 +547,30 @@ Abc_Obj_t * Abc_NtkLutCascadeDeriveSop( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNodeNe
|
|||
return pNodeNew;
|
||||
}
|
||||
}
|
||||
Abc_Ntk_t * Abc_NtkLutCascadeFromLuts( word * pLuts, Abc_Ntk_t * pNtk, int nLutSize, int fVerbose )
|
||||
Abc_Ntk_t * Abc_NtkLutCascadeFromLuts( word * pLuts, int nVars, Abc_Ntk_t * pNtk, int nLutSize, int fVerbose )
|
||||
{
|
||||
Abc_Ntk_t * pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP );
|
||||
Vec_Int_t * vCover = Vec_IntAlloc( 1000 ); word n, i, k, iLastLut = -1;
|
||||
assert( Abc_NtkCoNum(pNtk) == 1 );
|
||||
Abc_Ntk_t * pNtkNew = NULL;
|
||||
Abc_Obj_t * pObj; int Id; char pName[2] = {0};
|
||||
Vec_Ptr_t * vCopy = Vec_PtrStart( nVars + pLuts[0] + 1000 );
|
||||
if ( pNtk ) {
|
||||
pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP );
|
||||
}
|
||||
else {
|
||||
pNtkNew = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_SOP , 0 );
|
||||
pNtkNew->pName = Extra_UtilStrsav("cas");
|
||||
//pNtkNew->pSpec = Extra_UtilStrsav(pNtk->pSpec);
|
||||
for ( Id = 0; Id < nVars; Id++ ) {
|
||||
pObj = Abc_NtkCreatePi(pNtkNew);
|
||||
pName[0] = 'a' + Id;
|
||||
Abc_ObjAssignName( pObj, pName, NULL );
|
||||
}
|
||||
pObj = Abc_NtkCreatePo(pNtkNew);
|
||||
Abc_ObjAssignName( pObj, "Out", NULL );
|
||||
}
|
||||
Abc_NtkForEachCi( pNtkNew, pObj, Id )
|
||||
Vec_PtrWriteEntry( vCopy, Id, pObj );
|
||||
Vec_Int_t * vCover = Vec_IntAlloc( 1000 );
|
||||
word n, i, k, iLastLut = -1;
|
||||
for ( n = 0, i = 1; n < pLuts[0]; n++, i += pLuts[i] )
|
||||
{
|
||||
word nIns = pLuts[i+1];
|
||||
|
|
@ -237,12 +578,15 @@ Abc_Ntk_t * Abc_NtkLutCascadeFromLuts( word * pLuts, Abc_Ntk_t * pNtk, int nLutS
|
|||
word * pT = pLuts+i+2+nIns+1;
|
||||
Abc_Obj_t * pNodeNew = Abc_NtkCreateNode( pNtkNew );
|
||||
for ( k = 0; k < nIns; k++ )
|
||||
Abc_ObjAddFanin( pNodeNew, Abc_NtkCi(pNtk, pIns[k])->pCopy );
|
||||
Abc_NtkCi(pNtk, pIns[nIns])->pCopy = Abc_NtkLutCascadeDeriveSop( pNtkNew, pNodeNew, pT, nIns, vCover );
|
||||
Abc_ObjAddFanin( pNodeNew, (Abc_Obj_t *)Vec_PtrEntry(vCopy, pIns[k]) );
|
||||
Abc_Obj_t * pObjNew = Abc_NtkLutCascadeDeriveSop( pNtkNew, pNodeNew, pT, nIns, vCover );
|
||||
Vec_PtrWriteEntry( vCopy, pIns[nIns], pObjNew );
|
||||
iLastLut = pIns[nIns];
|
||||
}
|
||||
Vec_IntFree( vCover );
|
||||
Abc_ObjAddFanin( Abc_NtkCo(pNtk, 0)->pCopy, Abc_NtkCi(pNtk, iLastLut)->pCopy );
|
||||
assert( Abc_NtkCoNum(pNtkNew) == 1 );
|
||||
Abc_ObjAddFanin( Abc_NtkCo(pNtkNew, 0), (Abc_Obj_t *)Vec_PtrEntry(vCopy, iLastLut) );
|
||||
Vec_PtrFree( vCopy );
|
||||
if ( !Abc_NtkCheck( pNtkNew ) )
|
||||
{
|
||||
printf( "Abc_NtkLutCascadeFromLuts: The network check has failed.\n" );
|
||||
|
|
@ -251,20 +595,489 @@ Abc_Ntk_t * Abc_NtkLutCascadeFromLuts( word * pLuts, Abc_Ntk_t * pNtk, int nLutS
|
|||
}
|
||||
return pNtkNew;
|
||||
}
|
||||
Abc_Ntk_t * Abc_NtkLutCascade( Abc_Ntk_t * pNtk, int nLutSize, int fVerbose )
|
||||
Abc_Ntk_t * Abc_NtkLutCascade( Abc_Ntk_t * pNtk, int nLutSize, int nLuts, int nRails, int nIters, int fVerbose )
|
||||
{
|
||||
extern Gia_Man_t * Abc_NtkStrashToGia( Abc_Ntk_t * pNtk );
|
||||
extern Mini_Aig_t * Gia_ManToMiniAig( Gia_Man_t * pGia );
|
||||
extern word * Abc_LutCascade( Mini_Aig_t * p, int nLutSize, int fVerbose );
|
||||
extern word * Abc_LutCascade( Mini_Aig_t * p, int nLutSize, int nLuts, int nRails, int nIters, int fVerbose );
|
||||
Gia_Man_t * pGia = Abc_NtkStrashToGia( pNtk );
|
||||
Mini_Aig_t * pM = Gia_ManToMiniAig( pGia );
|
||||
word * pLuts = Abc_LutCascade( pM, nLutSize, fVerbose );
|
||||
Abc_Ntk_t * pNew = pLuts ? Abc_NtkLutCascadeFromLuts( pLuts, pNtk, nLutSize, fVerbose ) : NULL;
|
||||
//word * pLuts = Abc_LutCascade( pM, nLutSize, nLuts, nRails, nIters, fVerbose );
|
||||
word * pLuts = Abc_LutCascadeTest( pM, nLutSize, 0 );
|
||||
Abc_Ntk_t * pNew = pLuts ? Abc_NtkLutCascadeFromLuts( pLuts, Abc_NtkCiNum(pNtk), pNtk, nLutSize, fVerbose ) : NULL;
|
||||
ABC_FREE( pLuts );
|
||||
Mini_AigStop( pM );
|
||||
Gia_ManStop( pGia );
|
||||
return pNew;
|
||||
}
|
||||
Abc_Ntk_t * Abc_NtkLutCascade2( Abc_Ntk_t * pNtk, int nLutSize, int nLuts, int nRails, int nIters, int fVerbose, char * pGuide )
|
||||
{
|
||||
extern Gia_Man_t * Abc_NtkStrashToGia( Abc_Ntk_t * pNtk );
|
||||
extern word * Abc_LutCascade2( word * p, int nVars, int nLutSize, int nLuts, int nRails, int nIters, int fVerbose );
|
||||
Gia_Man_t * pGia = Abc_NtkStrashToGia( pNtk );
|
||||
word * pTruth1 = Gia_ObjComputeTruthTable( pGia, Gia_ManCo(pGia, 0) );
|
||||
|
||||
int nVars = Abc_NtkCiNum(pNtk);
|
||||
Vec_Int_t * vVarIDs = Vec_IntStartNatural( nVars );
|
||||
Abc_TtMinimumBase( pTruth1, Vec_IntArray(vVarIDs), nVars, &nVars );
|
||||
if ( fVerbose ) {
|
||||
if ( Vec_IntSize(vVarIDs) != nVars )
|
||||
printf( "The support of the function is reduced from %d to %d variables.\n", Vec_IntSize(vVarIDs), nVars );
|
||||
printf( "Decomposing %d-var function into %d-rail cascade of %d-LUTs", nVars, nRails, nLutSize );
|
||||
if ( pGuide )
|
||||
printf( " using structural info: %s", pGuide );
|
||||
printf( ".\n" );
|
||||
}
|
||||
Vec_IntShrink( vVarIDs, nVars );
|
||||
|
||||
//word * pLuts = Abc_LutCascade2( pTruth1, nVars, nLutSize, nLuts, nRails, nIters, fVerbose );
|
||||
word * pLuts = Abc_LutCascadeDec( pGuide, pTruth1, vVarIDs, nRails, nLutSize, fVerbose );
|
||||
Abc_Ntk_t * pNew = pLuts ? Abc_NtkLutCascadeFromLuts( pLuts, nVars, pNtk, nLutSize, fVerbose ) : NULL;
|
||||
Vec_IntFree( vVarIDs );
|
||||
|
||||
if ( pLuts && fVerbose ) {
|
||||
word * pTruth2 = Abc_LutCascadeTruth( pLuts, Abc_NtkCiNum(pNtk) );
|
||||
if ( nVars < 9 ) {
|
||||
printf("Function before: "); Abc_TtPrintHexRev( stdout, pTruth1, nVars ); printf( "\n" );
|
||||
printf("Function after: "); Abc_TtPrintHexRev( stdout, pTruth2, nVars ); printf( "\n" );
|
||||
}
|
||||
Abc_LutCascadePrint( pLuts );
|
||||
ABC_FREE( pLuts );
|
||||
ABC_FREE( pTruth2 );
|
||||
}
|
||||
Gia_ManStop( pGia );
|
||||
//ABC_FREE( pTruth1 );
|
||||
return pNew;
|
||||
}
|
||||
Abc_Ntk_t * Abc_NtkLutCascadeGen( int nLutSize, int nStages, int nRails, int nShared, int fVerbose )
|
||||
{
|
||||
int nVars = nStages * nLutSize - (nStages-1) * (nRails + nShared);
|
||||
word * pLuts = Abc_LutCascadeGen( nVars, nLutSize, nRails, nShared );
|
||||
Abc_Ntk_t * pNew = Abc_NtkLutCascadeFromLuts( pLuts, nVars, NULL, nLutSize, fVerbose );
|
||||
Abc_LutCascadePrint( pLuts );
|
||||
if ( fVerbose ) {
|
||||
word * pTruth = Abc_LutCascadeTruth( pLuts, nVars );
|
||||
if ( nVars <= 10 ) {
|
||||
printf( "Function: "); Abc_TtPrintHexRev( stdout, pTruth, nVars ); printf( "\n" );
|
||||
}
|
||||
ABC_FREE( pTruth );
|
||||
}
|
||||
ABC_FREE( pLuts );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Structural LUT cascade mapping.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
typedef struct Abc_LutCas_t_ Abc_LutCas_t;
|
||||
struct Abc_LutCas_t_
|
||||
{
|
||||
// mapped network
|
||||
Abc_Ntk_t * pNtk;
|
||||
// parameters
|
||||
int nLutSize;
|
||||
int nLutsMax;
|
||||
int nIters;
|
||||
int fDelayLut;
|
||||
int fDelayRoute;
|
||||
int fDelayDirect;
|
||||
int fVerbose;
|
||||
// internal data
|
||||
int DelayMax;
|
||||
Vec_Int_t * vTime[2]; // timing info
|
||||
Vec_Int_t * vCrits[2]; // critical terminals
|
||||
Vec_Int_t * vPath[2]; // direct connections
|
||||
Vec_Wec_t * vStack; // processing queue
|
||||
Vec_Int_t * vZeroSlack; // zero-slack nodes
|
||||
Vec_Int_t * vCands; // direct edge candidates
|
||||
Vec_Int_t * vTrace; // modification trace
|
||||
Vec_Int_t * vTraceBest; // modification trace
|
||||
};
|
||||
|
||||
Abc_LutCas_t * Abc_LutCasAlloc( Abc_Ntk_t * pNtk, int nLutsMax, int nIters, int fDelayLut, int fDelayRoute, int fDelayDirect, int fVerbose )
|
||||
{
|
||||
Abc_LutCas_t * p = ABC_ALLOC( Abc_LutCas_t, 1 );
|
||||
p->pNtk = pNtk;
|
||||
p->nLutSize = 6;
|
||||
p->nLutsMax = nLutsMax;
|
||||
p->nIters = nIters;
|
||||
p->fDelayLut = fDelayLut;
|
||||
p->fDelayRoute = fDelayRoute;
|
||||
p->fDelayDirect = fDelayDirect;
|
||||
p->fVerbose = fVerbose;
|
||||
p->vTime[0] = Vec_IntStart( Abc_NtkObjNumMax(pNtk) );
|
||||
p->vTime[1] = Vec_IntStart( Abc_NtkObjNumMax(pNtk) );
|
||||
p->vCrits[0] = Vec_IntAlloc(1000);
|
||||
p->vCrits[1] = Vec_IntAlloc(1000);
|
||||
p->vPath[0] = Vec_IntStart( Abc_NtkObjNumMax(pNtk) );
|
||||
p->vPath[1] = Vec_IntStart( Abc_NtkObjNumMax(pNtk) );
|
||||
p->vStack = Vec_WecStart( Abc_NtkLevel(pNtk) + 1 );
|
||||
p->vZeroSlack = Vec_IntAlloc( 1000 );
|
||||
p->vCands = Vec_IntAlloc( 1000 );
|
||||
p->vTrace = Vec_IntAlloc( 1000 );
|
||||
p->vTraceBest = Vec_IntAlloc( 1000 );
|
||||
return p;
|
||||
}
|
||||
void Abc_LutCasFree( Abc_LutCas_t * p )
|
||||
{
|
||||
Vec_IntFree( p->vTime[0] );
|
||||
Vec_IntFree( p->vTime[1] );
|
||||
Vec_IntFree( p->vCrits[0] );
|
||||
Vec_IntFree( p->vCrits[1] );
|
||||
Vec_IntFree( p->vPath[0] );
|
||||
Vec_IntFree( p->vPath[1] );
|
||||
Vec_WecFree( p->vStack );
|
||||
Vec_IntFree( p->vZeroSlack );
|
||||
Vec_IntFree( p->vCands );
|
||||
Vec_IntFree( p->vTrace );
|
||||
Vec_IntFree( p->vTraceBest );
|
||||
ABC_FREE( p );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Structural LUT cascade mapping.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NtkFindPathTimeD_rec( Abc_LutCas_t * p, Abc_Obj_t * pObj )
|
||||
{
|
||||
if ( !Abc_ObjIsNode(pObj) || !Abc_ObjFaninNum(pObj) )
|
||||
return 0;
|
||||
if ( Vec_IntEntry(p->vTime[0], pObj->Id) > 0 )
|
||||
return Vec_IntEntry(p->vTime[0], pObj->Id);
|
||||
Abc_Obj_t * pNext; int i, Delay, DelayMax = 0;
|
||||
Abc_ObjForEachFanin( pObj, pNext, i ) {
|
||||
Delay = Abc_NtkFindPathTimeD_rec( p, pNext );
|
||||
Delay += Vec_IntEntry(p->vPath[0], pObj->Id) == pNext->Id ? p->fDelayDirect : p->fDelayRoute;
|
||||
DelayMax = Abc_MaxInt( DelayMax, Delay + p->fDelayLut );
|
||||
}
|
||||
Vec_IntWriteEntry( p->vTime[0], pObj->Id, DelayMax );
|
||||
return DelayMax;
|
||||
}
|
||||
int Abc_NtkFindPathTimeD( Abc_LutCas_t * p )
|
||||
{
|
||||
Abc_Obj_t * pObj; int i, Delay, DelayMax = 0;
|
||||
Vec_IntFill( p->vTime[0], Abc_NtkObjNumMax(p->pNtk), 0 );
|
||||
Abc_NtkForEachCo( p->pNtk, pObj, i ) {
|
||||
Delay = Abc_NtkFindPathTimeD_rec( p, Abc_ObjFanin0(pObj) );
|
||||
DelayMax = Abc_MaxInt( DelayMax, Delay + p->fDelayRoute );
|
||||
}
|
||||
Vec_IntClear( p->vCrits[0] );
|
||||
Abc_NtkForEachCo( p->pNtk, pObj, i )
|
||||
if ( DelayMax == Vec_IntEntry(p->vTime[0], Abc_ObjFaninId0(pObj)) + p->fDelayRoute )
|
||||
Vec_IntPush( p->vCrits[0], pObj->Id );
|
||||
return DelayMax;
|
||||
}
|
||||
int Abc_NtkFindPathTimeR_rec( Abc_LutCas_t * p, Abc_Obj_t * pObj )
|
||||
{
|
||||
if ( Abc_ObjIsCo(pObj) )
|
||||
return 0;
|
||||
if ( Vec_IntEntry(p->vTime[1], pObj->Id) > 0 )
|
||||
return Vec_IntEntry(p->vTime[1], pObj->Id) + (Abc_ObjIsNode(pObj) ? p->fDelayLut : 0);
|
||||
Abc_Obj_t * pNext; int i; float Delay, DelayMax = 0;
|
||||
Abc_ObjForEachFanout( pObj, pNext, i ) {
|
||||
Delay = Abc_NtkFindPathTimeR_rec( p, pNext );
|
||||
Delay += Vec_IntEntry(p->vPath[0], pNext->Id) == pObj->Id ? p->fDelayDirect : p->fDelayRoute;
|
||||
DelayMax = Abc_MaxInt( DelayMax, Delay );
|
||||
}
|
||||
Vec_IntWriteEntry( p->vTime[1], pObj->Id, DelayMax );
|
||||
return DelayMax + (Abc_ObjIsNode(pObj) ? p->fDelayLut : 0);
|
||||
}
|
||||
int Abc_NtkFindPathTimeR( Abc_LutCas_t * p )
|
||||
{
|
||||
Abc_Obj_t * pObj; int i; int Delay, DelayMax = 0;
|
||||
Vec_IntFill( p->vTime[1], Abc_NtkObjNumMax(p->pNtk), 0 );
|
||||
Abc_NtkForEachCi( p->pNtk, pObj, i ) {
|
||||
Delay = Abc_NtkFindPathTimeR_rec( p, pObj );
|
||||
DelayMax = Abc_MaxInt( DelayMax, Delay );
|
||||
}
|
||||
Vec_IntClear( p->vCrits[1] );
|
||||
Abc_NtkForEachCi( p->pNtk, pObj, i )
|
||||
if ( DelayMax == Vec_IntEntry(p->vTime[1], pObj->Id) )
|
||||
Vec_IntPush( p->vCrits[1], pObj->Id );
|
||||
return DelayMax;
|
||||
}
|
||||
void Abc_NtkFindCriticalEdges( Abc_LutCas_t * p )
|
||||
{
|
||||
Abc_Obj_t * pObj, * pFanin; int i, k;
|
||||
Vec_IntClear( p->vCands );
|
||||
Abc_NtkForEachNode( p->pNtk, pObj, i ) {
|
||||
if ( Vec_IntEntry(p->vPath[0], pObj->Id) )
|
||||
continue;
|
||||
if ( Vec_IntEntry(p->vTime[0], pObj->Id) + Vec_IntEntry(p->vTime[1], pObj->Id) < p->DelayMax )
|
||||
continue;
|
||||
assert( Vec_IntEntry(p->vTime[0], pObj->Id) + Vec_IntEntry(p->vTime[1], pObj->Id == p->DelayMax) );
|
||||
Abc_ObjForEachFanin( pObj, pFanin, k )
|
||||
if ( Abc_ObjIsNode(pFanin) && !Vec_IntEntry(p->vPath[1], pFanin->Id) &&
|
||||
Vec_IntEntry(p->vTime[0], pFanin->Id) + p->fDelayRoute + p->fDelayLut == Vec_IntEntry(p->vTime[0], pObj->Id) )
|
||||
Vec_IntPushTwo( p->vCands, pObj->Id, pFanin->Id );
|
||||
}
|
||||
}
|
||||
int Abc_NtkFindTiming( Abc_LutCas_t * p )
|
||||
{
|
||||
int Delay0 = Abc_NtkFindPathTimeD( p );
|
||||
int Delay1 = Abc_NtkFindPathTimeR( p );
|
||||
assert( Delay0 == Delay1 );
|
||||
p->DelayMax = Delay0;
|
||||
Abc_NtkFindCriticalEdges( p );
|
||||
return Delay0;
|
||||
}
|
||||
|
||||
int Abc_NtkUpdateNodeD( Abc_LutCas_t * p, Abc_Obj_t * pObj )
|
||||
{
|
||||
Abc_Obj_t * pNext; int i; int Delay, DelayMax = 0;
|
||||
Abc_ObjForEachFanin( pObj, pNext, i ) {
|
||||
Delay = Vec_IntEntry( p->vTime[0], pNext->Id );
|
||||
Delay += Vec_IntEntry(p->vPath[0], pObj->Id) == pNext->Id ? p->fDelayDirect : p->fDelayRoute;
|
||||
DelayMax = Abc_MaxInt( DelayMax, Delay + p->fDelayLut );
|
||||
}
|
||||
int DelayOld = Vec_IntEntry( p->vTime[0], pObj->Id );
|
||||
Vec_IntWriteEntry( p->vTime[0], pObj->Id, DelayMax );
|
||||
assert( DelayOld >= DelayMax );
|
||||
return DelayOld > DelayMax;
|
||||
}
|
||||
int Abc_NtkUpdateNodeR( Abc_LutCas_t * p, Abc_Obj_t * pObj )
|
||||
{
|
||||
Abc_Obj_t * pNext; int i; float Delay, DelayMax = 0;
|
||||
Abc_ObjForEachFanout( pObj, pNext, i ) {
|
||||
Delay = Vec_IntEntry(p->vTime[1], pNext->Id) + (Abc_ObjIsNode(pNext) ? p->fDelayLut : 0);
|
||||
Delay += Vec_IntEntry(p->vPath[0], pNext->Id) == pObj->Id ? p->fDelayDirect : p->fDelayRoute;
|
||||
DelayMax = Abc_MaxInt( DelayMax, Delay );
|
||||
}
|
||||
int DelayOld = Vec_IntEntry( p->vTime[1], pObj->Id );
|
||||
Vec_IntWriteEntry( p->vTime[1], pObj->Id, DelayMax );
|
||||
assert( DelayOld >= DelayMax );
|
||||
return DelayOld > DelayMax;
|
||||
}
|
||||
int Abc_NtkUpdateTiming( Abc_LutCas_t * p, int Node, int Fanin )
|
||||
{
|
||||
Abc_Obj_t * pNode = Abc_NtkObj( p->pNtk, Node );
|
||||
Abc_Obj_t * pFanin = Abc_NtkObj( p->pNtk, Fanin );
|
||||
Abc_Obj_t * pNext, * pTemp; Vec_Int_t * vLevel; int i, k, j;
|
||||
assert( Abc_ObjIsNode(pNode) && Abc_ObjIsNode(pFanin) );
|
||||
Vec_WecForEachLevel( p->vStack, vLevel, i )
|
||||
Vec_IntClear( vLevel );
|
||||
Abc_NtkIncrementTravId( p->pNtk );
|
||||
Abc_NodeSetTravIdCurrentId( p->pNtk, Node );
|
||||
Abc_NodeSetTravIdCurrentId( p->pNtk, Fanin );
|
||||
Vec_WecPush( p->vStack, pNode->Level, Node );
|
||||
Vec_WecPush( p->vStack, pFanin->Level, Fanin );
|
||||
Vec_WecForEachLevelStart( p->vStack, vLevel, i, pNode->Level )
|
||||
Abc_NtkForEachObjVec( vLevel, p->pNtk, pTemp, k ) {
|
||||
if ( !Abc_NtkUpdateNodeD(p, pTemp) )
|
||||
continue;
|
||||
Abc_ObjForEachFanout( pTemp, pNext, j ) {
|
||||
if ( Abc_NodeIsTravIdCurrent(pNext) || Abc_ObjIsCo(pNext) )
|
||||
continue;
|
||||
Abc_NodeSetTravIdCurrent( pNext );
|
||||
Vec_WecPush( p->vStack, pNext->Level, pNext->Id );
|
||||
}
|
||||
}
|
||||
Vec_WecForEachLevelReverseStartStop( p->vStack, vLevel, i, pFanin->Level+1, 0 )
|
||||
Abc_NtkForEachObjVec( vLevel, p->pNtk, pTemp, k ) {
|
||||
if ( !Abc_NtkUpdateNodeR(p, pTemp) )
|
||||
continue;
|
||||
Abc_ObjForEachFanin( pTemp, pNext, j ) {
|
||||
if ( Abc_NodeIsTravIdCurrent(pNext) )
|
||||
continue;
|
||||
Abc_NodeSetTravIdCurrent( pNext );
|
||||
Vec_WecPush( p->vStack, pNext->Level, pNext->Id );
|
||||
}
|
||||
}
|
||||
j = 0;
|
||||
Abc_NtkForEachObjVec( p->vCrits[0], p->pNtk, pTemp, i )
|
||||
if ( Vec_IntEntry(p->vTime[0], Abc_ObjFaninId0(pTemp)) + p->fDelayRoute == p->DelayMax )
|
||||
Vec_IntWriteEntry( p->vCrits[0], j++, pTemp->Id );
|
||||
Vec_IntShrink( p->vCrits[0], j );
|
||||
j = 0;
|
||||
Abc_NtkForEachObjVec( p->vCrits[1], p->pNtk, pTemp, i )
|
||||
if ( Vec_IntEntry(p->vTime[1], pTemp->Id) == p->DelayMax )
|
||||
Vec_IntWriteEntry( p->vCrits[1], j++, pTemp->Id );
|
||||
Vec_IntShrink( p->vCrits[1], j );
|
||||
if ( Vec_IntSize(p->vCrits[0]) && Vec_IntSize(p->vCrits[1]) ) {
|
||||
int j = 0, Node2, Fanin2;
|
||||
Vec_IntForEachEntryDouble( p->vCands, Node2, Fanin2, i )
|
||||
if ( !Vec_IntEntry(p->vPath[0], Node2) && !Vec_IntEntry(p->vPath[1], Fanin2) &&
|
||||
Vec_IntEntry(p->vTime[0], Node2) + Vec_IntEntry(p->vTime[1], Node2) == p->DelayMax &&
|
||||
Vec_IntEntry(p->vTime[0], Fanin2) + p->fDelayRoute + p->fDelayLut == Vec_IntEntry(p->vTime[0], Node2) )
|
||||
Vec_IntWriteEntry( p->vCands, j++, Node2 ), Vec_IntWriteEntry( p->vCands, j++, Fanin2 );
|
||||
Vec_IntShrink( p->vCands, j );
|
||||
return p->DelayMax;
|
||||
}
|
||||
int DelayOld = p->DelayMax;
|
||||
Abc_NtkFindTiming(p);
|
||||
assert( DelayOld > p->DelayMax );
|
||||
return p->DelayMax;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Structural LUT cascade mapping.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NtkAddEdges( Abc_LutCas_t * p )
|
||||
{
|
||||
int nEdgesMax = 10000;
|
||||
Vec_IntClear( p->vTrace );
|
||||
Vec_IntFill( p->vPath[0], Vec_IntSize(p->vPath[0]), 0 );
|
||||
Vec_IntFill( p->vPath[1], Vec_IntSize(p->vPath[1]), 0 );
|
||||
Abc_NtkFindTiming( p );
|
||||
if ( p->fVerbose )
|
||||
printf( "Start : %d\n", p->DelayMax );
|
||||
int i, LastChange = 0;
|
||||
for ( i = 0; i < nEdgesMax; i++ )
|
||||
{
|
||||
float DelayPrev = p->DelayMax;
|
||||
if ( Vec_IntSize(p->vCands) == 0 )
|
||||
break;
|
||||
int Index = rand() % Vec_IntSize(p->vCands)/2;
|
||||
int Node = Vec_IntEntry( p->vCands, 2*Index );
|
||||
int Fanin = Vec_IntEntry( p->vCands, 2*Index+1 );
|
||||
assert( Vec_IntEntry( p->vPath[0], Node ) == 0 );
|
||||
Vec_IntWriteEntry( p->vPath[0], Node, Fanin );
|
||||
assert( Vec_IntEntry( p->vPath[1], Fanin ) == 0 );
|
||||
Vec_IntWriteEntry( p->vPath[1], Fanin, Node );
|
||||
Vec_IntPushTwo( p->vTrace, Node, Fanin );
|
||||
//Abc_NtkFindTiming( p );
|
||||
Abc_NtkUpdateTiming( p, Node, Fanin );
|
||||
assert( DelayPrev >= p->DelayMax );
|
||||
if ( DelayPrev > p->DelayMax )
|
||||
LastChange = i+1;
|
||||
DelayPrev = p->DelayMax;
|
||||
if ( p->fVerbose )
|
||||
printf( "%5d : %d : %4d -> %4d\n", i, p->DelayMax, Fanin, Node );
|
||||
}
|
||||
Vec_IntShrink( p->vTrace, 2*LastChange );
|
||||
return p->DelayMax;
|
||||
}
|
||||
Vec_Wec_t * Abc_NtkProfileCascades( Abc_Ntk_t * pNtk, Vec_Int_t * vTrace )
|
||||
{
|
||||
Vec_Wec_t * vCasc = Vec_WecAlloc( 100 );
|
||||
Vec_Int_t * vMap = Vec_IntStart( Abc_NtkObjNumMax(pNtk) );
|
||||
Vec_Int_t * vPath = Vec_IntStart( Abc_NtkObjNumMax(pNtk) );
|
||||
Vec_Int_t * vCounts = Vec_IntStart( Abc_NtkObjNumMax(pNtk) );
|
||||
Abc_Obj_t * pObj; int i, Node, Fanin, Count, nCascs = 0;
|
||||
Vec_IntForEachEntryDouble( vTrace, Node, Fanin, i ) {
|
||||
assert( Vec_IntEntry(vPath, Node) == 0 );
|
||||
Vec_IntWriteEntry( vPath, Node, Fanin );
|
||||
Vec_IntWriteEntry( vMap, Fanin, 1 );
|
||||
}
|
||||
Abc_NtkForEachNode( pNtk, pObj, i ) {
|
||||
if ( Vec_IntEntry(vMap, pObj->Id) )
|
||||
continue;
|
||||
if ( Vec_IntEntry(vPath, pObj->Id) == 0 )
|
||||
continue;
|
||||
Vec_Int_t * vLevel = Vec_WecPushLevel( vCasc );
|
||||
Node = pObj->Id;
|
||||
Vec_IntPush( vLevel, Node );
|
||||
while ( (Node = Vec_IntEntry(vPath, Node)) )
|
||||
Vec_IntPush( vLevel, Node );
|
||||
Vec_IntAddToEntry( vCounts, Vec_IntSize(vLevel), 1 );
|
||||
}
|
||||
printf( "Cascades: " );
|
||||
Vec_IntForEachEntry( vCounts, Count, i )
|
||||
if ( Count )
|
||||
printf( "%d=%d ", i, Count ), nCascs += Count;
|
||||
printf( "\n" );
|
||||
Vec_IntFree( vMap );
|
||||
Vec_IntFree( vPath );
|
||||
Vec_IntFree( vCounts );
|
||||
return vCasc;
|
||||
}
|
||||
void Abc_LutCasAssignNames( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew, Vec_Wec_t * vCascs )
|
||||
{
|
||||
Abc_Obj_t * pObj; Vec_Int_t * vLevel; int i, k; char pName[100];
|
||||
Vec_Int_t * vMap = Vec_IntStart( Abc_NtkObjNumMax(pNtk) );
|
||||
Abc_NtkForEachCo( pNtkNew, pObj, i )
|
||||
Vec_IntWriteEntry( vMap, Abc_ObjFaninId0(pObj), pObj->Id );
|
||||
Vec_WecForEachLevel( vCascs, vLevel, i ) {
|
||||
Abc_NtkForEachObjVec( vLevel, pNtk, pObj, k ) {
|
||||
assert( Abc_ObjIsNode(pObj) );
|
||||
sprintf( pName, "c%d_n%d", i, k );
|
||||
if ( Vec_IntEntry(vMap, pObj->pCopy->Id) == 0 )
|
||||
Abc_ObjAssignName( Abc_NtkObj(pNtkNew, pObj->pCopy->Id), pName, NULL );
|
||||
else {
|
||||
Nm_ManDeleteIdName( pNtkNew->pManName, Vec_IntEntry(vMap, pObj->pCopy->Id) );
|
||||
Abc_ObjAssignName( Abc_NtkObj(pNtkNew, Vec_IntEntry(vMap, pObj->pCopy->Id)), pName, NULL );
|
||||
}
|
||||
}
|
||||
}
|
||||
Vec_IntFree( vMap );
|
||||
}
|
||||
void Abc_NtkLutCascadeDumpResults( char * pDumpFile, char * pTest, int Nodes, int Edges, int Levs, int DelStart, int DelStop, float DelRatio, int EdgesUsed, float EdgeRatio, int Cascs, float AveLength, abctime time )
|
||||
{
|
||||
FILE * pTable = fopen( pDumpFile, "a+" );
|
||||
fprintf( pTable, "%s,", pTest+28 );
|
||||
fprintf( pTable, "%d,", Nodes );
|
||||
fprintf( pTable, "%d,", Edges );
|
||||
fprintf( pTable, "%d,", Levs );
|
||||
fprintf( pTable, "%d,", DelStart );
|
||||
fprintf( pTable, "%d,", DelStop );
|
||||
fprintf( pTable, "%.2f,", DelRatio );
|
||||
fprintf( pTable, "%d,", EdgesUsed );
|
||||
fprintf( pTable, "%.2f,", EdgeRatio );
|
||||
fprintf( pTable, "%d,", Cascs );
|
||||
fprintf( pTable, "%.1f,", AveLength );
|
||||
fprintf( pTable, "%.2f,", 1.0*((double)(time))/((double)CLOCKS_PER_SEC) );
|
||||
fprintf( pTable, "\n" );
|
||||
fclose( pTable );
|
||||
}
|
||||
|
||||
Abc_Ntk_t * Abc_NtkLutCascadeMap( Abc_Ntk_t * pNtk, int nLutsMax, int nIters, int fDelayLut, int fDelayRoute, int fDelayDirect, int fVerbose )
|
||||
{
|
||||
abctime clk = Abc_Clock();
|
||||
Abc_Ntk_t * pNtkNew = NULL;
|
||||
Abc_LutCas_t * p = Abc_LutCasAlloc( pNtk, nLutsMax, nIters, fDelayLut, fDelayRoute, fDelayDirect, fVerbose );
|
||||
int i, IterBest = 0, DelayStart = Abc_NtkFindTiming( p ), DelayBest = DelayStart, nEdges = Abc_NtkGetTotalFanins(pNtk);
|
||||
//printf( "Delays: LUT (%d) Route (%d) Direct (%d). Iters = %d. LUTs = %d.\n", fDelayLut, fDelayRoute, fDelayDirect, nIters, Abc_NtkNodeNum(pNtk) );
|
||||
Vec_IntFill( p->vTraceBest, Abc_NtkNodeNum(pNtk), 0 );
|
||||
for ( i = 0; i < nIters; i++ )
|
||||
{
|
||||
if ( fVerbose )
|
||||
printf( "ITERATION %2d:\n", i );
|
||||
float Delay = Abc_NtkAddEdges( p );
|
||||
if ( DelayBest < Delay || (DelayBest == Delay && Vec_IntSize(p->vTraceBest) <= Vec_IntSize(p->vTrace)) )
|
||||
continue;
|
||||
IterBest = i;
|
||||
DelayBest = Delay;
|
||||
ABC_SWAP( Vec_Int_t *, p->vTrace, p->vTraceBest );
|
||||
}
|
||||
printf( "Delay reduction %d -> %d (-%.2f %%) is found after iter %d with %d edges (%.2f %%). ",
|
||||
DelayStart, DelayBest, 100.0*(DelayStart - DelayBest)/DelayStart, IterBest, Vec_IntSize(p->vTraceBest)/2, 50.0*Vec_IntSize(p->vTraceBest)/nEdges );
|
||||
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
|
||||
Vec_Wec_t * vCascs = Abc_NtkProfileCascades( p->pNtk, p->vTraceBest );
|
||||
// Abc_NtkLutCascadeDumpResults( "stats.csv", pNtk->pName, Abc_NtkNodeNum(pNtk), nEdges, Abc_NtkLevel(pNtk), DelayStart, DelayBest, 100.0*(DelayStart - DelayBest)/DelayStart,
|
||||
// Vec_IntSize(p->vTraceBest)/2, 50.0*Vec_IntSize(p->vTraceBest)/nEdges, Vec_WecSize(vCascs), 0.5*Vec_IntSize(p->vTraceBest)/Abc_MaxInt(1, Vec_WecSize(vCascs)), Abc_Clock() - clk );
|
||||
Abc_LutCasFree( p );
|
||||
pNtkNew = Abc_NtkDup( pNtk );
|
||||
Abc_LutCasAssignNames( pNtk, pNtkNew, vCascs );
|
||||
Vec_WecFree( vCascs );
|
||||
return pNtkNew;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
|
|
|
|||
|
|
@ -1221,6 +1221,8 @@ Abc_Ntk_t * Abc_NtkFromDarChoices( Abc_Ntk_t * pNtkOld, Aig_Man_t * pMan )
|
|||
Aig_ManForEachNode( pMan, pObj, i )
|
||||
{
|
||||
pObj->pData = Abc_AigAnd( (Abc_Aig_t *)pNtkNew->pManFunc, (Abc_Obj_t *)Aig_ObjChild0Copy(pObj), (Abc_Obj_t *)Aig_ObjChild1Copy(pObj) );
|
||||
}
|
||||
Aig_ManForEachNode( pMan, pObj, i ) {
|
||||
if ( (pTemp = Aig_ObjEquiv(pMan, pObj)) )
|
||||
{
|
||||
assert( pTemp->pData != NULL );
|
||||
|
|
|
|||
|
|
@ -430,10 +430,10 @@ Abc_Obj_t * Abc_NtkBddCurtis( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode, Vec_Ptr_t
|
|||
int b, c, u, i;
|
||||
assert( nBits + 2 <= nLutSize );
|
||||
assert( nLutSize < Abc_ObjFaninNum(pNode) );
|
||||
// start BDDs for the decompoosed blocks
|
||||
// start BDDs for the decomposed blocks
|
||||
for ( b = 0; b < nBits; b++ )
|
||||
bBits[b] = Cudd_ReadLogicZero(ddNew), Cudd_Ref( bBits[b] );
|
||||
// add each bound set minterm to one of the blccks
|
||||
// add each bound set minterm to one of the blocks
|
||||
Vec_PtrForEachEntry( DdNode *, vCofs, bCof, c )
|
||||
{
|
||||
Vec_PtrForEachEntry( DdNode *, vUniq, bUniq, u )
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ static Abc_Obj_t * Abc_NodeFromMapSuperChoice_rec( Abc_Ntk_t * pNtkNew, Map_Sup
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Ntk_t * Abc_NtkMap( Abc_Ntk_t * pNtk, double DelayTarget, double AreaMulti, double DelayMulti, float LogFan, float Slew, float Gain, int nGatesMin, int fRecovery, int fSwitching, int fSkipFanout, int fUseProfile, int fUseBuffs, int fVerbose )
|
||||
Abc_Ntk_t * Abc_NtkMap( Abc_Ntk_t * pNtk, Mio_Library_t* userLib, double DelayTarget, double AreaMulti, double DelayMulti, float LogFan, float Slew, float Gain, int nGatesMin, int fRecovery, int fSwitching, int fSkipFanout, int fUseProfile, int fUseBuffs, int fVerbose )
|
||||
{
|
||||
static int fUseMulti = 0;
|
||||
int fShowSwitching = 1;
|
||||
|
|
@ -88,6 +88,11 @@ Abc_Ntk_t * Abc_NtkMap( Abc_Ntk_t * pNtk, double DelayTarget, double AreaMulti,
|
|||
Map_SuperLibFree( (Map_SuperLib_t *)Abc_FrameReadLibSuper() );
|
||||
Abc_FrameSetLibSuper( NULL );
|
||||
}
|
||||
|
||||
if ( userLib != NULL ) {
|
||||
pLib = userLib;
|
||||
}
|
||||
|
||||
// quit if there is no library
|
||||
if ( pLib == NULL )
|
||||
{
|
||||
|
|
@ -847,7 +852,7 @@ Vec_Int_t * Abc_NtkWriteMiniMapping( Abc_Ntk_t * pNtk )
|
|||
// write the numbers of CI/CO/Node/FF
|
||||
Vec_IntPush( vMapping, Abc_NtkCiNum(pNtk) );
|
||||
Vec_IntPush( vMapping, Abc_NtkCoNum(pNtk) );
|
||||
Vec_IntPush( vMapping, Abc_NtkNodeNum(pNtk) );
|
||||
Vec_IntPush( vMapping, Vec_PtrSize(vNodes) );
|
||||
Vec_IntPush( vMapping, Abc_NtkLatchNum(pNtk) );
|
||||
// write the nodes
|
||||
vGates = Vec_StrAlloc( 10000 );
|
||||
|
|
@ -863,6 +868,15 @@ Vec_Int_t * Abc_NtkWriteMiniMapping( Abc_Ntk_t * pNtk )
|
|||
// write the COs literals
|
||||
Abc_NtkForEachCo( pNtk, pObj, i )
|
||||
Vec_IntPush( vMapping, Abc_ObjFanin0(pObj)->iTemp );
|
||||
// write signal names
|
||||
Abc_NtkForEachCi( pNtk, pObj, i ) {
|
||||
Vec_StrPrintStr( vGates, Abc_ObjName(pObj) );
|
||||
Vec_StrPush( vGates, '\0' );
|
||||
}
|
||||
Abc_NtkForEachCo( pNtk, pObj, i ) {
|
||||
Vec_StrPrintStr( vGates, Abc_ObjName(pObj) );
|
||||
Vec_StrPush( vGates, '\0' );
|
||||
}
|
||||
// finish off the array
|
||||
nExtra = 4 - Vec_StrSize(vGates) % 4;
|
||||
for ( i = 0; i < nExtra; i++ )
|
||||
|
|
@ -879,6 +893,129 @@ Vec_Int_t * Abc_NtkWriteMiniMapping( Abc_Ntk_t * pNtk )
|
|||
return vMapping;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Build mapped network from the mini-mapped format.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Ntk_t * Abc_NtkFromMiniMapping( int *pArray )
|
||||
{
|
||||
if ( !pArray ) {
|
||||
printf("Mapping is not available.\n");
|
||||
return NULL;
|
||||
}
|
||||
Mio_Library_t * pLib = (Mio_Library_t *)Abc_FrameReadLibGen();
|
||||
if ( !pLib ) {
|
||||
printf("Library is not available.\n");
|
||||
return NULL;
|
||||
}
|
||||
Abc_Ntk_t *pNtkMapped = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_MAP, 1 );
|
||||
pNtkMapped->pName = Extra_UtilStrsav( "mapped" );
|
||||
pNtkMapped->pManFunc = pLib;
|
||||
int nCis, nCos, nNodes, nFlops;
|
||||
int i, k, nLeaves, Pos = 4;
|
||||
char * pBuffer, * pName;
|
||||
Mio_Gate_t *pGate;
|
||||
Abc_Obj_t * pObj;
|
||||
nCis = pArray[0];
|
||||
nCos = pArray[1];
|
||||
nNodes = pArray[2];
|
||||
nFlops = pArray[3];
|
||||
// create pis
|
||||
for ( i = 0; i < nCis-nFlops; i++ )
|
||||
Abc_NtkCreatePi( pNtkMapped );
|
||||
// create pos
|
||||
for ( i = 0; i < nCos-nFlops; i++ )
|
||||
Abc_NtkCreatePo( pNtkMapped );
|
||||
// create flops
|
||||
for ( i = 0; i < nFlops; i++ )
|
||||
Abc_NtkAddLatch( pNtkMapped, NULL, ABC_INIT_ZERO );
|
||||
// create nodes
|
||||
for ( i = 0; i < nNodes; i++ )
|
||||
Abc_NtkCreateNode( pNtkMapped );
|
||||
// connect nodes
|
||||
for ( i = 0; i < nNodes; i++ )
|
||||
{
|
||||
nLeaves = pArray[Pos++];
|
||||
for ( k = 0; k < nLeaves; k++ )
|
||||
Abc_ObjAddFanin( Abc_NtkObj( pNtkMapped, nCis + i + 1 ), Abc_NtkObj( pNtkMapped, pArray[Pos++] + 1 ) );
|
||||
}
|
||||
for ( i = 0; i < nCos; i++ )
|
||||
Abc_ObjAddFanin( Abc_NtkCo( pNtkMapped, i ), Abc_NtkObj( pNtkMapped, pArray[Pos++] + 1 ) );
|
||||
|
||||
pBuffer = (char *)(pArray + Pos);
|
||||
for ( i = 0; i < nNodes; i++ )
|
||||
{
|
||||
pName = pBuffer;
|
||||
pBuffer += strlen(pName) + 1;
|
||||
pGate = Mio_LibraryReadGateByName( pLib, pName, NULL );
|
||||
Abc_NtkObj( pNtkMapped, nCis + i + 1 )->pData = pGate;
|
||||
}
|
||||
|
||||
assert( Abc_NtkCiNum(pNtkMapped) == nCis );
|
||||
Abc_NtkForEachCi( pNtkMapped, pObj, i ) {
|
||||
pName = pBuffer;
|
||||
pBuffer += strlen(pName) + 1;
|
||||
Abc_ObjAssignName( pObj, pName, NULL );
|
||||
}
|
||||
assert( Abc_NtkCoNum(pNtkMapped) == nCos );
|
||||
Abc_NtkForEachCo( pNtkMapped, pObj, i ) {
|
||||
pName = pBuffer;
|
||||
pBuffer += strlen(pName) + 1;
|
||||
Abc_ObjAssignName( pObj, pName, NULL );
|
||||
}
|
||||
|
||||
if ( !Abc_NtkCheck( pNtkMapped ) ) {
|
||||
fprintf( stdout, "Abc_NtkFromMiniMapping(): Network check has failed.\n" );
|
||||
}
|
||||
|
||||
return pNtkMapped;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [File IO.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Ntk_t * Abc_NtkReadFromFile( char * pFileName )
|
||||
{
|
||||
int nSize = Extra_FileSize( pFileName );
|
||||
if ( nSize == 0 )
|
||||
return NULL;
|
||||
FILE * pFile = fopen( pFileName, "rb" );
|
||||
char * pArray = ABC_ALLOC( char, nSize );
|
||||
int nSize2 = fread( pArray, sizeof(char), nSize, pFile );
|
||||
assert( nSize2 == nSize );
|
||||
fclose( pFile );
|
||||
Abc_Ntk_t * pNtk = Abc_NtkFromMiniMapping( (int*)pArray );
|
||||
ABC_FREE( pArray );
|
||||
return pNtk;
|
||||
}
|
||||
int Abc_NtkWriteToFile( char * pFileName, Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Vec_Int_t * vRes = Abc_NtkWriteMiniMapping( pNtk );
|
||||
FILE * pFile = fopen( pFileName, "wb" );
|
||||
if ( pFile == NULL ) { printf( "Cannot open input file \"%s\" for writing.\n", pFileName ); return 0; }
|
||||
int nSize = fwrite( Vec_IntArray(vRes), sizeof(int), Vec_IntSize(vRes), pFile );
|
||||
assert( nSize == Vec_IntSize(vRes) );
|
||||
Vec_IntFree( vRes );
|
||||
fclose( pFile );
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Prints mapped network represented in mini-mapped format.]
|
||||
|
|
@ -903,8 +1040,8 @@ void Abc_NtkPrintMiniMapping( int * pArray )
|
|||
printf( "The first %d object IDs (from 0 to %d) are reserved for the CIs.\n", nCis, nCis - 1 );
|
||||
for ( i = 0; i < nNodes; i++ )
|
||||
{
|
||||
printf( "Node %d has fanins {", nCis + i );
|
||||
nLeaves = pArray[Pos++];
|
||||
printf( "Node %d has %d fanins {", nCis + i, nLeaves );
|
||||
for ( k = 0; k < nLeaves; k++ )
|
||||
printf( " %d", pArray[Pos++] );
|
||||
printf( " }\n" );
|
||||
|
|
@ -918,6 +1055,38 @@ void Abc_NtkPrintMiniMapping( int * pArray )
|
|||
pBuffer += strlen(pName) + 1;
|
||||
printf( "Node %d has gate \"%s\"\n", nCis + i, pName );
|
||||
}
|
||||
for ( i = 0; i < nCis; i++ )
|
||||
{
|
||||
pName = pBuffer;
|
||||
pBuffer += strlen(pName) + 1;
|
||||
printf( "CI %d has name \"%s\"\n", i, pName );
|
||||
}
|
||||
for ( i = 0; i < nCos; i++ )
|
||||
{
|
||||
pName = pBuffer;
|
||||
pBuffer += strlen(pName) + 1;
|
||||
printf( "CO %d has name \"%s\"\n", i, pName );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Procedures to update internal ABC network using mini-mapped network.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NtkInputMiniMapping( Abc_Frame_t * pAbc, void *p )
|
||||
{
|
||||
Abc_Ntk_t * pNtk;
|
||||
if ( pAbc == NULL )
|
||||
printf( "ABC framework is not initialized by calling Abc_Start()\n" );
|
||||
pNtk = Abc_NtkFromMiniMapping( (int *)p );
|
||||
Abc_FrameReplaceCurrentNetwork( pAbc, pNtk );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#include "bool/kit/kit.h"
|
||||
#include "opt/sfm/sfm.h"
|
||||
#include "base/io/ioAbc.h"
|
||||
#include "misc/util/utilTruth.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
|
@ -330,6 +331,7 @@ void Abc_NtkInsertMfs( Abc_Ntk_t * pNtk, Sfm_Ntk_t * p )
|
|||
// update fanins
|
||||
vArray = Sfm_NodeReadFanins( p, pNode->iTemp );
|
||||
pTruth = Sfm_NodeReadTruth( p, pNode->iTemp );
|
||||
Abc_TtFlipVar5( pTruth, Vec_IntSize(vArray) );
|
||||
pNode->pData = Abc_SopCreateFromTruthIsop( (Mem_Flex_t *)pNtk->pManFunc, Vec_IntSize(vArray), pTruth, vCover );
|
||||
if ( Abc_SopGetVarNum((char *)pNode->pData) == 0 )
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -144,6 +144,22 @@ Mini_Aig_t * Abc_NtkToMiniAig( Abc_Ntk_t * pNtk )
|
|||
Mini_AigSetRegNum( p, Abc_NtkLatchNum(pNtk) );
|
||||
return p;
|
||||
}
|
||||
Mini_Aig_t * Abc_MiniAigFromNtk ( Abc_Ntk_t *pNtk )
|
||||
{
|
||||
Abc_Ntk_t *pNtkRes = NULL;
|
||||
Mini_Aig_t *pAig;
|
||||
if (Abc_NtkHasMapping(pNtk)) {
|
||||
pNtk = pNtkRes = Abc_NtkStrash( pNtk, 0, 1, 0 );
|
||||
if ( pNtkRes == NULL )
|
||||
{
|
||||
printf("Strashing has failed.\n" );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
pAig = Abc_NtkToMiniAig(pNtk);
|
||||
if (pNtkRes) Abc_NtkDelete(pNtkRes);
|
||||
return pAig;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
|
|
|
|||
|
|
@ -3383,26 +3383,43 @@ clk = Abc_Clock();
|
|||
Rwr_ManAddTimeUpdate( pManRwr, Abc_Clock() - clk );
|
||||
if ( fCompl ) Dec_GraphComplement( pGraph );
|
||||
ops_rwr++;
|
||||
if(pFFormRef != NULL){
|
||||
Dec_GraphFree( pFFormRef );
|
||||
}
|
||||
if(pFFormRes != NULL){
|
||||
Dec_GraphFree( pFFormRes );
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// if (((! (pManRes->nLastGain < 0)) && (! (pManRes->nLastGain < nGain)) && (! (nGain < pManRef->nLastGain))) || ((! (pManRes->nLastGain < 0)) && (! (pManRes->nLastGain < pManRef->nLastGain)) && (! (pManRef->nLastGain < nGain)))){
|
||||
if (((! (pManRes->nLastGain < 0)) && (! (pManRes->nLastGain < nGain)) && (! (pManRes->nLastGain < pManRef->nLastGain)))){
|
||||
// update with Resub
|
||||
if ( pFFormRes == NULL )
|
||||
if ( pFFormRes == NULL ) {
|
||||
if (pFFormRef != NULL) {
|
||||
Dec_GraphFree(pFFormRef);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
pManRes->nTotalGain += pManRes->nLastGain;
|
||||
clk = Abc_Clock();
|
||||
Dec_GraphUpdateNetwork( pNode, pFFormRes, fUpdateLevel, pManRes->nLastGain );
|
||||
pManRes->timeNtk += Abc_Clock() - clk;
|
||||
Dec_GraphFree( pFFormRes );
|
||||
ops_res++;
|
||||
if( pFFormRef != NULL ){
|
||||
Dec_GraphFree( pFFormRef);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// if (((! (pManRef->nLastGain < 0)) && (! (pManRef->nLastGain < nGain)) && (! (nGain < pManRes->nLastGain))) || ((! (pManRef->nLastGain < 0)) && (! (pManRef->nLastGain < pManRes->nLastGain)) && (! (pManRes->nLastGain < nGain)))){
|
||||
if (((! (pManRef->nLastGain < 0)) && (! (pManRef->nLastGain < nGain)) && (! (pManRef->nLastGain < pManRes->nLastGain)))){
|
||||
// update with Refactor
|
||||
if ( pFFormRef == NULL )
|
||||
if ( pFFormRef == NULL ) {
|
||||
if( pFFormRes != NULL) {
|
||||
Dec_GraphFree(pFFormRes);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
clk = Abc_Clock();
|
||||
if ( !Dec_GraphUpdateNetwork( pNode, pFFormRef, fUpdateLevel, pManRef->nLastGain ) )
|
||||
{
|
||||
|
|
@ -3413,9 +3430,21 @@ clk = Abc_Clock();
|
|||
pManRef->timeNtk += Abc_Clock() - clk;
|
||||
Dec_GraphFree( pFFormRef );
|
||||
ops_ref++;
|
||||
if(pFFormRes != NULL){
|
||||
Dec_GraphFree( pFFormRes );
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else{
|
||||
ops_null++;
|
||||
if( pFFormRef != NULL ){
|
||||
Dec_GraphFree( pFFormRef);
|
||||
}
|
||||
if(pFFormRes != NULL){
|
||||
Dec_GraphFree( pFFormRes );
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else{ops_null++; continue;}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -21,6 +21,14 @@
|
|||
#include "base/abc/abc.h"
|
||||
#include "base/main/main.h"
|
||||
#include "base/cmd/cmd.h"
|
||||
#include "map/mio/mio.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#include <process.h>
|
||||
#define unlink _unlink
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
|
@ -1197,6 +1205,690 @@ void Abc_NtkFraigPartitionedTime( Abc_Ntk_t * pNtk, void * pParams )
|
|||
ABC_PRT( "Partitioned fraiging time", Abc_Clock() - clk );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Optimization.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NtkStochSynthesis( Vec_Ptr_t * vWins, char * pScript )
|
||||
{
|
||||
Abc_Ntk_t * pNtk, * pNew; int i;
|
||||
Vec_PtrForEachEntry( Abc_Ntk_t *, vWins, pNtk, i )
|
||||
{
|
||||
Abc_FrameReplaceCurrentNetwork( Abc_FrameGetGlobalFrame(), Abc_NtkDupDfs(pNtk) );
|
||||
if ( Abc_FrameIsBatchMode() )
|
||||
{
|
||||
if ( Cmd_CommandExecute(Abc_FrameGetGlobalFrame(), pScript) )
|
||||
{
|
||||
Abc_Print( 1, "Something did not work out with the command \"%s\".\n", pScript );
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Abc_FrameSetBatchMode( 1 );
|
||||
if ( Cmd_CommandExecute(Abc_FrameGetGlobalFrame(), pScript) )
|
||||
{
|
||||
Abc_Print( 1, "Something did not work out with the command \"%s\".\n", pScript );
|
||||
Abc_FrameSetBatchMode( 0 );
|
||||
return;
|
||||
}
|
||||
Abc_FrameSetBatchMode( 0 );
|
||||
}
|
||||
pNew = Abc_FrameReadNtk(Abc_FrameGetGlobalFrame());
|
||||
if ( Abc_NtkIsMappedLogic(pNew) && Abc_NtkIsMappedLogic(pNtk) )
|
||||
{
|
||||
if ( Abc_NtkGetMappedArea(pNew) < Abc_NtkGetMappedArea(pNtk) )
|
||||
{
|
||||
Abc_NtkDelete( pNtk );
|
||||
pNtk = Abc_NtkDupDfs( pNew );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( Abc_NtkNodeNum(pNew) < Abc_NtkNodeNum(pNtk) )
|
||||
{
|
||||
Abc_NtkDelete( pNtk );
|
||||
pNtk = Abc_NtkDupDfs( pNew );
|
||||
}
|
||||
}
|
||||
Vec_PtrWriteEntry( vWins, i, pNtk );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Generic concurrent processing.]
|
||||
|
||||
Description [User-defined problem-specific data and the way to process it.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
typedef struct StochSynData_t_
|
||||
{
|
||||
Abc_Ntk_t * pIn;
|
||||
Abc_Ntk_t * pOut;
|
||||
char * pScript;
|
||||
int Rand;
|
||||
int TimeOut;
|
||||
} StochSynData_t;
|
||||
|
||||
Abc_Ntk_t * Abc_NtkStochProcessOne( Abc_Ntk_t * p, char * pScript0, int Rand, int TimeSecs )
|
||||
{
|
||||
extern int Abc_NtkWriteToFile( char * pFileName, Abc_Ntk_t * pNtk );
|
||||
extern Abc_Ntk_t * Abc_NtkReadFromFile( char * pFileName );
|
||||
Abc_Ntk_t * pNew, * pTemp;
|
||||
char FileName[100], Command[1000], PreCommand[500] = {0};
|
||||
char * pLibFileName = Abc_NtkIsMappedLogic(p) ? Mio_LibraryReadFileName((Mio_Library_t *)p->pManFunc) : NULL;
|
||||
if ( pLibFileName ) sprintf( PreCommand, "read_genlib %s; ", pLibFileName );
|
||||
sprintf( FileName, "%06x.mm", Rand );
|
||||
Abc_NtkWriteToFile( FileName, p );
|
||||
char * pScript = Abc_UtilStrsav( pScript0 );
|
||||
sprintf( Command, "./abc -q \"%sread_mm %s; %s; write_mm %s\"", PreCommand[0] ? PreCommand : "", FileName, pScript, FileName );
|
||||
#if defined(__wasm)
|
||||
if ( 1 )
|
||||
#else
|
||||
if ( system( (char *)Command ) )
|
||||
#endif
|
||||
{
|
||||
fprintf( stderr, "The following command has returned non-zero exit status:\n" );
|
||||
fprintf( stderr, "\"%s\"\n", (char *)Command );
|
||||
fprintf( stderr, "Sorry for the inconvenience.\n" );
|
||||
fflush( stdout );
|
||||
unlink( FileName );
|
||||
ABC_FREE( pScript );
|
||||
return Abc_NtkDupDfs(p);
|
||||
}
|
||||
ABC_FREE( pScript );
|
||||
pNew = Abc_NtkReadFromFile( FileName );
|
||||
unlink( FileName );
|
||||
if ( pNew && Abc_NtkGetMappedArea(pNew) < Abc_NtkGetMappedArea(p) ) {
|
||||
pNew = Abc_NtkDupDfs( pTemp = pNew );
|
||||
Abc_NtkDelete( pTemp );
|
||||
return pNew;
|
||||
}
|
||||
if ( pNew ) Abc_NtkDelete( pNew );
|
||||
return Abc_NtkDupDfs(p);
|
||||
}
|
||||
|
||||
int Abc_NtkStochProcess1( void * p )
|
||||
{
|
||||
StochSynData_t * pData = (StochSynData_t *)p;
|
||||
assert( pData->pIn != NULL );
|
||||
assert( pData->pOut == NULL );
|
||||
pData->pOut = Abc_NtkStochProcessOne( pData->pIn, pData->pScript, pData->Rand, pData->TimeOut );
|
||||
return 1;
|
||||
}
|
||||
|
||||
Vec_Ptr_t * Abc_NtkStochProcess( Vec_Ptr_t * vWins, char * pScript, int nProcs, int TimeSecs, int fVerbose )
|
||||
{
|
||||
if ( nProcs <= 2 ) {
|
||||
Abc_NtkStochSynthesis( vWins, pScript );
|
||||
return NULL;
|
||||
}
|
||||
StochSynData_t * pData = ABC_CALLOC( StochSynData_t, Vec_PtrSize(vWins) );
|
||||
Vec_Ptr_t * vData = Vec_PtrAlloc( Vec_PtrSize(vWins) );
|
||||
Abc_Ntk_t * pNtk; int i;
|
||||
Abc_Random(1);
|
||||
Vec_PtrForEachEntry( Abc_Ntk_t *, vWins, pNtk, i ) {
|
||||
pData[i].pIn = pNtk;
|
||||
pData[i].pOut = NULL;
|
||||
pData[i].pScript = pScript;
|
||||
pData[i].Rand = Abc_Random(0) % 0x1000000;
|
||||
pData[i].TimeOut = TimeSecs;
|
||||
Vec_PtrPush( vData, pData+i );
|
||||
}
|
||||
Util_ProcessThreads( Abc_NtkStochProcess1, vData, nProcs, TimeSecs, fVerbose );
|
||||
// replace old AIGs by new AIGs
|
||||
Vec_PtrForEachEntry( Abc_Ntk_t *, vWins, pNtk, i ) {
|
||||
Abc_NtkDelete( pNtk );
|
||||
Vec_PtrWriteEntry( vWins, i, pData[i].pOut );
|
||||
}
|
||||
Vec_PtrFree( vData );
|
||||
ABC_FREE( pData );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns 1 if this window has a topo error (forward path from an output to an input).]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NtkWindowCheckTopoError_rec( Abc_Obj_t * pObj )
|
||||
{
|
||||
if ( !Abc_ObjIsNode(pObj) )
|
||||
return 0;
|
||||
if ( Abc_NodeIsTravIdPrevious(pObj) )
|
||||
return 1; // there is an error
|
||||
if ( Abc_NodeIsTravIdCurrent(pObj) )
|
||||
return 0; // there is no error; visited this node before
|
||||
Abc_NodeSetTravIdPrevious(pObj);
|
||||
Abc_Obj_t * pFanin; int i;
|
||||
Abc_ObjForEachFanin( pObj, pFanin, i )
|
||||
if ( Abc_NtkWindowCheckTopoError_rec(pFanin) )
|
||||
return 1;
|
||||
Abc_NodeSetTravIdCurrent(pObj);
|
||||
return 0;
|
||||
}
|
||||
int Abc_NtkWindowCheckTopoError( Abc_Ntk_t * p, Vec_Int_t * vIns, Vec_Int_t * vOuts )
|
||||
{
|
||||
Abc_Obj_t * pObj; int i, fError = 0;
|
||||
// outputs should be internal nodes
|
||||
Abc_NtkForEachObjVec( vOuts, p, pObj, i )
|
||||
assert(Abc_ObjIsNode(pObj));
|
||||
// mark outputs
|
||||
Abc_NtkIncrementTravId( p );
|
||||
Abc_NtkForEachObjVec( vOuts, p, pObj, i )
|
||||
Abc_NodeSetTravIdCurrent(pObj);
|
||||
// start from inputs and make sure we do not reach any of the outputs
|
||||
Abc_NtkIncrementTravId( p );
|
||||
Abc_NtkForEachObjVec( vIns, p, pObj, i )
|
||||
fError |= Abc_NtkWindowCheckTopoError_rec(pObj);
|
||||
return fError;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Updates the AIG after multiple windows have been optimized.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NtkCreateNodeMapped( Abc_Ntk_t * pNew, Abc_Obj_t * pObj )
|
||||
{
|
||||
Abc_Obj_t * pObjNew = Abc_NtkDupObj( pNew, pObj, 0 );
|
||||
Abc_Obj_t * pFanin; int i;
|
||||
Abc_ObjForEachFanin( pObj, pFanin, i )
|
||||
Abc_ObjAddFanin( pObjNew, pFanin->pCopy );
|
||||
}
|
||||
void Abc_NtkInsertPartitions_rec( Abc_Ntk_t * pNew, Abc_Obj_t * pObj, Vec_Int_t * vMap, Vec_Ptr_t * vvIns, Vec_Ptr_t * vvOuts, Vec_Ptr_t * vWins )
|
||||
{
|
||||
if ( pObj->pCopy )
|
||||
return;
|
||||
assert( Abc_ObjIsNode(pObj) );
|
||||
if ( Vec_IntEntry(vMap, Abc_ObjId(pObj)) == -1 ) // this is a regular node
|
||||
{
|
||||
Abc_Obj_t * pFanin; int i;
|
||||
Abc_ObjForEachFanin( pObj, pFanin, i )
|
||||
Abc_NtkInsertPartitions_rec( pNew, pFanin, vMap, vvIns, vvOuts, vWins );
|
||||
Abc_NtkCreateNodeMapped( pNew, pObj );
|
||||
return;
|
||||
}
|
||||
// this node is an output of a window
|
||||
int iWin = Vec_IntEntry(vMap, Abc_ObjId(pObj));
|
||||
Vec_Int_t * vIns = (Vec_Int_t *)Vec_PtrEntry(vvIns, iWin);
|
||||
Vec_Int_t * vOuts = (Vec_Int_t *)Vec_PtrEntry(vvOuts, iWin);
|
||||
Abc_Ntk_t * pWin = (Abc_Ntk_t *)Vec_PtrEntry(vWins, iWin);
|
||||
// build transinvite fanins of window inputs
|
||||
Abc_Obj_t * pNode; int i;
|
||||
Abc_NtkForEachObjVec( vIns, pObj->pNtk, pNode, i ) {
|
||||
Abc_NtkInsertPartitions_rec( pNew, pNode, vMap, vvIns, vvOuts, vWins );
|
||||
Abc_NtkPi(pWin, i)->pCopy = pNode->pCopy;
|
||||
}
|
||||
// add window nodes
|
||||
Vec_Ptr_t * vNodes = Abc_NtkDfs( pWin, 0 );
|
||||
Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNode, i )
|
||||
Abc_NtkCreateNodeMapped( pNew, pNode );
|
||||
Vec_PtrFree( vNodes );
|
||||
// transfer to window outputs
|
||||
Abc_NtkForEachObjVec( vOuts, pObj->pNtk, pNode, i )
|
||||
pNode->pCopy = Abc_ObjFanin0(Abc_NtkPo(pWin, i))->pCopy;
|
||||
assert( pObj->pCopy );
|
||||
}
|
||||
Abc_Ntk_t * Abc_NtkInsertPartitions( Abc_Ntk_t * p, Vec_Ptr_t * vvIns, Vec_Ptr_t * vvOuts, Vec_Ptr_t * vWins )
|
||||
{
|
||||
if ( vvIns == NULL ) {
|
||||
assert( vvOuts == NULL );
|
||||
assert( Vec_PtrSize(vWins) == 1 );
|
||||
return Abc_NtkDupDfs( (Abc_Ntk_t *)Vec_PtrEntry(vWins, 0) );
|
||||
}
|
||||
// check consistency of input data
|
||||
Abc_Ntk_t * pNew, * pTemp; Abc_Obj_t * pObj; int i, k, iNode;
|
||||
Vec_PtrForEachEntry( Abc_Ntk_t *, vWins, pTemp, i ) {
|
||||
Vec_Int_t * vIns = (Vec_Int_t *)Vec_PtrEntry(vvIns, i);
|
||||
Vec_Int_t * vOuts = (Vec_Int_t *)Vec_PtrEntry(vvOuts, i);
|
||||
assert( Vec_IntSize(vIns) == Abc_NtkPiNum(pTemp) );
|
||||
assert( Vec_IntSize(vOuts) == Abc_NtkPoNum(pTemp) );
|
||||
assert( !Abc_NtkWindowCheckTopoError(p, vIns, vOuts) );
|
||||
}
|
||||
// create mapping of window outputs into window IDs
|
||||
Vec_Int_t * vMap = Vec_IntStartFull( Abc_NtkObjNumMax(p) ), * vOuts;
|
||||
Vec_PtrForEachEntry( Vec_Int_t *, vvOuts, vOuts, i )
|
||||
Vec_IntForEachEntry( vOuts, iNode, k ) {
|
||||
assert( Vec_IntEntry(vMap, iNode) == -1 );
|
||||
Vec_IntWriteEntry( vMap, iNode, i );
|
||||
}
|
||||
Abc_NtkCleanCopy( p );
|
||||
pNew = Abc_NtkStartFrom( p, p->ntkType, p->ntkFunc );
|
||||
pNew->pManFunc = p->pManFunc;
|
||||
Abc_NtkForEachCo( p, pObj, i )
|
||||
Abc_NtkInsertPartitions_rec( pNew, Abc_ObjFanin0(pObj), vMap, vvIns, vvOuts, vWins );
|
||||
Abc_NtkForEachCo( p, pObj, i )
|
||||
Abc_ObjAddFanin( Abc_NtkCo(pNew, i), Abc_ObjFanin0(pObj)->pCopy );
|
||||
Vec_IntFree( vMap );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Partitioning.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_ObjDfsMark_rec( Abc_Obj_t * p )
|
||||
{
|
||||
Abc_Obj_t * pFanin; int i;
|
||||
assert( !p->fMarkA );
|
||||
if ( Abc_NodeIsTravIdCurrent( p ) )
|
||||
return;
|
||||
Abc_NodeSetTravIdCurrent( p );
|
||||
Abc_ObjForEachFanin( p, pFanin, i )
|
||||
Abc_ObjDfsMark_rec( pFanin );
|
||||
}
|
||||
void Abc_ObjDfsMark2_rec( Abc_Obj_t * p )
|
||||
{
|
||||
Abc_Obj_t * pFanout; int i;
|
||||
assert( !p->fMarkA );
|
||||
if ( Abc_NodeIsTravIdCurrent( p ) )
|
||||
return;
|
||||
Abc_NodeSetTravIdCurrent( p );
|
||||
Abc_ObjForEachFanout( p, pFanout, i )
|
||||
Abc_ObjDfsMark2_rec( pFanout );
|
||||
}
|
||||
Vec_Int_t * Abc_NtkDeriveWinNodes( Abc_Ntk_t * pNtk, Vec_Int_t * vIns, Vec_Wec_t * vStore )
|
||||
{
|
||||
Vec_Int_t * vLevel, * vNodes = Vec_IntAlloc( 100 );
|
||||
Abc_Obj_t * pObj, * pNext; int i, k, iLevel;
|
||||
Vec_WecForEachLevel( vStore, vLevel, i )
|
||||
Vec_IntClear( vLevel );
|
||||
// mark the TFI cones of the inputs
|
||||
Abc_NtkIncrementTravId( pNtk );
|
||||
Abc_NtkForEachObjVec( vIns, pNtk, pObj, i )
|
||||
Abc_ObjDfsMark_rec( pObj );
|
||||
// add unrelated fanouts of the inputs to storage
|
||||
Abc_NtkForEachObjVec( vIns, pNtk, pObj, i )
|
||||
Abc_ObjForEachFanout( pObj, pNext, k )
|
||||
if ( Abc_ObjIsNode(pNext) && !Abc_NodeIsTravIdCurrent(pNext) && !pNext->fMarkA ) {
|
||||
pNext->fMarkA = 1;
|
||||
Vec_WecPush( vStore, Abc_ObjLevel(pNext), Abc_ObjId(pNext) );
|
||||
}
|
||||
// mark the inputs
|
||||
Abc_NtkIncrementTravId( pNtk );
|
||||
Abc_NtkForEachObjVec( vIns, pNtk, pObj, i )
|
||||
Abc_NodeSetTravIdCurrent(pObj);
|
||||
// collect those fanouts that are completely supported by the inputs
|
||||
Vec_WecForEachLevel( vStore, vLevel, iLevel )
|
||||
Abc_NtkForEachObjVec( vLevel, pNtk, pObj, i ) {
|
||||
assert( !Abc_NodeIsTravIdCurrent(pObj) );
|
||||
assert( pObj->fMarkA );
|
||||
pObj->fMarkA = 0;
|
||||
Abc_ObjForEachFanin( pObj, pNext, k )
|
||||
if ( !Abc_NodeIsTravIdCurrent(pNext) )
|
||||
break;
|
||||
if ( k < Abc_ObjFaninNum(pObj) )
|
||||
continue;
|
||||
Abc_NodeSetTravIdCurrent(pObj);
|
||||
Vec_IntPush( vNodes, Abc_ObjId(pObj) );
|
||||
assert( Abc_ObjIsNode(pObj) );
|
||||
// add fanouts of this node to storage
|
||||
Abc_ObjForEachFanout( pObj, pNext, k )
|
||||
if ( Abc_ObjIsNode(pNext) && !Abc_NodeIsTravIdCurrent(pNext) && !pNext->fMarkA ) {
|
||||
pNext->fMarkA = 1;
|
||||
assert( Abc_ObjLevel(pNext) > iLevel );
|
||||
Vec_WecPush( vStore, Abc_ObjLevel(pNext), Abc_ObjId(pNext) );
|
||||
}
|
||||
}
|
||||
Vec_IntSort( vNodes, 0 );
|
||||
return vNodes;
|
||||
}
|
||||
Vec_Ptr_t * Abc_NtkDeriveWinNodesAll( Abc_Ntk_t * pNtk, Vec_Ptr_t * vvIns, Vec_Wec_t * vStore )
|
||||
{
|
||||
Vec_Int_t * vIns; int i;
|
||||
Vec_Ptr_t * vvNodes = Vec_PtrAlloc( Vec_PtrSize(vvIns) );
|
||||
Vec_PtrForEachEntry( Vec_Int_t *, vvIns, vIns, i )
|
||||
Vec_PtrPush( vvNodes, Abc_NtkDeriveWinNodes(pNtk, vIns, vStore) );
|
||||
return vvNodes;
|
||||
}
|
||||
Vec_Int_t * Abc_NtkDeriveWinOuts( Abc_Ntk_t * pNtk, Vec_Int_t * vNodes )
|
||||
{
|
||||
Vec_Int_t * vOuts = Vec_IntAlloc( 100 );
|
||||
Abc_Obj_t * pObj, * pNext; int i, k;
|
||||
// mark the nodes in the window
|
||||
Abc_NtkIncrementTravId( pNtk );
|
||||
Abc_NtkForEachObjVec( vNodes, pNtk, pObj, i )
|
||||
Abc_NodeSetTravIdCurrent(pObj);
|
||||
// collect nodes that have unmarked fanouts
|
||||
Abc_NtkForEachObjVec( vNodes, pNtk, pObj, i ) {
|
||||
Abc_ObjForEachFanout( pObj, pNext, k )
|
||||
if ( !Abc_NodeIsTravIdCurrent(pNext) )
|
||||
break;
|
||||
if ( k < Abc_ObjFanoutNum(pObj) )
|
||||
Vec_IntPush( vOuts, Abc_ObjId(pObj) );
|
||||
}
|
||||
if ( Vec_IntSize(vOuts) == 0 )
|
||||
printf( "Window with %d internal nodes has no outputs (are these dangling nodes?).\n", Vec_IntSize(vNodes) );
|
||||
return vOuts;
|
||||
}
|
||||
Vec_Ptr_t * Abc_NtkDeriveWinOutsAll( Abc_Ntk_t * pNtk, Vec_Ptr_t * vvNodes )
|
||||
{
|
||||
Vec_Int_t * vNodes; int i;
|
||||
Vec_Ptr_t * vvOuts = Vec_PtrAlloc( Vec_PtrSize(vvNodes) );
|
||||
Vec_PtrForEachEntry( Vec_Int_t *, vvNodes, vNodes, i )
|
||||
Vec_PtrPush( vvOuts, Abc_NtkDeriveWinOuts(pNtk, vNodes) );
|
||||
return vvOuts;
|
||||
}
|
||||
void Abc_NtkPermuteLevel( Abc_Ntk_t * pNtk, int Level )
|
||||
{
|
||||
Abc_Obj_t * pObj, * pNext; int i, k;
|
||||
Abc_NtkForEachNode( pNtk, pObj, i ) {
|
||||
int LevelMin = Abc_ObjLevel(pObj), LevelMax = Level + 1;
|
||||
Abc_ObjForEachFanout( pObj, pNext, k )
|
||||
if ( Abc_ObjIsNode(pNext) )
|
||||
LevelMax = Abc_MinInt( LevelMax, Abc_ObjLevel(pNext) );
|
||||
assert( LevelMin < LevelMax );
|
||||
// randomly set level between LevelMin and LevelMax-1
|
||||
pObj->Level = LevelMin + (Abc_Random(0) % (LevelMax - LevelMin));
|
||||
assert( pObj->Level < LevelMax );
|
||||
}
|
||||
}
|
||||
Vec_Int_t * Abc_NtkCollectObjectsPointedTo( Abc_Ntk_t * pNtk, int Level )
|
||||
{
|
||||
Vec_Int_t * vRes = Vec_IntAlloc( 100 );
|
||||
Abc_Obj_t * pObj, * pFanin; int i, k;
|
||||
Abc_NtkIncrementTravId( pNtk );
|
||||
Abc_NtkForEachNode( pNtk, pObj, i ) {
|
||||
if ( Abc_ObjLevel(pObj) <= Level )
|
||||
continue;
|
||||
Abc_ObjForEachFanin( pObj, pFanin, k )
|
||||
if ( Abc_ObjLevel(pFanin) <= Level && !Abc_NodeIsTravIdCurrent(pFanin) ) {
|
||||
Abc_NodeSetTravIdCurrent(pFanin);
|
||||
Vec_IntPush( vRes, Abc_ObjId(pFanin) );
|
||||
}
|
||||
}
|
||||
Abc_NtkForEachCo( pNtk, pObj, i ) {
|
||||
pFanin = Abc_ObjFanin0(pObj);
|
||||
if ( Abc_ObjLevel(pFanin) <= Level && !Abc_NodeIsTravIdCurrent(pFanin) && Abc_ObjFaninNum(pFanin) > 0 ) {
|
||||
Abc_NodeSetTravIdCurrent(pFanin);
|
||||
Vec_IntPush( vRes, Abc_ObjId(pFanin) );
|
||||
}
|
||||
}
|
||||
Vec_IntSort( vRes, 0 );
|
||||
return vRes;
|
||||
}
|
||||
Vec_Wec_t * Abc_NtkCollectObjectsWithSuppLimit( Abc_Ntk_t * pNtk, int Level, int nSuppMax )
|
||||
{
|
||||
Vec_Wec_t * vResSupps = NULL;
|
||||
Vec_Int_t * vBelow = Abc_NtkCollectObjectsPointedTo( pNtk, Level );
|
||||
Vec_Wec_t * vSupps = Vec_WecStart( Vec_IntSize(vBelow) );
|
||||
Vec_Int_t * vSuppIds = Vec_IntStartFull( Abc_NtkObjNumMax(pNtk)+1 );
|
||||
Vec_Int_t * vTemp[2] = { Vec_IntAlloc(100), Vec_IntAlloc(100) };
|
||||
Abc_Obj_t * pObj, * pFanin; int i, k, Count = 0;
|
||||
Abc_NtkForEachObjVec( vBelow, pNtk, pObj, i ) {
|
||||
Vec_IntWriteEntry( vSuppIds, Abc_ObjId(pObj), i );
|
||||
Vec_IntPush( Vec_WecEntry(vSupps, i), Abc_ObjId(pObj) );
|
||||
}
|
||||
Abc_NtkForEachNode( pNtk, pObj, i ) {
|
||||
if ( Abc_ObjLevel(pObj) <= Level )
|
||||
continue;
|
||||
Vec_IntClear( vTemp[0] );
|
||||
Abc_ObjForEachFanin( pObj, pFanin, k ) {
|
||||
int iSuppId = Vec_IntEntry( vSuppIds, Abc_ObjId(pFanin) );
|
||||
if ( iSuppId == -1 )
|
||||
break;
|
||||
Vec_IntTwoMerge2( Vec_WecEntry(vSupps, iSuppId), vTemp[0], vTemp[1] );
|
||||
ABC_SWAP( Vec_Int_t *, vTemp[0], vTemp[1] );
|
||||
}
|
||||
if ( k < Abc_ObjFaninNum(pObj) || Vec_IntSize(vTemp[0]) > nSuppMax ) {
|
||||
Count++;
|
||||
continue;
|
||||
}
|
||||
Vec_IntWriteEntry( vSuppIds, Abc_ObjId(pObj), Vec_WecSize(vSupps) );
|
||||
Vec_IntAppend( Vec_WecPushLevel(vSupps), vTemp[0] );
|
||||
}
|
||||
// remove those supported nodes that are in the TFI cones of others
|
||||
Abc_NtkIncrementTravId( pNtk );
|
||||
Abc_NtkForEachNode( pNtk, pObj, i )
|
||||
if ( Abc_ObjLevel(pObj) > Level && Vec_IntEntry(vSuppIds, i) >= 0 && !Abc_NodeIsTravIdCurrent(pObj) ) {
|
||||
Abc_ObjDfsMark_rec(pObj);
|
||||
Abc_NodeSetTravIdPrevious(pObj);
|
||||
}
|
||||
// create the result
|
||||
vResSupps = Vec_WecAlloc( 100 );
|
||||
Abc_NtkForEachNode( pNtk, pObj, i )
|
||||
if ( Abc_ObjLevel(pObj) > Level && Vec_IntEntry(vSuppIds, i) >= 0 && !Abc_NodeIsTravIdCurrent(pObj) ) {
|
||||
Vec_Int_t * vSupp = Vec_WecEntry( vSupps, Vec_IntEntry(vSuppIds, i) );
|
||||
if ( Vec_IntSize(vSupp) < 4 )
|
||||
continue;
|
||||
Vec_Int_t * vThis = Vec_WecPushLevel( vResSupps );
|
||||
Vec_IntGrow( vThis, Vec_IntSize(vSupp) + 1 );
|
||||
Vec_IntAppend( vThis, vSupp );
|
||||
//Vec_IntPush( vThis, Abc_ObjId(pObj) );
|
||||
}
|
||||
//printf( "Inputs = %d. Nodes with %d-support = %d. Nodes with larger support = %d. Selected outputs = %d.\n",
|
||||
// Vec_IntSize(vBelow), nSuppMax, Vec_WecSize(vSupps), Count, Vec_WecSize(vResSupps) );
|
||||
Vec_WecFree( vSupps );
|
||||
Vec_IntFree( vSuppIds );
|
||||
Vec_IntFree( vBelow );
|
||||
Vec_IntFree( vTemp[0] );
|
||||
Vec_IntFree( vTemp[1] );
|
||||
return vResSupps;
|
||||
}
|
||||
// removes all supports that overlap with this one
|
||||
void Abc_NtKSelectRemove( Vec_Wec_t * vSupps, Vec_Int_t * vOne )
|
||||
{
|
||||
Vec_Int_t * vLevel; int i;
|
||||
Vec_WecForEachLevel( vSupps, vLevel, i )
|
||||
if ( Vec_IntTwoCountCommon(vLevel, vOne) > 0 )
|
||||
Vec_IntClear( vLevel );
|
||||
Vec_WecRemoveEmpty( vSupps );
|
||||
}
|
||||
// removes all supports that overlap with the TFI/TFO cones of this one
|
||||
void Abc_NtKSelectRemove2( Vec_Wec_t * vSupps, Vec_Int_t * vOne, Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Vec_Int_t * vLevel; int i, k; Abc_Obj_t * pObj;
|
||||
Abc_NtkForEachObjVec( vOne, pNtk, pObj, i ) {
|
||||
Abc_NodeSetTravIdPrevious(pObj);
|
||||
Abc_ObjDfsMark_rec( pObj );
|
||||
Abc_NodeSetTravIdPrevious(pObj);
|
||||
Abc_ObjDfsMark2_rec( pObj );
|
||||
}
|
||||
Vec_WecForEachLevel( vSupps, vLevel, i ) {
|
||||
Abc_NtkForEachObjVec( vLevel, pNtk, pObj, k )
|
||||
if ( Abc_NodeIsTravIdCurrent(pObj) )
|
||||
break;
|
||||
if ( k < Vec_IntSize(vLevel) )
|
||||
Vec_IntClear( vLevel );
|
||||
}
|
||||
Vec_WecRemoveEmpty( vSupps );
|
||||
}
|
||||
Vec_Ptr_t * Abc_NtkDeriveWinInsAll( Vec_Wec_t * vSupps, int nSuppMax, Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Vec_Ptr_t * vRes = Vec_PtrAlloc( 100 );
|
||||
Abc_NtkIncrementTravId( pNtk );
|
||||
while ( Vec_WecSize(vSupps) > 0 ) {
|
||||
int i, Item, iRand = Abc_Random(0) % Vec_WecSize(vSupps);
|
||||
Vec_Int_t * vLevel, * vLevel2 = Vec_WecEntry( vSupps, iRand );
|
||||
Vec_Int_t * vCopy = Vec_IntDup( vLevel2 );
|
||||
if ( Vec_IntSize(vLevel2) == nSuppMax ) {
|
||||
Vec_PtrPush( vRes, vCopy );
|
||||
Abc_NtKSelectRemove2( vSupps, vCopy, pNtk );
|
||||
continue;
|
||||
}
|
||||
// find another support, which maximizes the union but does not exceed nSuppMax
|
||||
int iBest = iRand, nUnion = Vec_IntSize(vCopy);
|
||||
Vec_WecForEachLevel( vSupps, vLevel, i ) {
|
||||
if ( i == iRand ) continue;
|
||||
int nCommon = Vec_IntTwoCountCommon(vLevel, vCopy);
|
||||
int nUnionCur = Vec_IntSize(vLevel) + Vec_IntSize(vCopy) - nCommon;
|
||||
if ( nUnionCur <= nSuppMax && nUnion < nUnionCur ) {
|
||||
nUnion = nUnionCur;
|
||||
iBest = i;
|
||||
}
|
||||
}
|
||||
vLevel = Vec_WecEntry( vSupps, iBest );
|
||||
Vec_IntForEachEntry( vLevel, Item, i )
|
||||
Vec_IntPushUniqueOrder( vCopy, Item );
|
||||
Vec_PtrPush( vRes, vCopy );
|
||||
Abc_NtKSelectRemove2( vSupps, vCopy, pNtk );
|
||||
}
|
||||
return vRes;
|
||||
}
|
||||
Abc_Ntk_t * Abc_NtkDupWindow( Abc_Ntk_t * p, Vec_Int_t * vIns, Vec_Int_t * vNodes, Vec_Int_t * vOuts )
|
||||
{
|
||||
Abc_Ntk_t * pNew = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_MAP, 0 );
|
||||
pNew->pName = Abc_UtilStrsav( p->pName );
|
||||
pNew->pSpec = Abc_UtilStrsav( p->pSpec );
|
||||
pNew->pManFunc = p->pManFunc;
|
||||
Abc_Obj_t * pObj; int i;
|
||||
Abc_NtkForEachObjVec( vIns, p, pObj, i )
|
||||
pObj->pCopy = Abc_NtkCreatePi(pNew);
|
||||
Abc_NtkForEachObjVec( vOuts, p, pObj, i )
|
||||
Abc_NtkCreatePo( pNew );
|
||||
Abc_NtkForEachObjVec( vNodes, p, pObj, i )
|
||||
Abc_NtkCreateNodeMapped( pNew, pObj );
|
||||
Abc_NtkForEachObjVec( vOuts, p, pObj, i )
|
||||
Abc_ObjAddFanin( Abc_NtkCo(pNew, i), pObj->pCopy );
|
||||
Abc_NtkForEachObjVec( vIns, p, pObj, i )
|
||||
pObj->pCopy = NULL;
|
||||
Abc_NtkForEachObjVec( vNodes, p, pObj, i )
|
||||
pObj->pCopy = NULL;
|
||||
Abc_NtkAddDummyPiNames( pNew );
|
||||
Abc_NtkAddDummyPoNames( pNew );
|
||||
return pNew;
|
||||
}
|
||||
Vec_Ptr_t * Abc_NtkDupWindows( Abc_Ntk_t * pNtk, Vec_Ptr_t * vvIns, Vec_Ptr_t * vvNodes, Vec_Ptr_t * vvOuts )
|
||||
{
|
||||
Vec_Int_t * vNodes; int i;
|
||||
Vec_Ptr_t * vWins = Vec_PtrAlloc( Vec_PtrSize(vvIns) );
|
||||
assert( Vec_PtrSize(vvIns) == Vec_PtrSize(vvNodes) );
|
||||
assert( Vec_PtrSize(vvOuts) == Vec_PtrSize(vvNodes) );
|
||||
Abc_NtkCleanCopy( pNtk );
|
||||
Abc_NtkCleanMarkABC( pNtk );
|
||||
Vec_PtrForEachEntry( Vec_Int_t *, vvNodes, vNodes, i ) {
|
||||
Vec_Int_t * vIns = (Vec_Int_t *)Vec_PtrEntry(vvIns, i);
|
||||
Vec_Int_t * vOuts = (Vec_Int_t *)Vec_PtrEntry(vvOuts, i);
|
||||
Abc_Ntk_t * pNew = Abc_NtkDupWindow( pNtk, vIns, vNodes, vOuts );
|
||||
Vec_PtrPush( vWins, pNew );
|
||||
}
|
||||
return vWins;
|
||||
}
|
||||
Vec_Ptr_t * Abc_NtkExtractPartitions( Abc_Ntk_t * pNtk, int Iter, int nSuppMax, Vec_Ptr_t ** pvIns, Vec_Ptr_t ** pvOuts, Vec_Ptr_t ** pvNodes )
|
||||
{
|
||||
if ( Abc_NtkCiNum(pNtk) <= nSuppMax ) {
|
||||
Vec_Ptr_t * vWins = Vec_PtrAlloc( 1 );
|
||||
Vec_PtrPush( vWins, Abc_NtkDupDfs(pNtk) );
|
||||
*pvIns = *pvOuts = *pvNodes = NULL;
|
||||
return vWins;
|
||||
}
|
||||
int iUseRevL = Iter % 3 == 0 ? 0 : Abc_Random(0) & 1;
|
||||
int LevelMax = iUseRevL ? Abc_NtkLevelR(pNtk) : Abc_NtkLevel(pNtk);
|
||||
int LevelCut = Iter % 3 == 0 ? 0 : LevelMax > 8 ? 2 + (Abc_Random(0) % (LevelMax - 4)) : 0;
|
||||
//printf( "Using %s cut level %d (out of %d)\n", iUseRevL ? "reverse": "direct", LevelCut, LevelMax );
|
||||
Abc_NtkPermuteLevel( pNtk, LevelMax );
|
||||
Vec_Wec_t * vStore = Vec_WecStart( LevelMax+1 );
|
||||
Vec_Wec_t * vSupps = Abc_NtkCollectObjectsWithSuppLimit( pNtk, LevelCut, nSuppMax );
|
||||
Vec_Ptr_t * vIns = Abc_NtkDeriveWinInsAll( vSupps, nSuppMax, pNtk );
|
||||
Vec_Ptr_t * vNodes = Abc_NtkDeriveWinNodesAll( pNtk, vIns, vStore );
|
||||
Vec_Ptr_t * vOuts = Abc_NtkDeriveWinOutsAll( pNtk, vNodes );
|
||||
Vec_Ptr_t * vWins = Abc_NtkDupWindows( pNtk, vIns, vNodes, vOuts );
|
||||
Vec_WecFree( vSupps );
|
||||
Vec_WecFree( vStore );
|
||||
*pvIns = vIns;
|
||||
*pvOuts = vOuts;
|
||||
*pvNodes = vNodes;
|
||||
return vWins;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs stochastic mapping.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NtkStochMap( int nSuppMax, int nIters, int TimeOut, int Seed, int fVerbose, char * pScript, int nProcs )
|
||||
{
|
||||
abctime clkStart = Abc_Clock(); int i;
|
||||
abctime nTimeToStop = TimeOut ? Abc_Clock() + TimeOut * CLOCKS_PER_SEC : 0;
|
||||
float aEnd, aBeg = Abc_NtkGetMappedArea(Abc_FrameReadNtk(Abc_FrameGetGlobalFrame()));
|
||||
assert( Abc_NtkIsMappedLogic(Abc_FrameReadNtk(Abc_FrameGetGlobalFrame())) );
|
||||
Abc_Random(1);
|
||||
for ( i = 0; i < 10+Seed; i++ )
|
||||
Abc_Random(0);
|
||||
if ( fVerbose ) {
|
||||
printf( "Running %d iterations of the script \"%s\"", nIters, pScript );
|
||||
if ( nProcs > 2 )
|
||||
printf( " using %d concurrent threads.\n", nProcs-1 );
|
||||
else
|
||||
printf( " without concurrency.\n" );
|
||||
fflush(stdout);
|
||||
}
|
||||
Vec_Ptr_t * vIns = NULL, * vOuts = NULL, * vNodes = NULL;
|
||||
for ( i = 0; i < nIters; i++ )
|
||||
{
|
||||
abctime clk = Abc_Clock();
|
||||
Abc_Ntk_t * pNtk = Abc_NtkDupDfs(Abc_FrameReadNtk(Abc_FrameGetGlobalFrame()));
|
||||
Vec_Ptr_t * vWins = Abc_NtkExtractPartitions( pNtk, i, nSuppMax, &vIns, &vOuts, &vNodes );
|
||||
Vec_Ptr_t * vOpts = Abc_NtkStochProcess( vWins, pScript, nProcs, 0, 0 );
|
||||
Abc_Ntk_t * pNew = Abc_NtkInsertPartitions( pNtk, vIns, vOuts, vWins );
|
||||
Abc_FrameReplaceCurrentNetwork( Abc_FrameGetGlobalFrame(), pNew );
|
||||
if ( fVerbose )
|
||||
printf( "Iteration %3d : Using %3d partitions. Reducing area from %.2f to %.2f. ",
|
||||
i, Vec_PtrSize(vWins), Abc_NtkGetMappedArea(pNtk), Abc_NtkGetMappedArea(pNew) );
|
||||
if ( fVerbose )
|
||||
Abc_PrintTime( 0, "Time", Abc_Clock() - clk );
|
||||
// cleanup
|
||||
Abc_NtkDelete( pNtk );
|
||||
Vec_PtrFreeFunc( vWins, (void (*)(void *)) Abc_NtkDelete );
|
||||
//Vec_PtrFreeFunc( vOpts, (void (*)(void *)) Abc_NtkDelete );
|
||||
vOpts = NULL;
|
||||
if ( vIns ) Vec_PtrFreeFunc( vIns, (void (*)(void *)) Vec_IntFree );
|
||||
if ( vOuts ) Vec_PtrFreeFunc( vOuts, (void (*)(void *)) Vec_IntFree );
|
||||
if ( vNodes ) Vec_PtrFreeFunc( vNodes, (void (*)(void *)) Vec_IntFree );
|
||||
if ( nTimeToStop && Abc_Clock() > nTimeToStop )
|
||||
{
|
||||
printf( "Runtime limit (%d sec) is reached after %d iterations.\n", TimeOut, i );
|
||||
break;
|
||||
}
|
||||
}
|
||||
aEnd = Abc_NtkGetMappedArea(Abc_FrameReadNtk(Abc_FrameGetGlobalFrame()));
|
||||
if ( fVerbose )
|
||||
printf( "Cumulatively reduced area by %.2f %% after %d iterations. ", 100.0*(aBeg - aEnd)/aBeg, nIters );
|
||||
if ( fVerbose )
|
||||
Abc_PrintTime( 0, "Total time", Abc_Clock() - clkStart );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -1083,7 +1083,7 @@ void Abc_NtkPrintMffc( FILE * pFile, Abc_Ntk_t * pNtk )
|
|||
int i;
|
||||
extern void Abc_NodeMffcConeSuppPrint( Abc_Obj_t * pNode );
|
||||
Abc_NtkForEachNode( pNtk, pNode, i )
|
||||
if ( Abc_ObjFanoutNum(pNode) > 1 )
|
||||
if ( Abc_ObjFanoutNum(pNode) > 1 || (Abc_ObjFanoutNum(pNode) == 1 && Abc_ObjIsCo(Abc_ObjFanout0(pNode))))
|
||||
Abc_NodeMffcConeSuppPrint( pNode );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,16 @@
|
|||
***********************************************************************/
|
||||
|
||||
#include "base/abc/abc.h"
|
||||
#include "opt/cut/cut.h"
|
||||
#include "base/main/main.h"
|
||||
#include "base/cmd/cmd.h"
|
||||
#include "misc/util/utilTruth.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#include <process.h>
|
||||
#define unlink _unlink
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
|
@ -42,8 +51,79 @@ ABC_NAMESPACE_IMPL_START
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Acb_NtkRunGen( char * pFileNames[2], int fVerbose )
|
||||
int Abc_NtkRunGenOne( Abc_Ntk_t * p, char * pScript )
|
||||
{
|
||||
Abc_FrameReplaceCurrentNetwork( Abc_FrameGetGlobalFrame(), p );
|
||||
if ( Abc_FrameIsBatchMode() )
|
||||
{
|
||||
if ( Cmd_CommandExecute(Abc_FrameGetGlobalFrame(), pScript) )
|
||||
{
|
||||
Abc_Print( 1, "Something did not work out with the command \"%s\".\n", pScript );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Abc_FrameSetBatchMode( 1 );
|
||||
if ( Cmd_CommandExecute(Abc_FrameGetGlobalFrame(), pScript) )
|
||||
{
|
||||
Abc_Print( 1, "Something did not work out with the command \"%s\".\n", pScript );
|
||||
return 0;
|
||||
}
|
||||
Abc_FrameSetBatchMode( 0 );
|
||||
}
|
||||
Abc_Ntk_t * pTemp = Abc_FrameReadNtk(Abc_FrameGetGlobalFrame());
|
||||
return Abc_NtkNodeNum(pTemp);
|
||||
}
|
||||
void Acb_NtkRunGen( int nInputs, int nMints, int nFuncs, int Seed, int fVerbose, char * pScript )
|
||||
{
|
||||
abctime clkStart = Abc_Clock();
|
||||
Vec_Int_t * vNodes = Vec_IntAlloc( 1000 );
|
||||
int i, k, nNodes, nWords = Abc_TtWordNum(nInputs);
|
||||
word * pFun = ABC_ALLOC( word, nWords );
|
||||
Abc_Ntk_t * pNtkNew; char * pTtStr, * pSop;
|
||||
Abc_Random(1);
|
||||
for ( i = 0; i < 10+Seed; i++ )
|
||||
Abc_Random(0);
|
||||
printf( "Synthesizing %d random %d-variable functions with %d positive minterms using script \"%s\".\n", nFuncs, nInputs, nMints, pScript );
|
||||
for ( i = 0; i < nFuncs; i++ )
|
||||
{
|
||||
if ( nMints == 0 )
|
||||
for ( k = 0; k < nWords; k++ )
|
||||
pFun[k] = Abc_RandomW(0);
|
||||
else {
|
||||
Abc_TtClear( pFun, nWords );
|
||||
for ( k = 0; k < nMints; k++ ) {
|
||||
int iMint = 0;
|
||||
do iMint = Abc_Random(0) % (1 << nInputs);
|
||||
while ( Abc_TtGetBit(pFun, iMint) );
|
||||
Abc_TtSetBit( pFun, iMint );
|
||||
}
|
||||
}
|
||||
pTtStr = ABC_CALLOC( char, nInputs > 2 ? (1 << (nInputs-2)) + 1 : 2 );
|
||||
Extra_PrintHexadecimalString( pTtStr, (unsigned *)pFun, nInputs );
|
||||
pSop = Abc_SopFromTruthHex( pTtStr );
|
||||
pNtkNew = Abc_NtkCreateWithNode( pSop );
|
||||
nNodes = Abc_NtkRunGenOne( pNtkNew, pScript );
|
||||
if ( nNodes >= Vec_IntSize(vNodes) )
|
||||
Vec_IntSetEntry( vNodes, nNodes, 0 );
|
||||
Vec_IntAddToEntry( vNodes, nNodes, 1 );
|
||||
|
||||
if ( fVerbose ) {
|
||||
printf( "Iteration %3d : ", i );
|
||||
printf( "Random function has %d positive minterms ", nMints );
|
||||
printf( "and maps into %d nodes.\n", nNodes );
|
||||
if ( fVerbose )
|
||||
printf( "Truth table : %s\n", pTtStr );
|
||||
}
|
||||
ABC_FREE( pTtStr );
|
||||
ABC_FREE( pSop );
|
||||
}
|
||||
Vec_IntForEachEntry( vNodes, i, k )
|
||||
if ( i )
|
||||
printf( "Nodes %3d : Functions %3d Ratio %5.2f %%\n", k, i, 100.0*i/nFuncs );
|
||||
ABC_FREE( pFun );
|
||||
Abc_PrintTime( 0, "Total time", Abc_Clock() - clkStart );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -324,6 +324,12 @@ void Abc_NtkCecFraigPart( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, in
|
|||
}
|
||||
else if ( RetValue == 0 )
|
||||
{
|
||||
if(!pMiterPart)
|
||||
{
|
||||
printf("ERROR: Failed to create cone for output %d.\n", i);
|
||||
Status = -1;
|
||||
break;
|
||||
}
|
||||
int * pSimInfo = Abc_NtkVerifySimulatePattern( pMiterPart, pMiterPart->pModel );
|
||||
if ( pSimInfo[0] != 1 )
|
||||
printf( "ERROR in Abc_NtkMiterProve(): Generated counter-example is invalid.\n" );
|
||||
|
|
|
|||
177
src/base/io/io.c
177
src/base/io/io.c
|
|
@ -60,6 +60,7 @@ static int IoCommandReadGig ( Abc_Frame_t * pAbc, int argc, char **argv );
|
|||
static int IoCommandReadJson ( Abc_Frame_t * pAbc, int argc, char **argv );
|
||||
static int IoCommandReadSF ( Abc_Frame_t * pAbc, int argc, char **argv );
|
||||
static int IoCommandReadRom ( Abc_Frame_t * pAbc, int argc, char **argv );
|
||||
static int IoCommandReadMM ( Abc_Frame_t * pAbc, int argc, char **argv );
|
||||
|
||||
static int IoCommandWrite ( Abc_Frame_t * pAbc, int argc, char **argv );
|
||||
static int IoCommandWriteHie ( Abc_Frame_t * pAbc, int argc, char **argv );
|
||||
|
|
@ -79,6 +80,7 @@ static int IoCommandWriteCex ( Abc_Frame_t * pAbc, int argc, char **argv );
|
|||
static int IoCommandWriteDot ( Abc_Frame_t * pAbc, int argc, char **argv );
|
||||
static int IoCommandWriteEqn ( Abc_Frame_t * pAbc, int argc, char **argv );
|
||||
static int IoCommandWriteGml ( Abc_Frame_t * pAbc, int argc, char **argv );
|
||||
static int IoCommandWriteHMetis ( Abc_Frame_t * pAbc, int argc, char **argv );
|
||||
static int IoCommandWriteList ( Abc_Frame_t * pAbc, int argc, char **argv );
|
||||
static int IoCommandWritePla ( Abc_Frame_t * pAbc, int argc, char **argv );
|
||||
static int IoCommandWriteVerilog( Abc_Frame_t * pAbc, int argc, char **argv );
|
||||
|
|
@ -89,6 +91,7 @@ static int IoCommandWriteStatus ( Abc_Frame_t * pAbc, int argc, char **argv );
|
|||
static int IoCommandWriteSmv ( Abc_Frame_t * pAbc, int argc, char **argv );
|
||||
static int IoCommandWriteJson ( Abc_Frame_t * pAbc, int argc, char **argv );
|
||||
static int IoCommandWriteResub ( Abc_Frame_t * pAbc, int argc, char **argv );
|
||||
static int IoCommandWriteMM ( Abc_Frame_t * pAbc, int argc, char **argv );
|
||||
|
||||
extern void Abc_FrameCopyLTLDataBase( Abc_Frame_t *pAbc, Abc_Ntk_t * pNtk );
|
||||
|
||||
|
|
@ -135,6 +138,7 @@ void Io_Init( Abc_Frame_t * pAbc )
|
|||
Cmd_CommandAdd( pAbc, "I/O", "read_json", IoCommandReadJson, 0 );
|
||||
Cmd_CommandAdd( pAbc, "I/O", "read_sf", IoCommandReadSF, 0 );
|
||||
Cmd_CommandAdd( pAbc, "I/O", "read_rom", IoCommandReadRom, 1 );
|
||||
Cmd_CommandAdd( pAbc, "I/O", "read_mm", IoCommandReadMM, 1 );
|
||||
|
||||
Cmd_CommandAdd( pAbc, "I/O", "write", IoCommandWrite, 0 );
|
||||
Cmd_CommandAdd( pAbc, "I/O", "write_hie", IoCommandWriteHie, 0 );
|
||||
|
|
@ -155,16 +159,19 @@ void Io_Init( Abc_Frame_t * pAbc )
|
|||
Cmd_CommandAdd( pAbc, "I/O", "write_edgelist",IoCommandWriteEdgelist, 0 );
|
||||
Cmd_CommandAdd( pAbc, "I/O", "write_gml", IoCommandWriteGml, 0 );
|
||||
// Cmd_CommandAdd( pAbc, "I/O", "write_list", IoCommandWriteList, 0 );
|
||||
Cmd_CommandAdd( pAbc, "I/O", "write_hmetis", IoCommandWriteHMetis, 0 );
|
||||
Cmd_CommandAdd( pAbc, "I/O", "write_pla", IoCommandWritePla, 0 );
|
||||
Cmd_CommandAdd( pAbc, "I/O", "write_verilog", IoCommandWriteVerilog, 0 );
|
||||
// Cmd_CommandAdd( pAbc, "I/O", "write_verlib", IoCommandWriteVerLib, 0 );
|
||||
Cmd_CommandAdd( pAbc, "I/O", "write_sorter_cnf", IoCommandWriteSortCnf, 0 );
|
||||
Cmd_CommandAdd( pAbc, "I/O", "write_truth", IoCommandWriteTruth, 0 );
|
||||
Cmd_CommandAdd( pAbc, "I/O", "&write_truth", IoCommandWriteTruths, 0 );
|
||||
Cmd_CommandAdd( pAbc, "I/O", "&write_truths", IoCommandWriteTruths, 0 );
|
||||
Cmd_CommandAdd( pAbc, "I/O", "write_status", IoCommandWriteStatus, 0 );
|
||||
Cmd_CommandAdd( pAbc, "I/O", "write_smv", IoCommandWriteSmv, 0 );
|
||||
Cmd_CommandAdd( pAbc, "I/O", "write_json", IoCommandWriteJson, 0 );
|
||||
Cmd_CommandAdd( pAbc, "I/O", "&write_resub", IoCommandWriteResub, 0 );
|
||||
Cmd_CommandAdd( pAbc, "I/O", "write_mm", IoCommandWriteMM, 0 );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
@ -1996,6 +2003,51 @@ usage:
|
|||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int IoCommandReadMM( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||
{
|
||||
extern Abc_Ntk_t * Abc_NtkReadFromFile( char * pFileName );
|
||||
Abc_Ntk_t * pNtk; char * pFileName; int c;
|
||||
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case 'h':
|
||||
goto usage;
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
if ( argc != globalUtilOptind + 1 )
|
||||
goto usage;
|
||||
pFileName = argv[globalUtilOptind];
|
||||
pNtk = Abc_NtkReadFromFile( pFileName );
|
||||
if ( pNtk == NULL )
|
||||
return 0;
|
||||
Abc_FrameReplaceCurrentNetwork( pAbc, pNtk );
|
||||
Abc_FrameClearVerifStatus( pAbc );
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
fprintf( pAbc->Err, "usage: read_mm [-h] <file>\n" );
|
||||
fprintf( pAbc->Err, "\t reads mapped network from file\n" );
|
||||
fprintf( pAbc->Err, "\t-h : prints the command summary\n" );
|
||||
fprintf( pAbc->Err, "\tfile : the name of a file to read\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
|
@ -3398,6 +3450,78 @@ usage:
|
|||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int IoCommandWriteHMetis( Abc_Frame_t * pAbc, int argc, char **argv )
|
||||
{
|
||||
char * pFileName;
|
||||
int fVerbose;
|
||||
int fSkipPo;
|
||||
int fWeightEdges;
|
||||
int c;
|
||||
|
||||
fSkipPo = 1;
|
||||
fWeightEdges = 0;
|
||||
fVerbose = 0;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "swvh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case 's':
|
||||
fSkipPo ^= 1;
|
||||
break;
|
||||
case 'w':
|
||||
fWeightEdges ^= 1;
|
||||
break;
|
||||
case 'v':
|
||||
fVerbose ^= 1;
|
||||
break;
|
||||
case 'h':
|
||||
goto usage;
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
if ( pAbc->pNtkCur == NULL )
|
||||
{
|
||||
fprintf( pAbc->Out, "Empty network.\n" );
|
||||
return 0;
|
||||
}
|
||||
if ( argc != globalUtilOptind + 1 )
|
||||
goto usage;
|
||||
// get the output file name
|
||||
pFileName = argv[globalUtilOptind];
|
||||
// call the corresponding file writer
|
||||
if ( !Abc_NtkIsStrash(pAbc->pNtkCur) )
|
||||
{
|
||||
fprintf( stdout, "Writing this format is only possible for structurally hashed AIGs.\n" );
|
||||
return 1;
|
||||
}
|
||||
Io_WriteHMetis( pAbc->pNtkCur, pFileName, fSkipPo, fWeightEdges, fVerbose );
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
fprintf( pAbc->Err, "usage: write_hmetis <file>\n" );
|
||||
fprintf( pAbc->Err, "\t writes the network in the hMetis format (https://karypis.github.io/glaros/files/sw/hmetis/manual.pdf)\n" );
|
||||
fprintf( pAbc->Err, "\t-s : skip PO as sink explictly [default = %s]\n", fSkipPo? "yes" : "no" );
|
||||
fprintf( pAbc->Err, "\t-w : simulate weight on hyperedges [default = %s]\n", fWeightEdges? "yes" : "no" );
|
||||
fprintf( pAbc->Err, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes" : "no" );
|
||||
fprintf( pAbc->Err, "\t-h : print the help massage\n" );
|
||||
fprintf( pAbc->Err, "\tfile : the name of the file to write\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
|
|
@ -3934,7 +4058,7 @@ int IoCommandWriteTruths( Abc_Frame_t * pAbc, int argc, char **argv )
|
|||
return 0;
|
||||
|
||||
usage:
|
||||
fprintf( pAbc->Err, "usage: &write_truths [-rxbh] <file>\n" );
|
||||
fprintf( pAbc->Err, "usage: &write_truth [-rxbh] <file>\n" );
|
||||
fprintf( pAbc->Err, "\t writes truth tables of each PO of GIA manager into a file\n" );
|
||||
fprintf( pAbc->Err, "\t-r : toggle reversing bits in the truth table [default = %s]\n", fReverse? "yes":"no" );
|
||||
fprintf( pAbc->Err, "\t-x : toggle writing in the hex notation [default = %s]\n", fHex? "yes":"no" );
|
||||
|
|
@ -4142,6 +4266,57 @@ usage:
|
|||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int IoCommandWriteMM( Abc_Frame_t * pAbc, int argc, char **argv )
|
||||
{
|
||||
extern int Abc_NtkWriteToFile( char * pFileName, Abc_Ntk_t * pNtk );
|
||||
Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc);
|
||||
char * pFileName = NULL; int c;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case 'h':
|
||||
goto usage;
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
if ( argc != globalUtilOptind + 1 )
|
||||
goto usage;
|
||||
pFileName = argv[globalUtilOptind];
|
||||
if ( pNtk == NULL )
|
||||
{
|
||||
Abc_Print( -1, "IoCommandWriteMM(): There is no current network.\n" );
|
||||
return 1;
|
||||
}
|
||||
if ( !Abc_NtkIsMappedLogic(pNtk) )
|
||||
{
|
||||
Abc_Print( -1, "IoCommandWriteMM(): The current network is not mapped.\n" );
|
||||
return 1;
|
||||
}
|
||||
Abc_NtkWriteToFile( pFileName, pNtk );
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
fprintf( pAbc->Err, "usage: write_mm [-h] <file>\n" );
|
||||
fprintf( pAbc->Err, "\t write mapped network into a file\n" );
|
||||
fprintf( pAbc->Err, "\t-h : print the help message\n" );
|
||||
fprintf( pAbc->Err, "\tfile : the name of the file to write\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -57,7 +57,8 @@ typedef enum {
|
|||
IO_FILE_DOT,
|
||||
IO_FILE_EDIF,
|
||||
IO_FILE_EQN,
|
||||
IO_FILE_GML,
|
||||
IO_FILE_GML,
|
||||
IO_FILE_HMETIS,
|
||||
IO_FILE_JSON,
|
||||
IO_FILE_LIST,
|
||||
IO_FILE_PLA,
|
||||
|
|
@ -129,6 +130,8 @@ extern void Io_WriteEqn( Abc_Ntk_t * pNtk, char * pFileName );
|
|||
extern void Io_WriteEdgelist( Abc_Ntk_t * pNtk, char * pFileName, int fWriteLatches, int fBb2Wb, int fSeq , int fName);
|
||||
/*=== abcWriteGml.c ===========================================================*/
|
||||
extern void Io_WriteGml( Abc_Ntk_t * pNtk, char * pFileName );
|
||||
/*=== abcWriteHMetis.c ===========================================================*/
|
||||
extern void Io_WriteHMetis( Abc_Ntk_t * pNtk, char * pFileName, int fSkipPo, int fWeightEdges, int fVerbose );
|
||||
/*=== abcWriteList.c ==========================================================*/
|
||||
extern void Io_WriteList( Abc_Ntk_t * pNtk, char * pFileName, int fUseHost );
|
||||
/*=== abcWritePla.c ===========================================================*/
|
||||
|
|
|
|||
|
|
@ -433,14 +433,14 @@ Abc_Ntk_t * Io_ReadAiger( char * pFileName, int fCheck )
|
|||
else
|
||||
{
|
||||
assert( Init == Abc_Var2Lit(1+Abc_NtkPiNum(pNtkNew)+i, 0) );
|
||||
// unitialized value of the latch is the latch literal according to http://fmv.jku.at/hwmcc11/beyond1.pdf
|
||||
// uninitialized value of the latch is the latch literal according to http://fmv.jku.at/hwmcc11/beyond1.pdf
|
||||
Abc_LatchSetInitDc( Abc_NtkBox(pNtkNew, i) );
|
||||
}
|
||||
while ( *pCur != ' ' && *pCur != '\n' ) pCur++;
|
||||
}
|
||||
if ( *pCur != '\n' )
|
||||
{
|
||||
fprintf( stdout, "The initial value of latch number %d is not recongnized.\n", i );
|
||||
fprintf( stdout, "The initial value of latch number %d is not recognized.\n", i );
|
||||
return NULL;
|
||||
}
|
||||
pCur++;
|
||||
|
|
|
|||
|
|
@ -680,7 +680,7 @@ void Io_WriteAiger( Abc_Ntk_t * pNtk, char * pFileName, int fWriteSymbols, int f
|
|||
b.f = fopen( pFileName, "wb" );
|
||||
if ( b.f == NULL )
|
||||
{
|
||||
fprintf( stdout, "Ioa_WriteBlif(): Cannot open the output file \"%s\".\n", pFileName );
|
||||
fprintf( stdout, "Io_WriteAiger(): Cannot open the output file \"%s\".\n", pFileName );
|
||||
ABC_FREE(b.buf);
|
||||
return;
|
||||
}
|
||||
|
|
@ -688,7 +688,7 @@ void Io_WriteAiger( Abc_Ntk_t * pNtk, char * pFileName, int fWriteSymbols, int f
|
|||
b.b = BZ2_bzWriteOpen( &bzError, b.f, 9, 0, 0 );
|
||||
if ( bzError != BZ_OK ) {
|
||||
BZ2_bzWriteClose( &bzError, b.b, 0, NULL, NULL );
|
||||
fprintf( stdout, "Ioa_WriteBlif(): Cannot start compressed stream.\n" );
|
||||
fprintf( stdout, "Io_WriteAiger(): Cannot start compressed stream.\n" );
|
||||
fclose( b.f );
|
||||
ABC_FREE(b.buf);
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -317,7 +317,7 @@ void Io_WriteDotNtk( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesSho
|
|||
if ( AigNodeId > 0 )
|
||||
fprintf( pFile, " Node%d [label = \"%s%d\\n%s\"", pNode->Id, Abc_LitIsCompl(AigNodeId) ? "-":"+", Abc_Lit2Var(AigNodeId), pSopString );
|
||||
else
|
||||
fprintf( pFile, " Node%d [label = \"%d\\n%s\"", pNode->Id, pNode->Id, pSopString );
|
||||
fprintf( pFile, " Node%d [label = \"%d\\n%s\"", pNode->Id, pNode->Id+1, pSopString );
|
||||
// fprintf( pFile, " Node%d [label = \"%d\\n%s\"", pNode->Id,
|
||||
// SuppSize,
|
||||
// pSopString );
|
||||
|
|
|
|||
|
|
@ -0,0 +1,112 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [ioWriteHMetis.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Command processing package.]
|
||||
|
||||
Synopsis [Procedures to write hMetis format developed by
|
||||
George Karypis and Vipin Kumar from the University of Minnesota
|
||||
(https://karypis.github.io/glaros/files/sw/hmetis/manual.pdf)]
|
||||
|
||||
Author [Jingren Wang]
|
||||
|
||||
Affiliation []
|
||||
|
||||
Date [Ver. 1.0. Started - December 16, 2006.]
|
||||
|
||||
Revision []
|
||||
|
||||
***********************************************************************/
|
||||
#include "ioAbc.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
void Io_WriteHMetis( Abc_Ntk_t *pNtk, char *pFileName, int fSkipPo, int fWeightEdges, int fVerbose )
|
||||
{
|
||||
Abc_Obj_t *pObj;
|
||||
Abc_Obj_t *pFanout;
|
||||
int i, j;
|
||||
Vec_Int_t *vHyperEdgeEachWrite;
|
||||
int iEntry;
|
||||
int nHyperNodesNum = 0;
|
||||
// check that the network is valid
|
||||
assert( Abc_NtkIsStrash( pNtk ) && Abc_NtkIsComb( pNtk ) );
|
||||
|
||||
FILE *pFHMetis = fopen( pFileName, "wb" );
|
||||
Vec_Ptr_t *vHyperEdges = Vec_PtrAlloc( 1000 );
|
||||
if ( pFHMetis == NULL )
|
||||
{
|
||||
fprintf( stdout, "Io_WriteHMetis(): Cannot open the output file \"%s\".\n", pFileName );
|
||||
fclose( pFHMetis );
|
||||
return;
|
||||
}
|
||||
|
||||
// show pi/po/and number
|
||||
if ( fVerbose )
|
||||
{
|
||||
Abc_Print( 1, "Writing hMetis file \"%s\" with %d nodes (%d pi, %d po, %d and nodes).\n", pFileName, Abc_NtkObjNum( pNtk ), Abc_NtkPiNum( pNtk ), Abc_NtkPoNum( pNtk ), Abc_NtkNodeNum( pNtk ) );
|
||||
}
|
||||
|
||||
Abc_NtkForEachObj( pNtk, pObj, i )
|
||||
{
|
||||
Vec_Int_t *vHyperEdgeEach = Vec_IntAlloc( 20 );
|
||||
// push the node itself, which is a source node
|
||||
Vec_IntPush( vHyperEdgeEach, Abc_ObjId( pObj ) );
|
||||
// iterate through all the fanouts(sink) of the node
|
||||
if ( !Abc_ObjIsCo( pObj ) )
|
||||
{
|
||||
Abc_ObjForEachFanout( pObj, pFanout, j )
|
||||
{
|
||||
Vec_IntPush( vHyperEdgeEach, Abc_ObjId( pFanout ) );
|
||||
}
|
||||
} else
|
||||
{
|
||||
if ( fSkipPo )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
Vec_IntPush( vHyperEdgeEach, Abc_ObjId( Abc_ObjFanin0( pObj ) ) );
|
||||
}
|
||||
Vec_PtrPush( vHyperEdges, vHyperEdgeEach );
|
||||
}
|
||||
|
||||
nHyperNodesNum = Abc_NtkObjNum( pNtk );
|
||||
|
||||
// write the number of hyperedges and the number of vertices
|
||||
if ( fWeightEdges )
|
||||
{
|
||||
fprintf( pFHMetis, "%d %d 1\n", Vec_PtrSize( vHyperEdges ), nHyperNodesNum );
|
||||
} else
|
||||
{
|
||||
fprintf( pFHMetis, "%d %d\n", Vec_PtrSize( vHyperEdges ), nHyperNodesNum );
|
||||
}
|
||||
// write the hyperedges
|
||||
Vec_PtrForEachEntry( Vec_Int_t *, vHyperEdges, vHyperEdgeEachWrite, i )
|
||||
{
|
||||
if ( fWeightEdges )
|
||||
{
|
||||
fprintf( pFHMetis, "%d ", Vec_IntSize( vHyperEdgeEachWrite ) );
|
||||
}
|
||||
|
||||
Vec_IntForEachEntry( vHyperEdgeEachWrite, iEntry, j )
|
||||
{
|
||||
if ( j == Vec_IntSize( vHyperEdgeEachWrite ) - 1 )
|
||||
{
|
||||
fprintf( pFHMetis, "%d", iEntry );
|
||||
} else
|
||||
{
|
||||
fprintf( pFHMetis, "%d ", iEntry );
|
||||
}
|
||||
}
|
||||
fprintf( pFHMetis, "\n" );
|
||||
}
|
||||
// comments should be started with "%" in hMetis format
|
||||
fprintf( pFHMetis, "%%This file was written by ABC on %s\n", Extra_TimeStamp() );
|
||||
fprintf( pFHMetis, "%%For information about hMetis format, refer to %s\n", "https://karypis.github.io/glaros/files/sw/hmetis/manual.pdf" );
|
||||
Vec_PtrFreeFree( vHyperEdges );
|
||||
fclose( pFHMetis );
|
||||
}
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
|
@ -26,6 +26,7 @@ SRC += src/base/io/io.c \
|
|||
src/base/io/ioWriteEqn.c \
|
||||
src/base/io/ioWriteEdgelist.c \
|
||||
src/base/io/ioWriteGml.c \
|
||||
src/base/io/ioWriteHMetis.c \
|
||||
src/base/io/ioWriteList.c \
|
||||
src/base/io/ioWritePla.c \
|
||||
src/base/io/ioWriteVerilog.c \
|
||||
|
|
|
|||
|
|
@ -81,6 +81,8 @@ extern ABC_DLL void Abc_FrameGiaInputMiniLut( Abc_Frame_t * pAbc, void * pMini
|
|||
extern ABC_DLL void Abc_FrameGiaInputMiniLut2( Abc_Frame_t * pAbc, void * pMiniLut );
|
||||
extern ABC_DLL void * Abc_FrameGiaOutputMiniLut( Abc_Frame_t * pAbc );
|
||||
extern ABC_DLL char * Abc_FrameGiaOutputMiniLutAttr( Abc_Frame_t * pAbc, void * pMiniLut );
|
||||
extern ABC_DLL int * Abc_FrameGiaOutputMiniLutObj( Abc_Frame_t * pAbc );
|
||||
extern ABC_DLL void Abc_FrameSetObjDelays( Abc_Frame_t * pAbc, int * pDelays, int nDelays );
|
||||
extern ABC_DLL int * Abc_FrameReadMiniLutSwitching( Abc_Frame_t * pAbc );
|
||||
extern ABC_DLL int * Abc_FrameReadMiniLutSwitching2( Abc_Frame_t * pAbc, int nRandPiFactor );
|
||||
extern ABC_DLL int * Abc_FrameReadMiniLutSwitchingPo( Abc_Frame_t * pAbc );
|
||||
|
|
|
|||
|
|
@ -158,6 +158,8 @@ struct Abc_Frame_t_
|
|||
Gia_Man_t * pGiaMiniLut;
|
||||
Vec_Int_t * vCopyMiniAig;
|
||||
Vec_Int_t * vCopyMiniLut;
|
||||
Vec_Int_t * vMiniLutObjs;
|
||||
Vec_Int_t * vObjDelays;
|
||||
int * pArray;
|
||||
int * pBoxes;
|
||||
void * pNdr;
|
||||
|
|
|
|||
|
|
@ -1513,9 +1513,12 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn )
|
|||
nRange2 = 0;
|
||||
|
||||
// create new box
|
||||
if ( vTables == NULL )
|
||||
if ( vTables == NULL ) {
|
||||
Tim_ManSetDelayTables( pManTime, (vTables = Vec_PtrAlloc(100)) );
|
||||
Vec_PtrPush( vTables, NULL );
|
||||
}
|
||||
Tim_ManCreateBox( pManTime, curPo, nRange0 + nRange1 + nRange2, curPi, nRange, Vec_PtrSize(vTables), 0 );
|
||||
Tim_ManBoxSetCopy( pManTime, Tim_ManBoxNum(pManTime)-1, Tim_ManBoxNum(pManTime)-1 );
|
||||
curPi += nRange;
|
||||
curPo += nRange0 + nRange1 + nRange2;
|
||||
|
||||
|
|
@ -2105,8 +2108,10 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn )
|
|||
assert( pObj->Type == WLC_OBJ_FF );
|
||||
|
||||
// create new box
|
||||
if ( vTables == NULL )
|
||||
if ( vTables == NULL ) {
|
||||
Tim_ManSetDelayTables( pManTime, (vTables = Vec_PtrAlloc(100)) );
|
||||
Vec_PtrPush( vTables, NULL );
|
||||
}
|
||||
Tim_ManCreateBox( pManTime, curPo, nRangeIn, curPi, nRange, Vec_PtrSize(vTables), 0 );
|
||||
curPi += nRange;
|
||||
curPo += nRangeIn;
|
||||
|
|
|
|||
|
|
@ -27,6 +27,11 @@
|
|||
#define inline __inline // compatible with MS VS 6.0
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# include <intrin.h>
|
||||
# define __builtin_popcount __popcnt
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
|
@ -107,6 +112,159 @@ Vec_Ptr_t * Abc_LutCasCollapse( Mini_Aig_t * p, DdManager * dd, int nBddLimit, i
|
|||
return vFuncs;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Ptr_t * Abc_LutBddScan( DdManager * dd, DdNode * bFunc, int nVars )
|
||||
{
|
||||
Vec_Ptr_t * vRes = Vec_PtrAlloc( 1 << nVars );
|
||||
Vec_Ptr_t * vRes2 = Vec_PtrAlloc( 1 << nVars );
|
||||
Vec_PtrPush( vRes, bFunc );
|
||||
int v, Level = Cudd_ReadPerm( dd, Cudd_NodeReadIndex(bFunc) );
|
||||
for ( v = 0; v < dd->size; v++ )
|
||||
printf( "%2d : perm = %d invperm = %d\n", v, dd->perm[v], dd->invperm[v] );
|
||||
for ( v = 0; v < nVars; v++ )
|
||||
{
|
||||
int i, LevelCur = Level + v;
|
||||
Vec_PtrClear( vRes2 );
|
||||
DdNode * bTemp;
|
||||
Vec_PtrForEachEntry( DdNode *, vRes, bTemp, i ) {
|
||||
int LevelTemp = Cudd_ReadPerm( dd, Cudd_NodeReadIndex(bTemp) );
|
||||
if ( LevelTemp == LevelCur ) {
|
||||
Vec_PtrPush( vRes2, Cudd_NotCond(Cudd_E(bTemp), Cudd_IsComplement(bTemp)) );
|
||||
Vec_PtrPush( vRes2, Cudd_NotCond(Cudd_T(bTemp), Cudd_IsComplement(bTemp)) );
|
||||
}
|
||||
else if ( LevelTemp > LevelCur ) {
|
||||
Vec_PtrPush( vRes2, bTemp );
|
||||
Vec_PtrPush( vRes2, bTemp );
|
||||
}
|
||||
else assert( 0 );
|
||||
}
|
||||
ABC_SWAP( Vec_Ptr_t *, vRes, vRes2 );
|
||||
//Vec_PtrForEachEntry( DdNode *, vRes, bTemp, i )
|
||||
// printf( "%p ", bTemp );
|
||||
//printf( "\n" );
|
||||
}
|
||||
Vec_PtrFree( vRes2 );
|
||||
assert( Vec_PtrSize(vRes) == (1 << nVars) );
|
||||
return vRes;
|
||||
}
|
||||
char * Abc_LutBddToTruth( Vec_Ptr_t * vFuncs )
|
||||
{
|
||||
assert( Vec_PtrSize(vFuncs) <= 256 );
|
||||
char * pRes = ABC_CALLOC( char, Vec_PtrSize(vFuncs)+1 );
|
||||
void * pTemp, * pStore[256] = {Vec_PtrEntry(vFuncs, 0)};
|
||||
int i, k, nStore = 1; pRes[0] = 'a';
|
||||
Vec_PtrForEachEntryStart( void *, vFuncs, pTemp, i, 1 ) {
|
||||
for ( k = 0; k < nStore; k++ )
|
||||
if ( pStore[k] == pTemp )
|
||||
break;
|
||||
if ( k == nStore )
|
||||
pStore[nStore++] = pTemp;
|
||||
pRes[i] = 'a' + (char)k;
|
||||
}
|
||||
return pRes;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
char * Abc_NtkPrecomputeData()
|
||||
{
|
||||
char * pRes = ABC_CALLOC( char, 1 << 16 );
|
||||
int i, k, b;
|
||||
for ( i = 0; i < 256; i++ ) {
|
||||
int nOnes = __builtin_popcount(i);
|
||||
char * pTemp = pRes + 256*i;
|
||||
for ( k = 0; k < 256; k++ ) {
|
||||
int iMask = 0, Counts[2] = {nOnes, 0};
|
||||
for ( b = 0; b < 8; Counts[(i >> b++)&1]++ )
|
||||
if ( (k >> b) & 1 )
|
||||
iMask |= 1 << Counts[(i >> b)&1];
|
||||
pTemp[iMask] = (char)k;
|
||||
assert( Counts[1] == nOnes );
|
||||
}
|
||||
}
|
||||
for ( i = 0; i < 16; i++, printf("\n") )
|
||||
for ( printf("%x : ", i), k = 0; k < 16; k++ )
|
||||
printf( "%x=%x ", k, (int)pRes[i*256+k] );
|
||||
return pRes;
|
||||
}
|
||||
|
||||
int Abc_NtkDecPatCount( int iFirst, int nStep, int MyuMax, char * pDecPat, char * pPermInfo )
|
||||
{
|
||||
int s, k, nPats = 1;
|
||||
char Pats[256] = { pDecPat[(int)pPermInfo[iFirst]] };
|
||||
assert( MyuMax <= 256 );
|
||||
for ( s = 1; s < nStep; s++ ) {
|
||||
char Entry = pDecPat[(int)pPermInfo[iFirst+s]];
|
||||
for ( k = 0; k < nPats; k++ )
|
||||
if ( Pats[k] == Entry )
|
||||
break;
|
||||
if ( k < nPats )
|
||||
continue;
|
||||
if ( nPats == MyuMax )
|
||||
return MyuMax + 1;
|
||||
assert( nPats < 256 );
|
||||
Pats[nPats++] = Entry;
|
||||
}
|
||||
return nPats;
|
||||
}
|
||||
int Abc_NtkDecPatDecompose_rec( int Mask, int nMaskVars, int iStart, int nVars, int nDiffs, int nRails, char * pDecPat, char * pPermInfo )
|
||||
{
|
||||
if ( nDiffs == 0 || iStart == nVars )
|
||||
return 0;
|
||||
int v, m, nMints = 1 << nVars;
|
||||
for ( v = iStart; v < nVars; v++ ) {
|
||||
int MaskThis = Mask & ~(1 << v);
|
||||
int nStep = 1 << (nMaskVars - 1);
|
||||
int MyuMax = 0;
|
||||
for ( m = 0; m < nMints; m += nStep ) {
|
||||
int MyuCur = Abc_NtkDecPatCount( m, nStep, 1 << nDiffs, pDecPat, pPermInfo+256*MaskThis );
|
||||
MyuMax = Abc_MaxInt( MyuMax, MyuCur );
|
||||
}
|
||||
if ( MyuMax > (1 << nDiffs) )
|
||||
continue;
|
||||
if ( MyuMax <= (1 << nRails) )
|
||||
return MaskThis;
|
||||
MaskThis = Abc_NtkDecPatDecompose_rec( MaskThis, nMaskVars-1, v+1, nVars, nDiffs-1, nRails, pDecPat, pPermInfo );
|
||||
if ( MaskThis )
|
||||
return MaskThis;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int Abc_NtkDecPatDecompose( int nVars, int nRails, char * pDecPat, char * pPermInfo )
|
||||
{
|
||||
int BoundSet = ~(~0 << nVars);
|
||||
int Myu = Abc_NtkDecPatCount( 0, 1 << nVars, 256, pDecPat, pPermInfo + 256*BoundSet );
|
||||
int Log2 = Abc_Base2Log( Myu );
|
||||
if ( Log2 <= nRails )
|
||||
return BoundSet;
|
||||
return Abc_NtkDecPatDecompose_rec( BoundSet, nVars, 0, nVars, Log2 - nRails, nRails, pDecPat, pPermInfo );
|
||||
}
|
||||
|
||||
int Abc_NtkCascadeDecompose( int nVars, int nRails, char * pDecPat, char * pPermInfo )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
|
|
@ -159,12 +317,12 @@ void Abc_LutCasPrintDsd( DdManager * dd, DdNode * bFunc, int fVerbose )
|
|||
}
|
||||
Dsd_ManagerStop( pManDsd );
|
||||
}
|
||||
DdNode * Abc_LutCasBuildBdds( Mini_Aig_t * p, DdManager ** pdd )
|
||||
DdNode * Abc_LutCasBuildBdds( Mini_Aig_t * p, DdManager ** pdd, int fReorder )
|
||||
{
|
||||
DdManager * dd = Cudd_Init( Mini_AigPiNum(p), 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 );
|
||||
Cudd_AutodynEnable( dd, CUDD_REORDER_SYMM_SIFT );
|
||||
if ( fReorder ) Cudd_AutodynEnable( dd, CUDD_REORDER_SYMM_SIFT );
|
||||
Vec_Ptr_t * vFuncs = Abc_LutCasCollapse( p, dd, 10000, 0 );
|
||||
Cudd_AutodynDisable( dd );
|
||||
if ( fReorder ) Cudd_AutodynDisable( dd );
|
||||
if ( vFuncs == NULL ) {
|
||||
Extra_StopManager( dd );
|
||||
return NULL;
|
||||
|
|
@ -174,15 +332,28 @@ DdNode * Abc_LutCasBuildBdds( Mini_Aig_t * p, DdManager ** pdd )
|
|||
*pdd = dd;
|
||||
return bNode;
|
||||
}
|
||||
static inline word * Abc_LutCascade( Mini_Aig_t * p, int nLutSize, int fVerbose )
|
||||
static inline word * Abc_LutCascade( Mini_Aig_t * p, int nLutSize, int nLuts, int nRails, int nIters, int fVerbose )
|
||||
{
|
||||
DdManager * dd = NULL;
|
||||
DdNode * bFunc = Abc_LutCasBuildBdds( p, &dd );
|
||||
DdNode * bFunc = Abc_LutCasBuildBdds( p, &dd, 0 );
|
||||
if ( bFunc == NULL ) return NULL;
|
||||
char * pPermInfo = Abc_NtkPrecomputeData();
|
||||
Abc_LutCasPrintDsd( dd, bFunc, 1 );
|
||||
|
||||
Vec_Ptr_t * vTemp = Abc_LutBddScan( dd, bFunc, nLutSize );
|
||||
char * pTruth = Abc_LutBddToTruth( vTemp );
|
||||
|
||||
int BoundSet = Abc_NtkDecPatDecompose( nLutSize, nRails, pTruth, pPermInfo );
|
||||
printf( "Pattern %s : Bound set = %d\n", pTruth, BoundSet );
|
||||
|
||||
ABC_FREE( pTruth );
|
||||
Vec_PtrFree( vTemp );
|
||||
|
||||
Cudd_RecursiveDeref( dd, bFunc );
|
||||
Extra_StopManager( dd );
|
||||
ABC_FREE( pPermInfo );
|
||||
|
||||
printf( "\n" );
|
||||
word * pLuts = NULL;
|
||||
return pLuts;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -294,6 +294,7 @@ private:
|
|||
pst->num_luts = best_multiplicity <= 2 ? 2 : best_multiplicity <= 4 ? 3
|
||||
: best_multiplicity <= 8 ? 4
|
||||
: 5;
|
||||
pst->num_edges = ( pst->num_luts - 1 ) * ( num_vars - best_free_set ) + ( pst->num_luts - 1 ) + best_free_set;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -510,8 +511,8 @@ private:
|
|||
}
|
||||
} while ( combinations_offset_next( free_set_size, offset, pComb, pInvPerm, tt ) );
|
||||
|
||||
std::array<uint32_t, max_num_vars> res_perm = {0};
|
||||
|
||||
std::array<uint32_t, max_num_vars> res_perm;
|
||||
|
||||
if ( best_cost > ( 1 << ( ps.lut_size - free_set_size ) ) )
|
||||
{
|
||||
return std::make_tuple( local_best_tt, res_perm, UINT32_MAX );
|
||||
|
|
@ -543,7 +544,7 @@ private:
|
|||
}
|
||||
|
||||
/* enumerate combinations */
|
||||
std::array<uint32_t, max_num_vars> res_perm = {0};
|
||||
std::array<uint32_t, max_num_vars> res_perm;
|
||||
|
||||
do
|
||||
{
|
||||
|
|
@ -803,31 +804,43 @@ private:
|
|||
}
|
||||
}
|
||||
support_minimization_encodings = std::vector<std::array<uint32_t, 2>>( num_combs );
|
||||
generate_support_minimization_encodings_rec<false, true>( 0, 0, 0, count );
|
||||
generate_support_minimization_encodings_rec<false, true>( 0, 0, 0, count, best_multiplicity >> 1, true );
|
||||
assert( count == num_combs );
|
||||
return;
|
||||
}
|
||||
else if ( best_multiplicity > 8 )
|
||||
|
||||
/* constraint the number of offset classes for a strict encoding */
|
||||
int32_t min_set_size = 1;
|
||||
if ( best_multiplicity <= 4 )
|
||||
min_set_size = 2;
|
||||
else if ( best_multiplicity <= 8 )
|
||||
min_set_size = 4;
|
||||
else
|
||||
min_set_size = 8;
|
||||
min_set_size = best_multiplicity - min_set_size;
|
||||
|
||||
if ( best_multiplicity > 8 )
|
||||
{
|
||||
/* combinations are 2^(mu - 1) */
|
||||
num_combs = 1u << ( best_multiplicity - 1 );
|
||||
/* distinct elements in 2 indistinct bins with at least `min_set_size` elements in the indistinct bins */
|
||||
uint32_t class_sizes[13] = { 3, 3, 15, 25, 35, 35, 255, 501, 957, 1749, 3003, 4719, 6435 };
|
||||
num_combs = class_sizes[best_multiplicity - 3];
|
||||
support_minimization_encodings = std::vector<std::array<uint32_t, 2>>( num_combs );
|
||||
generate_support_minimization_encodings_rec<false, false>( 0, 0, 0, count );
|
||||
generate_support_minimization_encodings_rec<false, false>( 0, 0, 0, count, min_set_size, true );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* combinations are 2*3^(mu - 1) */
|
||||
for ( uint32_t i = 1; i < best_multiplicity; ++i )
|
||||
{
|
||||
num_combs = ( num_combs << 1 ) + num_combs;
|
||||
}
|
||||
/* distinct elements in 3 bins, of which 2 are indistinct, and with at least `min_set_size` elements in the indistinct bins */
|
||||
uint32_t class_sizes[13] = { 6, 3, 90, 130, 105, 35, 9330, 23436, 48708, 78474, 91377, 70785, 32175 };
|
||||
num_combs = class_sizes[best_multiplicity - 3];
|
||||
support_minimization_encodings = std::vector<std::array<uint32_t, 2>>( num_combs );
|
||||
generate_support_minimization_encodings_rec<true, false>( 0, 0, 0, count );
|
||||
generate_support_minimization_encodings_rec<true, false>( 0, 0, 0, count, min_set_size, true );
|
||||
}
|
||||
|
||||
assert( count == num_combs );
|
||||
}
|
||||
|
||||
template<bool enable_dcset, bool equal_size_partition>
|
||||
void generate_support_minimization_encodings_rec( uint32_t onset, uint32_t offset, uint32_t var, uint32_t& count )
|
||||
void generate_support_minimization_encodings_rec( uint32_t onset, uint32_t offset, uint32_t var, uint32_t& count, int32_t min_set_size, bool first )
|
||||
{
|
||||
if ( var == best_multiplicity )
|
||||
{
|
||||
|
|
@ -839,6 +852,11 @@ private:
|
|||
return;
|
||||
}
|
||||
}
|
||||
else if ( __builtin_popcount( onset ) < min_set_size || __builtin_popcount( offset ) < min_set_size )
|
||||
{
|
||||
/* ON-set and OFF-set must be populated with at least min_set_size elements */
|
||||
return;
|
||||
}
|
||||
|
||||
support_minimization_encodings[count][0] = onset;
|
||||
support_minimization_encodings[count][1] = offset;
|
||||
|
|
@ -849,23 +867,23 @@ private:
|
|||
/* var in DCSET */
|
||||
if ( enable_dcset )
|
||||
{
|
||||
generate_support_minimization_encodings_rec<enable_dcset, equal_size_partition>( onset, offset, var + 1, count );
|
||||
generate_support_minimization_encodings_rec<enable_dcset, equal_size_partition>( onset, offset, var + 1, count, min_set_size, first );
|
||||
}
|
||||
|
||||
/* move var in ONSET */
|
||||
onset |= 1 << var;
|
||||
generate_support_minimization_encodings_rec<enable_dcset, equal_size_partition>( onset, offset, var + 1, count );
|
||||
generate_support_minimization_encodings_rec<enable_dcset, equal_size_partition>( onset, offset, var + 1, count, min_set_size, false );
|
||||
onset &= ~( 1 << var );
|
||||
|
||||
/* remove symmetries */
|
||||
if ( var == 0 )
|
||||
if ( first )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* move var in OFFSET */
|
||||
offset |= 1 << var;
|
||||
generate_support_minimization_encodings_rec<enable_dcset, equal_size_partition>( onset, offset, var + 1, count );
|
||||
generate_support_minimization_encodings_rec<enable_dcset, equal_size_partition>( onset, offset, var + 1, count, min_set_size, false );
|
||||
offset &= ~( 1 << var );
|
||||
}
|
||||
|
||||
|
|
@ -1016,15 +1034,6 @@ private:
|
|||
uint32_t const onset = support_minimization_encodings[i][0];
|
||||
uint32_t const offset = support_minimization_encodings[i][1];
|
||||
|
||||
uint32_t ones_onset = __builtin_popcount( onset );
|
||||
uint32_t ones_offset = __builtin_popcount( offset );
|
||||
|
||||
/* filter columns that do not distinguish pairs */
|
||||
if ( ones_onset == 0 || ones_offset == 0 || ones_onset == best_multiplicity || ones_offset == best_multiplicity )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/* compute function and distinguishable seed dichotomies */
|
||||
uint64_t column[2] = { 0, 0 };
|
||||
STT tt;
|
||||
|
|
@ -1503,4 +1512,4 @@ private:
|
|||
|
||||
ABC_NAMESPACE_CXX_HEADER_END
|
||||
|
||||
#endif // _ACD_H_
|
||||
#endif // _ACD_H_
|
||||
|
|
|
|||
|
|
@ -610,7 +610,7 @@ private:
|
|||
: cost <= 32 ? 4
|
||||
: 5;
|
||||
|
||||
if ( ss_vars_needed + free_set_size < 6 )
|
||||
if ( ss_vars_needed + free_set_size < ps.lut_size )
|
||||
{
|
||||
/* look for a shared variable */
|
||||
best_multiplicity = cost;
|
||||
|
|
@ -665,7 +665,7 @@ private:
|
|||
: cost <= 32 ? 4
|
||||
: 5;
|
||||
|
||||
if ( ss_vars_needed + free_set_size < 6 )
|
||||
if ( ss_vars_needed + free_set_size < ps.lut_size )
|
||||
{
|
||||
/* look for a shared variable */
|
||||
best_multiplicity = cost;
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@ static int If_CommandReadLut ( Abc_Frame_t * pAbc, int argc, char **argv );
|
|||
static int If_CommandPrintLut( Abc_Frame_t * pAbc, int argc, char **argv );
|
||||
static int If_CommandReadBox ( Abc_Frame_t * pAbc, int argc, char **argv );
|
||||
static int If_CommandPrintBox( Abc_Frame_t * pAbc, int argc, char **argv );
|
||||
static int If_CommandWriteBox( Abc_Frame_t * pAbc, int argc, char **argv );
|
||||
static int If_CommandPrintTim( Abc_Frame_t * pAbc, int argc, char **argv );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
|
|
@ -59,6 +61,8 @@ void If_Init( Abc_Frame_t * pAbc )
|
|||
|
||||
Cmd_CommandAdd( pAbc, "FPGA mapping", "read_box", If_CommandReadBox, 0 );
|
||||
Cmd_CommandAdd( pAbc, "FPGA mapping", "print_box", If_CommandPrintBox, 0 );
|
||||
Cmd_CommandAdd( pAbc, "FPGA mapping", "write_box", If_CommandWriteBox, 0 );
|
||||
Cmd_CommandAdd( pAbc, "FPGA mapping", "print_tim", If_CommandPrintTim, 0 );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
@ -362,6 +366,113 @@ usage:
|
|||
return 1; /* error exit */
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Command procedure to read LUT libraries.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int If_CommandWriteBox( Abc_Frame_t * pAbc, int argc, char **argv )
|
||||
{
|
||||
FILE * pOut, * pErr;
|
||||
Abc_Ntk_t * pNet;
|
||||
int fVerbose;
|
||||
int c;
|
||||
|
||||
pNet = Abc_FrameReadNtk(pAbc);
|
||||
pOut = Abc_FrameReadOut(pAbc);
|
||||
pErr = Abc_FrameReadErr(pAbc);
|
||||
|
||||
fVerbose = 1;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( (c = Extra_UtilGetopt(argc, argv, "vh")) != EOF )
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case 'v':
|
||||
fVerbose ^= 1;
|
||||
break;
|
||||
case 'h':
|
||||
goto usage;
|
||||
break;
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
|
||||
if ( argc != globalUtilOptind+1 )
|
||||
goto usage;
|
||||
|
||||
If_LibBoxWrite( argv[globalUtilOptind], (If_LibBox_t *)Abc_FrameReadLibBox() );
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
fprintf( pErr, "\nusage: write_box [-vh] <file>\n");
|
||||
fprintf( pErr, "\t write the current box library into a file\n" );
|
||||
fprintf( pErr, "\t-v : toggles enabling of verbose output [default = %s]\n", (fVerbose? "yes" : "no") );
|
||||
fprintf( pErr, "\t-h : print the command usage\n");
|
||||
fprintf( pErr, "\t<file> : the output file name\n");
|
||||
return 1; /* error exit */
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Command procedure to read LUT libraries.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int If_CommandPrintTim( Abc_Frame_t * pAbc, int argc, char **argv )
|
||||
{
|
||||
Gia_Man_t * pGia = Abc_FrameReadGia(pAbc);
|
||||
int c, fVerbose = 0;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( (c = Extra_UtilGetopt(argc, argv, "vh")) != EOF )
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case 'v':
|
||||
fVerbose ^= 1;
|
||||
break;
|
||||
case 'h':
|
||||
goto usage;
|
||||
break;
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
if ( pGia == NULL )
|
||||
{
|
||||
Abc_Print( -1, "There is no AIG in the &-space.\n" );
|
||||
return 1;
|
||||
}
|
||||
if ( pGia->pManTime == NULL )
|
||||
{
|
||||
Abc_Print( -1, "The current AIG does not have a timing manager.\n" );
|
||||
return 1;
|
||||
}
|
||||
Tim_ManPrint( (Tim_Man_t *)pGia->pManTime );
|
||||
if ( fVerbose )
|
||||
Tim_ManPrintBoxCopy( (Tim_Man_t *)pGia->pManTime );
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
Abc_Print( -2, "\nusage: print_tim [-vh]\n");
|
||||
Abc_Print( -2, "\t print the timing manager\n" );
|
||||
Abc_Print( -2, "\t-v : toggles enabling of verbose output [default = %s]\n", (fVerbose? "yes" : "no") );
|
||||
Abc_Print( -2, "\t-h : print the command usage\n");
|
||||
return 1; /* error exit */
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
|
|
|
|||
|
|
@ -345,7 +345,7 @@ void If_LibBoxPrint( FILE * pFile, If_LibBox_t * p )
|
|||
If_LibBoxForEachBox( p, pBox, i )
|
||||
{
|
||||
fprintf( pFile, "%s %d %d %d %d\n", pBox->pName, pBox->Id, !pBox->fBlack, pBox->nPis, pBox->nPos );
|
||||
for ( j = 0; j < pBox->nPos; j++, printf("\n") )
|
||||
for ( j = 0; j < pBox->nPos; j++, fprintf(pFile, "\n") )
|
||||
for ( k = 0; k < pBox->nPis; k++ )
|
||||
if ( pBox->pDelays[j * pBox->nPis + k] == -ABC_INFINITY )
|
||||
fprintf( pFile, " - " );
|
||||
|
|
@ -364,6 +364,7 @@ void If_LibBoxWrite( char * pFileName, If_LibBox_t * p )
|
|||
}
|
||||
If_LibBoxPrint( pFile, p );
|
||||
fclose( pFile );
|
||||
printf( "Finished writing box library into file \"%s\".\n", pFileName );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ static int Mio_CommandPrintProfile( Abc_Frame_t * pAbc, int argc, char **argv );
|
|||
|
||||
/*
|
||||
// internal version of genlib library
|
||||
static char * pMcncGenlib[25] = {
|
||||
static char * pMcncGenlib[] = {
|
||||
"GATE inv1 1 O=!a; PIN * INV 1 999 0.9 0.0 0.9 0.0\n",
|
||||
"GATE inv2 2 O=!a; PIN * INV 2 999 1.0 0.0 1.0 0.0\n",
|
||||
"GATE inv3 3 O=!a; PIN * INV 3 999 1.1 0.0 1.1 0.0\n",
|
||||
|
|
@ -68,13 +68,57 @@ static char * pMcncGenlib[25] = {
|
|||
"GATE oai22 4 O=!((a+b)*(c+d)); PIN * INV 1 999 2.0 0.0 2.0 0.0\n",
|
||||
"GATE buf 1 O=a; PIN * NONINV 1 999 1.0 0.0 1.0 0.0\n",
|
||||
"GATE zero 0 O=CONST0;\n",
|
||||
"GATE one 0 O=CONST1;\n"
|
||||
"GATE one 0 O=CONST1;\n",
|
||||
NULL
|
||||
};
|
||||
*/
|
||||
|
||||
// internal version of genlib library
|
||||
static char * pSimpleGenlib[] = {
|
||||
"GATE zero 0 O=CONST0;\n",
|
||||
"GATE one 0 O=CONST1;\n",
|
||||
"GATE buf 4 O=a; PIN * NONINV 1 999 1.0 0.0 1.0 0.0\n",
|
||||
"GATE inv 2 O=!a; PIN * INV 1 999 1.0 0.0 1.0 0.0\n",
|
||||
"GATE nand2 4 O=!(a*b); PIN * INV 1 999 1.0 0.0 1.0 0.0\n",
|
||||
"GATE nand3 6 O=!(a*b*c); PIN * INV 1 999 1.0 0.0 1.0 0.0\n",
|
||||
"GATE nor2 4 O=!(a+b); PIN * INV 1 999 1.0 0.0 1.0 0.0\n",
|
||||
"GATE nor3 6 O=!(a+b+c); PIN * INV 1 999 1.0 0.0 1.0 0.0\n",
|
||||
"GATE aoi21 6 O=!(a*b+c); PIN * INV 1 999 1.0 0.0 1.0 0.0\n",
|
||||
"GATE oai21 6 O=!((a+b)*c); PIN * INV 1 999 1.0 0.0 1.0 0.0\n",
|
||||
"GATE aoi22 8 O=!(a*b+c*d); PIN * INV 1 999 1.0 0.0 1.0 0.0\n",
|
||||
"GATE oai22 8 O=!((a+b)*(c+d)); PIN * INV 1 999 1.0 0.0 1.0 0.0\n",
|
||||
NULL
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Mio_IntallSimpleLibrary()
|
||||
{
|
||||
extern Mio_Library_t * Mio_LibraryReadBuffer( char * pBuffer, int fExtendedFormat, st__table * tExcludeGate, int nFaninLimit, int fVerbose );
|
||||
Mio_Library_t * pLib; int i;
|
||||
Vec_Str_t * vLibStr = Vec_StrAlloc( 1000 );
|
||||
for ( i = 0; pSimpleGenlib[i]; i++ )
|
||||
Vec_StrAppend( vLibStr, pSimpleGenlib[i] );
|
||||
Vec_StrPush( vLibStr, '\0' );
|
||||
pLib = Mio_LibraryReadBuffer( Vec_StrArray(vLibStr), 0, NULL, 0, 0 );
|
||||
Mio_LibrarySetName( pLib, Abc_UtilStrsav("simple.genlib") );
|
||||
Mio_UpdateGenlib( pLib );
|
||||
Vec_StrFree( vLibStr );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
|
@ -292,7 +336,7 @@ int Mio_CommandReadGenlib( Abc_Frame_t * pAbc, int argc, char **argv )
|
|||
double WireDelay = 0.0;
|
||||
int fShortNames = 0;
|
||||
int nFaninLimit = 0;
|
||||
int c, fVerbose = 1;
|
||||
int c, fVerbose = 0;
|
||||
|
||||
pOut = Abc_FrameReadOut(pAbc);
|
||||
pErr = Abc_FrameReadErr(pAbc);
|
||||
|
|
|
|||
|
|
@ -109,6 +109,7 @@ extern void Mio_UpdateGenlib( Mio_Library_t * pLib );
|
|||
extern int Mio_UpdateGenlib2( Vec_Str_t * vStr, Vec_Str_t * vStr2, char * pFileName, int fVerbose );
|
||||
/*=== mioApi.c =============================================================*/
|
||||
extern char * Mio_LibraryReadName ( Mio_Library_t * pLib );
|
||||
extern char * Mio_LibraryReadFileName ( Mio_Library_t * pLib );
|
||||
extern int Mio_LibraryReadGateNum ( Mio_Library_t * pLib );
|
||||
extern Mio_Gate_t * Mio_LibraryReadGates ( Mio_Library_t * pLib );
|
||||
extern Mio_Gate_t ** Mio_LibraryReadGateArray ( Mio_Library_t * pLib );
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ ABC_NAMESPACE_IMPL_START
|
|||
|
||||
***********************************************************************/
|
||||
char * Mio_LibraryReadName ( Mio_Library_t * pLib ) { return pLib->pName; }
|
||||
char * Mio_LibraryReadFileName ( Mio_Library_t * pLib ) { return pLib->pFileName; }
|
||||
int Mio_LibraryReadGateNum ( Mio_Library_t * pLib ) { return pLib->nGates; }
|
||||
Mio_Gate_t * Mio_LibraryReadGates ( Mio_Library_t * pLib ) { return pLib->pGates; }
|
||||
Mio_Gate_t ** Mio_LibraryReadGateArray ( Mio_Library_t * pLib ) { return pLib->ppGatesName;}
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ ABC_NAMESPACE_HEADER_START
|
|||
struct Mio_LibraryStruct_t_
|
||||
{
|
||||
char * pName; // the name of the library
|
||||
char * pFileName; // the original file name
|
||||
int nGates; // the number of the gates
|
||||
Mio_Gate_t ** ppGates0; // the array of gates in the original order
|
||||
Mio_Gate_t ** ppGatesName; // the array of gates sorted by name
|
||||
|
|
|
|||
|
|
@ -97,6 +97,7 @@ Mio_Library_t * Mio_LibraryRead( char * FileName, char * pBuffer, char * Exclude
|
|||
if ( tExcludeGate )
|
||||
st__free_table( tExcludeGate );
|
||||
|
||||
pLib->pFileName = Abc_UtilStrsav( FileName );
|
||||
return pLib;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ void Mio_LibraryDelete( Mio_Library_t * pLib )
|
|||
// Cudd_Quit( pLib->dd );
|
||||
ABC_FREE( pLib->ppGates0 );
|
||||
ABC_FREE( pLib->ppGatesName );
|
||||
ABC_FREE( pLib->pFileName );
|
||||
ABC_FREE( pLib );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#include <fnmatch.h>
|
||||
#endif
|
||||
|
||||
#include "misc/zlib/zlib.h"
|
||||
#include "sclLib.h"
|
||||
#include "misc/st/st.h"
|
||||
#include "map/mio/mio.h"
|
||||
|
|
@ -552,14 +553,59 @@ long Scl_LibertyFileSize( char * pFileName )
|
|||
fclose( pFile );
|
||||
return nFileSize;
|
||||
}
|
||||
char * Scl_LibertyFileContents( char * pFileName, long nContents )
|
||||
|
||||
static char * Io_LibLoadFileGz( char * pFileName, long * pnFileSize )
|
||||
{
|
||||
FILE * pFile = fopen( pFileName, "rb" );
|
||||
char * pContents = ABC_ALLOC( char, nContents+1 );
|
||||
long RetValue = 0;
|
||||
RetValue = fread( pContents, nContents, 1, pFile );
|
||||
fclose( pFile );
|
||||
pContents[nContents] = 0;
|
||||
const int READ_BLOCK_SIZE = 100000;
|
||||
gzFile pFile;
|
||||
char * pContents;
|
||||
long amtRead, readBlock, nFileSize = READ_BLOCK_SIZE;
|
||||
pFile = gzopen( pFileName, "rb" ); // if pFileName doesn't end in ".gz" then this acts as a passthrough to fopen
|
||||
pContents = ABC_ALLOC( char, nFileSize );
|
||||
readBlock = 0;
|
||||
while ((amtRead = gzread(pFile, pContents + readBlock * READ_BLOCK_SIZE, READ_BLOCK_SIZE)) == READ_BLOCK_SIZE) {
|
||||
//Abc_Print( 1,"%d: read %d bytes\n", readBlock, amtRead);
|
||||
nFileSize += READ_BLOCK_SIZE;
|
||||
pContents = ABC_REALLOC(char, pContents, nFileSize);
|
||||
++readBlock;
|
||||
}
|
||||
//Abc_Print( 1,"%d: read %d bytes\n", readBlock, amtRead);
|
||||
assert( amtRead != -1 ); // indicates a zlib error
|
||||
nFileSize -= (READ_BLOCK_SIZE - amtRead);
|
||||
gzclose(pFile);
|
||||
*pnFileSize = nFileSize;
|
||||
return pContents;
|
||||
}
|
||||
|
||||
char * Scl_LibertyFileContents( char * pFileName, long * nContents )
|
||||
{
|
||||
char * pContents = NULL;
|
||||
//if file ends in ".gz" then use gzopen
|
||||
if ( !strncmp(pFileName+strlen(pFileName)-3,".gz", 3) )
|
||||
{
|
||||
FILE * pFile = fopen( pFileName, "rb" );
|
||||
//char * pContents;
|
||||
long RetValue = 0;
|
||||
pContents = Io_LibLoadFileGz( pFileName, nContents );
|
||||
if(pContents == NULL) {
|
||||
printf( "Scl_LibertyFileContents(): The input file is unavailable (absent or open).\n" );
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
RetValue = 1;
|
||||
}
|
||||
fclose( pFile );
|
||||
}
|
||||
// original .lib file
|
||||
else
|
||||
{
|
||||
FILE * pFile = fopen( pFileName, "rb" );
|
||||
pContents = ABC_ALLOC( char, *nContents+1 );
|
||||
long RetValue = 0;
|
||||
RetValue = fread( pContents, *nContents, 1, pFile );
|
||||
fclose( pFile );
|
||||
pContents[*nContents] = 0;
|
||||
}
|
||||
return pContents;
|
||||
}
|
||||
void Scl_LibertyStringDump( char * pFileName, Vec_Str_t * vStr )
|
||||
|
|
@ -600,7 +646,7 @@ Scl_Tree_t * Scl_LibertyStart( char * pFileName )
|
|||
memset( p, 0, sizeof(Scl_Tree_t) );
|
||||
p->clkStart = Abc_Clock();
|
||||
p->nContents = RetValue;
|
||||
p->pContents = Scl_LibertyFileContents( pFileName, p->nContents );
|
||||
p->pContents = Scl_LibertyFileContents( pFileName, &p->nContents );
|
||||
// other
|
||||
p->pFileName = Abc_UtilStrsav( pFileName );
|
||||
p->nItermAlloc = 10 + Scl_LibertyCountItems( p->pContents, p->pContents+p->nContents );
|
||||
|
|
|
|||
|
|
@ -200,7 +200,7 @@ void Abc_SclTimeNtkPrint( SC_Man * p, int fShowAll, int fPrintPath )
|
|||
while ( pObj && Abc_ObjIsNode(pObj) )
|
||||
{
|
||||
i++;
|
||||
nLength = Abc_MaxInt( nLength, strlen(Abc_SclObjCell(pObj)->pName) );
|
||||
nLength = Abc_MaxInt( nLength, Abc_SclObjCell(pObj) ? strlen(Abc_SclObjCell(pObj)->pName) : 2 /* strlen("pi") */ );
|
||||
pObj = Abc_SclFindMostCriticalFanin( p, &fRise, pObj );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -237,7 +237,7 @@ extern void Bbl_ManDumpBinaryBlif( Bbl_Man_t * p, char * pFileName );
|
|||
// (3) reading the data manager from file
|
||||
extern Bbl_Man_t * Bbl_ManReadBinaryBlif( char * pFileName );
|
||||
|
||||
// (4) returning the mapped network after reading the data manaager from file
|
||||
// (4) returning the mapped network after reading the data manager from file
|
||||
extern char * Bbl_ManName( Bbl_Man_t * p );
|
||||
extern int Bbl_ObjIsInput( Bbl_Obj_t * p );
|
||||
extern int Bbl_ObjIsOutput( Bbl_Obj_t * p );
|
||||
|
|
|
|||
|
|
@ -276,7 +276,8 @@ int Mvc_CoverSetCubeSizes( Mvc_Cover_t * pCover )
|
|||
int nBytes, nOnes;
|
||||
|
||||
// get the number of unsigned chars in the cube's bit strings
|
||||
nBytes = pCover->nBits / (8 * sizeof(unsigned char)) + (int)(pCover->nBits % (8 * sizeof(unsigned char)) > 0);
|
||||
// nBytes = pCover->nBits / (8 * sizeof(unsigned char)) + (int)(pCover->nBits % (8 * sizeof(unsigned char)) > 0);
|
||||
nBytes = sizeof(Mvc_CubeWord_t) * pCover->nWords; // big-endian issue
|
||||
// iterate through the cubes
|
||||
Mvc_CoverForEachCube( pCover, pCube )
|
||||
{
|
||||
|
|
@ -298,13 +299,14 @@ int Mvc_CoverSetCubeSizes( Mvc_Cover_t * pCover )
|
|||
|
||||
Synopsis [Counts the cube sizes.]
|
||||
|
||||
Description []
|
||||
Description [This procedure works incorrectly on big-endian machines.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
/*
|
||||
int Mvc_CoverGetCubeSize( Mvc_Cube_t * pCube )
|
||||
{
|
||||
unsigned char * pByte, * pByteStart, * pByteStop;
|
||||
|
|
@ -322,6 +324,7 @@ int Mvc_CoverGetCubeSize( Mvc_Cube_t * pCube )
|
|||
nOnes += bit_count[*pByte];
|
||||
return nOnes;
|
||||
}
|
||||
*/
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
|
|
@ -351,7 +354,8 @@ int Mvc_CoverCountCubePairDiffs( Mvc_Cover_t * pCover, unsigned char pDiffs[] )
|
|||
// allocate a temporary mask
|
||||
pMask = Mvc_CubeAlloc( pCover );
|
||||
// get the number of unsigned chars in the cube's bit strings
|
||||
nBytes = pCover->nBits / (8 * sizeof(unsigned char)) + (int)(pCover->nBits % (8 * sizeof(unsigned char)) > 0);
|
||||
// nBytes = pCover->nBits / (8 * sizeof(unsigned char)) + (int)(pCover->nBits % (8 * sizeof(unsigned char)) > 0);
|
||||
nBytes = sizeof(Mvc_CubeWord_t) * pCover->nWords; // big-endian issue
|
||||
// iterate through the cubes
|
||||
nCubePairs = 0;
|
||||
Mvc_CoverForEachCube( pCover, pCube1 )
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ char * Nm_ManStoreIdName( Nm_Man_t * p, int ObjId, int Type, char * pName, char
|
|||
// check if the object with this ID is already stored
|
||||
if ( (pEntry = Nm_ManTableLookupId(p, ObjId)) )
|
||||
{
|
||||
printf( "Nm_ManStoreIdName(): Entry with the same ID already exists.\n" );
|
||||
printf( "Nm_ManStoreIdName(): Entry with ID %d already exists.\n", ObjId );
|
||||
return NULL;
|
||||
}
|
||||
// create a new entry
|
||||
|
|
@ -152,7 +152,7 @@ void Nm_ManDeleteIdName( Nm_Man_t * p, int ObjId )
|
|||
pEntry = Nm_ManTableLookupId(p, ObjId);
|
||||
if ( pEntry == NULL )
|
||||
{
|
||||
printf( "Nm_ManDeleteIdName(): This entry is not in the table.\n" );
|
||||
printf( "Nm_ManDeleteIdName(): Entry with ID %d is not in the table.\n", ObjId );
|
||||
return;
|
||||
}
|
||||
// remove entry from the table
|
||||
|
|
|
|||
|
|
@ -140,6 +140,7 @@ extern float * Tim_ManGetReqTimes( Tim_Man_t * p );
|
|||
extern void Tim_ManStop( Tim_Man_t * p );
|
||||
extern void Tim_ManStopP( Tim_Man_t ** p );
|
||||
extern void Tim_ManPrint( Tim_Man_t * p );
|
||||
extern void Tim_ManPrintBoxCopy( Tim_Man_t * p );
|
||||
extern void Tim_ManPrintStats( Tim_Man_t * p, int nAnd2Delay );
|
||||
extern int Tim_ManCiNum( Tim_Man_t * p );
|
||||
extern int Tim_ManCoNum( Tim_Man_t * p );
|
||||
|
|
|
|||
|
|
@ -564,10 +564,10 @@ void Tim_ManPrint( Tim_Man_t * p )
|
|||
if ( Tim_ManBoxNum(p) > 0 )
|
||||
Tim_ManForEachBox( p, pBox, i )
|
||||
{
|
||||
printf( "*** Box %5d : I =%4d. O =%4d. I1 =%6d. O1 =%6d. Table =%4d\n",
|
||||
printf( "*** Box %5d : I =%4d. O =%4d. I1 =%6d. O1 =%6d. Table =%4d. Copy = %d.\n",
|
||||
i, pBox->nInputs, pBox->nOutputs,
|
||||
Tim_ManBoxInputFirst(p, i), Tim_ManBoxOutputFirst(p, i),
|
||||
pBox->iDelayTable );
|
||||
pBox->iDelayTable, pBox->iCopy );
|
||||
|
||||
// print box inputs
|
||||
pPrev = Tim_ManBoxInput( p, pBox, 0 );
|
||||
|
|
@ -591,7 +591,7 @@ void Tim_ManPrint( Tim_Man_t * p )
|
|||
Tim_ManBoxForEachOutput( p, pBox, pObj, k )
|
||||
printf( "box-out%3d : arrival = %5.3f required = %5.3f\n", k, pObj->timeArr, pObj->timeReq );
|
||||
|
||||
if ( i > 2 )
|
||||
if ( i == 7 )
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -611,6 +611,8 @@ void Tim_ManPrint( Tim_Man_t * p )
|
|||
printf( "%5s", "-" );
|
||||
else
|
||||
printf( "%5.0f", pTable[3+j*TableX+k] );
|
||||
if ( i == 7 )
|
||||
break;
|
||||
}
|
||||
printf( "\n" );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -248,6 +248,7 @@ typedef ABC_INT64_T iword;
|
|||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define ABC_INFINITY (1000000000)
|
||||
#define ABC_INT_MAX (2147483647)
|
||||
|
||||
#define ABC_SWAP(Type, a, b) { Type t = a; a = b; b = t; }
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
SRC += src/misc/util/utilBridge.c \
|
||||
src/misc/util/utilBSet.c \
|
||||
src/misc/util/utilCex.c \
|
||||
src/misc/util/utilColor.c \
|
||||
src/misc/util/utilFile.c \
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -74,6 +74,25 @@ static word s_Truths6Neg[6] = {
|
|||
ABC_CONST(0x00000000FFFFFFFF)
|
||||
};
|
||||
|
||||
static word s_Truth26[2][6] = {
|
||||
{
|
||||
ABC_CONST(0xAAAAAAAAAAAAAAAA),
|
||||
ABC_CONST(0xCCCCCCCCCCCCCCCC),
|
||||
ABC_CONST(0xF0F0F0F0F0F0F0F0),
|
||||
ABC_CONST(0xFF00FF00FF00FF00),
|
||||
ABC_CONST(0xFFFF0000FFFF0000),
|
||||
ABC_CONST(0xFFFFFFFF00000000)
|
||||
},
|
||||
{
|
||||
ABC_CONST(0x5555555555555555),
|
||||
ABC_CONST(0x3333333333333333),
|
||||
ABC_CONST(0x0F0F0F0F0F0F0F0F),
|
||||
ABC_CONST(0x00FF00FF00FF00FF),
|
||||
ABC_CONST(0x0000FFFF0000FFFF),
|
||||
ABC_CONST(0x00000000FFFFFFFF)
|
||||
}
|
||||
};
|
||||
|
||||
static word s_TruthXors[6] = {
|
||||
ABC_CONST(0x0000000000000000),
|
||||
ABC_CONST(0x6666666666666666),
|
||||
|
|
@ -1988,6 +2007,27 @@ static inline word Abc_Tt6RemoveVar( word t, int iVar )
|
|||
t = Abc_Tt6SwapAdjacent( t, iVar++ );
|
||||
return t;
|
||||
}
|
||||
// permutes two variables while keeping track of their places
|
||||
static inline void Abc_TtPermuteTwo( word * p, int nTTVars, int * Var2Pla, int * Pla2Var, int Var0, int Var1 )
|
||||
{
|
||||
int iPlace0 = Var2Pla[Var0];
|
||||
int iPlace1 = Var2Pla[Var1];
|
||||
if ( iPlace0 == iPlace1 )
|
||||
return;
|
||||
Abc_TtSwapVars( p, nTTVars, iPlace0, iPlace1 );
|
||||
Var2Pla[Pla2Var[iPlace0]] = iPlace1;
|
||||
Var2Pla[Pla2Var[iPlace1]] = iPlace0;
|
||||
Pla2Var[iPlace0] ^= Pla2Var[iPlace1];
|
||||
Pla2Var[iPlace1] ^= Pla2Var[iPlace0];
|
||||
Pla2Var[iPlace0] ^= Pla2Var[iPlace1];
|
||||
}
|
||||
// restores natural variable order
|
||||
static inline void Abc_TtRestoreOrder( word * p, int nTTVars, int * Var2Pla, int * Pla2Var, int nPermVars )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < nPermVars; i++ )
|
||||
Abc_TtPermuteTwo( p, nTTVars, Var2Pla, Pla2Var, i, Var2Pla[i] );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
|
|
@ -3663,6 +3703,7 @@ static inline void Abc_TtProcessBiDecExperiment()
|
|||
// Dau_DsdPrintFromTruth( &This, Abc_TtBitCount16(resThis) );
|
||||
// Dau_DsdPrintFromTruth( &That, Abc_TtBitCount16(resThat) );
|
||||
nVars = nSuppLim;
|
||||
This = s_Truth26[0][0];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
@ -3854,6 +3895,23 @@ static inline word * Abc_TtSymFunGenerate( char * pOnes, int nVars )
|
|||
return pTruth;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Fix big-endian when dealilng with 5-var truth tables.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Abc_TtFlipVar5( word * p, int nVars )
|
||||
{
|
||||
int Test = 1;
|
||||
if ( *((char *)&Test) == 0 && nVars > 5 )
|
||||
Abc_TtFlip( p, Abc_TtWordNum(nVars), 5 );
|
||||
}
|
||||
|
||||
ABC_NAMESPACE_HEADER_END
|
||||
|
||||
|
|
|
|||
|
|
@ -350,6 +350,7 @@ static inline void Vec_BitGrow( Vec_Bit_t * p, int nCapMin )
|
|||
{
|
||||
if ( p->nCap >= nCapMin )
|
||||
return;
|
||||
assert( p->nCap < ABC_INT_MAX );
|
||||
nCapMin = (nCapMin >> 5) + ((nCapMin & 31) > 0);
|
||||
p->pArray = ABC_REALLOC( int, p->pArray, nCapMin );
|
||||
assert( p->pArray );
|
||||
|
|
@ -405,7 +406,7 @@ static inline void Vec_BitFillExtra( Vec_Bit_t * p, int nSize, int Fill )
|
|||
if ( nSize > 2 * p->nCap )
|
||||
Vec_BitGrow( p, nSize );
|
||||
else if ( nSize > p->nCap )
|
||||
Vec_BitGrow( p, 2 * p->nCap );
|
||||
Vec_BitGrow( p, p->nCap < ABC_INT_MAX/2 ? 2 * p->nCap : ABC_INT_MAX );
|
||||
|
||||
assert( p->nSize < nSize );
|
||||
if ( (p->nSize >> 5) == (nSize >> 5) )
|
||||
|
|
@ -527,7 +528,7 @@ static inline void Vec_BitPush( Vec_Bit_t * p, int Entry )
|
|||
if ( p->nCap < 16 )
|
||||
Vec_BitGrow( p, 16 );
|
||||
else
|
||||
Vec_BitGrow( p, 2 * p->nCap );
|
||||
Vec_BitGrow( p, p->nCap < ABC_INT_MAX/2 ? 2 * p->nCap : ABC_INT_MAX );
|
||||
}
|
||||
if ( Entry == 1 )
|
||||
p->pArray[p->nSize >> 5] |= (1 << (p->nSize & 31));
|
||||
|
|
|
|||
|
|
@ -454,6 +454,7 @@ static inline void Vec_FltGrow( Vec_Flt_t * p, int nCapMin )
|
|||
{
|
||||
if ( p->nCap >= nCapMin )
|
||||
return;
|
||||
assert( p->nCap < ABC_INT_MAX );
|
||||
p->pArray = ABC_REALLOC( float, p->pArray, nCapMin );
|
||||
p->nCap = nCapMin;
|
||||
}
|
||||
|
|
@ -497,7 +498,7 @@ static inline void Vec_FltFillExtra( Vec_Flt_t * p, int nSize, float Fill )
|
|||
if ( nSize > 2 * p->nCap )
|
||||
Vec_FltGrow( p, nSize );
|
||||
else if ( nSize > p->nCap )
|
||||
Vec_FltGrow( p, 2 * p->nCap );
|
||||
Vec_FltGrow( p, p->nCap < ABC_INT_MAX/2 ? 2 * p->nCap : ABC_INT_MAX );
|
||||
for ( i = p->nSize; i < nSize; i++ )
|
||||
p->pArray[i] = Fill;
|
||||
p->nSize = nSize;
|
||||
|
|
@ -554,7 +555,7 @@ static inline void Vec_FltPush( Vec_Flt_t * p, float Entry )
|
|||
if ( p->nCap < 16 )
|
||||
Vec_FltGrow( p, 16 );
|
||||
else
|
||||
Vec_FltGrow( p, 2 * p->nCap );
|
||||
Vec_FltGrow( p, p->nCap < ABC_INT_MAX/2 ? 2 * p->nCap : ABC_INT_MAX );
|
||||
}
|
||||
p->pArray[p->nSize++] = Entry;
|
||||
}
|
||||
|
|
@ -578,7 +579,7 @@ static inline void Vec_FltPushOrder( Vec_Flt_t * p, float Entry )
|
|||
if ( p->nCap < 16 )
|
||||
Vec_FltGrow( p, 16 );
|
||||
else
|
||||
Vec_FltGrow( p, 2 * p->nCap );
|
||||
Vec_FltGrow( p, p->nCap < ABC_INT_MAX/2 ? 2 * p->nCap : ABC_INT_MAX );
|
||||
}
|
||||
p->nSize++;
|
||||
for ( i = p->nSize-2; i >= 0; i-- )
|
||||
|
|
|
|||
|
|
@ -552,6 +552,7 @@ static inline void Vec_IntGrow( Vec_Int_t * p, int nCapMin )
|
|||
{
|
||||
if ( p->nCap >= nCapMin )
|
||||
return;
|
||||
assert( p->nCap < ABC_INT_MAX );
|
||||
p->pArray = ABC_REALLOC( int, p->pArray, nCapMin );
|
||||
assert( p->pArray );
|
||||
p->nCap = nCapMin;
|
||||
|
|
@ -633,7 +634,7 @@ static inline void Vec_IntFillExtra( Vec_Int_t * p, int nSize, int Fill )
|
|||
if ( nSize > 2 * p->nCap )
|
||||
Vec_IntGrow( p, nSize );
|
||||
else if ( nSize > p->nCap )
|
||||
Vec_IntGrow( p, 2 * p->nCap );
|
||||
Vec_IntGrow( p, p->nCap < ABC_INT_MAX/2 ? 2 * p->nCap : ABC_INT_MAX );
|
||||
for ( i = p->nSize; i < nSize; i++ )
|
||||
p->pArray[i] = Fill;
|
||||
p->nSize = nSize;
|
||||
|
|
@ -751,7 +752,7 @@ static inline void Vec_IntPush( Vec_Int_t * p, int Entry )
|
|||
if ( p->nCap < 16 )
|
||||
Vec_IntGrow( p, 16 );
|
||||
else
|
||||
Vec_IntGrow( p, 2 * p->nCap );
|
||||
Vec_IntGrow( p, p->nCap < ABC_INT_MAX/2 ? 2 * p->nCap : ABC_INT_MAX );
|
||||
}
|
||||
p->pArray[p->nSize++] = Entry;
|
||||
}
|
||||
|
|
@ -810,7 +811,7 @@ static inline void Vec_IntPushFirst( Vec_Int_t * p, int Entry )
|
|||
if ( p->nCap < 16 )
|
||||
Vec_IntGrow( p, 16 );
|
||||
else
|
||||
Vec_IntGrow( p, 2 * p->nCap );
|
||||
Vec_IntGrow( p, p->nCap < ABC_INT_MAX/2 ? 2 * p->nCap : ABC_INT_MAX );
|
||||
}
|
||||
p->nSize++;
|
||||
for ( i = p->nSize - 1; i >= 1; i-- )
|
||||
|
|
@ -837,7 +838,7 @@ static inline void Vec_IntPushOrder( Vec_Int_t * p, int Entry )
|
|||
if ( p->nCap < 16 )
|
||||
Vec_IntGrow( p, 16 );
|
||||
else
|
||||
Vec_IntGrow( p, 2 * p->nCap );
|
||||
Vec_IntGrow( p, p->nCap < ABC_INT_MAX/2 ? 2 * p->nCap : ABC_INT_MAX );
|
||||
}
|
||||
p->nSize++;
|
||||
for ( i = p->nSize-2; i >= 0; i-- )
|
||||
|
|
@ -855,7 +856,7 @@ static inline void Vec_IntPushOrderCost( Vec_Int_t * p, int Entry, Vec_Int_t * v
|
|||
if ( p->nCap < 16 )
|
||||
Vec_IntGrow( p, 16 );
|
||||
else
|
||||
Vec_IntGrow( p, 2 * p->nCap );
|
||||
Vec_IntGrow( p, p->nCap < ABC_INT_MAX/2 ? 2 * p->nCap : ABC_INT_MAX );
|
||||
}
|
||||
p->nSize++;
|
||||
for ( i = p->nSize-2; i >= 0; i-- )
|
||||
|
|
@ -931,7 +932,7 @@ static inline void Vec_IntPushOrderReverse( Vec_Int_t * p, int Entry )
|
|||
if ( p->nCap < 16 )
|
||||
Vec_IntGrow( p, 16 );
|
||||
else
|
||||
Vec_IntGrow( p, 2 * p->nCap );
|
||||
Vec_IntGrow( p, p->nCap < ABC_INT_MAX/2 ? 2 * p->nCap : ABC_INT_MAX );
|
||||
}
|
||||
p->nSize++;
|
||||
for ( i = p->nSize-2; i >= 0; i-- )
|
||||
|
|
|
|||
|
|
@ -455,6 +455,7 @@ static inline void Vec_PtrGrow( Vec_Ptr_t * p, int nCapMin )
|
|||
{
|
||||
if ( p->nCap >= nCapMin )
|
||||
return;
|
||||
assert( p->nCap < ABC_INT_MAX );
|
||||
p->pArray = ABC_REALLOC( void *, p->pArray, nCapMin );
|
||||
p->nCap = nCapMin;
|
||||
}
|
||||
|
|
@ -506,7 +507,7 @@ static inline void Vec_PtrFillExtra( Vec_Ptr_t * p, int nSize, void * Fill )
|
|||
if ( nSize > 2 * p->nCap )
|
||||
Vec_PtrGrow( p, nSize );
|
||||
else if ( nSize > p->nCap )
|
||||
Vec_PtrGrow( p, 2 * p->nCap );
|
||||
Vec_PtrGrow( p, p->nCap < ABC_INT_MAX/2 ? 2 * p->nCap : ABC_INT_MAX );
|
||||
for ( i = p->nSize; i < nSize; i++ )
|
||||
p->pArray[i] = Fill;
|
||||
p->nSize = nSize;
|
||||
|
|
@ -682,7 +683,7 @@ static inline void Vec_PtrPush( Vec_Ptr_t * p, void * Entry )
|
|||
if ( p->nCap < 16 )
|
||||
Vec_PtrGrow( p, 16 );
|
||||
else
|
||||
Vec_PtrGrow( p, 2 * p->nCap );
|
||||
Vec_PtrGrow( p, p->nCap < ABC_INT_MAX/2 ? 2 * p->nCap : ABC_INT_MAX );
|
||||
}
|
||||
p->pArray[p->nSize++] = Entry;
|
||||
}
|
||||
|
|
@ -717,7 +718,7 @@ static inline void Vec_PtrPushFirst( Vec_Ptr_t * p, void * Entry )
|
|||
if ( p->nCap < 16 )
|
||||
Vec_PtrGrow( p, 16 );
|
||||
else
|
||||
Vec_PtrGrow( p, 2 * p->nCap );
|
||||
Vec_PtrGrow( p, p->nCap < ABC_INT_MAX/2 ? 2 * p->nCap : ABC_INT_MAX );
|
||||
}
|
||||
p->nSize++;
|
||||
for ( i = p->nSize - 1; i >= 1; i-- )
|
||||
|
|
|
|||
|
|
@ -101,6 +101,7 @@ static inline void Vec_QueGrow( Vec_Que_t * p, int nCapMin )
|
|||
{
|
||||
if ( p->nCap >= nCapMin )
|
||||
return;
|
||||
assert( p->nCap < ABC_INT_MAX );
|
||||
p->pHeap = ABC_REALLOC( int, p->pHeap, nCapMin );
|
||||
p->pOrder = ABC_REALLOC( int, p->pOrder, nCapMin );
|
||||
memset( p->pHeap + p->nCap, 0xff, (size_t)(nCapMin - p->nCap) * sizeof(int) );
|
||||
|
|
@ -225,9 +226,9 @@ static inline int Vec_QueIsMember( Vec_Que_t * p, int v )
|
|||
static inline void Vec_QuePush( Vec_Que_t * p, int v )
|
||||
{
|
||||
if ( p->nSize >= p->nCap )
|
||||
Vec_QueGrow( p, Abc_MaxInt(p->nSize+1, 2*p->nCap) );
|
||||
Vec_QueGrow( p, Abc_MaxInt(p->nSize+1, p->nCap < ABC_INT_MAX/2 ? 2 * p->nCap : ABC_INT_MAX) );
|
||||
if ( v >= p->nCap )
|
||||
Vec_QueGrow( p, Abc_MaxInt(v+1, 2*p->nCap) );
|
||||
Vec_QueGrow( p, Abc_MaxInt(v+1, p->nCap < ABC_INT_MAX/2 ? 2 * p->nCap : ABC_INT_MAX) );
|
||||
assert( p->nSize < p->nCap );
|
||||
assert( p->pOrder[v] == -1 );
|
||||
assert( p->pHeap[p->nSize] == -1 );
|
||||
|
|
|
|||
|
|
@ -423,6 +423,7 @@ static inline void Vec_StrGrow( Vec_Str_t * p, int nCapMin )
|
|||
{
|
||||
if ( p->nCap >= nCapMin )
|
||||
return;
|
||||
assert( p->nCap < ABC_INT_MAX );
|
||||
p->pArray = ABC_REALLOC( char, p->pArray, nCapMin );
|
||||
p->nCap = nCapMin;
|
||||
}
|
||||
|
|
@ -466,7 +467,7 @@ static inline void Vec_StrFillExtra( Vec_Str_t * p, int nSize, char Fill )
|
|||
if ( nSize > 2 * p->nCap )
|
||||
Vec_StrGrow( p, nSize );
|
||||
else if ( nSize > p->nCap )
|
||||
Vec_StrGrow( p, 2 * p->nCap );
|
||||
Vec_StrGrow( p, p->nCap < ABC_INT_MAX/2 ? 2 * p->nCap : ABC_INT_MAX );
|
||||
for ( i = p->nSize; i < nSize; i++ )
|
||||
p->pArray[i] = Fill;
|
||||
p->nSize = nSize;
|
||||
|
|
@ -557,7 +558,7 @@ static inline void Vec_StrPush( Vec_Str_t * p, char Entry )
|
|||
if ( p->nCap < 16 )
|
||||
Vec_StrGrow( p, 16 );
|
||||
else
|
||||
Vec_StrGrow( p, 2 * p->nCap );
|
||||
Vec_StrGrow( p, p->nCap < ABC_INT_MAX/2 ? 2 * p->nCap : ABC_INT_MAX );
|
||||
}
|
||||
p->pArray[p->nSize++] = Entry;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -221,6 +221,37 @@ static inline Vec_Wrd_t * Vec_WrdStartTruthTablesRev( int nVars )
|
|||
}
|
||||
return p;
|
||||
}
|
||||
static inline Vec_Wrd_t * Vec_WrdStartTruthTables6( int nVars )
|
||||
{
|
||||
word Masks[6] = {
|
||||
ABC_CONST(0xAAAAAAAAAAAAAAAA),
|
||||
ABC_CONST(0xCCCCCCCCCCCCCCCC),
|
||||
ABC_CONST(0xF0F0F0F0F0F0F0F0),
|
||||
ABC_CONST(0xFF00FF00FF00FF00),
|
||||
ABC_CONST(0xFFFF0000FFFF0000),
|
||||
ABC_CONST(0xFFFFFFFF00000000)
|
||||
};
|
||||
int i, k, nWords = nVars <= 6 ? 1 : (1 << (nVars - 6));
|
||||
Vec_Wrd_t * p = Vec_WrdStart( nWords * nVars );
|
||||
for ( i = 0; i < nVars; i++ )
|
||||
{
|
||||
word * pTruth = p->pArray + nWords * i;
|
||||
if ( i < 6 )
|
||||
{
|
||||
for ( k = 0; k < nWords; k++ )
|
||||
pTruth[k] = Masks[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( k = 0; k < nWords; k++ )
|
||||
if ( k & (1 << (i-6)) )
|
||||
pTruth[k] = ~(word)0;
|
||||
else
|
||||
pTruth[k] = 0;
|
||||
}
|
||||
}
|
||||
return p;
|
||||
}
|
||||
static inline int Vec_WrdShiftOne( Vec_Wrd_t * p, int nWords )
|
||||
{
|
||||
int i, nObjs = p->nSize/nWords;
|
||||
|
|
@ -553,6 +584,7 @@ static inline void Vec_WrdGrow( Vec_Wrd_t * p, int nCapMin )
|
|||
{
|
||||
if ( p->nCap >= nCapMin )
|
||||
return;
|
||||
assert( p->nCap < ABC_INT_MAX );
|
||||
p->pArray = ABC_REALLOC( word, p->pArray, nCapMin );
|
||||
assert( p->pArray );
|
||||
p->nCap = nCapMin;
|
||||
|
|
@ -597,7 +629,7 @@ static inline void Vec_WrdFillExtra( Vec_Wrd_t * p, int nSize, word Fill )
|
|||
if ( nSize > 2 * p->nCap )
|
||||
Vec_WrdGrow( p, nSize );
|
||||
else if ( nSize > p->nCap )
|
||||
Vec_WrdGrow( p, 2 * p->nCap );
|
||||
Vec_WrdGrow( p, p->nCap < ABC_INT_MAX/2 ? 2 * p->nCap : ABC_INT_MAX );
|
||||
for ( i = p->nSize; i < nSize; i++ )
|
||||
p->pArray[i] = Fill;
|
||||
p->nSize = nSize;
|
||||
|
|
@ -705,7 +737,7 @@ static inline void Vec_WrdPush( Vec_Wrd_t * p, word Entry )
|
|||
if ( p->nCap < 16 )
|
||||
Vec_WrdGrow( p, 16 );
|
||||
else
|
||||
Vec_WrdGrow( p, 2 * p->nCap );
|
||||
Vec_WrdGrow( p, p->nCap < ABC_INT_MAX/2 ? 2 * p->nCap : ABC_INT_MAX );
|
||||
}
|
||||
p->pArray[p->nSize++] = Entry;
|
||||
}
|
||||
|
|
@ -753,7 +785,7 @@ static inline void Vec_WrdPushFirst( Vec_Wrd_t * p, word Entry )
|
|||
if ( p->nCap < 16 )
|
||||
Vec_WrdGrow( p, 16 );
|
||||
else
|
||||
Vec_WrdGrow( p, 2 * p->nCap );
|
||||
Vec_WrdGrow( p, p->nCap < ABC_INT_MAX/2 ? 2 * p->nCap : ABC_INT_MAX );
|
||||
}
|
||||
p->nSize++;
|
||||
for ( i = p->nSize - 1; i >= 1; i-- )
|
||||
|
|
@ -780,7 +812,7 @@ static inline void Vec_WrdPushOrder( Vec_Wrd_t * p, word Entry )
|
|||
if ( p->nCap < 16 )
|
||||
Vec_WrdGrow( p, 16 );
|
||||
else
|
||||
Vec_WrdGrow( p, 2 * p->nCap );
|
||||
Vec_WrdGrow( p, p->nCap < ABC_INT_MAX/2 ? 2 * p->nCap : ABC_INT_MAX );
|
||||
}
|
||||
p->nSize++;
|
||||
for ( i = p->nSize-2; i >= 0; i-- )
|
||||
|
|
|
|||
|
|
@ -444,7 +444,7 @@ int Dsm_ManTruthToGia( void * p, word * pTruth, Vec_Int_t * vLeaves, Vec_Int_t *
|
|||
int fDelayBalance = 1;
|
||||
Gia_Man_t * pGia = (Gia_Man_t *)p;
|
||||
int nSizeNonDec;
|
||||
char pDsd[1000];
|
||||
char pDsd[DAU_MAX_STR];
|
||||
word pTruthCopy[DAU_MAX_WORD];
|
||||
Abc_TtCopy( pTruthCopy, pTruth, Abc_TtWordNum(Vec_IntSize(vLeaves)), 0 );
|
||||
m_Calls++;
|
||||
|
|
|
|||
|
|
@ -560,7 +560,7 @@ void Dau_DsdRemoveBraces( char * pDsd, int * pMatches )
|
|||
for ( q = p; *p; p++ )
|
||||
if ( *p != ' ' )
|
||||
{
|
||||
if ( *p == '!' && *(q-1) == '!' && p != q )
|
||||
if ( *p == '!' && p != q && *(q-1) == '!' )
|
||||
{
|
||||
q--;
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -1,394 +0,0 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [mfsCore.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [The good old minimization with complete don't-cares.]
|
||||
|
||||
Synopsis [Core procedures of this package.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: mfsCore.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "mfsInt.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NtkMfsParsDefault( Mfs_Par_t * pPars )
|
||||
{
|
||||
memset( pPars, 0, sizeof(Mfs_Par_t) );
|
||||
pPars->nWinTfoLevs = 2;
|
||||
pPars->nFanoutsMax = 10;
|
||||
pPars->nDepthMax = 20;
|
||||
pPars->nWinSizeMax = 300;
|
||||
pPars->nGrowthLevel = 0;
|
||||
pPars->nBTLimit = 5000;
|
||||
pPars->fResub = 1;
|
||||
pPars->fArea = 0;
|
||||
pPars->fMoreEffort = 0;
|
||||
pPars->fSwapEdge = 0;
|
||||
pPars->fOneHotness = 0;
|
||||
pPars->fVerbose = 0;
|
||||
pPars->fVeryVerbose = 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NtkMfsResub( Mfs_Man_t * p, Abc_Obj_t * pNode )
|
||||
{
|
||||
clock_t clk;
|
||||
p->nNodesTried++;
|
||||
// prepare data structure for this node
|
||||
Mfs_ManClean( p );
|
||||
// compute window roots, window support, and window nodes
|
||||
clk = clock();
|
||||
p->vRoots = Abc_MfsComputeRoots( pNode, p->pPars->nWinTfoLevs, p->pPars->nFanoutsMax );
|
||||
p->vSupp = Abc_NtkNodeSupport( p->pNtk, (Abc_Obj_t **)Vec_PtrArray(p->vRoots), Vec_PtrSize(p->vRoots) );
|
||||
p->vNodes = Abc_NtkDfsNodes( p->pNtk, (Abc_Obj_t **)Vec_PtrArray(p->vRoots), Vec_PtrSize(p->vRoots) );
|
||||
p->timeWin += clock() - clk;
|
||||
if ( p->pPars->nWinSizeMax && Vec_PtrSize(p->vNodes) > p->pPars->nWinSizeMax )
|
||||
return 1;
|
||||
// compute the divisors of the window
|
||||
clk = clock();
|
||||
p->vDivs = Abc_MfsComputeDivisors( p, pNode, Abc_ObjRequiredLevel(pNode) - 1 );
|
||||
p->nTotalDivs += Vec_PtrSize(p->vDivs) - Abc_ObjFaninNum(pNode);
|
||||
p->timeDiv += clock() - clk;
|
||||
// construct AIG for the window
|
||||
clk = clock();
|
||||
p->pAigWin = Abc_NtkConstructAig( p, pNode );
|
||||
p->timeAig += clock() - clk;
|
||||
// translate it into CNF
|
||||
clk = clock();
|
||||
p->pCnf = Cnf_DeriveSimple( p->pAigWin, 1 + Vec_PtrSize(p->vDivs) );
|
||||
p->timeCnf += clock() - clk;
|
||||
// create the SAT problem
|
||||
clk = clock();
|
||||
p->pSat = Abc_MfsCreateSolverResub( p, NULL, 0, 0 );
|
||||
if ( p->pSat == NULL )
|
||||
{
|
||||
p->nNodesBad++;
|
||||
return 1;
|
||||
}
|
||||
// solve the SAT problem
|
||||
if ( p->pPars->fPower )
|
||||
Abc_NtkMfsEdgePower( p, pNode );
|
||||
else if ( p->pPars->fSwapEdge )
|
||||
Abc_NtkMfsEdgeSwapEval( p, pNode );
|
||||
else
|
||||
{
|
||||
Abc_NtkMfsResubNode( p, pNode );
|
||||
if ( p->pPars->fMoreEffort )
|
||||
Abc_NtkMfsResubNode2( p, pNode );
|
||||
}
|
||||
p->timeSat += clock() - clk;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NtkMfsNode( Mfs_Man_t * p, Abc_Obj_t * pNode )
|
||||
{
|
||||
Hop_Obj_t * pObj;
|
||||
int RetValue;
|
||||
float dProb;
|
||||
extern Hop_Obj_t * Abc_NodeIfNodeResyn( Bdc_Man_t * p, Hop_Man_t * pHop, Hop_Obj_t * pRoot, int nVars, Vec_Int_t * vTruth, unsigned * puCare, float dProb );
|
||||
|
||||
int nGain;
|
||||
clock_t clk;
|
||||
p->nNodesTried++;
|
||||
// prepare data structure for this node
|
||||
Mfs_ManClean( p );
|
||||
// compute window roots, window support, and window nodes
|
||||
clk = clock();
|
||||
p->vRoots = Abc_MfsComputeRoots( pNode, p->pPars->nWinTfoLevs, p->pPars->nFanoutsMax );
|
||||
p->vSupp = Abc_NtkNodeSupport( p->pNtk, (Abc_Obj_t **)Vec_PtrArray(p->vRoots), Vec_PtrSize(p->vRoots) );
|
||||
p->vNodes = Abc_NtkDfsNodes( p->pNtk, (Abc_Obj_t **)Vec_PtrArray(p->vRoots), Vec_PtrSize(p->vRoots) );
|
||||
p->timeWin += clock() - clk;
|
||||
// count the number of patterns
|
||||
// p->dTotalRatios += Abc_NtkConstraintRatio( p, pNode );
|
||||
// construct AIG for the window
|
||||
clk = clock();
|
||||
p->pAigWin = Abc_NtkConstructAig( p, pNode );
|
||||
p->timeAig += clock() - clk;
|
||||
// translate it into CNF
|
||||
clk = clock();
|
||||
p->pCnf = Cnf_DeriveSimple( p->pAigWin, Abc_ObjFaninNum(pNode) );
|
||||
p->timeCnf += clock() - clk;
|
||||
// create the SAT problem
|
||||
clk = clock();
|
||||
p->pSat = Cnf_DataWriteIntoSolver( p->pCnf, 1, 0 );
|
||||
if ( p->pSat && p->pPars->fOneHotness )
|
||||
Abc_NtkAddOneHotness( p );
|
||||
if ( p->pSat == NULL )
|
||||
return 0;
|
||||
// solve the SAT problem
|
||||
RetValue = Abc_NtkMfsSolveSat( p, pNode );
|
||||
p->nTotConfLevel += p->pSat->stats.conflicts;
|
||||
p->timeSat += clock() - clk;
|
||||
if ( RetValue == 0 )
|
||||
{
|
||||
p->nTimeOutsLevel++;
|
||||
p->nTimeOuts++;
|
||||
return 0;
|
||||
}
|
||||
// minimize the local function of the node using bi-decomposition
|
||||
assert( p->nFanins == Abc_ObjFaninNum(pNode) );
|
||||
dProb = p->pPars->fPower? ((float *)p->vProbs->pArray)[pNode->Id] : -1.0;
|
||||
pObj = Abc_NodeIfNodeResyn( p->pManDec, pNode->pNtk->pManFunc, pNode->pData, p->nFanins, p->vTruth, p->uCare, dProb );
|
||||
nGain = Hop_DagSize(pNode->pData) - Hop_DagSize(pObj);
|
||||
if ( nGain >= 0 )
|
||||
{
|
||||
p->nNodesDec++;
|
||||
p->nNodesGained += nGain;
|
||||
p->nNodesGainedLevel += nGain;
|
||||
pNode->pData = pObj;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NtkMfs( Abc_Ntk_t * pNtk, Mfs_Par_t * pPars )
|
||||
{
|
||||
extern Aig_Man_t * Abc_NtkToDar( Abc_Ntk_t * pNtk, int fExors, int fRegisters );
|
||||
|
||||
Bdc_Par_t Pars = {0}, * pDecPars = &Pars;
|
||||
ProgressBar * pProgress;
|
||||
Mfs_Man_t * p;
|
||||
Abc_Obj_t * pObj;
|
||||
Vec_Vec_t * vLevels;
|
||||
Vec_Ptr_t * vNodes;
|
||||
int i, k, nNodes, nFaninMax;
|
||||
clock_t clk = clock(), clk2;
|
||||
int nTotalNodesBeg = Abc_NtkNodeNum(pNtk);
|
||||
int nTotalEdgesBeg = Abc_NtkGetTotalFanins(pNtk);
|
||||
|
||||
assert( Abc_NtkIsLogic(pNtk) );
|
||||
nFaninMax = Abc_NtkGetFaninMax(pNtk);
|
||||
if ( pPars->fResub )
|
||||
{
|
||||
if ( nFaninMax > 8 )
|
||||
{
|
||||
printf( "Nodes with more than %d fanins will not be processed.\n", 8 );
|
||||
nFaninMax = 8;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( nFaninMax > MFS_FANIN_MAX )
|
||||
{
|
||||
printf( "Nodes with more than %d fanins will not be processed.\n", MFS_FANIN_MAX );
|
||||
nFaninMax = MFS_FANIN_MAX;
|
||||
}
|
||||
}
|
||||
// perform the network sweep
|
||||
Abc_NtkSweep( pNtk, 0 );
|
||||
// convert into the AIG
|
||||
if ( !Abc_NtkToAig(pNtk) )
|
||||
{
|
||||
fprintf( stdout, "Converting to AIGs has failed.\n" );
|
||||
return 0;
|
||||
}
|
||||
assert( Abc_NtkHasAig(pNtk) );
|
||||
|
||||
// start the manager
|
||||
p = Mfs_ManAlloc( pPars );
|
||||
p->pNtk = pNtk;
|
||||
p->nFaninMax = nFaninMax;
|
||||
|
||||
// precomputer power-aware metrics
|
||||
if ( pPars->fPower )
|
||||
{
|
||||
extern Vec_Int_t * Abc_NtkPowerEstimate( Abc_Ntk_t * pNtk, int fProbOne );
|
||||
if ( pPars->fResub )
|
||||
p->vProbs = Abc_NtkPowerEstimate( pNtk, 0 );
|
||||
else
|
||||
p->vProbs = Abc_NtkPowerEstimate( pNtk, 1 );
|
||||
printf( "Total switching before = %7.2f.\n", Abc_NtkMfsTotalSwitching(pNtk) );
|
||||
}
|
||||
|
||||
if ( pNtk->pExcare )
|
||||
{
|
||||
Abc_Ntk_t * pTemp;
|
||||
if ( Abc_NtkPiNum(pNtk->pExcare) != Abc_NtkCiNum(pNtk) )
|
||||
printf( "The PI count of careset (%d) and logic network (%d) differ. Careset is not used.\n",
|
||||
Abc_NtkPiNum(pNtk->pExcare), Abc_NtkCiNum(pNtk) );
|
||||
else
|
||||
{
|
||||
pTemp = Abc_NtkStrash( pNtk->pExcare, 0, 0, 0 );
|
||||
p->pCare = Abc_NtkToDar( pTemp, 0, 0 );
|
||||
Abc_NtkDelete( pTemp );
|
||||
p->vSuppsInv = Aig_ManSupportsInverse( p->pCare );
|
||||
}
|
||||
}
|
||||
if ( p->pCare != NULL )
|
||||
printf( "Performing optimization with %d external care clauses.\n", Aig_ManPoNum(p->pCare) );
|
||||
// prepare the BDC manager
|
||||
if ( !pPars->fResub )
|
||||
{
|
||||
pDecPars->nVarsMax = (nFaninMax < 3) ? 3 : nFaninMax;
|
||||
pDecPars->fVerbose = pPars->fVerbose;
|
||||
p->vTruth = Vec_IntAlloc( 0 );
|
||||
p->pManDec = Bdc_ManAlloc( pDecPars );
|
||||
}
|
||||
|
||||
// label the register outputs
|
||||
if ( p->pCare )
|
||||
{
|
||||
Abc_NtkForEachCi( pNtk, pObj, i )
|
||||
pObj->pData = (void *)(PORT_PTRUINT_T)i;
|
||||
}
|
||||
|
||||
// compute levels
|
||||
Abc_NtkLevel( pNtk );
|
||||
Abc_NtkStartReverseLevels( pNtk, pPars->nGrowthLevel );
|
||||
|
||||
// compute don't-cares for each node
|
||||
nNodes = 0;
|
||||
p->nTotalNodesBeg = nTotalNodesBeg;
|
||||
p->nTotalEdgesBeg = nTotalEdgesBeg;
|
||||
if ( pPars->fResub )
|
||||
{
|
||||
pProgress = Extra_ProgressBarStart( stdout, Abc_NtkObjNumMax(pNtk) );
|
||||
Abc_NtkForEachNode( pNtk, pObj, i )
|
||||
{
|
||||
if ( p->pPars->nDepthMax && (int)pObj->Level > p->pPars->nDepthMax )
|
||||
continue;
|
||||
if ( Abc_ObjFaninNum(pObj) < 2 || Abc_ObjFaninNum(pObj) > nFaninMax )
|
||||
continue;
|
||||
if ( !p->pPars->fVeryVerbose )
|
||||
Extra_ProgressBarUpdate( pProgress, i, NULL );
|
||||
if ( pPars->fResub )
|
||||
Abc_NtkMfsResub( p, pObj );
|
||||
else
|
||||
Abc_NtkMfsNode( p, pObj );
|
||||
}
|
||||
Extra_ProgressBarStop( pProgress );
|
||||
}
|
||||
else
|
||||
{
|
||||
pProgress = Extra_ProgressBarStart( stdout, Abc_NtkNodeNum(pNtk) );
|
||||
vLevels = Abc_NtkLevelize( pNtk );
|
||||
Vec_VecForEachLevelStart( vLevels, vNodes, k, 1 )
|
||||
{
|
||||
if ( !p->pPars->fVeryVerbose )
|
||||
Extra_ProgressBarUpdate( pProgress, nNodes, NULL );
|
||||
p->nNodesGainedLevel = 0;
|
||||
p->nTotConfLevel = 0;
|
||||
p->nTimeOutsLevel = 0;
|
||||
clk2 = clock();
|
||||
Vec_PtrForEachEntry( vNodes, pObj, i )
|
||||
{
|
||||
if ( p->pPars->nDepthMax && (int)pObj->Level > p->pPars->nDepthMax )
|
||||
break;
|
||||
if ( Abc_ObjFaninNum(pObj) < 2 || Abc_ObjFaninNum(pObj) > nFaninMax )
|
||||
continue;
|
||||
if ( pPars->fResub )
|
||||
Abc_NtkMfsResub( p, pObj );
|
||||
else
|
||||
Abc_NtkMfsNode( p, pObj );
|
||||
}
|
||||
nNodes += Vec_PtrSize(vNodes);
|
||||
if ( pPars->fVerbose )
|
||||
{
|
||||
printf( "Lev = %2d. Node = %5d. Ave gain = %5.2f. Ave conf = %5.2f. T/o = %6.2f %% ",
|
||||
k, Vec_PtrSize(vNodes),
|
||||
1.0*p->nNodesGainedLevel/Vec_PtrSize(vNodes),
|
||||
1.0*p->nTotConfLevel/Vec_PtrSize(vNodes),
|
||||
100.0*p->nTimeOutsLevel/Vec_PtrSize(vNodes) );
|
||||
PRT( "Time", clock() - clk2 );
|
||||
}
|
||||
}
|
||||
Extra_ProgressBarStop( pProgress );
|
||||
Vec_VecFree( vLevels );
|
||||
}
|
||||
Abc_NtkStopReverseLevels( pNtk );
|
||||
|
||||
// perform the sweeping
|
||||
if ( !pPars->fResub )
|
||||
{
|
||||
extern void Abc_NtkBidecResyn( Abc_Ntk_t * pNtk, int fVerbose );
|
||||
// Abc_NtkSweep( pNtk, 0 );
|
||||
// Abc_NtkBidecResyn( pNtk, 0 );
|
||||
}
|
||||
|
||||
p->nTotalNodesEnd = Abc_NtkNodeNum(pNtk);
|
||||
p->nTotalEdgesEnd = Abc_NtkGetTotalFanins(pNtk);
|
||||
|
||||
// undo labesl
|
||||
if ( p->pCare )
|
||||
{
|
||||
Abc_NtkForEachCi( pNtk, pObj, i )
|
||||
pObj->pData = NULL;
|
||||
}
|
||||
if ( pPars->fPower )
|
||||
printf( "Total switching after = %7.2f.\n", Abc_NtkMfsTotalSwitching(pNtk) );
|
||||
|
||||
// free the manager
|
||||
p->timeTotal = clock() - clk;
|
||||
Mfs_ManStop( p );
|
||||
return 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
@ -1,567 +0,0 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [mfsResub.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [The good old minimization with complete don't-cares.]
|
||||
|
||||
Synopsis [Procedures to perform resubstitution.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: mfsResub.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "mfsInt.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Updates the network after resubstitution.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NtkMfsUpdateNetwork( Mfs_Man_t * p, Abc_Obj_t * pObj, Vec_Ptr_t * vFanins, Hop_Obj_t * pFunc )
|
||||
{
|
||||
Abc_Obj_t * pObjNew, * pFanin;
|
||||
int k;
|
||||
// create the new node
|
||||
pObjNew = Abc_NtkCreateNode( pObj->pNtk );
|
||||
pObjNew->pData = pFunc;
|
||||
Vec_PtrForEachEntry( vFanins, pFanin, k )
|
||||
Abc_ObjAddFanin( pObjNew, pFanin );
|
||||
// replace the old node by the new node
|
||||
//printf( "Replacing node " ); Abc_ObjPrint( stdout, pObj );
|
||||
//printf( "Inserting node " ); Abc_ObjPrint( stdout, pObjNew );
|
||||
// update the level of the node
|
||||
Abc_NtkUpdate( pObj, pObjNew, p->vLevels );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Prints resub candidate stats.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NtkMfsPrintResubStats( Mfs_Man_t * p )
|
||||
{
|
||||
Abc_Obj_t * pFanin, * pNode;
|
||||
int i, k, nAreaCrits = 0, nAreaExpanse = 0;
|
||||
int nFaninMax = Abc_NtkGetFaninMax(p->pNtk);
|
||||
Abc_NtkForEachNode( p->pNtk, pNode, i )
|
||||
Abc_ObjForEachFanin( pNode, pFanin, k )
|
||||
{
|
||||
if ( !Abc_ObjIsCi(pFanin) && Abc_ObjFanoutNum(pFanin) == 1 )
|
||||
{
|
||||
nAreaCrits++;
|
||||
nAreaExpanse += (int)(Abc_ObjFaninNum(pNode) < nFaninMax);
|
||||
}
|
||||
}
|
||||
printf( "Total area-critical fanins = %d. Belonging to expandable nodes = %d.\n",
|
||||
nAreaCrits, nAreaExpanse );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Tries resubstitution.]
|
||||
|
||||
Description [Returns 1 if it is feasible, or 0 if c-ex is found.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NtkMfsTryResubOnce( Mfs_Man_t * p, int * pCands, int nCands )
|
||||
{
|
||||
unsigned * pData;
|
||||
int RetValue, iVar, i;
|
||||
p->nSatCalls++;
|
||||
RetValue = sat_solver_solve( p->pSat, pCands, pCands + nCands, (sint64)p->pPars->nBTLimit, (sint64)0, (sint64)0, (sint64)0 );
|
||||
// assert( RetValue == l_False || RetValue == l_True );
|
||||
if ( RetValue == l_False )
|
||||
return 1;
|
||||
if ( RetValue != l_True )
|
||||
{
|
||||
p->nTimeOuts++;
|
||||
return -1;
|
||||
}
|
||||
p->nSatCexes++;
|
||||
// store the counter-example
|
||||
Vec_IntForEachEntry( p->vProjVars, iVar, i )
|
||||
{
|
||||
pData = Vec_PtrEntry( p->vDivCexes, i );
|
||||
if ( !sat_solver_var_value( p->pSat, iVar ) ) // remove 0s!!!
|
||||
{
|
||||
assert( Aig_InfoHasBit(pData, p->nCexes) );
|
||||
Aig_InfoXorBit( pData, p->nCexes );
|
||||
}
|
||||
}
|
||||
p->nCexes++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs resubstitution for the node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NtkMfsSolveSatResub( Mfs_Man_t * p, Abc_Obj_t * pNode, int iFanin, int fOnlyRemove, int fSkipUpdate )
|
||||
{
|
||||
int fVeryVerbose = p->pPars->fVeryVerbose && Vec_PtrSize(p->vDivs) < 80;
|
||||
unsigned * pData;
|
||||
int pCands[MFS_FANIN_MAX];
|
||||
int RetValue, iVar, i, nCands, nWords, w;
|
||||
clock_t clk;
|
||||
Abc_Obj_t * pFanin;
|
||||
Hop_Obj_t * pFunc;
|
||||
assert( iFanin >= 0 );
|
||||
|
||||
// clean simulation info
|
||||
Vec_PtrFillSimInfo( p->vDivCexes, 0, p->nDivWords );
|
||||
p->nCexes = 0;
|
||||
if ( fVeryVerbose )
|
||||
{
|
||||
printf( "\n" );
|
||||
printf( "Node %5d : Level = %2d. Divs = %3d. Fanin = %d (out of %d). MFFC = %d\n",
|
||||
pNode->Id, pNode->Level, Vec_PtrSize(p->vDivs)-Abc_ObjFaninNum(pNode),
|
||||
iFanin, Abc_ObjFaninNum(pNode),
|
||||
Abc_ObjFanoutNum(Abc_ObjFanin(pNode, iFanin)) == 1 ? Abc_NodeMffcLabel(Abc_ObjFanin(pNode, iFanin)) : 0 );
|
||||
}
|
||||
|
||||
// try fanins without the critical fanin
|
||||
nCands = 0;
|
||||
Vec_PtrClear( p->vFanins );
|
||||
Abc_ObjForEachFanin( pNode, pFanin, i )
|
||||
{
|
||||
if ( i == iFanin )
|
||||
continue;
|
||||
Vec_PtrPush( p->vFanins, pFanin );
|
||||
iVar = Vec_PtrSize(p->vDivs) - Abc_ObjFaninNum(pNode) + i;
|
||||
pCands[nCands++] = toLitCond( Vec_IntEntry( p->vProjVars, iVar ), 1 );
|
||||
}
|
||||
RetValue = Abc_NtkMfsTryResubOnce( p, pCands, nCands );
|
||||
if ( RetValue == -1 )
|
||||
return 0;
|
||||
if ( RetValue == 1 )
|
||||
{
|
||||
if ( fVeryVerbose )
|
||||
printf( "Node %d: Fanin %d can be removed.\n", pNode->Id, iFanin );
|
||||
p->nNodesResub++;
|
||||
p->nNodesGainedLevel++;
|
||||
if ( fSkipUpdate )
|
||||
return 1;
|
||||
clk = clock();
|
||||
// derive the function
|
||||
pFunc = Abc_NtkMfsInterplate( p, pCands, nCands );
|
||||
if ( pFunc == NULL )
|
||||
return 0;
|
||||
// update the network
|
||||
Abc_NtkMfsUpdateNetwork( p, pNode, p->vFanins, pFunc );
|
||||
p->timeInt += clock() - clk;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ( fOnlyRemove )
|
||||
return 0;
|
||||
|
||||
if ( fVeryVerbose )
|
||||
{
|
||||
for ( i = 0; i < 8; i++ )
|
||||
printf( " " );
|
||||
for ( i = 0; i < Vec_PtrSize(p->vDivs)-Abc_ObjFaninNum(pNode); i++ )
|
||||
printf( "%d", i % 10 );
|
||||
for ( i = 0; i < Abc_ObjFaninNum(pNode); i++ )
|
||||
if ( i == iFanin )
|
||||
printf( "*" );
|
||||
else
|
||||
printf( "%c", 'a' + i );
|
||||
printf( "\n" );
|
||||
}
|
||||
iVar = -1;
|
||||
while ( 1 )
|
||||
{
|
||||
float * pProbab = (float *)(p->vProbs? p->vProbs->pArray : NULL);
|
||||
assert( (pProbab != NULL) == p->pPars->fPower );
|
||||
if ( fVeryVerbose )
|
||||
{
|
||||
printf( "%3d: %2d ", p->nCexes, iVar );
|
||||
for ( i = 0; i < Vec_PtrSize(p->vDivs); i++ )
|
||||
{
|
||||
pData = Vec_PtrEntry( p->vDivCexes, i );
|
||||
printf( "%d", Aig_InfoHasBit(pData, p->nCexes-1) );
|
||||
}
|
||||
printf( "\n" );
|
||||
}
|
||||
|
||||
// find the next divisor to try
|
||||
nWords = Aig_BitWordNum(p->nCexes);
|
||||
assert( nWords <= p->nDivWords );
|
||||
for ( iVar = 0; iVar < Vec_PtrSize(p->vDivs)-Abc_ObjFaninNum(pNode); iVar++ )
|
||||
{
|
||||
if ( p->pPars->fPower )
|
||||
{
|
||||
Abc_Obj_t * pDiv = Vec_PtrEntry(p->vDivs, iVar);
|
||||
// only accept the divisor if it is "cool"
|
||||
if ( pProbab[Abc_ObjId(pDiv)] >= 0.2 )
|
||||
continue;
|
||||
}
|
||||
pData = Vec_PtrEntry( p->vDivCexes, iVar );
|
||||
for ( w = 0; w < nWords; w++ )
|
||||
if ( pData[w] != ~0 )
|
||||
break;
|
||||
if ( w == nWords )
|
||||
break;
|
||||
}
|
||||
if ( iVar == Vec_PtrSize(p->vDivs)-Abc_ObjFaninNum(pNode) )
|
||||
return 0;
|
||||
|
||||
pCands[nCands] = toLitCond( Vec_IntEntry(p->vProjVars, iVar), 1 );
|
||||
RetValue = Abc_NtkMfsTryResubOnce( p, pCands, nCands+1 );
|
||||
if ( RetValue == -1 )
|
||||
return 0;
|
||||
if ( RetValue == 1 )
|
||||
{
|
||||
if ( fVeryVerbose )
|
||||
printf( "Node %d: Fanin %d can be replaced by divisor %d.\n", pNode->Id, iFanin, iVar );
|
||||
p->nNodesResub++;
|
||||
p->nNodesGainedLevel++;
|
||||
if ( fSkipUpdate )
|
||||
return 1;
|
||||
clk = clock();
|
||||
// derive the function
|
||||
pFunc = Abc_NtkMfsInterplate( p, pCands, nCands+1 );
|
||||
if ( pFunc == NULL )
|
||||
return 0;
|
||||
// update the network
|
||||
Vec_PtrPush( p->vFanins, Vec_PtrEntry(p->vDivs, iVar) );
|
||||
Abc_NtkMfsUpdateNetwork( p, pNode, p->vFanins, pFunc );
|
||||
p->timeInt += clock() - clk;
|
||||
return 1;
|
||||
}
|
||||
if ( p->nCexes >= p->pPars->nDivMax )
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs resubstitution for the node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NtkMfsSolveSatResub2( Mfs_Man_t * p, Abc_Obj_t * pNode, int iFanin, int iFanin2 )
|
||||
{
|
||||
int fVeryVerbose = p->pPars->fVeryVerbose && Vec_PtrSize(p->vDivs) < 80;
|
||||
unsigned * pData, * pData2;
|
||||
int pCands[MFS_FANIN_MAX];
|
||||
int RetValue, iVar, iVar2, i, w, nCands, nWords, fBreak;
|
||||
clock_t clk;
|
||||
Abc_Obj_t * pFanin;
|
||||
Hop_Obj_t * pFunc;
|
||||
assert( iFanin >= 0 );
|
||||
assert( iFanin2 >= 0 || iFanin2 == -1 );
|
||||
|
||||
// clean simulation info
|
||||
Vec_PtrFillSimInfo( p->vDivCexes, 0, p->nDivWords );
|
||||
p->nCexes = 0;
|
||||
if ( fVeryVerbose )
|
||||
{
|
||||
printf( "\n" );
|
||||
printf( "Node %5d : Level = %2d. Divs = %3d. Fanins = %d/%d (out of %d). MFFC = %d\n",
|
||||
pNode->Id, pNode->Level, Vec_PtrSize(p->vDivs)-Abc_ObjFaninNum(pNode),
|
||||
iFanin, iFanin2, Abc_ObjFaninNum(pNode),
|
||||
Abc_ObjFanoutNum(Abc_ObjFanin(pNode, iFanin)) == 1 ? Abc_NodeMffcLabel(Abc_ObjFanin(pNode, iFanin)) : 0 );
|
||||
}
|
||||
|
||||
// try fanins without the critical fanin
|
||||
nCands = 0;
|
||||
Vec_PtrClear( p->vFanins );
|
||||
Abc_ObjForEachFanin( pNode, pFanin, i )
|
||||
{
|
||||
if ( i == iFanin || i == iFanin2 )
|
||||
continue;
|
||||
Vec_PtrPush( p->vFanins, pFanin );
|
||||
iVar = Vec_PtrSize(p->vDivs) - Abc_ObjFaninNum(pNode) + i;
|
||||
pCands[nCands++] = toLitCond( Vec_IntEntry( p->vProjVars, iVar ), 1 );
|
||||
}
|
||||
RetValue = Abc_NtkMfsTryResubOnce( p, pCands, nCands );
|
||||
if ( RetValue == -1 )
|
||||
return 0;
|
||||
if ( RetValue == 1 )
|
||||
{
|
||||
if ( fVeryVerbose )
|
||||
printf( "Node %d: Fanins %d/%d can be removed.\n", pNode->Id, iFanin, iFanin2 );
|
||||
p->nNodesResub++;
|
||||
p->nNodesGainedLevel++;
|
||||
clk = clock();
|
||||
// derive the function
|
||||
pFunc = Abc_NtkMfsInterplate( p, pCands, nCands );
|
||||
if ( pFunc == NULL )
|
||||
return 0;
|
||||
// update the network
|
||||
Abc_NtkMfsUpdateNetwork( p, pNode, p->vFanins, pFunc );
|
||||
p->timeInt += clock() - clk;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ( fVeryVerbose )
|
||||
{
|
||||
for ( i = 0; i < 11; i++ )
|
||||
printf( " " );
|
||||
for ( i = 0; i < Vec_PtrSize(p->vDivs)-Abc_ObjFaninNum(pNode); i++ )
|
||||
printf( "%d", i % 10 );
|
||||
for ( i = 0; i < Abc_ObjFaninNum(pNode); i++ )
|
||||
if ( i == iFanin || i == iFanin2 )
|
||||
printf( "*" );
|
||||
else
|
||||
printf( "%c", 'a' + i );
|
||||
printf( "\n" );
|
||||
}
|
||||
iVar = iVar2 = -1;
|
||||
while ( 1 )
|
||||
{
|
||||
if ( fVeryVerbose )
|
||||
{
|
||||
printf( "%3d: %2d %2d ", p->nCexes, iVar, iVar2 );
|
||||
for ( i = 0; i < Vec_PtrSize(p->vDivs); i++ )
|
||||
{
|
||||
pData = Vec_PtrEntry( p->vDivCexes, i );
|
||||
printf( "%d", Aig_InfoHasBit(pData, p->nCexes-1) );
|
||||
}
|
||||
printf( "\n" );
|
||||
}
|
||||
|
||||
// find the next divisor to try
|
||||
nWords = Aig_BitWordNum(p->nCexes);
|
||||
assert( nWords <= p->nDivWords );
|
||||
fBreak = 0;
|
||||
for ( iVar = 1; iVar < Vec_PtrSize(p->vDivs)-Abc_ObjFaninNum(pNode); iVar++ )
|
||||
{
|
||||
pData = Vec_PtrEntry( p->vDivCexes, iVar );
|
||||
for ( iVar2 = 0; iVar2 < iVar; iVar2++ )
|
||||
{
|
||||
pData2 = Vec_PtrEntry( p->vDivCexes, iVar2 );
|
||||
for ( w = 0; w < nWords; w++ )
|
||||
if ( (pData[w] | pData2[w]) != ~0 )
|
||||
break;
|
||||
if ( w == nWords )
|
||||
{
|
||||
fBreak = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( fBreak )
|
||||
break;
|
||||
}
|
||||
if ( iVar == Vec_PtrSize(p->vDivs)-Abc_ObjFaninNum(pNode) )
|
||||
return 0;
|
||||
|
||||
pCands[nCands] = toLitCond( Vec_IntEntry(p->vProjVars, iVar2), 1 );
|
||||
pCands[nCands+1] = toLitCond( Vec_IntEntry(p->vProjVars, iVar), 1 );
|
||||
RetValue = Abc_NtkMfsTryResubOnce( p, pCands, nCands+2 );
|
||||
if ( RetValue == -1 )
|
||||
return 0;
|
||||
if ( RetValue == 1 )
|
||||
{
|
||||
if ( fVeryVerbose )
|
||||
printf( "Node %d: Fanins %d/%d can be replaced by divisors %d/%d.\n", pNode->Id, iFanin, iFanin2, iVar, iVar2 );
|
||||
p->nNodesResub++;
|
||||
p->nNodesGainedLevel++;
|
||||
clk = clock();
|
||||
// derive the function
|
||||
pFunc = Abc_NtkMfsInterplate( p, pCands, nCands+2 );
|
||||
if ( pFunc == NULL )
|
||||
return 0;
|
||||
// update the network
|
||||
Vec_PtrPush( p->vFanins, Vec_PtrEntry(p->vDivs, iVar2) );
|
||||
Vec_PtrPush( p->vFanins, Vec_PtrEntry(p->vDivs, iVar) );
|
||||
assert( Vec_PtrSize(p->vFanins) == nCands + 2 );
|
||||
Abc_NtkMfsUpdateNetwork( p, pNode, p->vFanins, pFunc );
|
||||
p->timeInt += clock() - clk;
|
||||
return 1;
|
||||
}
|
||||
if ( p->nCexes >= p->pPars->nDivMax )
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Evaluates the possibility of replacing given edge by another edge.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NtkMfsEdgeSwapEval( Mfs_Man_t * p, Abc_Obj_t * pNode )
|
||||
{
|
||||
Abc_Obj_t * pFanin;
|
||||
int i;
|
||||
Abc_ObjForEachFanin( pNode, pFanin, i )
|
||||
Abc_NtkMfsSolveSatResub( p, pNode, i, 0, 1 );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Evaluates the possibility of replacing given edge by another edge.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NtkMfsEdgePower( Mfs_Man_t * p, Abc_Obj_t * pNode )
|
||||
{
|
||||
Abc_Obj_t * pFanin;
|
||||
float * pProbab = (float *)p->vProbs->pArray;
|
||||
int i;
|
||||
// try replacing area critical fanins
|
||||
Abc_ObjForEachFanin( pNode, pFanin, i )
|
||||
if ( pProbab[pFanin->Id] >= 0.4 )
|
||||
{
|
||||
if ( Abc_NtkMfsSolveSatResub( p, pNode, i, 0, 0 ) )
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs resubstitution for the node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NtkMfsResubNode( Mfs_Man_t * p, Abc_Obj_t * pNode )
|
||||
{
|
||||
Abc_Obj_t * pFanin;
|
||||
int i;
|
||||
// try replacing area critical fanins
|
||||
Abc_ObjForEachFanin( pNode, pFanin, i )
|
||||
if ( !Abc_ObjIsCi(pFanin) && Abc_ObjFanoutNum(pFanin) == 1 )
|
||||
{
|
||||
if ( Abc_NtkMfsSolveSatResub( p, pNode, i, 0, 0 ) )
|
||||
return 1;
|
||||
}
|
||||
// try removing redundant edges
|
||||
if ( !p->pPars->fArea )
|
||||
{
|
||||
Abc_ObjForEachFanin( pNode, pFanin, i )
|
||||
if ( Abc_ObjIsCi(pFanin) || Abc_ObjFanoutNum(pFanin) != 1 )
|
||||
{
|
||||
if ( Abc_NtkMfsSolveSatResub( p, pNode, i, 1, 0 ) )
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if ( Abc_ObjFaninNum(pNode) == p->nFaninMax )
|
||||
return 0;
|
||||
// try replacing area critical fanins while adding two new fanins
|
||||
Abc_ObjForEachFanin( pNode, pFanin, i )
|
||||
if ( !Abc_ObjIsCi(pFanin) && Abc_ObjFanoutNum(pFanin) == 1 )
|
||||
{
|
||||
if ( Abc_NtkMfsSolveSatResub2( p, pNode, i, -1 ) )
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs resubstitution for the node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NtkMfsResubNode2( Mfs_Man_t * p, Abc_Obj_t * pNode )
|
||||
{
|
||||
Abc_Obj_t * pFanin, * pFanin2;
|
||||
int i, k;
|
||||
/*
|
||||
Abc_ObjForEachFanin( pNode, pFanin, i )
|
||||
if ( !Abc_ObjIsCi(pFanin) && Abc_ObjFanoutNum(pFanin) == 1 )
|
||||
{
|
||||
if ( Abc_NtkMfsSolveSatResub( p, pNode, i, 0, 0 ) )
|
||||
return 1;
|
||||
}
|
||||
*/
|
||||
if ( Abc_ObjFaninNum(pNode) < 2 )
|
||||
return 0;
|
||||
// try replacing one area critical fanin and one other fanin while adding two new fanins
|
||||
Abc_ObjForEachFanin( pNode, pFanin, i )
|
||||
{
|
||||
if ( !Abc_ObjIsCi(pFanin) && Abc_ObjFanoutNum(pFanin) == 1 )
|
||||
{
|
||||
// consider second fanin to remove at the same time
|
||||
Abc_ObjForEachFanin( pNode, pFanin2, k )
|
||||
{
|
||||
if ( i != k && Abc_NtkMfsSolveSatResub2( p, pNode, i, k ) )
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
SRC += src/opt/rar/rewire_rng.c \
|
||||
src/opt/rar/rewire_map.c \
|
||||
src/opt/rar/rewire_rar.c \
|
||||
src/opt/rar/rewire_miaig.cpp
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [rewire_map.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Re-wiring.]
|
||||
|
||||
Synopsis []
|
||||
|
||||
Author [Jiun-Hao Chen]
|
||||
|
||||
Affiliation [National Taiwan University]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: rewire_map.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "rewire_map.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
extern Abc_Ntk_t *Abc_NtkFromAigPhase(Aig_Man_t *pMan);
|
||||
extern Abc_Ntk_t *Abc_NtkDarAmap(Abc_Ntk_t *pNtk, Amap_Par_t *pPars);
|
||||
extern void *Abc_FrameReadLibGen2();
|
||||
extern Vec_Int_t * Abc_NtkWriteMiniMapping( Abc_Ntk_t * pNtk );
|
||||
extern void Abc_NtkPrintMiniMapping( int * pArray );
|
||||
extern Abc_Ntk_t * Abc_NtkFromMiniMapping( int *vMapping );
|
||||
extern Mini_Aig_t * Abc_MiniAigFromNtk ( Abc_Ntk_t *pNtk );
|
||||
|
||||
Abc_Ntk_t *Gia_ManRewirePut(Gia_Man_t *pGia) {
|
||||
Aig_Man_t *pMan = Gia_ManToAig(pGia, 0);
|
||||
Abc_Ntk_t *pNtk = Abc_NtkFromAigPhase(pMan);
|
||||
Aig_ManStop(pMan);
|
||||
return pNtk;
|
||||
}
|
||||
|
||||
Abc_Ntk_t *Abc_ManRewireMap(Abc_Ntk_t *pNtk) {
|
||||
Amap_Par_t Pars, *pPars = &Pars;
|
||||
Amap_ManSetDefaultParams(pPars);
|
||||
Abc_Ntk_t *pNtkMapped = Abc_NtkDarAmap(pNtk, pPars);
|
||||
if (pNtkMapped == NULL) {
|
||||
Abc_NtkDelete(pNtk);
|
||||
Abc_Print(-1, "Mapping has failed.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pNtkMapped;
|
||||
}
|
||||
|
||||
Vec_Int_t *Abc_ManRewireNtkWriteMiniMapping(Abc_Ntk_t *pNtk) {
|
||||
return Abc_NtkWriteMiniMapping(pNtk);
|
||||
}
|
||||
|
||||
Abc_Ntk_t *Abc_ManRewireNtkFromMiniMapping(int *vMapping) {
|
||||
return Abc_NtkFromMiniMapping(vMapping);
|
||||
}
|
||||
|
||||
Mini_Aig_t *Abc_ManRewireMiniAigFromNtk(Abc_Ntk_t *pNtk) {
|
||||
return Abc_MiniAigFromNtk(pNtk);
|
||||
}
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [rewire_map.h]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Re-wiring.]
|
||||
|
||||
Synopsis []
|
||||
|
||||
Author [Jiun-Hao Chen]
|
||||
|
||||
Affiliation [National Taiwan University]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: rewire_map.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef REWIRE_MAP_H
|
||||
#define REWIRE_MAP_H
|
||||
|
||||
#include "base/abc/abc.h"
|
||||
#include "aig/gia/giaAig.h"
|
||||
#include "map/amap/amap.h"
|
||||
#include "map/mio/mio.h"
|
||||
#include "aig/miniaig/miniaig.h"
|
||||
|
||||
ABC_NAMESPACE_HEADER_START
|
||||
|
||||
Abc_Ntk_t *Gia_ManRewirePut(Gia_Man_t *pGia);
|
||||
Abc_Ntk_t *Abc_ManRewireMap(Abc_Ntk_t *pNtk);
|
||||
Vec_Int_t *Abc_ManRewireNtkWriteMiniMapping(Abc_Ntk_t *pNtk);
|
||||
Abc_Ntk_t *Abc_ManRewireNtkFromMiniMapping(int *vMapping);
|
||||
Mini_Aig_t *Abc_ManRewireMiniAigFromNtk(Abc_Ntk_t *pNtk);
|
||||
|
||||
ABC_NAMESPACE_HEADER_END
|
||||
|
||||
#endif // REWIRE_MAP_H
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,493 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [rewire_miaig.h]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Re-wiring.]
|
||||
|
||||
Synopsis []
|
||||
|
||||
Author [Jiun-Hao Chen]
|
||||
|
||||
Affiliation [National Taiwan University]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: rewire_miaig.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef REWIRE_MIAIG_H
|
||||
#define REWIRE_MIAIG_H
|
||||
|
||||
#define RW_ABC
|
||||
|
||||
#ifdef RW_ABC
|
||||
#include "base/abc/abc.h"
|
||||
#include "aig/miniaig/miniaig.h"
|
||||
#include "rewire_map.h"
|
||||
#else
|
||||
#ifdef _WIN32
|
||||
typedef unsigned __int64 word; // 32-bit windows
|
||||
#else
|
||||
typedef long long unsigned word; // other platforms
|
||||
#endif
|
||||
#ifdef _WIN32
|
||||
typedef __int64 iword; // 32-bit windows
|
||||
#else
|
||||
typedef long long iword; // other platforms
|
||||
#endif
|
||||
#endif // RW_ABC
|
||||
#include "rewire_vec.h"
|
||||
#include "rewire_tt.h"
|
||||
#include "rewire_time.h"
|
||||
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
#ifdef RW_ABC
|
||||
ABC_NAMESPACE_CXX_HEADER_START
|
||||
#endif // RW_ABC
|
||||
|
||||
namespace Rewire {
|
||||
|
||||
#if RW_THREADS
|
||||
// exchange-add operation for atomic operations on reference counters
|
||||
#if defined __riscv && !defined __riscv_atomic
|
||||
// riscv target without A extension
|
||||
static inline int RW_XADD(int *addr, int delta) {
|
||||
int tmp = *addr;
|
||||
*addr += delta;
|
||||
return tmp;
|
||||
}
|
||||
#elif defined __INTEL_COMPILER && !(defined WIN32 || defined _WIN32)
|
||||
// atomic increment on the linux version of the Intel(tm) compiler
|
||||
#define RW_XADD(addr, delta) \
|
||||
(int)_InterlockedExchangeAdd( \
|
||||
const_cast<void *>(reinterpret_cast<volatile void *>(addr)), delta)
|
||||
#elif defined __GNUC__
|
||||
#if defined __clang__ && __clang_major__ >= 3 && !defined __ANDROID__ && !defined __EMSCRIPTEN__ && !defined(__CUDACC__)
|
||||
#ifdef __ATOMIC_ACQ_REL
|
||||
#define RW_XADD(addr, delta) \
|
||||
__c11_atomic_fetch_add((_Atomic(int) *)(addr), delta, __ATOMIC_ACQ_REL)
|
||||
#else
|
||||
#define RW_XADD(addr, delta) \
|
||||
__atomic_fetch_add((_Atomic(int) *)(addr), delta, 4)
|
||||
#endif
|
||||
#else
|
||||
#if defined __ATOMIC_ACQ_REL && !defined __clang__
|
||||
// version for gcc >= 4.7
|
||||
#define RW_XADD(addr, delta) \
|
||||
(int)__atomic_fetch_add((unsigned *)(addr), (unsigned)(delta), \
|
||||
__ATOMIC_ACQ_REL)
|
||||
#else
|
||||
#define RW_XADD(addr, delta) \
|
||||
(int)__sync_fetch_and_add((unsigned *)(addr), (unsigned)(delta))
|
||||
#endif
|
||||
#endif
|
||||
#elif defined _MSC_VER && !defined RC_INVOKED
|
||||
#define RW_XADD(addr, delta) \
|
||||
(int)_InterlockedExchangeAdd((long volatile *)addr, delta)
|
||||
#else
|
||||
// thread-unsafe branch
|
||||
static inline int RW_XADD(int *addr, int delta) {
|
||||
int tmp = *addr;
|
||||
*addr += delta;
|
||||
return tmp;
|
||||
}
|
||||
#endif
|
||||
#else // RW_THREADS
|
||||
static inline int RW_XADD(int *addr, int delta) {
|
||||
int tmp = *addr;
|
||||
*addr += delta;
|
||||
return tmp;
|
||||
}
|
||||
#endif // RW_THREADS
|
||||
|
||||
#define Miaig_CustomForEachConstInput(p, i) for (i = 0; i <= p->nIns; i++)
|
||||
#define Miaig_CustomForEachInput(p, i) for (i = 1; i <= p->nIns; i++)
|
||||
#define Miaig_CustomForEachNode(p, i) for (i = 1 + p->nIns; i < p->nObjs - p->nOuts; i++)
|
||||
#define Miaig_CustomForEachNodeReverse(p, i) for (i = p->nObjs - p->nOuts - 1; i > 1 + p->nIns; i--)
|
||||
#define Miaig_CustomForEachInputNode(p, i) for (i = 1; i < p->nObjs - p->nOuts; i++)
|
||||
#define Miaig_CustomForEachNodeStart(p, i, s) for (i = s; i < p->nObjs - p->nOuts; i++)
|
||||
#define Miaig_CustomForEachOutput(p, i) for (i = p->nObjs - p->nOuts; i < p->nObjs; i++)
|
||||
#define Miaig_CustomForEachNodeOutput(p, i) for (i = 1 + p->nIns; i < p->nObjs; i++)
|
||||
#define Miaig_CustomForEachNodeOutputStart(p, i, s) for (i = s; i < p->nObjs; i++)
|
||||
#define Miaig_CustomForEachObj(p, i) for (i = 0; i < p->nObjs; i++)
|
||||
#define Miaig_CustomForEachObjFanin(p, i, iLit, k) Vi_ForEachEntry(&p->pvFans[i], iLit, k)
|
||||
|
||||
#define Miaig_ForEachConstInput(i) for (i = 0; i <= _data->nIns; i++)
|
||||
#define Miaig_ForEachInput(i) for (i = 1; i <= _data->nIns; i++)
|
||||
#define Miaig_ForEachNode(i) for (i = 1 + _data->nIns; i < _data->nObjs - _data->nOuts; i++)
|
||||
#define Miaig_ForEachNodeReverse(i) for (i = _data->nObjs - p->nOuts - 1; i > 1 + _data->nIns; i--)
|
||||
#define Miaig_ForEachInputNode(i) for (i = 1; i < _data->nObjs - _data->nOuts; i++)
|
||||
#define Miaig_ForEachNodeStart(i, s) for (i = s; i < _data->nObjs - _data->nOuts; i++)
|
||||
#define Miaig_ForEachOutput(i) for (i = _data->nObjs - _data->nOuts; i < _data->nObjs; i++)
|
||||
#define Miaig_ForEachNodeOutput(i) for (i = 1 + _data->nIns; i < _data->nObjs; i++)
|
||||
#define Miaig_ForEachNodeOutputStart(i, s) for (i = s; i < _data->nObjs; i++)
|
||||
#define Miaig_ForEachObj(i) for (i = 0; i < _data->nObjs; i++)
|
||||
#define Miaig_ForEachObjFanin(i, iLit, k) Vi_ForEachEntry(&_data->pvFans[i], iLit, k)
|
||||
|
||||
static inline int Rw_Lit2LitV(int *pMapV2V, int Lit) {
|
||||
assert(Lit >= 0);
|
||||
return Abc_Var2Lit(pMapV2V[Abc_Lit2Var(Lit)], Abc_LitIsCompl(Lit));
|
||||
}
|
||||
|
||||
static inline int Rw_Lit2LitL(int *pMapV2L, int Lit) {
|
||||
assert(Lit >= 0);
|
||||
return Abc_LitNotCond(pMapV2L[Abc_Lit2Var(Lit)], Abc_LitIsCompl(Lit));
|
||||
}
|
||||
|
||||
struct Miaig_Data {
|
||||
int refcount; // Reference counter
|
||||
int nIns; // primary inputs
|
||||
int nOuts; // primary outputs
|
||||
int nObjs; // all objects
|
||||
int nObjsAlloc; // allocated space
|
||||
int nWords; // the truth table size
|
||||
int nTravIds; // traversal ID counter
|
||||
int *pTravIds; // traversal IDs
|
||||
int *pCopy; // temp copy
|
||||
int *pRefs; // reference counters
|
||||
int *pLevel; // levels
|
||||
int *pDist; // distances
|
||||
word *pTruths[3]; // truth tables
|
||||
word *pCare; // careset
|
||||
word *pProd; // product
|
||||
vi *vOrder; // node order
|
||||
vi *vOrderF; // fanin order
|
||||
vi *vOrderF2; // fanin order
|
||||
vi *vTfo; // transitive fanout cone
|
||||
vi *pvFans; // the array of objects' fanins
|
||||
int *pTable; // structural hashing table
|
||||
int TableSize; // the size of the hash table
|
||||
float nTransistor; // objective value
|
||||
vi *pNtkMapped; // mapped network
|
||||
};
|
||||
|
||||
class Miaig {
|
||||
public:
|
||||
Miaig(void);
|
||||
~Miaig(void);
|
||||
Miaig(const Miaig &m);
|
||||
Miaig &operator=(const Miaig &m);
|
||||
Miaig(int nIns, int nOuts, int nObjsAlloc);
|
||||
#ifdef RW_ABC
|
||||
Miaig(Gia_Man_t *pGia);
|
||||
Miaig(Abc_Ntk_t *pNtk);
|
||||
Miaig(Mini_Aig_t *pMiniAig);
|
||||
#endif // RW_ABC
|
||||
|
||||
public:
|
||||
void addref(void);
|
||||
void release(void);
|
||||
|
||||
private:
|
||||
void create(int nIns, int nOuts, int nObjsAlloc);
|
||||
|
||||
public:
|
||||
int fromGia(Gia_Man_t *pGia);
|
||||
int fromMiniAig(Mini_Aig_t *pMiniAig);
|
||||
|
||||
public:
|
||||
int &nIns(void);
|
||||
int &nOuts(void);
|
||||
int &nObjs(void);
|
||||
int &nObjsAlloc(void);
|
||||
int objIsPi(int i);
|
||||
int objIsPo(int i);
|
||||
int objIsNode(int i);
|
||||
void print(void);
|
||||
int appendObj(void);
|
||||
void appendFanin(int i, int iLit);
|
||||
int objFaninNum(int i);
|
||||
int objFanin0(int i);
|
||||
int objFanin1(int i);
|
||||
int &objLevel(int i);
|
||||
int &objRef(int i);
|
||||
int &objTravId(int i);
|
||||
int &objCopy(int i);
|
||||
int &objDist(int i);
|
||||
int &nTravIds(void);
|
||||
word *objTruth(int i, int n);
|
||||
int objType(int i);
|
||||
int nWords(void);
|
||||
void refObj(int iObj);
|
||||
void derefObj(int iObj);
|
||||
void derefObj_rec(int iObj, int iLitSkip);
|
||||
|
||||
private:
|
||||
int initializeLevels_rec(int iObj);
|
||||
void initializeLevels(void);
|
||||
void initializeRefs(void);
|
||||
void verifyRefs(void);
|
||||
void initializeTruth(void);
|
||||
void initializeDists(void);
|
||||
|
||||
private:
|
||||
void markDfs_rec(int iObj);
|
||||
int markDfs(void);
|
||||
void markDistanceN_rec(int iObj, int n, int limit);
|
||||
void markDistanceN(int Obj, int n);
|
||||
void topoCollect_rec(int iObj);
|
||||
vi *topoCollect(void);
|
||||
void reduceFanins(vi *v);
|
||||
int *createStops(void);
|
||||
void collectSuper_rec(int iLit, int *pStop, vi *vSuper);
|
||||
int checkConst(int iObj, word *pCare, int fVerbose);
|
||||
void truthSimNode(int i);
|
||||
word *truthSimNodeSubset(int i, int m);
|
||||
word *truthSimNodeSubset2(int i, vi *vFanins, int nFanins);
|
||||
void truthUpdate(vi *vTfo);
|
||||
int computeTfo_rec(int iObj);
|
||||
vi *computeTfo(int iObj);
|
||||
word *computeCareSet(int iObj);
|
||||
vi *createRandomOrder(void);
|
||||
void addPair(vi *vPair, int iFan1, int iFan2);
|
||||
int findPair(vi *vPair);
|
||||
int updateFanins(vi *vFans, int iFan1, int iFan2, int iLit);
|
||||
void extractBest(vi *vPairs);
|
||||
vi *findPairs(word *pSto, int nWords);
|
||||
int findShared(int nNewNodesMax);
|
||||
int hashTwo(int l0, int l1, int TableSize);
|
||||
int *hashLookup(int *pTable, int l0, int l1, int TableSize);
|
||||
|
||||
public:
|
||||
float countAnd2(int reset = 0);
|
||||
float countTransistors(int reset = 0);
|
||||
int countLevel(void);
|
||||
|
||||
private:
|
||||
void dupDfs_rec(Miaig &pNew, int iObj);
|
||||
int buildNodeBalance_rec(Miaig &pNew, vi *vFanins, int begin, int end, int fCprop, int fStrash);
|
||||
|
||||
private:
|
||||
int buildNode(int l0, int l1, int fCprop, int fStrash);
|
||||
int buildNodeBalance(Miaig &pNew, vi *vFanins, int fCprop, int fStrash);
|
||||
int buildNodeCascade(Miaig &pNew, vi *vFanins, int fCprop, int fStrash);
|
||||
|
||||
private:
|
||||
int expandOne(int iObj, int nAddedMax, int nDist, int fVerbose);
|
||||
int reduceOne(int iObj, int fOnlyConst, int fOnlyBuffer, int fHeuristic, int fVerbose);
|
||||
int expandThenReduceOne(int iNode, int nFaninAddLimit, int nDist, int fVerbose);
|
||||
|
||||
public:
|
||||
Miaig dup(int fRemDangle, int fMapped = 0);
|
||||
Miaig dupDfs(void);
|
||||
Miaig dupStrash(int fCprop, int fStrash, int fCascade);
|
||||
Miaig dupMulti(int nFaninMax_, int nGrowth);
|
||||
Miaig expand(int nFaninAddLimitAll, int nDist, int nVerbose);
|
||||
Miaig share(int nNewNodesMax);
|
||||
Miaig reduce(int fVerbose);
|
||||
Miaig expandThenReduce(int nFaninAddLimit, int nDist, int fVerbose);
|
||||
Miaig expandShareReduce(int nFaninAddLimitAll, int nDivs, int nDist, int nVerbose);
|
||||
Miaig rewire(int nIters, int nExpands, int nGrowth, int nDivs, int nFaninMax, int nTimeOut, int nMode, int nDist, int nVerbose);
|
||||
#ifdef RW_ABC
|
||||
Gia_Man_t *toGia(void);
|
||||
Abc_Ntk_t *toNtk(int fMapped = 0);
|
||||
Mini_Aig_t *toMiniAig(void);
|
||||
#endif // RW_ABC
|
||||
|
||||
private:
|
||||
int *_refcount;
|
||||
Miaig_Data *_data;
|
||||
};
|
||||
|
||||
inline Miaig::Miaig(void)
|
||||
: _refcount(nullptr), _data(nullptr) {
|
||||
}
|
||||
|
||||
inline Miaig::Miaig(int nIns, int nOuts, int nObjsAlloc)
|
||||
: Miaig() {
|
||||
create(nIns, nOuts, nObjsAlloc);
|
||||
}
|
||||
|
||||
#ifdef RW_ABC
|
||||
inline Miaig::Miaig(Gia_Man_t *pGia) : Miaig() {
|
||||
fromGia(pGia);
|
||||
}
|
||||
|
||||
inline Miaig::Miaig(Abc_Ntk_t *pNtk) : Miaig() {
|
||||
Mini_Aig_t *pMiniAig = Abc_ManRewireMiniAigFromNtk(pNtk);
|
||||
fromMiniAig(pMiniAig);
|
||||
Mini_AigStop(pMiniAig);
|
||||
}
|
||||
|
||||
inline Miaig::Miaig(Mini_Aig_t *pMiniAig) : Miaig() {
|
||||
fromMiniAig(pMiniAig);
|
||||
}
|
||||
#endif // RW_ABC
|
||||
|
||||
inline Miaig::~Miaig(void) {
|
||||
release();
|
||||
}
|
||||
|
||||
inline Miaig::Miaig(const Miaig &m)
|
||||
: _refcount(m._refcount), _data(m._data) {
|
||||
addref();
|
||||
}
|
||||
|
||||
inline Miaig &Miaig::operator=(const Miaig &m) {
|
||||
if (this == &m) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
if (m._refcount) {
|
||||
RW_XADD(m._refcount, 1);
|
||||
}
|
||||
|
||||
release();
|
||||
|
||||
_refcount = m._refcount;
|
||||
_data = m._data;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline void Miaig::addref(void) {
|
||||
if (_refcount) {
|
||||
RW_XADD(_refcount, 1);
|
||||
}
|
||||
}
|
||||
|
||||
inline void Miaig::release(void) {
|
||||
if (_refcount && RW_XADD(_refcount, -1) == 1) {
|
||||
if (_data) {
|
||||
for (int i = 0; i < _data->nObjsAlloc; ++i)
|
||||
if (_data->pvFans[i].ptr)
|
||||
free(_data->pvFans[i].ptr);
|
||||
free(_data->pvFans);
|
||||
Vi_Free(_data->vOrder);
|
||||
Vi_Free(_data->vOrderF);
|
||||
Vi_Free(_data->vOrderF2);
|
||||
Vi_Free(_data->vTfo);
|
||||
free(_data->pTravIds);
|
||||
free(_data->pCopy);
|
||||
free(_data->pRefs);
|
||||
free(_data->pTruths[0]);
|
||||
if (_data->pCare) free(_data->pCare);
|
||||
if (_data->pProd) free(_data->pProd);
|
||||
if (_data->pLevel) free(_data->pLevel);
|
||||
if (_data->pDist) free(_data->pDist);
|
||||
if (_data->pTable) free(_data->pTable);
|
||||
if (_data->pNtkMapped) Vi_Free(_data->pNtkMapped);
|
||||
delete _data;
|
||||
}
|
||||
}
|
||||
|
||||
_data = nullptr;
|
||||
_refcount = nullptr;
|
||||
}
|
||||
|
||||
inline int &Miaig::nIns(void) {
|
||||
return _data->nIns;
|
||||
}
|
||||
|
||||
inline int &Miaig::nOuts(void) {
|
||||
return _data->nOuts;
|
||||
}
|
||||
|
||||
inline int &Miaig::nObjs(void) {
|
||||
return _data->nObjs;
|
||||
}
|
||||
|
||||
inline int &Miaig::nObjsAlloc(void) {
|
||||
return _data->nObjsAlloc;
|
||||
}
|
||||
|
||||
inline int Miaig::objIsPi(int i) {
|
||||
return i > 0 && i <= _data->nIns;
|
||||
}
|
||||
|
||||
inline int Miaig::objIsPo(int i) {
|
||||
return i >= _data->nObjs - _data->nOuts;
|
||||
}
|
||||
|
||||
inline int Miaig::objIsNode(int i) {
|
||||
return i > _data->nIns && i < _data->nObjs - _data->nOuts;
|
||||
}
|
||||
|
||||
inline int Miaig::appendObj(void) {
|
||||
assert(_data->nObjs < _data->nObjsAlloc);
|
||||
return _data->nObjs++;
|
||||
}
|
||||
|
||||
inline void Miaig::appendFanin(int i, int iLit) {
|
||||
Vi_PushOrder(_data->pvFans + i, iLit);
|
||||
}
|
||||
|
||||
inline int Miaig::objFaninNum(int i) {
|
||||
return Vi_Size(_data->pvFans + i);
|
||||
}
|
||||
|
||||
inline int Miaig::objFanin0(int i) {
|
||||
return Vi_Read(_data->pvFans + i, 0);
|
||||
}
|
||||
|
||||
inline int Miaig::objFanin1(int i) {
|
||||
assert(objFaninNum(i) == 2);
|
||||
return Vi_Read(_data->pvFans + i, 1);
|
||||
}
|
||||
|
||||
inline int &Miaig::objLevel(int i) {
|
||||
return _data->pLevel[i];
|
||||
}
|
||||
|
||||
inline int &Miaig::objRef(int i) {
|
||||
return _data->pRefs[i];
|
||||
}
|
||||
|
||||
inline int &Miaig::objTravId(int i) {
|
||||
return _data->pTravIds[i];
|
||||
}
|
||||
|
||||
inline int &Miaig::objCopy(int i) {
|
||||
return _data->pCopy[i];
|
||||
}
|
||||
|
||||
inline int &Miaig::objDist(int i) {
|
||||
return _data->pDist[i];
|
||||
}
|
||||
|
||||
inline int &Miaig::nTravIds(void) {
|
||||
return _data->nTravIds;
|
||||
}
|
||||
|
||||
inline int Miaig::nWords(void) {
|
||||
return _data->nWords;
|
||||
}
|
||||
|
||||
inline float Miaig::countAnd2(int reset) {
|
||||
int i, Counter = 0;
|
||||
Miaig_ForEachNode(i) {
|
||||
Counter += objFaninNum(i) - 1;
|
||||
}
|
||||
return Counter;
|
||||
}
|
||||
|
||||
inline int Miaig::countLevel(void) {
|
||||
initializeLevels();
|
||||
int i, Level = -1;
|
||||
Miaig_ForEachOutput(i) {
|
||||
Level = Abc_MaxInt(Level, objLevel(i));
|
||||
}
|
||||
return Level;
|
||||
}
|
||||
|
||||
inline word *Miaig::objTruth(int i, int n) {
|
||||
return _data->pTruths[n] + nWords() * i;
|
||||
}
|
||||
|
||||
inline int Miaig::objType(int i) {
|
||||
return objTravId(i) == nTravIds();
|
||||
}
|
||||
|
||||
} // namespace Rewire
|
||||
|
||||
#ifdef RW_ABC
|
||||
ABC_NAMESPACE_CXX_HEADER_END
|
||||
#endif // RW_ABC
|
||||
|
||||
#endif // REWIRE_MIAIG_H
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [rewire_rar.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Re-wiring.]
|
||||
|
||||
Synopsis []
|
||||
|
||||
Author [Jiun-Hao Chen]
|
||||
|
||||
Affiliation [National Taiwan University]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: rewire_rar.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "rewire_rar.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
Gia_Man_t *Gia_ManRewire(Gia_Man_t *pGia, int nIters, int nExpands, int nGrowth, int nDivs, int nFaninMax, int nTimeOut, int nMode, int nDist, int nSeed, int fVerbose) {
|
||||
return Gia_ManRewireInt(pGia, nIters, nExpands, nGrowth, nDivs, nFaninMax, nTimeOut, nMode, nDist, nSeed, fVerbose);
|
||||
}
|
||||
|
||||
Abc_Ntk_t *Abc_ManRewire(Abc_Ntk_t *pNtk, int nIters, int nExpands, int nGrowth, int nDivs, int nFaninMax, int nTimeOut, int nMode, int nDist, int nSeed, int fVerbose) {
|
||||
return Abc_ManRewireInt(pNtk, nIters, nExpands, nGrowth, nDivs, nFaninMax, nTimeOut, nMode, nDist, nSeed, fVerbose);
|
||||
}
|
||||
|
||||
Mini_Aig_t *MiniAig_ManRewire(Mini_Aig_t *pAig, int nIters, int nExpands, int nGrowth, int nDivs, int nFaninMax, int nTimeOut, int nMode, int nDist, int nSeed, int fVerbose) {
|
||||
return MiniAig_ManRewireInt(pAig, nIters, nExpands, nGrowth, nDivs, nFaninMax, nTimeOut, nMode, nDist, nSeed, fVerbose);
|
||||
}
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [rewire_rar.h]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Re-wiring.]
|
||||
|
||||
Synopsis []
|
||||
|
||||
Author [Jiun-Hao Chen]
|
||||
|
||||
Affiliation [National Taiwan University]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: rewire_rar.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef RAR_H
|
||||
#define RAR_H
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// INCLUDES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "base/abc/abc.h"
|
||||
#include "aig/gia/gia.h"
|
||||
#include "aig/miniaig/miniaig.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// PARAMETERS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ABC_NAMESPACE_HEADER_START
|
||||
|
||||
Gia_Man_t *Gia_ManRewire(Gia_Man_t *pGia, int nIters, int nExpands, int nGrowth, int nDivs, int nFaninMax, int nTimeOut, int nMode, int nDist, int nSeed, int fVerbose);
|
||||
Gia_Man_t *Gia_ManRewireInt(Gia_Man_t *pGia, int nIters, int nExpands, int nGrowth, int nDivs, int nFaninMax, int nTimeOut, int nMode, int nDist, int nSeed, int fVerbose);
|
||||
Abc_Ntk_t *Abc_ManRewire(Abc_Ntk_t *pNtk, int nIters, int nExpands, int nGrowth, int nDivs, int nFaninMax, int nTimeOut, int nMode, int nDist, int nSeed, int fVerbose);
|
||||
Abc_Ntk_t *Abc_ManRewireInt(Abc_Ntk_t *pNtk, int nIters, int nExpands, int nGrowth, int nDivs, int nFaninMax, int nTimeOut, int nMode, int nDist, int nSeed, int fVerbose);
|
||||
Mini_Aig_t *MiniAig_ManRewire(Mini_Aig_t *pAig, int nIters, int nExpands, int nGrowth, int nDivs, int nFaninMax, int nTimeOut, int nMode, int nDist, int nSeed, int fVerbose);
|
||||
Mini_Aig_t *MiniAig_ManRewireInt(Mini_Aig_t *pAig, int nIters, int nExpands, int nGrowth, int nDivs, int nFaninMax, int nTimeOut, int nMode, int nDist, int nSeed, int fVerbose);
|
||||
|
||||
ABC_NAMESPACE_HEADER_END
|
||||
|
||||
#endif // RAR_H
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [rewire_rng.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Re-wiring.]
|
||||
|
||||
Synopsis []
|
||||
|
||||
Author [Jiun-Hao Chen]
|
||||
|
||||
Affiliation [National Taiwan University]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: rewire_rng.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "rewire_rng.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
unsigned Random_Int(int fReset) {
|
||||
static unsigned int m_z = NUMBER1;
|
||||
static unsigned int m_w = NUMBER2;
|
||||
if (fReset) {
|
||||
m_z = NUMBER1;
|
||||
m_w = NUMBER2;
|
||||
}
|
||||
m_z = 36969 * (m_z & 65535) + (m_z >> 16);
|
||||
m_w = 18000 * (m_w & 65535) + (m_w >> 16);
|
||||
return (m_z << 16) + m_w;
|
||||
}
|
||||
|
||||
word Random_Word(int fReset) {
|
||||
return ((word)Random_Int(fReset) << 32) | ((word)Random_Int(fReset) << 0);
|
||||
}
|
||||
|
||||
// This procedure should be called once with Seed > 0 to initialize the generator.
|
||||
// After initialization, the generator should be always called with Seed == 0.
|
||||
unsigned Random_Num(int Seed) {
|
||||
static unsigned RandMask = 0;
|
||||
if (Seed == 0)
|
||||
return RandMask ^ Random_Int(0);
|
||||
RandMask = Random_Int(1);
|
||||
for (int i = 0; i < Seed; i++)
|
||||
RandMask = Random_Int(0);
|
||||
return RandMask;
|
||||
}
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [rewire_rng.h]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Re-wiring.]
|
||||
|
||||
Synopsis []
|
||||
|
||||
Author [Jiun-Hao Chen]
|
||||
|
||||
Affiliation [National Taiwan University]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: rewire_rng.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef RAR_RNG_H
|
||||
#define RAR_RNG_H
|
||||
|
||||
/*************************************************************
|
||||
random number generation
|
||||
**************************************************************/
|
||||
|
||||
#include "base/abc/abc.h"
|
||||
|
||||
// Creates a sequence of random numbers.
|
||||
// http://www.codeproject.com/KB/recipes/SimpleRNG.aspx
|
||||
|
||||
ABC_NAMESPACE_HEADER_START
|
||||
|
||||
#define NUMBER1 3716960521u
|
||||
#define NUMBER2 2174103536u
|
||||
|
||||
unsigned Random_Int(int fReset);
|
||||
|
||||
word Random_Word(int fReset);
|
||||
|
||||
// This procedure should be called once with Seed > 0 to initialize the generator.
|
||||
// After initialization, the generator should be always called with Seed == 0.
|
||||
unsigned Random_Num(int Seed);
|
||||
|
||||
ABC_NAMESPACE_HEADER_END
|
||||
|
||||
#endif // RAR_RNG_H
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [rewire_time.h]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Re-wiring.]
|
||||
|
||||
Synopsis []
|
||||
|
||||
Author [Jiun-Hao Chen]
|
||||
|
||||
Affiliation [National Taiwan University]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: rewire_time.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef RAR_TIME_H
|
||||
#define RAR_TIME_H
|
||||
|
||||
/*************************************************************
|
||||
counting wall time
|
||||
**************************************************************/
|
||||
|
||||
#include "base/abc/abc.h"
|
||||
|
||||
ABC_NAMESPACE_HEADER_START
|
||||
|
||||
static inline iword Time_Clock() {
|
||||
#if defined(__APPLE__) && defined(__MACH__)
|
||||
#define APPLE_MACH (__APPLE__ & __MACH__)
|
||||
#else
|
||||
#define APPLE_MACH 0
|
||||
#endif
|
||||
#if (defined(LIN) || defined(LIN64)) && !APPLE_MACH && !defined(__MINGW32__)
|
||||
struct timespec ts;
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &ts) < 0)
|
||||
return (iword)-1;
|
||||
iword res = ((iword)ts.tv_sec) * CLOCKS_PER_SEC;
|
||||
res += (((iword)ts.tv_nsec) * CLOCKS_PER_SEC) / 1000000000;
|
||||
return res;
|
||||
#else
|
||||
return (iword)clock();
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void Time_Print(const char *pStr, iword time) {
|
||||
printf("%s = %10.2f sec", pStr, (float)1.0 * ((double)(time)) / ((double)CLOCKS_PER_SEC));
|
||||
}
|
||||
|
||||
static inline void Time_PrintEndl(const char *pStr, iword time) {
|
||||
Time_Print(pStr, time);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
ABC_NAMESPACE_HEADER_END
|
||||
|
||||
#endif // RAR_TIME_H
|
||||
|
|
@ -0,0 +1,230 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [rewire_tt.h]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Re-wiring.]
|
||||
|
||||
Synopsis []
|
||||
|
||||
Author [Jiun-Hao Chen]
|
||||
|
||||
Affiliation [National Taiwan University]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: rewire_tt.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef RAR_TT_H
|
||||
#define RAR_TT_H
|
||||
|
||||
/*************************************************************
|
||||
truth table manipulation
|
||||
**************************************************************/
|
||||
|
||||
#include "base/abc/abc.h"
|
||||
|
||||
ABC_NAMESPACE_HEADER_START
|
||||
|
||||
// the bit count for the first 256 integer numbers
|
||||
static int Tt_BitCount8[256] = {
|
||||
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
|
||||
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
|
||||
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
|
||||
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
|
||||
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
|
||||
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
|
||||
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
|
||||
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8};
|
||||
|
||||
static inline int Tt_BitCount16(int i) {
|
||||
return Tt_BitCount8[i & 0xFF] + Tt_BitCount8[i >> 8];
|
||||
}
|
||||
|
||||
static word ss_Truths6[6] = {
|
||||
ABC_CONST(0xAAAAAAAAAAAAAAAA),
|
||||
ABC_CONST(0xCCCCCCCCCCCCCCCC),
|
||||
ABC_CONST(0xF0F0F0F0F0F0F0F0),
|
||||
ABC_CONST(0xFF00FF00FF00FF00),
|
||||
ABC_CONST(0xFFFF0000FFFF0000),
|
||||
ABC_CONST(0xFFFFFFFF00000000)};
|
||||
|
||||
static inline int Tt_HexDigitNum(int n) {
|
||||
return n <= 2 ? 1 : 1 << (n - 2);
|
||||
}
|
||||
|
||||
static inline void Tt_Print(word *p, int nWords) {
|
||||
int k, Digit, nDigits = nWords * 16;
|
||||
for (k = nDigits - 1; k >= 0; k--) {
|
||||
Digit = (int)((p[k / 16] >> ((k % 16) * 4)) & 15);
|
||||
if (Digit < 10)
|
||||
printf("%d", Digit);
|
||||
else
|
||||
printf("%c", 'A' + Digit - 10);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static inline int Tt_CountOnes(word x) {
|
||||
x = x - ((x >> 1) & ABC_CONST(0x5555555555555555));
|
||||
x = (x & ABC_CONST(0x3333333333333333)) + ((x >> 2) & ABC_CONST(0x3333333333333333));
|
||||
x = (x + (x >> 4)) & ABC_CONST(0x0F0F0F0F0F0F0F0F);
|
||||
x = x + (x >> 8);
|
||||
x = x + (x >> 16);
|
||||
x = x + (x >> 32);
|
||||
return (int)(x & 0xFF);
|
||||
}
|
||||
|
||||
static inline int Tt_CountOnes2(word x) {
|
||||
return x ? Tt_CountOnes(x) : 0;
|
||||
}
|
||||
|
||||
static inline int Tt_CountOnesVec(word *x, int nWords) {
|
||||
int w, Count = 0;
|
||||
for (w = 0; w < nWords; w++)
|
||||
Count += Tt_CountOnes2(x[w]);
|
||||
return Count;
|
||||
}
|
||||
|
||||
static inline int Tt_CountOnesVecMask(word *x, word *pMask, int nWords) {
|
||||
int w, Count = 0;
|
||||
for (w = 0; w < nWords; w++)
|
||||
Count += Tt_CountOnes2(pMask[w] & x[w]);
|
||||
return Count;
|
||||
}
|
||||
|
||||
static inline void Tt_Clear(word *pOut, int nWords) {
|
||||
int w;
|
||||
for (w = 0; w < nWords; w++)
|
||||
pOut[w] = 0;
|
||||
}
|
||||
|
||||
static inline void Tt_Fill(word *pOut, int nWords) {
|
||||
int w;
|
||||
for (w = 0; w < nWords; w++)
|
||||
pOut[w] = ~(word)0;
|
||||
}
|
||||
|
||||
static inline void Tt_Dup(word *pOut, word *pIn, int nWords) {
|
||||
int w;
|
||||
for (w = 0; w < nWords; w++)
|
||||
pOut[w] = pIn[w];
|
||||
}
|
||||
|
||||
static inline void Tt_DupC(word *pOut, word *pIn, int fC, int nWords) {
|
||||
int w;
|
||||
if (fC)
|
||||
for (w = 0; w < nWords; w++)
|
||||
pOut[w] = ~pIn[w];
|
||||
else
|
||||
for (w = 0; w < nWords; w++)
|
||||
pOut[w] = pIn[w];
|
||||
}
|
||||
|
||||
static inline void Tt_Not(word *pOut, word *pIn, int nWords) {
|
||||
int w;
|
||||
for (w = 0; w < nWords; w++)
|
||||
pOut[w] = ~pIn[w];
|
||||
}
|
||||
|
||||
static inline void Tt_And(word *pOut, word *pIn1, word *pIn2, int nWords) {
|
||||
int w;
|
||||
for (w = 0; w < nWords; w++)
|
||||
pOut[w] = pIn1[w] & pIn2[w];
|
||||
}
|
||||
|
||||
static inline void Tt_Sharp(word *pOut, word *pIn, int fC, int nWords) {
|
||||
int w;
|
||||
if (fC)
|
||||
for (w = 0; w < nWords; w++)
|
||||
pOut[w] &= ~pIn[w];
|
||||
else
|
||||
for (w = 0; w < nWords; w++)
|
||||
pOut[w] &= pIn[w];
|
||||
}
|
||||
|
||||
static inline void Tt_OrXor(word *pOut, word *pIn1, word *pIn2, int nWords) {
|
||||
int w;
|
||||
for (w = 0; w < nWords; w++)
|
||||
pOut[w] |= pIn1[w] ^ pIn2[w];
|
||||
}
|
||||
|
||||
static inline int Tt_WordNum(int n) {
|
||||
return n > 6 ? (1 << (n - 6)) : 1;
|
||||
}
|
||||
|
||||
static inline void Tt_ElemInit(word *pTruth, int iVar, int nWords) {
|
||||
int k;
|
||||
if (iVar < 6)
|
||||
for (k = 0; k < nWords; k++)
|
||||
pTruth[k] = ss_Truths6[iVar];
|
||||
else
|
||||
for (k = 0; k < nWords; k++)
|
||||
pTruth[k] = (k & (1 << (iVar - 6))) ? ~(word)0 : 0;
|
||||
}
|
||||
|
||||
static inline int Tt_IntersectC(word *pIn1, word *pIn2, int fC, int nWords) {
|
||||
int w;
|
||||
if (fC) {
|
||||
for (w = 0; w < nWords; w++)
|
||||
if (pIn1[w] & ~pIn2[w])
|
||||
return 1;
|
||||
} else {
|
||||
for (w = 0; w < nWords; w++)
|
||||
if (pIn1[w] & pIn2[w])
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int Tt_Equal(word *pIn1, word *pIn2, int nWords) {
|
||||
int w;
|
||||
for (w = 0; w < nWords; w++)
|
||||
if (pIn1[w] != pIn2[w])
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline int Tt_EqualOnCare(word *pCare, word *pIn1, word *pIn2, int nWords) {
|
||||
int w;
|
||||
for (w = 0; w < nWords; w++)
|
||||
if (pCare[w] & (pIn1[w] ^ pIn2[w]))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline int Tt_IsConst0(word *pIn, int nWords) {
|
||||
int w;
|
||||
for (w = 0; w < nWords; w++)
|
||||
if (pIn[w])
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline int Tt_IsConst1(word *pIn, int nWords) {
|
||||
int w;
|
||||
for (w = 0; w < nWords; w++)
|
||||
if (pIn[w] != ~(word)0)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// read/write/flip i-th bit of a bit string table:
|
||||
static inline int Tt_GetBit(word *p, int k) {
|
||||
return (int)(p[k >> 6] >> (k & 63)) & 1;
|
||||
}
|
||||
|
||||
static inline void Tt_SetBit(word *p, int k) {
|
||||
p[k >> 6] |= (((word)1) << (k & 63));
|
||||
}
|
||||
|
||||
static inline void Tt_XorBit(word *p, int k) {
|
||||
p[k >> 6] ^= (((word)1) << (k & 63));
|
||||
}
|
||||
|
||||
ABC_NAMESPACE_HEADER_END
|
||||
|
||||
#endif // RAR_TT_H
|
||||
|
|
@ -0,0 +1,226 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [rewire_vec.h]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Re-wiring.]
|
||||
|
||||
Synopsis []
|
||||
|
||||
Author [Jiun-Hao Chen]
|
||||
|
||||
Affiliation [National Taiwan University]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: rewire_vec.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef RAR_VI_H
|
||||
#define RAR_VI_H
|
||||
|
||||
/*************************************************************
|
||||
vector of 32-bit integers
|
||||
**************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "rewire_rng.h"
|
||||
|
||||
ABC_NAMESPACE_HEADER_START
|
||||
|
||||
// swapping two variables
|
||||
#define RW_SWAP(Type, a, b) \
|
||||
{ \
|
||||
Type t = a; \
|
||||
a = b; \
|
||||
b = t; \
|
||||
}
|
||||
|
||||
typedef struct vi_ {
|
||||
int size;
|
||||
int cap;
|
||||
int *ptr;
|
||||
} vi;
|
||||
|
||||
// iterator through the entries in the vector
|
||||
#define Vi_ForEachEntry(v, entry, i) for (i = 0; (i < (v)->size) && (((entry) = Vi_Read((v), i)), 1); i++)
|
||||
#define Vi_ForEachEntryReverse(v, entry, i) for (i = (v)->size - 1; (i >= 0) && (((entry) = Vi_Read((v), i)), 1); i--)
|
||||
#define Vi_ForEachEntryStart(v, entry, i, start) for (i = start; (i < (v)->size) && (((entry) = Vi_Read((v), i)), 1); i++)
|
||||
#define Vi_ForEachEntryStop(v, entry, i, stop) for (i = 0; (i < stop) && (((entry) = Vi_Read((v), i)), 1); i++)
|
||||
|
||||
static inline void Vi_Start(vi *v, int cap) {
|
||||
v->size = 0;
|
||||
v->cap = cap;
|
||||
v->ptr = (int *)malloc(sizeof(int) * cap);
|
||||
}
|
||||
|
||||
static inline vi *Vi_Alloc(int cap) {
|
||||
vi *v = (vi *)malloc(sizeof(vi));
|
||||
Vi_Start(v, cap);
|
||||
return v;
|
||||
}
|
||||
|
||||
static inline void Vi_Stop(vi *v) {
|
||||
if (v->ptr) free(v->ptr);
|
||||
}
|
||||
|
||||
static inline void Vi_Free(vi *v) {
|
||||
if (v->ptr) free(v->ptr);
|
||||
free(v);
|
||||
}
|
||||
|
||||
static inline int Vi_Size(vi *v) {
|
||||
return v->size;
|
||||
}
|
||||
|
||||
static inline int Vi_Space(vi *v) {
|
||||
return v->cap - v->size;
|
||||
}
|
||||
|
||||
static inline int *Vi_Array(vi *v) {
|
||||
return v->ptr;
|
||||
}
|
||||
|
||||
static inline int Vi_Read(vi *v, int k) {
|
||||
assert(k < v->size);
|
||||
return v->ptr[k];
|
||||
}
|
||||
|
||||
static inline void Vi_Write(vi *v, int k, int e) {
|
||||
assert(k < v->size);
|
||||
v->ptr[k] = e;
|
||||
}
|
||||
|
||||
static inline void Vi_Shrink(vi *v, int k) {
|
||||
assert(k <= v->size);
|
||||
v->size = k;
|
||||
} // only safe to shrink !!
|
||||
|
||||
static inline int Vi_Pop(vi *v) {
|
||||
assert(v->size > 0);
|
||||
return v->ptr[--v->size];
|
||||
}
|
||||
|
||||
static inline void Vi_Grow(vi *v) {
|
||||
if (v->size < v->cap)
|
||||
return;
|
||||
int newcap = (v->cap < 4) ? 8 : (v->cap / 2) * 3;
|
||||
v->ptr = (int *)realloc(v->ptr, sizeof(int) * newcap);
|
||||
if (v->ptr == NULL) {
|
||||
printf("Failed to realloc memory from %.1f MB to %.1f MB.\n", 4.0 * v->cap / (1 << 20), (float)4.0 * newcap / (1 << 20));
|
||||
fflush(stdout);
|
||||
}
|
||||
v->cap = newcap;
|
||||
}
|
||||
|
||||
static inline vi *Vi_Dup(vi *v) {
|
||||
vi *pNew = Vi_Alloc(v->size);
|
||||
memcpy(pNew->ptr, v->ptr, sizeof(int) * v->size);
|
||||
pNew->size = v->size;
|
||||
return pNew;
|
||||
}
|
||||
|
||||
static inline void Vi_Push(vi *v, int e) {
|
||||
Vi_Grow(v);
|
||||
v->ptr[v->size++] = e;
|
||||
}
|
||||
|
||||
static inline void Vi_PushTwo(vi *v, int e1, int e2) {
|
||||
Vi_Push(v, e1);
|
||||
Vi_Push(v, e2);
|
||||
}
|
||||
|
||||
static inline void Vi_PushArray(vi *v, int *p, int n) {
|
||||
for (int i = 0; i < n; i++)
|
||||
Vi_Push(v, p[i]);
|
||||
}
|
||||
|
||||
static inline void Vi_PushOrder(vi *v, int e) {
|
||||
Vi_Push(v, e);
|
||||
if (v->size > 1)
|
||||
for (int i = v->size - 2; i >= 0; i--) {
|
||||
if (v->ptr[i] > v->ptr[i + 1]) {
|
||||
RW_SWAP(int, v->ptr[i], v->ptr[i + 1])
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void Vi_Fill(vi *v, int n, int fill) {
|
||||
int i;
|
||||
Vi_Shrink(v, 0);
|
||||
for (i = 0; i < n; i++)
|
||||
Vi_Push(v, fill);
|
||||
}
|
||||
|
||||
static inline int Vi_Drop(vi *v, int i) {
|
||||
assert(i >= 0 && i < v->size);
|
||||
int Entry = v->ptr[i];
|
||||
for (; i < v->size - 1; i++)
|
||||
v->ptr[i] = v->ptr[i + 1];
|
||||
Vi_Shrink(v, v->size - 1);
|
||||
return Entry;
|
||||
}
|
||||
|
||||
static inline int Vi_Find(vi *v, int e) {
|
||||
int j;
|
||||
for (j = 0; j < v->size; j++)
|
||||
if (v->ptr[j] == e)
|
||||
return j;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline int Vi_Remove(vi *v, int e) {
|
||||
int j = Vi_Find(v, e);
|
||||
if (j == -1)
|
||||
return 0;
|
||||
Vi_Drop(v, j);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline void Vi_Randomize(vi *v) {
|
||||
for (int i = 0; i < v->size; i++) {
|
||||
int iRand = Random_Num(0) % v->size;
|
||||
RW_SWAP(int, v->ptr[iRand], v->ptr[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void Vi_Reverse(vi *v) {
|
||||
int i, j;
|
||||
for (i = 0, j = v->size - 1; i < j; i++, j--)
|
||||
RW_SWAP(int, v->ptr[i], v->ptr[j]);
|
||||
}
|
||||
|
||||
static inline void Vi_Print(vi *v) {
|
||||
printf("Array with %d entries:", v->size);
|
||||
int i, entry;
|
||||
Vi_ForEachEntry(v, entry, i)
|
||||
printf(" %d", entry);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static inline void Vi_SelectSort(vi *v) {
|
||||
int *pArray = Vi_Array(v);
|
||||
int nSize = Vi_Size(v);
|
||||
int temp, i, j, best_i;
|
||||
for (i = 0; i < nSize - 1; i++) {
|
||||
best_i = i;
|
||||
for (j = i + 1; j < nSize; j++)
|
||||
if (pArray[j] < pArray[best_i])
|
||||
best_i = j;
|
||||
temp = pArray[i];
|
||||
pArray[i] = pArray[best_i];
|
||||
pArray[best_i] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
ABC_NAMESPACE_HEADER_END
|
||||
|
||||
#endif // RAR_VI_H
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
#pragma once
|
||||
|
||||
#include "rrrAndNetwork.h"
|
||||
#include "rrrScheduler.h"
|
||||
#include "rrrOptimizer.h"
|
||||
#include "rrrBddAnalyzer.h"
|
||||
#include "rrrBddMspfAnalyzer.h"
|
||||
#include "rrrAnalyzer.h"
|
||||
#include "rrrSatSolver.h"
|
||||
#include "rrrSimulator.h"
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_START
|
||||
|
||||
namespace rrr {
|
||||
|
||||
template <typename Ntk>
|
||||
void Perform(Ntk *pNtk, Parameter const *pPar) {
|
||||
assert(!pPar->fUseBddCspf || !pPar->fUseBddMspf);
|
||||
if(pPar->fUseBddCspf) {
|
||||
Scheduler<Ntk, rrr::Optimizer<Ntk, rrr::BddAnalyzer<Ntk>>> sch(pNtk, pPar);
|
||||
sch.Run();
|
||||
} else if(pPar->fUseBddMspf) {
|
||||
Scheduler<Ntk, rrr::Optimizer<Ntk, rrr::BddMspfAnalyzer<Ntk>>> sch(pNtk, pPar);
|
||||
sch.Run();
|
||||
} else {
|
||||
Scheduler<Ntk, rrr::Optimizer<Ntk, rrr::Analyzer<Ntk, rrr::Simulator<Ntk>, rrr::SatSolver<Ntk>>>> sch(pNtk, pPar);
|
||||
sch.Run();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_END
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
#pragma once
|
||||
|
||||
#include "aig/gia/gia.h"
|
||||
#include "base/main/main.h"
|
||||
#include "base/cmd/cmd.h"
|
||||
|
||||
#include "rrrUtils.h"
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_START
|
||||
|
||||
namespace rrr {
|
||||
|
||||
template <typename Ntk>
|
||||
void GiaReader(Gia_Man_t *pGia, Ntk *pNtk) {
|
||||
int i;
|
||||
Gia_Obj_t *pObj;
|
||||
pNtk->Reserve(Gia_ManObjNum(pGia));
|
||||
Gia_ManConst0(pGia)->Value = pNtk->GetConst0();
|
||||
Gia_ManForEachObj1(pGia, pObj, i) {
|
||||
if(Gia_ObjIsCi(pObj)) {
|
||||
pObj->Value = pNtk->AddPi();
|
||||
} else if(Gia_ObjIsCo(pObj)) {
|
||||
pNtk->AddPo(Gia_ObjFanin0(pObj)->Value, Gia_ObjFaninC0(pObj));
|
||||
} else {
|
||||
// TODO: support XOR (and BUF and MUX?), maybe create another function
|
||||
pObj->Value = pNtk->AddAnd(Gia_ObjFanin0(pObj)->Value, Gia_ObjFanin1(pObj)->Value, Gia_ObjFaninC0(pObj), Gia_ObjFaninC1(pObj));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Ntk>
|
||||
Gia_Man_t *CreateGia(Ntk *pNtk) {
|
||||
Gia_Man_t *pGia = Gia_ManStart(pNtk->GetNumNodes());
|
||||
Gia_ManHashStart(pGia);
|
||||
std::vector<int> v(pNtk->GetNumNodes());
|
||||
v[0] = Gia_ManConst0Lit();
|
||||
pNtk->ForEachPi([&](int id) {
|
||||
v[id] = Gia_ManAppendCi(pGia);
|
||||
});
|
||||
pNtk->ForEachInt([&](int id) {
|
||||
assert(pNtk->GetNodeType(id) == rrr::AND);
|
||||
int x = -1;
|
||||
pNtk->ForEachFanin(id, [&](int fi, bool c) {
|
||||
if(x == -1) {
|
||||
x = Abc_LitNotCond(v[fi], c);
|
||||
} else {
|
||||
x = Gia_ManHashAnd(pGia, x, Abc_LitNotCond(v[fi], c));
|
||||
}
|
||||
});
|
||||
if(x == -1) {
|
||||
x = Abc_LitNot(v[0]);
|
||||
}
|
||||
v[id] = x;
|
||||
});
|
||||
pNtk->ForEachPoDriver([&](int fi, bool c) {
|
||||
Gia_ManAppendCo(pGia, Abc_LitNotCond(v[fi], c));
|
||||
});
|
||||
Gia_ManHashStop(pGia);
|
||||
return pGia;
|
||||
}
|
||||
|
||||
template <typename Ntk>
|
||||
void Abc9Execute(Ntk *pNtk, std::string Command) {
|
||||
Abc_Frame_t *pAbc = Abc_FrameGetGlobalFrame();
|
||||
Abc_FrameUpdateGia(pAbc, CreateGia(pNtk));
|
||||
if(Abc_FrameIsBatchMode()) {
|
||||
int r = Cmd_CommandExecute(pAbc, Command.c_str());
|
||||
assert(r == 0);
|
||||
} else {
|
||||
Abc_FrameSetBatchMode(1);
|
||||
int r = Cmd_CommandExecute(pAbc, Command.c_str());
|
||||
assert(r == 0);
|
||||
Abc_FrameSetBatchMode(0);
|
||||
}
|
||||
pNtk->Read(Abc_FrameReadGia(pAbc), GiaReader<Ntk>);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_END
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
#pragma once
|
||||
|
||||
#include "rrrParameter.h"
|
||||
#include "rrrUtils.h"
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_START
|
||||
|
||||
namespace rrr {
|
||||
|
||||
template <typename Ntk, typename Sim, typename Sol>
|
||||
class Analyzer {
|
||||
private:
|
||||
// pointer to network
|
||||
Ntk *pNtk;
|
||||
|
||||
// parameters
|
||||
bool nVerbose;
|
||||
|
||||
// data
|
||||
Sim sim;
|
||||
Sol sol;
|
||||
|
||||
public:
|
||||
// constructors
|
||||
Analyzer(Parameter const *pPar);
|
||||
void UpdateNetwork(Ntk *pNtk_, bool fSame);
|
||||
|
||||
// checks
|
||||
bool CheckRedundancy(int id, int idx);
|
||||
bool CheckFeasibility(int id, int fi, bool c);
|
||||
};
|
||||
|
||||
/* {{{ Constructors */
|
||||
|
||||
template <typename Ntk, typename Sim, typename Sol>
|
||||
Analyzer<Ntk, Sim, Sol>::Analyzer(Parameter const *pPar) :
|
||||
pNtk(NULL),
|
||||
nVerbose(pPar->nAnalyzerVerbose),
|
||||
sim(pPar),
|
||||
sol(pPar) {
|
||||
}
|
||||
|
||||
template <typename Ntk, typename Sim, typename Sol>
|
||||
void Analyzer<Ntk, Sim, Sol>::UpdateNetwork(Ntk *pNtk_, bool fSame) {
|
||||
pNtk = pNtk_;
|
||||
sim.UpdateNetwork(pNtk, fSame);
|
||||
sol.UpdateNetwork(pNtk, fSame);
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ Checks */
|
||||
|
||||
template <typename Ntk, typename Sim, typename Sol>
|
||||
bool Analyzer<Ntk, Sim, Sol>::CheckRedundancy(int id, int idx) {
|
||||
if(sim.CheckRedundancy(id, idx)) {
|
||||
if(nVerbose) {
|
||||
std::cout << "node " << id << " fanin " << (pNtk->GetCompl(id, idx)? "!": "") << pNtk->GetFanin(id, idx) << " index " << idx << " seems redundant" << std::endl;
|
||||
}
|
||||
SatResult r = sol.CheckRedundancy(id, idx);
|
||||
if(r == UNSAT) {
|
||||
if(nVerbose) {
|
||||
std::cout << "node " << id << " fanin " << (pNtk->GetCompl(id, idx)? "!": "") << pNtk->GetFanin(id, idx) << " index " << idx << " is redundant" << std::endl;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if(r == SAT) {
|
||||
if(nVerbose) {
|
||||
std::cout << "node " << id << " fanin " << (pNtk->GetCompl(id, idx)? "!": "") << pNtk->GetFanin(id, idx) << " index " << idx << " is NOT redundant" << std::endl;
|
||||
}
|
||||
sim.AddCex(sol.GetCex());
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Ntk, typename Sim, typename Sol>
|
||||
bool Analyzer<Ntk, Sim, Sol>::CheckFeasibility(int id, int fi, bool c) {
|
||||
if(sim.CheckFeasibility(id, fi, c)) {
|
||||
if(nVerbose) {
|
||||
std::cout << "node " << id << " fanin " << (c? "!": "") << fi << " seems feasible" << std::endl;
|
||||
}
|
||||
SatResult r = sol.CheckFeasibility(id, fi, c);
|
||||
if(r == UNSAT) {
|
||||
if(nVerbose) {
|
||||
std::cout << "node " << id << " fanin " << (c? "!": "") << fi << " is feasible" << std::endl;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if(r == SAT) {
|
||||
if(nVerbose) {
|
||||
std::cout << "node " << id << " fanin " << (c? "!": "") << fi << " is NOT feasible" << std::endl;
|
||||
}
|
||||
sim.AddCex(sol.GetCex());
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
}
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_END
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,634 @@
|
|||
#pragma once
|
||||
|
||||
#include "rrrParameter.h"
|
||||
#include "rrrUtils.h"
|
||||
#include "rrrBddManager.h"
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_START
|
||||
|
||||
namespace rrr {
|
||||
|
||||
template <typename Ntk>
|
||||
class BddAnalyzer {
|
||||
private:
|
||||
// aliases
|
||||
using lit = int;
|
||||
static constexpr lit LitMax = 0xffffffff;
|
||||
|
||||
// pointer to network
|
||||
Ntk *pNtk;
|
||||
|
||||
// parameters
|
||||
int nVerbose;
|
||||
|
||||
// data
|
||||
NewBdd::Man *pBdd;
|
||||
int target;
|
||||
std::vector<lit> vFs;
|
||||
std::vector<lit> vGs;
|
||||
std::vector<std::vector<lit>> vvCs;
|
||||
bool fResim;
|
||||
std::vector<bool> vUpdates;
|
||||
std::vector<bool> vGUpdates;
|
||||
std::vector<bool> vCUpdates;
|
||||
|
||||
// backups
|
||||
std::vector<BddAnalyzer> vBackups;
|
||||
|
||||
// BDD utils
|
||||
void IncRef(lit x) const;
|
||||
void DecRef(lit x) const;
|
||||
void Assign(lit &x, lit y) const;
|
||||
void CopyVec(std::vector<lit> &x, std::vector<lit> const &y) const;
|
||||
void DelVec(std::vector<lit> &v) const;
|
||||
void CopyVecVec(std::vector<std::vector<lit>> &x, std::vector<std::vector<lit>> const &y) const;
|
||||
void DelVecVec(std::vector<std::vector<lit>> &v) const;
|
||||
lit Xor(lit x, lit y) const;
|
||||
|
||||
// callback
|
||||
void ActionCallback(Action const &action);
|
||||
|
||||
// allocation
|
||||
void Allocate();
|
||||
|
||||
// simulation
|
||||
void SimulateNode(int id, std::vector<lit> &v) const;
|
||||
void Simulate();
|
||||
|
||||
// CSPF computation
|
||||
bool ComputeG(int id);
|
||||
void ComputeC(int id);
|
||||
void CspfNode(int id);
|
||||
void Cspf(int id = -1, bool fC = true);
|
||||
|
||||
// save & load
|
||||
void Save(int slot);
|
||||
void Load(int slot);
|
||||
void PopBack();
|
||||
|
||||
public:
|
||||
// constructors
|
||||
BddAnalyzer();
|
||||
BddAnalyzer(Parameter const *pPar);
|
||||
~BddAnalyzer();
|
||||
void UpdateNetwork(Ntk *pNtk_, bool fSame);
|
||||
|
||||
// checks
|
||||
bool CheckRedundancy(int id, int idx);
|
||||
bool CheckFeasibility(int id, int fi, bool c);
|
||||
};
|
||||
|
||||
/* {{{ BDD utils */
|
||||
|
||||
template <typename Ntk>
|
||||
inline void BddAnalyzer<Ntk>::IncRef(lit x) const {
|
||||
if(x != LitMax) {
|
||||
pBdd->IncRef(x);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Ntk>
|
||||
inline void BddAnalyzer<Ntk>::DecRef(lit x) const {
|
||||
if(x != LitMax) {
|
||||
pBdd->DecRef(x);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Ntk>
|
||||
inline void BddAnalyzer<Ntk>::Assign(lit &x, lit y) const {
|
||||
DecRef(x);
|
||||
x = y;
|
||||
IncRef(x);
|
||||
}
|
||||
|
||||
template <typename Ntk>
|
||||
inline void BddAnalyzer<Ntk>::CopyVec(std::vector<lit> &x, std::vector<lit> const &y) const {
|
||||
for(size_t i = y.size(); i < x.size(); i++) {
|
||||
DecRef(x[i]);
|
||||
}
|
||||
x.resize(y.size(), LitMax);
|
||||
for(size_t i = 0; i < y.size(); i++) {
|
||||
if(x[i] != y[i]) {
|
||||
DecRef(x[i]);
|
||||
x[i] = y[i];
|
||||
IncRef(x[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Ntk>
|
||||
inline void BddAnalyzer<Ntk>::DelVec(std::vector<lit> &v) const {
|
||||
for(lit x: v) {
|
||||
DecRef(x);
|
||||
}
|
||||
v.clear();
|
||||
}
|
||||
|
||||
template <typename Ntk>
|
||||
inline void BddAnalyzer<Ntk>::CopyVecVec(std::vector<std::vector<lit>> &x, std::vector<std::vector<lit>> const &y) const {
|
||||
for(size_t i = y.size(); i < x.size(); i++) {
|
||||
DelVec(x[i]);
|
||||
}
|
||||
x.resize(y.size());
|
||||
for(size_t i = 0; i < y.size(); i++) {
|
||||
CopyVec(x[i], y[i]);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Ntk>
|
||||
inline void BddAnalyzer<Ntk>::DelVecVec(std::vector<std::vector<lit>> &v) const {
|
||||
for(size_t i = 0; i < v.size(); i++) {
|
||||
DelVec(v[i]);
|
||||
}
|
||||
v.clear();
|
||||
}
|
||||
|
||||
template <typename Ntk>
|
||||
inline int BddAnalyzer<Ntk>::Xor(lit x, lit y) const {
|
||||
lit f = pBdd->And(x, pBdd->LitNot(y));
|
||||
pBdd->IncRef(f);
|
||||
lit g = pBdd->And(pBdd->LitNot(x), y);
|
||||
pBdd->IncRef(g);
|
||||
lit r = pBdd->Or(f, g);
|
||||
pBdd->DecRef(f);
|
||||
pBdd->DecRef(g);
|
||||
return r;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ Callback */
|
||||
|
||||
template <typename Ntk>
|
||||
void BddAnalyzer<Ntk>::ActionCallback(Action const &action) {
|
||||
switch(action.type) {
|
||||
case REMOVE_FANIN:
|
||||
vUpdates[action.id] = true;
|
||||
vGUpdates[action.fi] = true;
|
||||
DecRef(vvCs[action.id][action.idx]);
|
||||
vvCs[action.id].erase(vvCs[action.id].begin() + action.idx);
|
||||
break;
|
||||
case REMOVE_UNUSED:
|
||||
if(vGUpdates[action.id] || vCUpdates[action.id]) {
|
||||
for(int fi: action.vFanins) {
|
||||
vGUpdates[fi] = true;
|
||||
}
|
||||
}
|
||||
Assign(vFs[action.id], LitMax);
|
||||
Assign(vGs[action.id], LitMax);
|
||||
DelVec(vvCs[action.id]);
|
||||
break;
|
||||
case REMOVE_BUFFER:
|
||||
if(vUpdates[action.id]) {
|
||||
for(int fo: action.vFanouts) {
|
||||
vUpdates[fo] = true;
|
||||
vCUpdates[fo] = true;
|
||||
}
|
||||
}
|
||||
if(vGUpdates[action.id] || vCUpdates[action.id]) {
|
||||
vGUpdates[action.fi] = true;
|
||||
}
|
||||
Assign(vFs[action.id], LitMax);
|
||||
Assign(vGs[action.id], LitMax);
|
||||
DelVec(vvCs[action.id]);
|
||||
break;
|
||||
case REMOVE_CONST:
|
||||
if(vUpdates[action.id]) {
|
||||
for(int fo: action.vFanouts) {
|
||||
vUpdates[fo] = true;
|
||||
vCUpdates[fo] = true;
|
||||
}
|
||||
}
|
||||
for(int fi: action.vFanins) {
|
||||
vGUpdates[fi] = true;
|
||||
}
|
||||
Assign(vFs[action.id], LitMax);
|
||||
Assign(vGs[action.id], LitMax);
|
||||
DelVec(vvCs[action.id]);
|
||||
break;
|
||||
case ADD_FANIN:
|
||||
vUpdates[action.id] = true;
|
||||
vCUpdates[action.id] = true;
|
||||
vvCs[action.id].insert(vvCs[action.id].begin() + action.idx, LitMax);
|
||||
break;
|
||||
case TRIVIAL_COLLAPSE: {
|
||||
if(vGUpdates[action.fi] || vCUpdates[action.fi]) {
|
||||
vCUpdates[action.id] = true;
|
||||
}
|
||||
std::vector<lit>::iterator it = vvCs[action.id].begin() + action.idx;
|
||||
DecRef(*it);
|
||||
it = vvCs[action.id].erase(it);
|
||||
vvCs[action.id].insert(it, vvCs[action.fi].begin(), vvCs[action.fi].end());
|
||||
vvCs[action.fi].clear();
|
||||
Assign(vFs[action.fi], LitMax);
|
||||
Assign(vGs[action.fi], LitMax);
|
||||
break;
|
||||
}
|
||||
case TRIVIAL_DECOMPOSE: {
|
||||
Allocate();
|
||||
SimulateNode(action.fi, vFs);
|
||||
assert(vGs[action.fi] == LitMax);
|
||||
Assign(vGs[action.fi], vGs[action.id]);
|
||||
std::vector<lit>::iterator it = vvCs[action.id].begin() + action.idx;
|
||||
assert(vvCs[action.fi].empty());
|
||||
vvCs[action.fi].insert(vvCs[action.fi].begin(), it, vvCs[action.id].end());
|
||||
vvCs[action.id].erase(it, vvCs[action.id].end());
|
||||
assert(vvCs[action.id].size() == action.idx);
|
||||
vvCs[action.id].resize(action.idx + 1, LitMax);
|
||||
Assign(vvCs[action.id][action.idx], vGs[action.fi]);
|
||||
vUpdates[action.fi] = false;
|
||||
vGUpdates[action.fi] = false;
|
||||
vCUpdates[action.fi] = vCUpdates[action.id];
|
||||
break;
|
||||
}
|
||||
case SORT_FANINS: {
|
||||
std::vector<lit> vCs = vvCs[action.id];
|
||||
vvCs[action.id].clear();
|
||||
for(int index: action.vIndices) {
|
||||
vvCs[action.id].push_back(vCs[index]);
|
||||
}
|
||||
if(!fResim && target != -1 && target != action.id) {
|
||||
pNtk->ForEachTfo(target, false, [&](int fo) {
|
||||
if(fResim) {
|
||||
return;
|
||||
}
|
||||
if(fo == action.id) {
|
||||
fResim = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
vCUpdates[action.id] = true;
|
||||
break;
|
||||
}
|
||||
case SAVE:
|
||||
Save(action.idx);
|
||||
break;
|
||||
case LOAD:
|
||||
Load(action.idx);
|
||||
break;
|
||||
case POP_BACK:
|
||||
PopBack();
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ Allocation */
|
||||
|
||||
template <typename Ntk>
|
||||
void BddAnalyzer<Ntk>::Allocate() {
|
||||
int nNodes = pNtk->GetNumNodes();
|
||||
vFs.resize(nNodes, LitMax);
|
||||
vGs.resize(nNodes, LitMax);
|
||||
vvCs.resize(nNodes);
|
||||
vUpdates.resize(nNodes);
|
||||
vGUpdates.resize(nNodes);
|
||||
vCUpdates.resize(nNodes);
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ Simulation */
|
||||
|
||||
template <typename Ntk>
|
||||
inline void BddAnalyzer<Ntk>::SimulateNode(int id, std::vector<lit> &v) const {
|
||||
if(nVerbose) {
|
||||
std::cout << "simulating node " << id << std::endl;
|
||||
}
|
||||
Assign(v[id], pBdd->Const1());
|
||||
pNtk->ForEachFanin(id, [&](int fi, bool c) {
|
||||
Assign(v[id], pBdd->And(v[id], pBdd->LitNotCond(v[fi], c)));
|
||||
});
|
||||
}
|
||||
|
||||
template <typename Ntk>
|
||||
void BddAnalyzer<Ntk>::Simulate() {
|
||||
if(nVerbose) {
|
||||
std::cout << "symbolic simulation with BDD" << std::endl;
|
||||
}
|
||||
pNtk->ForEachInt([&](int id) {
|
||||
if(vUpdates[id]) {
|
||||
lit x = vFs[id];
|
||||
IncRef(x);
|
||||
SimulateNode(id, vFs);
|
||||
DecRef(x);
|
||||
if(!pBdd->LitIsEq(x, vFs[id])) {
|
||||
pNtk->ForEachFanout(id, false, [&](int fo) {
|
||||
vUpdates[fo] = true;
|
||||
vCUpdates[fo] = true;
|
||||
});
|
||||
}
|
||||
vUpdates[id] = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ CSPF computation */
|
||||
|
||||
template <typename Ntk>
|
||||
inline bool BddAnalyzer<Ntk>::ComputeG(int id) {
|
||||
if(pNtk->GetNumFanouts(id) == 0) {
|
||||
if(pBdd->IsConst1(vGs[id])) {
|
||||
return false;
|
||||
}
|
||||
Assign(vGs[id], pBdd->Const1());
|
||||
return true;
|
||||
}
|
||||
lit x = pBdd->Const1();
|
||||
IncRef(x);
|
||||
pNtk->ForEachFanoutRidx(id, true, [&](int fo, int idx) {
|
||||
Assign(x, pBdd->And(x, vvCs[fo][idx]));
|
||||
});
|
||||
if(pBdd->LitIsEq(vGs[id], x)) {
|
||||
DecRef(x);
|
||||
return false;
|
||||
}
|
||||
Assign(vGs[id], x);
|
||||
DecRef(x);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Ntk>
|
||||
inline void BddAnalyzer<Ntk>::ComputeC(int id) {
|
||||
int nFanins = pNtk->GetNumFanins(id);
|
||||
assert(vvCs[id].size() == nFanins);
|
||||
if(pBdd->IsConst1(vGs[id])) {
|
||||
for(int idx = 0; idx < nFanins; idx++) {
|
||||
if(!pBdd->IsConst1(vvCs[id][idx])) {
|
||||
Assign(vvCs[id][idx], pBdd->Const1());
|
||||
int fi = pNtk->GetFanin(id, idx);
|
||||
vGUpdates[fi] = true;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
for(int idx = 0; idx < nFanins; idx++) {
|
||||
lit x = pBdd->Const1();
|
||||
IncRef(x);
|
||||
for(int idx2 = idx + 1; idx2 < nFanins; idx2++) {
|
||||
int fi = pNtk->GetFanin(id, idx2);
|
||||
bool c = pNtk->GetCompl(id, idx2);
|
||||
Assign(x, pBdd->And(x, pBdd->LitNotCond(vFs[fi], c)));
|
||||
}
|
||||
Assign(x, pBdd->Or(pBdd->LitNot(x), vGs[id]));
|
||||
if(!pBdd->LitIsEq(vvCs[id][idx], x)) {
|
||||
Assign(vvCs[id][idx], x);
|
||||
int fi = pNtk->GetFanin(id, idx);
|
||||
vGUpdates[fi] = true;
|
||||
}
|
||||
DecRef(x);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Ntk>
|
||||
void BddAnalyzer<Ntk>::CspfNode(int id) {
|
||||
if(!vGUpdates[id] && !vCUpdates[id]) {
|
||||
return;
|
||||
}
|
||||
if(vGUpdates[id]) {
|
||||
if(nVerbose) {
|
||||
std::cout << "computing node " << id << " G " << std::endl;
|
||||
}
|
||||
if(ComputeG(id)) {
|
||||
vCUpdates[id] = true;
|
||||
}
|
||||
vGUpdates[id] = false;
|
||||
}
|
||||
if(vCUpdates[id]) {
|
||||
if(nVerbose) {
|
||||
std::cout << "computing node " << id << " C " << std::endl;
|
||||
}
|
||||
ComputeC(id);
|
||||
vCUpdates[id] = false;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Ntk>
|
||||
void BddAnalyzer<Ntk>::Cspf(int id, bool fC) {
|
||||
if(id != -1) {
|
||||
pNtk->ForEachTfoReverse(id, false, [&](int fo) {
|
||||
CspfNode(fo);
|
||||
});
|
||||
bool fCUpdate = vCUpdates[id];
|
||||
if(!fC) {
|
||||
vCUpdates[id] = false;
|
||||
}
|
||||
CspfNode(id);
|
||||
if(!fC) {
|
||||
vCUpdates[id] = fCUpdate;
|
||||
}
|
||||
} else {
|
||||
pNtk->ForEachIntReverse([&](int id) {
|
||||
CspfNode(id);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ Save & load */
|
||||
|
||||
template <typename Ntk>
|
||||
void BddAnalyzer<Ntk>::Save(int slot) {
|
||||
if(slot >= int_size(vBackups)) {
|
||||
vBackups.resize(slot + 1);
|
||||
}
|
||||
vBackups[slot].target = target;
|
||||
CopyVec(vBackups[slot].vFs, vFs);
|
||||
CopyVec(vBackups[slot].vGs, vGs);
|
||||
CopyVecVec(vBackups[slot].vvCs, vvCs);
|
||||
vBackups[slot].vUpdates = vUpdates;
|
||||
vBackups[slot].vGUpdates = vGUpdates;
|
||||
vBackups[slot].vCUpdates = vCUpdates;
|
||||
}
|
||||
|
||||
template <typename Ntk>
|
||||
void BddAnalyzer<Ntk>::Load(int slot) {
|
||||
assert(slot < int_size(vBackups));
|
||||
target = vBackups[slot].target;
|
||||
CopyVec(vFs, vBackups[slot].vFs);
|
||||
CopyVec(vGs, vBackups[slot].vGs);
|
||||
CopyVecVec(vvCs, vBackups[slot].vvCs);
|
||||
vUpdates = vBackups[slot].vUpdates;
|
||||
vGUpdates = vBackups[slot].vGUpdates;
|
||||
vCUpdates = vBackups[slot].vCUpdates;
|
||||
}
|
||||
|
||||
template <typename Ntk>
|
||||
void BddAnalyzer<Ntk>::PopBack() {
|
||||
assert(!vBackups.empty());
|
||||
DelVec(vBackups.back().vFs);
|
||||
DelVec(vBackups.back().vGs);
|
||||
DelVecVec(vBackups.back().vvCs);
|
||||
vBackups.pop_back();
|
||||
}
|
||||
|
||||
/* }}} Save & load end */
|
||||
|
||||
/* {{{ Constructors */
|
||||
|
||||
template <typename Ntk>
|
||||
BddAnalyzer<Ntk>::BddAnalyzer() :
|
||||
pNtk(NULL),
|
||||
nVerbose(0),
|
||||
pBdd(NULL),
|
||||
target(-1),
|
||||
fResim(false) {
|
||||
}
|
||||
|
||||
template <typename Ntk>
|
||||
BddAnalyzer<Ntk>::BddAnalyzer(Parameter const *pPar) :
|
||||
pNtk(NULL),
|
||||
nVerbose(pPar->nAnalyzerVerbose),
|
||||
pBdd(NULL),
|
||||
target(-1),
|
||||
fResim(false) {
|
||||
}
|
||||
|
||||
template <typename Ntk>
|
||||
void BddAnalyzer<Ntk>::UpdateNetwork(Ntk *pNtk_, bool fSame) {
|
||||
// clear
|
||||
while(!vBackups.empty()) {
|
||||
PopBack();
|
||||
}
|
||||
DelVec(vFs);
|
||||
DelVec(vGs);
|
||||
DelVecVec(vvCs);
|
||||
pNtk = pNtk_;
|
||||
target = -1;
|
||||
fResim = false;
|
||||
vUpdates.clear();
|
||||
vGUpdates.clear();
|
||||
vCUpdates.clear();
|
||||
// alloc
|
||||
bool fUseReo = false;
|
||||
if(!pBdd || pBdd->GetNumVars() != pNtk->GetNumPis()) {
|
||||
// need to reset manager
|
||||
delete pBdd;
|
||||
NewBdd::Param Par;
|
||||
Par.nObjsMaxLog = 25;
|
||||
Par.nCacheMaxLog = 20;
|
||||
Par.fCountOnes = true;
|
||||
Par.nGbc = 1;
|
||||
Par.nReo = 4000;
|
||||
pBdd = new NewBdd::Man(pNtk->GetNumPis(), Par);
|
||||
fUseReo = true;
|
||||
} else if(!fSame) {
|
||||
// turning on reordering if network function changed
|
||||
pBdd->TurnOnReo();
|
||||
fUseReo = true;
|
||||
}
|
||||
Allocate();
|
||||
// prepare
|
||||
Assign(vFs[0], pBdd->Const0());
|
||||
int idx = 0;
|
||||
pNtk->ForEachPi([&](int id) {
|
||||
Assign(vFs[id], pBdd->IthVar(idx));
|
||||
idx++;
|
||||
});
|
||||
pNtk->ForEachInt([&](int id) {
|
||||
vUpdates[id] = true;
|
||||
});
|
||||
Simulate();
|
||||
if(fUseReo) {
|
||||
pBdd->Reorder();
|
||||
pBdd->TurnOffReo();
|
||||
}
|
||||
pNtk->ForEachInt([&](int id) {
|
||||
vvCs[id].resize(pNtk->GetNumFanins(id), LitMax);
|
||||
});
|
||||
pNtk->ForEachPo([&](int id) {
|
||||
vvCs[id].resize(1, LitMax);
|
||||
Assign(vvCs[id][0], pBdd->Const0());
|
||||
int fi = pNtk->GetFanin(id, 0);
|
||||
vGUpdates[fi] = true;
|
||||
});
|
||||
pNtk->AddCallback(std::bind(&BddAnalyzer<Ntk>::ActionCallback, this, std::placeholders::_1));
|
||||
}
|
||||
|
||||
template <typename Ntk>
|
||||
BddAnalyzer<Ntk>::~BddAnalyzer() {
|
||||
while(!vBackups.empty()) {
|
||||
PopBack();
|
||||
}
|
||||
DelVec(vFs);
|
||||
DelVec(vGs);
|
||||
DelVecVec(vvCs);
|
||||
if(pBdd) {
|
||||
pBdd->PrintStats();
|
||||
}
|
||||
delete pBdd;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ Checks */
|
||||
|
||||
template <typename Ntk>
|
||||
bool BddAnalyzer<Ntk>::CheckRedundancy(int id, int idx) {
|
||||
if(fResim) {
|
||||
Simulate();
|
||||
}
|
||||
Cspf(id);
|
||||
switch(pNtk->GetNodeType(id)) {
|
||||
case AND: {
|
||||
int fi = pNtk->GetFanin(id, idx);
|
||||
bool c = pNtk->GetCompl(id, idx);
|
||||
lit x = pBdd->Or(pBdd->LitNotCond(vFs[fi], c), vvCs[id][idx]);
|
||||
if(pBdd->IsConst1(x)) {
|
||||
if(nVerbose) {
|
||||
std::cout << "node " << id << " fanin " << (pNtk->GetCompl(id, idx)? "!": "") << pNtk->GetFanin(id, idx) << " index " << idx << " is redundant" << std::endl;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
if(nVerbose) {
|
||||
std::cout << "node " << id << " fanin " << (pNtk->GetCompl(id, idx)? "!": "") << pNtk->GetFanin(id, idx) << " index " << idx << " is NOT redundant" << std::endl;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Ntk>
|
||||
bool BddAnalyzer<Ntk>::CheckFeasibility(int id, int fi, bool c) {
|
||||
if(target != id) { // simualte if there has been update in non-tfo of this node
|
||||
Simulate();
|
||||
target = id;
|
||||
}
|
||||
Cspf(id, false);
|
||||
switch(pNtk->GetNodeType(id)) {
|
||||
case AND: {
|
||||
lit x = pBdd->Or(pBdd->LitNot(vFs[id]), vGs[id]);
|
||||
IncRef(x);
|
||||
lit y = pBdd->Or(x, pBdd->LitNotCond(vFs[fi], c));
|
||||
DecRef(x);
|
||||
if(pBdd->IsConst1(y)) {
|
||||
if(nVerbose) {
|
||||
std::cout << "node " << id << " fanin " << (c? "!": "") << fi << " is feasible" << std::endl;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
if(nVerbose) {
|
||||
std::cout << "node " << id << " fanin " << (c? "!": "") << fi << " is NOT feasible" << std::endl;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
}
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_END
|
||||
|
|
@ -0,0 +1,848 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstdlib>
|
||||
#include <limits>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <cmath>
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_START
|
||||
|
||||
namespace rrr {
|
||||
namespace NewBdd {
|
||||
|
||||
typedef unsigned short var;
|
||||
typedef int bvar;
|
||||
typedef unsigned lit;
|
||||
typedef unsigned short ref;
|
||||
typedef unsigned long long size;
|
||||
typedef unsigned edge;
|
||||
typedef unsigned uniq;
|
||||
typedef unsigned cac;
|
||||
static inline var VarMax() { return std::numeric_limits<var>::max(); }
|
||||
static inline bvar BvarMax() { return std::numeric_limits<bvar>::max(); }
|
||||
static inline lit LitMax() { return std::numeric_limits<lit>::max(); }
|
||||
static inline ref RefMax() { return std::numeric_limits<ref>::max(); }
|
||||
static inline size SizeMax() { return std::numeric_limits<size>::max(); }
|
||||
static inline uniq UniqHash(lit Arg0, lit Arg1) { return Arg0 + 4256249 * Arg1; }
|
||||
static inline cac CacHash(lit Arg0, lit Arg1) { return Arg0 + 4256249 * Arg1; }
|
||||
|
||||
static inline void fatal_error(const char* message) {
|
||||
std::cerr << message << std::endl;
|
||||
std::abort();
|
||||
}
|
||||
|
||||
class Cache {
|
||||
private:
|
||||
cac nSize;
|
||||
cac nMax;
|
||||
cac Mask;
|
||||
size nLookups;
|
||||
size nHits;
|
||||
size nThold;
|
||||
double HitRate;
|
||||
int nVerbose;
|
||||
std::vector<lit> vCache;
|
||||
|
||||
public:
|
||||
Cache(int nCacheSizeLog, int nCacheMaxLog, int nVerbose): nVerbose(nVerbose) {
|
||||
if(nCacheMaxLog < nCacheSizeLog)
|
||||
fatal_error("nCacheMax must not be smaller than nCacheSize");
|
||||
nMax = (cac)1 << nCacheMaxLog;
|
||||
if(!(nMax << 1))
|
||||
fatal_error("Memout (nCacheMax) in init");
|
||||
nSize = (cac)1 << nCacheSizeLog;
|
||||
if(nVerbose)
|
||||
std::cout << "Allocating " << nSize << " cache entries" << std::endl;
|
||||
vCache.resize(nSize * 3);
|
||||
Mask = nSize - 1;
|
||||
nLookups = 0;
|
||||
nHits = 0;
|
||||
nThold = (nSize == nMax)? SizeMax(): nSize;
|
||||
HitRate = 1;
|
||||
}
|
||||
~Cache() {
|
||||
if(nVerbose)
|
||||
std::cout << "Free " << nSize << " cache entries" << std::endl;
|
||||
}
|
||||
inline lit Lookup(lit x, lit y) {
|
||||
nLookups++;
|
||||
if(nLookups > nThold) {
|
||||
double NewHitRate = (double)nHits / nLookups;
|
||||
if(nVerbose >= 2)
|
||||
std::cout << "Cache Hits: " << std::setw(10) << nHits << ", "
|
||||
<< "Lookups: " << std::setw(10) << nLookups << ", "
|
||||
<< "Rate: " << std::setw(10) << NewHitRate
|
||||
<< std::endl;
|
||||
if(NewHitRate > HitRate)
|
||||
Resize();
|
||||
if(nSize == nMax)
|
||||
nThold = SizeMax();
|
||||
else {
|
||||
nThold <<= 1;
|
||||
if(!nThold)
|
||||
nThold = SizeMax();
|
||||
}
|
||||
HitRate = NewHitRate;
|
||||
}
|
||||
cac i = (CacHash(x, y) & Mask) * 3;
|
||||
if(vCache[i] == x && vCache[i + 1] == y) {
|
||||
if(nVerbose >= 3)
|
||||
std::cout << "Cache hit: "
|
||||
<< "x = " << std::setw(10) << x << ", "
|
||||
<< "y = " << std::setw(10) << y << ", "
|
||||
<< "z = " << std::setw(10) << vCache[i + 2] << ", "
|
||||
<< "hash = " << std::hex << (CacHash(x, y) & Mask) << std::dec
|
||||
<< std::endl;
|
||||
nHits++;
|
||||
return vCache[i + 2];
|
||||
}
|
||||
return LitMax();
|
||||
}
|
||||
inline void Insert(lit x, lit y, lit z) {
|
||||
cac i = (CacHash(x, y) & Mask) * 3;
|
||||
vCache[i] = x;
|
||||
vCache[i + 1] = y;
|
||||
vCache[i + 2] = z;
|
||||
if(nVerbose >= 3)
|
||||
std::cout << "Cache ent: "
|
||||
<< "x = " << std::setw(10) << x << ", "
|
||||
<< "y = " << std::setw(10) << y << ", "
|
||||
<< "z = " << std::setw(10) << z << ", "
|
||||
<< "hash = " << std::hex << (CacHash(x, y) & Mask) << std::dec
|
||||
<< std::endl;
|
||||
}
|
||||
inline void Clear() {
|
||||
std::fill(vCache.begin(), vCache.end(), 0);
|
||||
}
|
||||
void Resize() {
|
||||
cac nSizeOld = nSize;
|
||||
nSize <<= 1;
|
||||
if(nVerbose >= 2)
|
||||
std::cout << "Reallocating " << nSize << " cache entries" << std::endl;
|
||||
vCache.resize(nSize * 3);
|
||||
Mask = nSize - 1;
|
||||
for(cac j = 0; j < nSizeOld; j++) {
|
||||
cac i = j * 3;
|
||||
if(vCache[i] || vCache[i + 1]) {
|
||||
cac hash = (CacHash(vCache[i], vCache[i + 1]) & Mask) * 3;
|
||||
vCache[hash] = vCache[i];
|
||||
vCache[hash + 1] = vCache[i + 1];
|
||||
vCache[hash + 2] = vCache[i + 2];
|
||||
if(nVerbose >= 3)
|
||||
std::cout << "Cache mov: "
|
||||
<< "x = " << std::setw(10) << vCache[i] << ", "
|
||||
<< "y = " << std::setw(10) << vCache[i + 1] << ", "
|
||||
<< "z = " << std::setw(10) << vCache[i + 2] << ", "
|
||||
<< "hash = " << std::hex << (CacHash(vCache[i], vCache[i + 1]) & Mask) << std::dec
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct Param {
|
||||
int nObjsAllocLog;
|
||||
int nObjsMaxLog;
|
||||
int nUniqueSizeLog;
|
||||
double UniqueDensity;
|
||||
int nCacheSizeLog;
|
||||
int nCacheMaxLog;
|
||||
int nCacheVerbose;
|
||||
bool fCountOnes;
|
||||
int nGbc;
|
||||
bvar nReo;
|
||||
double MaxGrowth;
|
||||
bool fReoVerbose;
|
||||
int nVerbose;
|
||||
std::vector<var> *pVar2Level;
|
||||
Param() {
|
||||
nObjsAllocLog = 20;
|
||||
nObjsMaxLog = 25;
|
||||
nUniqueSizeLog = 10;
|
||||
UniqueDensity = 4;
|
||||
nCacheSizeLog = 15;
|
||||
nCacheMaxLog = 20;
|
||||
nCacheVerbose = 0;
|
||||
fCountOnes = false;
|
||||
nGbc = 0;
|
||||
nReo = BvarMax();
|
||||
MaxGrowth = 1.2;
|
||||
fReoVerbose = false;
|
||||
nVerbose = 0;
|
||||
pVar2Level = NULL;
|
||||
}
|
||||
};
|
||||
|
||||
class Man {
|
||||
private:
|
||||
var nVars;
|
||||
bvar nObjs;
|
||||
bvar nObjsAlloc;
|
||||
bvar nObjsMax;
|
||||
bvar RemovedHead;
|
||||
int nGbc;
|
||||
bvar nReo;
|
||||
double MaxGrowth;
|
||||
bool fReoVerbose;
|
||||
int nVerbose;
|
||||
std::vector<var> vVars;
|
||||
std::vector<var> Var2Level;
|
||||
std::vector<var> Level2Var;
|
||||
std::vector<lit> vObjs;
|
||||
std::vector<bvar> vNexts;
|
||||
std::vector<bool> vMarks;
|
||||
std::vector<ref> vRefs;
|
||||
std::vector<edge> vEdges;
|
||||
std::vector<double> vOneCounts;
|
||||
std::vector<uniq> vUniqueMasks;
|
||||
std::vector<bvar> vUniqueCounts;
|
||||
std::vector<bvar> vUniqueTholds;
|
||||
std::vector<std::vector<bvar> > vvUnique;
|
||||
Cache *cache;
|
||||
|
||||
public:
|
||||
inline lit Bvar2Lit(bvar a) const { return (lit)a << 1; }
|
||||
inline lit Bvar2Lit(bvar a, bool c) const { return ((lit)a << 1) ^ (lit)c; }
|
||||
inline bvar Lit2Bvar(lit x) const { return (bvar)(x >> 1); }
|
||||
inline var VarOfBvar(bvar a) const { return vVars[a]; }
|
||||
inline lit ThenOfBvar(bvar a) const { return vObjs[Bvar2Lit(a)]; }
|
||||
inline lit ElseOfBvar(bvar a) const { return vObjs[Bvar2Lit(a, true)]; }
|
||||
inline ref RefOfBvar(bvar a) const { return vRefs[a]; }
|
||||
inline lit Const0() const { return (lit)0; }
|
||||
inline lit Const1() const { return (lit)1; }
|
||||
inline bool IsConst0(lit x) const { return x == Const0(); }
|
||||
inline bool IsConst1(lit x) const { return x == Const1(); }
|
||||
inline lit IthVar(var v) const { return Bvar2Lit((bvar)v + 1); }
|
||||
inline lit LitRegular(lit x) const { return x & ~(lit)1; }
|
||||
inline lit LitIrregular(lit x) const { return x | (lit)1; }
|
||||
inline lit LitNot(lit x) const { return x ^ (lit)1; }
|
||||
inline lit LitNotCond(lit x, bool c) const { return x ^ (lit)c; }
|
||||
inline bool LitIsCompl(lit x) const { return x & (lit)1; }
|
||||
inline bool LitIsEq(lit x, lit y) const { return x == y; }
|
||||
inline var Var(lit x) const { return vVars[Lit2Bvar(x)]; }
|
||||
inline var Level(lit x) const { return Var2Level[Var(x)]; }
|
||||
inline lit Then(lit x) const { return LitNotCond(vObjs[LitRegular(x)], LitIsCompl(x)); }
|
||||
inline lit Else(lit x) const { return LitNotCond(vObjs[LitIrregular(x)], LitIsCompl(x)); }
|
||||
inline ref Ref(lit x) const { return vRefs[Lit2Bvar(x)]; }
|
||||
inline double OneCount(lit x) const {
|
||||
if(vOneCounts.empty())
|
||||
fatal_error("fCountOnes was not set");
|
||||
if(LitIsCompl(x))
|
||||
return std::pow(2.0, nVars) - vOneCounts[Lit2Bvar(x)];
|
||||
return vOneCounts[Lit2Bvar(x)];
|
||||
}
|
||||
|
||||
public:
|
||||
inline void IncRef(lit x) { if(!vRefs.empty() && Ref(x) != RefMax()) vRefs[Lit2Bvar(x)]++; }
|
||||
inline void DecRef(lit x) { if(!vRefs.empty() && Ref(x) != RefMax()) vRefs[Lit2Bvar(x)]--; }
|
||||
|
||||
private:
|
||||
inline bool Mark(lit x) const { return vMarks[Lit2Bvar(x)]; }
|
||||
inline edge Edge(lit x) const { return vEdges[Lit2Bvar(x)]; }
|
||||
inline void SetMark(lit x) { vMarks[Lit2Bvar(x)] = true; }
|
||||
inline void ResetMark(lit x) { vMarks[Lit2Bvar(x)] = false; }
|
||||
inline void IncEdge(lit x) { vEdges[Lit2Bvar(x)]++; }
|
||||
inline void DecEdge(lit x) { vEdges[Lit2Bvar(x)]--; }
|
||||
inline bool MarkOfBvar(bvar a) const { return vMarks[a]; }
|
||||
inline edge EdgeOfBvar(bvar a) const { return vEdges[a]; }
|
||||
inline void SetVarOfBvar(bvar a, var v) { vVars[a] = v; }
|
||||
inline void SetThenOfBvar(bvar a, lit x) { vObjs[Bvar2Lit(a)] = x; }
|
||||
inline void SetElseOfBvar(bvar a, lit x) { vObjs[Bvar2Lit(a, true)] = x; }
|
||||
inline void SetMarkOfBvar(bvar a) { vMarks[a] = true; }
|
||||
inline void ResetMarkOfBvar(bvar a) { vMarks[a] = false; }
|
||||
inline void RemoveBvar(bvar a) {
|
||||
var v = VarOfBvar(a);
|
||||
SetVarOfBvar(a, VarMax());
|
||||
std::vector<bvar>::iterator q = vvUnique[v].begin() + (UniqHash(ThenOfBvar(a), ElseOfBvar(a)) & vUniqueMasks[v]);
|
||||
for(; *q; q = vNexts.begin() + *q)
|
||||
if(*q == a)
|
||||
break;
|
||||
bvar next = vNexts[*q];
|
||||
vNexts[*q] = RemovedHead;
|
||||
RemovedHead = *q;
|
||||
*q = next;
|
||||
vUniqueCounts[v]--;
|
||||
}
|
||||
|
||||
private:
|
||||
void SetMark_rec(lit x) {
|
||||
if(x < 2 || Mark(x))
|
||||
return;
|
||||
SetMark(x);
|
||||
SetMark_rec(Then(x));
|
||||
SetMark_rec(Else(x));
|
||||
}
|
||||
void ResetMark_rec(lit x) {
|
||||
if(x < 2 || !Mark(x))
|
||||
return;
|
||||
ResetMark(x);
|
||||
ResetMark_rec(Then(x));
|
||||
ResetMark_rec(Else(x));
|
||||
}
|
||||
bvar CountNodes_rec(lit x) {
|
||||
if(x < 2 || Mark(x))
|
||||
return 0;
|
||||
SetMark(x);
|
||||
return 1 + CountNodes_rec(Then(x)) + CountNodes_rec(Else(x));
|
||||
}
|
||||
void CountEdges_rec(lit x) {
|
||||
if(x < 2)
|
||||
return;
|
||||
IncEdge(x);
|
||||
if(Mark(x))
|
||||
return;
|
||||
SetMark(x);
|
||||
CountEdges_rec(Then(x));
|
||||
CountEdges_rec(Else(x));
|
||||
}
|
||||
void CountEdges() {
|
||||
vEdges.resize(nObjsAlloc);
|
||||
for(bvar a = (bvar)nVars + 1; a < nObjs; a++)
|
||||
if(RefOfBvar(a))
|
||||
CountEdges_rec(Bvar2Lit(a));
|
||||
for(bvar a = 1; a <= (bvar)nVars; a++)
|
||||
vEdges[a]++;
|
||||
for(bvar a = (bvar)nVars + 1; a < nObjs; a++)
|
||||
if(RefOfBvar(a))
|
||||
ResetMark_rec(Bvar2Lit(a));
|
||||
}
|
||||
|
||||
public:
|
||||
bool Resize() {
|
||||
if(nObjsAlloc == nObjsMax)
|
||||
return false;
|
||||
lit nObjsAllocLit = (lit)nObjsAlloc << 1;
|
||||
if(nObjsAllocLit > (lit)BvarMax())
|
||||
nObjsAlloc = BvarMax();
|
||||
else
|
||||
nObjsAlloc = (bvar)nObjsAllocLit;
|
||||
if(nVerbose >= 2)
|
||||
std::cout << "Reallocating " << nObjsAlloc << " nodes" << std::endl;
|
||||
vVars.resize(nObjsAlloc);
|
||||
vObjs.resize((lit)nObjsAlloc * 2);
|
||||
vNexts.resize(nObjsAlloc);
|
||||
vMarks.resize(nObjsAlloc);
|
||||
if(!vRefs.empty())
|
||||
vRefs.resize(nObjsAlloc);
|
||||
if(!vEdges.empty())
|
||||
vEdges.resize(nObjsAlloc);
|
||||
if(!vOneCounts.empty())
|
||||
vOneCounts.resize(nObjsAlloc);
|
||||
return true;
|
||||
}
|
||||
void ResizeUnique(var v) {
|
||||
uniq nUniqueSize, nUniqueSizeOld;
|
||||
nUniqueSize = nUniqueSizeOld = vvUnique[v].size();
|
||||
nUniqueSize <<= 1;
|
||||
if(!nUniqueSize) {
|
||||
vUniqueTholds[v] = BvarMax();
|
||||
return;
|
||||
}
|
||||
if(nVerbose >= 2)
|
||||
std::cout << "Reallocating " << nUniqueSize << " unique table entries for Var " << v << std::endl;
|
||||
vvUnique[v].resize(nUniqueSize);
|
||||
vUniqueMasks[v] = nUniqueSize - 1;
|
||||
for(uniq i = 0; i < nUniqueSizeOld; i++) {
|
||||
std::vector<bvar>::iterator q, tail, tail1, tail2;
|
||||
q = tail1 = vvUnique[v].begin() + i;
|
||||
tail2 = q + nUniqueSizeOld;
|
||||
while(*q) {
|
||||
uniq hash = UniqHash(ThenOfBvar(*q), ElseOfBvar(*q)) & vUniqueMasks[v];
|
||||
if(hash == i)
|
||||
tail = tail1;
|
||||
else
|
||||
tail = tail2;
|
||||
if(tail != q)
|
||||
*tail = *q, *q = 0;
|
||||
q = vNexts.begin() + *tail;
|
||||
if(tail == tail1)
|
||||
tail1 = q;
|
||||
else
|
||||
tail2 = q;
|
||||
}
|
||||
}
|
||||
vUniqueTholds[v] <<= 1;
|
||||
if((lit)vUniqueTholds[v] > (lit)BvarMax())
|
||||
vUniqueTholds[v] = BvarMax();
|
||||
}
|
||||
bool Gbc() {
|
||||
if(nVerbose >= 2)
|
||||
std::cout << "Garbage collect" << std::endl;
|
||||
if(!vEdges.empty()) {
|
||||
for(bvar a = (bvar)nVars + 1; a < nObjs; a++)
|
||||
if(!EdgeOfBvar(a) && VarOfBvar(a) != VarMax())
|
||||
RemoveBvar(a);
|
||||
} else {
|
||||
for(bvar a = (bvar)nVars + 1; a < nObjs; a++)
|
||||
if(RefOfBvar(a))
|
||||
SetMark_rec(Bvar2Lit(a));
|
||||
for(bvar a = (bvar)nVars + 1; a < nObjs; a++)
|
||||
if(!MarkOfBvar(a) && VarOfBvar(a) != VarMax())
|
||||
RemoveBvar(a);
|
||||
for(bvar a = (bvar)nVars + 1; a < nObjs; a++)
|
||||
if(RefOfBvar(a))
|
||||
ResetMark_rec(Bvar2Lit(a));
|
||||
}
|
||||
cache->Clear();
|
||||
return RemovedHead;
|
||||
}
|
||||
|
||||
private:
|
||||
inline lit UniqueCreateInt(var v, lit x1, lit x0) {
|
||||
std::vector<bvar>::iterator p, q;
|
||||
p = q = vvUnique[v].begin() + (UniqHash(x1, x0) & vUniqueMasks[v]);
|
||||
for(; *q; q = vNexts.begin() + *q)
|
||||
if(VarOfBvar(*q) == v && ThenOfBvar(*q) == x1 && ElseOfBvar(*q) == x0)
|
||||
return Bvar2Lit(*q);
|
||||
bvar next = *p;
|
||||
if(nObjs < nObjsAlloc)
|
||||
*p = nObjs++;
|
||||
else if(RemovedHead)
|
||||
*p = RemovedHead, RemovedHead = vNexts[*p];
|
||||
else
|
||||
return LitMax();
|
||||
SetVarOfBvar(*p, v);
|
||||
SetThenOfBvar(*p, x1);
|
||||
SetElseOfBvar(*p, x0);
|
||||
vNexts[*p] = next;
|
||||
if(!vOneCounts.empty())
|
||||
vOneCounts[*p] = OneCount(x1) / 2 + OneCount(x0) / 2;
|
||||
if(nVerbose >= 3) {
|
||||
std::cout << "Create node " << std::setw(10) << *p << ": "
|
||||
<< "Var = " << std::setw(6) << v << ", "
|
||||
<< "Then = " << std::setw(10) << x1 << ", "
|
||||
<< "Else = " << std::setw(10) << x0;
|
||||
if(!vOneCounts.empty())
|
||||
std::cout << ", Ones = " << std::setw(10) << vOneCounts[*q];
|
||||
std::cout << std::endl;
|
||||
}
|
||||
vUniqueCounts[v]++;
|
||||
if(vUniqueCounts[v] > vUniqueTholds[v]) {
|
||||
bvar a = *p;
|
||||
ResizeUnique(v);
|
||||
return Bvar2Lit(a);
|
||||
}
|
||||
return Bvar2Lit(*p);
|
||||
}
|
||||
inline lit UniqueCreate(var v, lit x1, lit x0) {
|
||||
if(x1 == x0)
|
||||
return x1;
|
||||
lit x;
|
||||
while(true) {
|
||||
if(!LitIsCompl(x0))
|
||||
x = UniqueCreateInt(v, x1, x0);
|
||||
else
|
||||
x = UniqueCreateInt(v, LitNot(x1), LitNot(x0));
|
||||
if(x == LitMax()) {
|
||||
bool fRemoved = false;
|
||||
if(nGbc > 1)
|
||||
fRemoved = Gbc();
|
||||
if(!Resize() && !fRemoved && (nGbc != 1 || !Gbc()))
|
||||
fatal_error("Memout (node)");
|
||||
} else
|
||||
break;
|
||||
}
|
||||
return LitIsCompl(x0)? LitNot(x): x;
|
||||
}
|
||||
lit And_rec(lit x, lit y) {
|
||||
if(x == 0 || y == 1)
|
||||
return x;
|
||||
if(x == 1 || y == 0)
|
||||
return y;
|
||||
if(Lit2Bvar(x) == Lit2Bvar(y))
|
||||
return (x == y)? x: 0;
|
||||
if(x > y)
|
||||
std::swap(x, y);
|
||||
lit z = cache->Lookup(x, y);
|
||||
if(z != LitMax())
|
||||
return z;
|
||||
var v;
|
||||
lit x0, x1, y0, y1;
|
||||
if(Level(x) < Level(y))
|
||||
v = Var(x), x1 = Then(x), x0 = Else(x), y0 = y1 = y;
|
||||
else if(Level(x) > Level(y))
|
||||
v = Var(y), x0 = x1 = x, y1 = Then(y), y0 = Else(y);
|
||||
else
|
||||
v = Var(x), x1 = Then(x), x0 = Else(x), y1 = Then(y), y0 = Else(y);
|
||||
lit z1 = And_rec(x1, y1);
|
||||
IncRef(z1);
|
||||
lit z0 = And_rec(x0, y0);
|
||||
IncRef(z0);
|
||||
z = UniqueCreate(v, z1, z0);
|
||||
DecRef(z1);
|
||||
DecRef(z0);
|
||||
cache->Insert(x, y, z);
|
||||
return z;
|
||||
}
|
||||
|
||||
private:
|
||||
bvar Swap(var i) {
|
||||
var v1 = Level2Var[i];
|
||||
var v2 = Level2Var[i + 1];
|
||||
bvar f = 0;
|
||||
bvar diff = 0;
|
||||
for(std::vector<bvar>::iterator p = vvUnique[v1].begin(); p != vvUnique[v1].end(); p++) {
|
||||
std::vector<bvar>::iterator q = p;
|
||||
while(*q) {
|
||||
if(!EdgeOfBvar(*q)) {
|
||||
SetVarOfBvar(*q, VarMax());
|
||||
bvar next = vNexts[*q];
|
||||
vNexts[*q] = RemovedHead;
|
||||
RemovedHead = *q;
|
||||
*q = next;
|
||||
vUniqueCounts[v1]--;
|
||||
continue;
|
||||
}
|
||||
lit f1 = ThenOfBvar(*q);
|
||||
lit f0 = ElseOfBvar(*q);
|
||||
if(Var(f1) == v2 || Var(f0) == v2) {
|
||||
DecEdge(f1);
|
||||
if(Var(f1) == v2 && !Edge(f1))
|
||||
DecEdge(Then(f1)), DecEdge(Else(f1)), diff--;
|
||||
DecEdge(f0);
|
||||
if(Var(f0) == v2 && !Edge(f0))
|
||||
DecEdge(Then(f0)), DecEdge(Else(f0)), diff--;
|
||||
bvar next = vNexts[*q];
|
||||
vNexts[*q] = f;
|
||||
f = *q;
|
||||
*q = next;
|
||||
vUniqueCounts[v1]--;
|
||||
continue;
|
||||
}
|
||||
q = vNexts.begin() + *q;
|
||||
}
|
||||
}
|
||||
while(f) {
|
||||
lit f1 = ThenOfBvar(f);
|
||||
lit f0 = ElseOfBvar(f);
|
||||
lit f00, f01, f10, f11;
|
||||
if(Var(f1) == v2)
|
||||
f11 = Then(f1), f10 = Else(f1);
|
||||
else
|
||||
f10 = f11 = f1;
|
||||
if(Var(f0) == v2)
|
||||
f01 = Then(f0), f00 = Else(f0);
|
||||
else
|
||||
f00 = f01 = f0;
|
||||
if(f11 == f01)
|
||||
f1 = f11;
|
||||
else {
|
||||
f1 = UniqueCreate(v1, f11, f01);
|
||||
if(!Edge(f1))
|
||||
IncEdge(f11), IncEdge(f01), diff++;
|
||||
}
|
||||
IncEdge(f1);
|
||||
IncRef(f1);
|
||||
if(f10 == f00)
|
||||
f0 = f10;
|
||||
else {
|
||||
f0 = UniqueCreate(v1, f10, f00);
|
||||
if(!Edge(f0))
|
||||
IncEdge(f10), IncEdge(f00), diff++;
|
||||
}
|
||||
IncEdge(f0);
|
||||
DecRef(f1);
|
||||
SetVarOfBvar(f, v2);
|
||||
SetThenOfBvar(f, f1);
|
||||
SetElseOfBvar(f, f0);
|
||||
std::vector<bvar>::iterator q = vvUnique[v2].begin() + (UniqHash(f1, f0) & vUniqueMasks[v2]);
|
||||
lit next = vNexts[f];
|
||||
vNexts[f] = *q;
|
||||
*q = f;
|
||||
vUniqueCounts[v2]++;
|
||||
f = next;
|
||||
}
|
||||
Var2Level[v1] = i + 1;
|
||||
Var2Level[v2] = i;
|
||||
Level2Var[i] = v2;
|
||||
Level2Var[i + 1] = v1;
|
||||
return diff;
|
||||
}
|
||||
void Sift() {
|
||||
bvar count = CountNodes();
|
||||
std::vector<var> sift_order(nVars);
|
||||
for(var v = 0; v < nVars; v++)
|
||||
sift_order[v] = v;
|
||||
for(var i = 0; i < nVars; i++) {
|
||||
var max_j = i;
|
||||
for(var j = i + 1; j < nVars; j++)
|
||||
if(vUniqueCounts[sift_order[j]] > vUniqueCounts[sift_order[max_j]])
|
||||
max_j = j;
|
||||
if(max_j != i)
|
||||
std::swap(sift_order[max_j], sift_order[i]);
|
||||
}
|
||||
for(var v = 0; v < nVars; v++) {
|
||||
bvar lev = Var2Level[sift_order[v]];
|
||||
bool UpFirst = lev < (bvar)(nVars / 2);
|
||||
bvar min_lev = lev;
|
||||
bvar min_diff = 0;
|
||||
bvar diff = 0;
|
||||
bvar thold = count * (MaxGrowth - 1);
|
||||
if(fReoVerbose)
|
||||
std::cout << "Sift " << sift_order[v] << " : Level = " << lev << " Count = " << count << " Thold = " << thold << std::endl;
|
||||
if(UpFirst) {
|
||||
lev--;
|
||||
for(; lev >= 0; lev--) {
|
||||
diff += Swap(lev);
|
||||
if(fReoVerbose)
|
||||
std::cout << "\tSwap " << lev << " : Diff = " << diff << " Thold = " << thold << std::endl;
|
||||
if(diff < min_diff)
|
||||
min_lev = lev, min_diff = diff, thold = (count + diff) * (MaxGrowth - 1);
|
||||
else if(diff > thold) {
|
||||
lev--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
lev++;
|
||||
}
|
||||
for(; lev < (bvar)nVars - 1; lev++) {
|
||||
diff += Swap(lev);
|
||||
if(fReoVerbose)
|
||||
std::cout << "\tSwap " << lev << " : Diff = " << diff << " Thold = " << thold << std::endl;
|
||||
if(diff <= min_diff)
|
||||
min_lev = lev + 1, min_diff = diff, thold = (count + diff) * (MaxGrowth - 1);
|
||||
else if(diff > thold) {
|
||||
lev++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
lev--;
|
||||
if(UpFirst) {
|
||||
for(; lev >= min_lev; lev--) {
|
||||
diff += Swap(lev);
|
||||
if(fReoVerbose)
|
||||
std::cout << "\tSwap " << lev << " : Diff = " << diff << " Thold = " << thold << std::endl;
|
||||
}
|
||||
} else {
|
||||
for(; lev >= 0; lev--) {
|
||||
diff += Swap(lev);
|
||||
if(fReoVerbose)
|
||||
std::cout << "\tSwap " << lev << " : Diff = " << diff << " Thold = " << thold << std::endl;
|
||||
if(diff <= min_diff)
|
||||
min_lev = lev, min_diff = diff, thold = (count + diff) * (MaxGrowth - 1);
|
||||
else if(diff > thold) {
|
||||
lev--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
lev++;
|
||||
for(; lev < min_lev; lev++) {
|
||||
diff += Swap(lev);
|
||||
if(fReoVerbose)
|
||||
std::cout << "\tSwap " << lev << " : Diff = " << diff << " Thold = " << thold << std::endl;
|
||||
}
|
||||
}
|
||||
count += min_diff;
|
||||
if(fReoVerbose)
|
||||
std::cout << "Sifted " << sift_order[v] << " : Level = " << min_lev << " Count = " << count << " Thold = " << thold << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
Man(int nVars_, Param p) {
|
||||
nVerbose = p.nVerbose;
|
||||
// parameter sanity check
|
||||
if(p.nObjsMaxLog < p.nObjsAllocLog)
|
||||
fatal_error("nObjsMax must not be smaller than nObjsAlloc");
|
||||
if(nVars_ >= (int)VarMax())
|
||||
fatal_error("Memout (nVars) in init");
|
||||
nVars = nVars_;
|
||||
lit nObjsMaxLit = (lit)1 << p.nObjsMaxLog;
|
||||
if(!nObjsMaxLit)
|
||||
fatal_error("Memout (nObjsMax) in init");
|
||||
if(nObjsMaxLit > (lit)BvarMax())
|
||||
nObjsMax = BvarMax();
|
||||
else
|
||||
nObjsMax = (bvar)nObjsMaxLit;
|
||||
lit nObjsAllocLit = (lit)1 << p.nObjsAllocLog;
|
||||
if(!nObjsAllocLit)
|
||||
fatal_error("Memout (nObjsAlloc) in init");
|
||||
if(nObjsAllocLit > (lit)BvarMax())
|
||||
nObjsAlloc = BvarMax();
|
||||
else
|
||||
nObjsAlloc = (bvar)nObjsAllocLit;
|
||||
if(nObjsAlloc <= (bvar)nVars)
|
||||
fatal_error("nObjsAlloc must be larger than nVars");
|
||||
uniq nUniqueSize = (uniq)1 << p.nUniqueSizeLog;
|
||||
if(!nUniqueSize)
|
||||
fatal_error("Memout (nUniqueSize) in init");
|
||||
// allocation
|
||||
if(nVerbose)
|
||||
std::cout << "Allocating " << nObjsAlloc << " nodes and " << nVars << " x " << nUniqueSize << " unique table entries" << std::endl;
|
||||
vVars.resize(nObjsAlloc);
|
||||
vObjs.resize((lit)nObjsAlloc * 2);
|
||||
vNexts.resize(nObjsAlloc);
|
||||
vMarks.resize(nObjsAlloc);
|
||||
vvUnique.resize(nVars);
|
||||
vUniqueMasks.resize(nVars);
|
||||
vUniqueCounts.resize(nVars);
|
||||
vUniqueTholds.resize(nVars);
|
||||
for(var v = 0; v < nVars; v++) {
|
||||
vvUnique[v].resize(nUniqueSize);
|
||||
vUniqueMasks[v] = nUniqueSize - 1;
|
||||
if((lit)(nUniqueSize * p.UniqueDensity) > (lit)BvarMax())
|
||||
vUniqueTholds[v] = BvarMax();
|
||||
else
|
||||
vUniqueTholds[v] = (bvar)(nUniqueSize * p.UniqueDensity);
|
||||
}
|
||||
if(p.fCountOnes) {
|
||||
if(nVars > 1023)
|
||||
fatal_error("nVars must be less than 1024 to count ones");
|
||||
vOneCounts.resize(nObjsAlloc);
|
||||
}
|
||||
// set up cache
|
||||
cache = new Cache(p.nCacheSizeLog, p.nCacheMaxLog, p.nCacheVerbose);
|
||||
// create nodes for variables
|
||||
nObjs = 1;
|
||||
vVars[0] = VarMax();
|
||||
for(var v = 0; v < nVars; v++)
|
||||
UniqueCreateInt(v, 1, 0);
|
||||
// set up variable order
|
||||
Var2Level.resize(nVars);
|
||||
Level2Var.resize(nVars);
|
||||
for(var v = 0; v < nVars; v++) {
|
||||
if(p.pVar2Level)
|
||||
Var2Level[v] = (*p.pVar2Level)[v];
|
||||
else
|
||||
Var2Level[v] = v;
|
||||
Level2Var[Var2Level[v]] = v;
|
||||
}
|
||||
// set other parameters
|
||||
RemovedHead = 0;
|
||||
nGbc = p.nGbc;
|
||||
nReo = p.nReo;
|
||||
MaxGrowth = p.MaxGrowth;
|
||||
fReoVerbose = p.fReoVerbose;
|
||||
if(nGbc || nReo != BvarMax())
|
||||
vRefs.resize(nObjsAlloc);
|
||||
}
|
||||
~Man() {
|
||||
if(nVerbose) {
|
||||
std::cout << "Free " << nObjsAlloc << " nodes (" << nObjs << " live nodes)" << std::endl;
|
||||
std::cout << "Free {";
|
||||
std::string delim;
|
||||
for(var v = 0; v < nVars; v++) {
|
||||
std::cout << delim << vvUnique[v].size();
|
||||
delim = ", ";
|
||||
}
|
||||
std::cout << "} unique table entries" << std::endl;
|
||||
if(!vRefs.empty())
|
||||
std::cout << "Free " << vRefs.size() << " refs" << std::endl;
|
||||
}
|
||||
delete cache;
|
||||
}
|
||||
void Reorder() {
|
||||
if(nVerbose >= 2)
|
||||
std::cout << "Reorder" << std::endl;
|
||||
int nGbc_ = nGbc;
|
||||
nGbc = 0;
|
||||
CountEdges();
|
||||
Sift();
|
||||
vEdges.clear();
|
||||
cache->Clear();
|
||||
nGbc = nGbc_;
|
||||
}
|
||||
inline lit And(lit x, lit y) {
|
||||
if(nObjs > nReo) {
|
||||
Reorder();
|
||||
while(nReo < nObjs) {
|
||||
nReo <<= 1;
|
||||
if((lit)nReo > (lit)BvarMax())
|
||||
nReo = BvarMax();
|
||||
}
|
||||
}
|
||||
return And_rec(x, y);
|
||||
}
|
||||
inline lit Or(lit x, lit y) {
|
||||
return LitNot(And(LitNot(x), LitNot(y)));
|
||||
}
|
||||
|
||||
public:
|
||||
void SetRef(std::vector<lit> const &vLits) {
|
||||
vRefs.clear();
|
||||
vRefs.resize(nObjsAlloc);
|
||||
for(size_t i = 0; i < vLits.size(); i++)
|
||||
IncRef(vLits[i]);
|
||||
}
|
||||
void RemoveRefIfUnused() {
|
||||
if(!nGbc && nReo == BvarMax())
|
||||
vRefs.clear();
|
||||
}
|
||||
void TurnOnReo(int nReo_ = 0, std::vector<lit> const *vLits = NULL) {
|
||||
if(nReo_)
|
||||
nReo = nReo_;
|
||||
else
|
||||
nReo = nObjs << 1;
|
||||
if((lit)nReo > (lit)BvarMax())
|
||||
nReo = BvarMax();
|
||||
if(vRefs.empty()) {
|
||||
if(vLits)
|
||||
SetRef(*vLits);
|
||||
else
|
||||
vRefs.resize(nObjsAlloc);
|
||||
}
|
||||
}
|
||||
void TurnOffReo() {
|
||||
nReo = BvarMax();
|
||||
}
|
||||
var GetNumVars() const {
|
||||
return nVars;
|
||||
}
|
||||
void GetOrdering(std::vector<int> &Var2Level_) {
|
||||
Var2Level_.resize(nVars);
|
||||
for(var v = 0; v < nVars; v++)
|
||||
Var2Level_[v] = Var2Level[v];
|
||||
}
|
||||
bvar CountNodes() {
|
||||
bvar count = 1;
|
||||
if(!vEdges.empty()) {
|
||||
for(bvar a = 1; a < nObjs; a++)
|
||||
if(EdgeOfBvar(a))
|
||||
count++;
|
||||
return count;
|
||||
}
|
||||
for(bvar a = 1; a <= (bvar)nVars; a++) {
|
||||
count++;
|
||||
SetMarkOfBvar(a);
|
||||
}
|
||||
for(bvar a = (bvar)nVars + 1; a < nObjs; a++)
|
||||
if(RefOfBvar(a))
|
||||
count += CountNodes_rec(Bvar2Lit(a));
|
||||
for(bvar a = 1; a <= (bvar)nVars; a++)
|
||||
ResetMarkOfBvar(a);
|
||||
for(bvar a = (bvar)nVars + 1; a < nObjs; a++)
|
||||
if(RefOfBvar(a))
|
||||
ResetMark_rec(Bvar2Lit(a));
|
||||
return count;
|
||||
}
|
||||
bvar CountNodes(std::vector<lit> const &vLits) {
|
||||
bvar count = 1;
|
||||
for(size_t i = 0; i < vLits.size(); i++)
|
||||
count += CountNodes_rec(vLits[i]);
|
||||
for(size_t i = 0; i < vLits.size(); i++)
|
||||
ResetMark_rec(vLits[i]);
|
||||
return count;
|
||||
}
|
||||
void PrintStats() {
|
||||
bvar nRemoved = 0;
|
||||
bvar a = RemovedHead;
|
||||
while(a)
|
||||
a = vNexts[a], nRemoved++;
|
||||
bvar nLive = 1;
|
||||
for(var v = 0; v < nVars; v++)
|
||||
nLive += vUniqueCounts[v];
|
||||
std::cout << "ref: " << std::setw(10) << (vRefs.empty()? 0: CountNodes()) << ", "
|
||||
<< "used: " << std::setw(10) << nObjs << ", "
|
||||
<< "live: " << std::setw(10) << nLive << ", "
|
||||
<< "dead: " << std::setw(10) << nRemoved << ", "
|
||||
<< "alloc: " << std::setw(10) << nObjsAlloc
|
||||
<< std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_END
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue