Merge remote-tracking branch 'upstream/master' into yosys-experimental

This commit is contained in:
Martin Povišer 2025-03-11 19:28:00 +01:00
commit 43b9a4defe
493 changed files with 117419 additions and 1578 deletions

1
.gitignore vendored
View File

@ -31,6 +31,7 @@ src/aig/ddb/
*.plg
*.zip
*.DS_Store
abcspaceext.dsw
abcext.dsp

View File

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

View File

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

View 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

View File

@ -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;
}

View File

@ -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 );

View File

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

View 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 );

View File

@ -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) );

View File

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

View 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) );

View File

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

View File

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

View File

@ -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++ )

View File

@ -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);

View File

@ -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 );

37
src/aig/gia/giaRrr.cpp Normal file
View File

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

View File

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

View 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;
}

View File

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

View File

@ -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 )
{

View File

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

View 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

View File

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

View File

@ -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 );

View File

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

View File

@ -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);

File diff suppressed because it is too large Load Diff

View File

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

View 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 );

View File

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

View File

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

View File

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

View File

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

View File

@ -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;}
}
/*

View File

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

View 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 );
}

View File

@ -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 );
}
////////////////////////////////////////////////////////////////////////

View File

@ -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" );

View File

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

View 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 ===========================================================*/

View File

@ -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++;

View File

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

View File

@ -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 );

112
src/base/io/ioWriteHMetis.c Normal file
View File

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

View File

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

View File

@ -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 );

View File

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

View File

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

View File

@ -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;
}

View File

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

View File

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

View File

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

View 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*************************************************************

View File

@ -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);

View File

@ -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 );

View File

@ -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;}

View File

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

View File

@ -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;
}

View File

@ -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 );
}

View File

@ -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 );

View File

@ -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 );
}

View File

@ -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 );

View File

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

View File

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

View File

@ -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 );

View File

@ -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" );
}

View File

@ -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; }

View File

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

1036
src/misc/util/utilBSet.c Normal file

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -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));

View File

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

View File

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

View File

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

View File

@ -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 );

View File

@ -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;
}

View File

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

View File

@ -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++;

View File

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

View File

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

View File

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

4
src/opt/rar/module.make Normal file
View File

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

65
src/opt/rar/rewire_map.c Normal file
View File

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

40
src/opt/rar/rewire_map.h Normal file
View File

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

1179
src/opt/rar/rewire_miaig.cpp Normal file

File diff suppressed because it is too large Load Diff

493
src/opt/rar/rewire_miaig.h Normal file
View File

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

37
src/opt/rar/rewire_rar.c Normal file
View File

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

47
src/opt/rar/rewire_rar.h Normal file
View File

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

53
src/opt/rar/rewire_rng.c Normal file
View File

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

48
src/opt/rar/rewire_rng.h Normal file
View File

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

61
src/opt/rar/rewire_time.h Normal file
View File

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

230
src/opt/rar/rewire_tt.h Normal file
View File

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

226
src/opt/rar/rewire_vec.h Normal file
View File

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

33
src/opt/rrr/rrr.h Normal file
View File

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

80
src/opt/rrr/rrrAbc.h Normal file
View File

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

104
src/opt/rrr/rrrAnalyzer.h Normal file
View File

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

1497
src/opt/rrr/rrrAndNetwork.h Normal file

File diff suppressed because it is too large Load Diff

View File

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

848
src/opt/rrr/rrrBddManager.h Normal file
View File

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