2016-07-16 16:51:58 +02:00
/**CFile****************************************************************
FileName [ abcExact . c ]
SystemName [ ABC : Logic synthesis and verification system . ]
PackageName [ Network and node package . ]
Synopsis [ Find minimum size networks with a SAT solver . ]
Author [ Mathias Soeken ]
Affiliation [ EPFL ]
Date [ Ver . 1.0 . Started - July 15 , 2016. ]
Revision [ $ Id : abcFanio . c , v 1.00 2005 / 06 / 20 00 : 00 : 00 alanmi Exp $ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* This implementation is based on Exercises 477 and 478 in
* Donald E . Knuth TAOCP Fascicle 6 ( Satisfiability ) Section 7.2 .2 .2
*/
# include "base/abc/abc.h"
2016-07-28 20:37:09 +02:00
# include "aig/gia/gia.h"
2016-07-16 16:51:58 +02:00
# include "misc/util/utilTruth.h"
# include "misc/vec/vecInt.h"
# include "misc/vec/vecPtr.h"
2016-07-28 20:37:09 +02:00
# include "proof/cec/cec.h"
2016-07-16 16:51:58 +02:00
# include "sat/bsat/satSolver.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
2016-08-22 10:57:38 +02:00
static word s_Truths8 [ 32 ] = {
ABC_CONST ( 0xAAAAAAAAAAAAAAAA ) , ABC_CONST ( 0xAAAAAAAAAAAAAAAA ) , ABC_CONST ( 0xAAAAAAAAAAAAAAAA ) , ABC_CONST ( 0xAAAAAAAAAAAAAAAA ) ,
ABC_CONST ( 0xCCCCCCCCCCCCCCCC ) , ABC_CONST ( 0xCCCCCCCCCCCCCCCC ) , ABC_CONST ( 0xCCCCCCCCCCCCCCCC ) , ABC_CONST ( 0xCCCCCCCCCCCCCCCC ) ,
ABC_CONST ( 0xF0F0F0F0F0F0F0F0 ) , ABC_CONST ( 0xF0F0F0F0F0F0F0F0 ) , ABC_CONST ( 0xF0F0F0F0F0F0F0F0 ) , ABC_CONST ( 0xF0F0F0F0F0F0F0F0 ) ,
ABC_CONST ( 0xFF00FF00FF00FF00 ) , ABC_CONST ( 0xFF00FF00FF00FF00 ) , ABC_CONST ( 0xFF00FF00FF00FF00 ) , ABC_CONST ( 0xFF00FF00FF00FF00 ) ,
ABC_CONST ( 0xFFFF0000FFFF0000 ) , ABC_CONST ( 0xFFFF0000FFFF0000 ) , ABC_CONST ( 0xFFFF0000FFFF0000 ) , ABC_CONST ( 0xFFFF0000FFFF0000 ) ,
ABC_CONST ( 0xFFFFFFFF00000000 ) , ABC_CONST ( 0xFFFFFFFF00000000 ) , ABC_CONST ( 0xFFFFFFFF00000000 ) , ABC_CONST ( 0xFFFFFFFF00000000 ) ,
ABC_CONST ( 0x0000000000000000 ) , ABC_CONST ( 0xFFFFFFFFFFFFFFFF ) , ABC_CONST ( 0x0000000000000000 ) , ABC_CONST ( 0xFFFFFFFFFFFFFFFF ) ,
ABC_CONST ( 0x0000000000000000 ) , ABC_CONST ( 0x0000000000000000 ) , ABC_CONST ( 0xFFFFFFFFFFFFFFFF ) , ABC_CONST ( 0xFFFFFFFFFFFFFFFF )
} ;
2016-08-04 18:51:35 +02:00
# define ABC_EXACT_SOL_NVARS 0
# define ABC_EXACT_SOL_NFUNC 1
# define ABC_EXACT_SOL_NGATES 2
2016-08-24 15:03:52 +02:00
# define ANSI_COLOR_RED "\x1b[31m"
# define ANSI_COLOR_GREEN "\x1b[32m"
# define ANSI_COLOR_YELLOW "\x1b[33m"
# define ANSI_COLOR_BLUE "\x1b[34m"
# define ANSI_COLOR_MAGENTA "\x1b[35m"
# define ANSI_COLOR_CYAN "\x1b[36m"
# define ANSI_COLOR_RESET "\x1b[0m"
2016-07-16 16:51:58 +02:00
typedef struct Ses_Man_t_ Ses_Man_t ;
struct Ses_Man_t_
{
2016-08-24 09:29:02 +02:00
sat_solver * pSat ; /* SAT solver */
word * pSpec ; /* specification */
int bSpecInv ; /* remembers whether spec was inverted for normalization */
int nSpecVars ; /* number of variables in specification */
int nSpecFunc ; /* number of functions to synthesize */
int nSpecWords ; /* number of words for function */
int nRows ; /* number of rows in the specification (without 0) */
int nMaxDepth ; /* maximum depth (-1 if depth is not constrained) */
int nMaxDepthTmp ; /* temporary copy to modify nMaxDepth temporarily */
int * pArrTimeProfile ; /* arrival times of inputs (NULL if arrival times are ignored) */
int pArrTimeProfileTmp [ 8 ] ; /* temporary copy to modify pArrTimeProfile temporarily */
int nArrTimeDelta ; /* delta to the original arrival times (arrival times are normalized to have 0 as minimum element) */
int nArrTimeMax ; /* maximum normalized arrival time */
int nBTLimit ; /* conflict limit */
int fMakeAIG ; /* create AIG instead of general network */
int fVerbose ; /* be verbose */
int fVeryVerbose ; /* be very verbose */
int fExtractVerbose ; /* be verbose about solution extraction */
int fSatVerbose ; /* be verbose about SAT solving */
2016-08-24 15:03:52 +02:00
int fReasonVerbose ; /* be verbose about give-up reasons */
2016-08-24 09:29:02 +02:00
int nGates ; /* number of gates */
2016-08-24 15:03:52 +02:00
int nStartGates ; /* number of gates to start search (-1), i.e., to start from 1 gate, one needs to specify 0 */
2016-08-24 09:29:02 +02:00
int fDecStructure ; /* set to 1 or higher if nSpecFunc = 1 and f = x_i OP g(X \ {x_i}), otherwise 0 (determined when solving) */
2016-08-24 15:03:52 +02:00
int pDecVars ; /* mask of variables that can be decomposed at top-level */
2016-08-24 09:29:02 +02:00
int nSimVars ; /* number of simulation vars x(i, t) */
int nOutputVars ; /* number of output variables g(h, i) */
int nGateVars ; /* number of gate variables f(i, p, q) */
int nSelectVars ; /* number of select variables s(i, j, k) */
int nDepthVars ; /* number of depth variables d(i, j) */
int nOutputOffset ; /* offset where output variables start */
int nGateOffset ; /* offset where gate variables start */
int nSelectOffset ; /* offset where select variables start */
int nDepthOffset ; /* offset where depth variables start */
int fHitResLimit ; /* SAT solver gave up due to resource limit */
abctime timeSat ; /* SAT runtime */
abctime timeSatSat ; /* SAT runtime (sat instance) */
abctime timeSatUnsat ; /* SAT runtime (unsat instance) */
abctime timeSatUndef ; /* SAT runtime (undef instance) */
abctime timeInstance ; /* creating instance runtime */
abctime timeTotal ; /* all runtime */
int nSatCalls ; /* number of SAT calls */
int nUnsatCalls ; /* number of UNSAT calls */
int nUndefCalls ; /* number of UNDEF calls */
2016-07-16 16:51:58 +02:00
} ;
2016-07-31 12:24:02 +02:00
/***********************************************************************
Synopsis [ Store truth tables based on normalized arrival times . ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
// The hash table is a list of pointers to Ses_TruthEntry_t elements, which
// are arranged in a linked list, each of which pointing to a linked list
// of Ses_TimesEntry_t elements which contain the char* representation of the
// optimum netlist according to then normalized arrival times:
typedef struct Ses_TimesEntry_t_ Ses_TimesEntry_t ;
struct Ses_TimesEntry_t_
{
int pArrTimeProfile [ 8 ] ; /* normalized arrival time profile */
2016-08-22 10:57:38 +02:00
int fResLimit ; /* solution found after resource limit */
2016-07-31 12:24:02 +02:00
Ses_TimesEntry_t * next ; /* linked list pointer */
char * pNetwork ; /* pointer to char array representation of optimum network */
} ;
typedef struct Ses_TruthEntry_t_ Ses_TruthEntry_t ;
struct Ses_TruthEntry_t_
{
word pTruth [ 4 ] ; /* truth table for comparison */
2016-08-02 11:25:16 +02:00
int nVars ; /* number of variables */
2016-07-31 12:24:02 +02:00
Ses_TruthEntry_t * next ; /* linked list pointer */
Ses_TimesEntry_t * head ; /* pointer to head of sub list with arrival times */
} ;
# define SES_STORE_TABLE_SIZE 1024
typedef struct Ses_Store_t_ Ses_Store_t ;
struct Ses_Store_t_
{
2016-08-04 18:51:35 +02:00
int fMakeAIG ; /* create AIG instead of general network */
2016-08-02 13:24:21 +02:00
int fVerbose ; /* be verbose */
2016-08-08 12:59:21 +02:00
int fVeryVerbose ; /* be very verbose */
2016-08-02 13:24:21 +02:00
int nBTLimit ; /* conflict limit */
2016-08-04 18:51:35 +02:00
int nEntriesCount ; /* number of entries */
2016-08-08 12:59:21 +02:00
int nValidEntriesCount ; /* number of entries with network */
2016-07-31 12:24:02 +02:00
Ses_TruthEntry_t * pEntries [ SES_STORE_TABLE_SIZE ] ; /* hash table for truth table entries */
2016-08-21 19:28:55 +02:00
sat_solver * pSat ; /* own SAT solver instance to reuse when calling exact algorithm */
2016-08-22 10:57:38 +02:00
FILE * pDebugEntries ; /* debug unsynth. (rl) entries */
2016-08-04 14:22:31 +02:00
2016-08-09 10:53:58 +02:00
/* statistics */
unsigned long nCutCount ; /* number of cuts investigated */
unsigned long pCutCount [ 9 ] ; /* -> per cut size */
unsigned long nUnsynthesizedImp ; /* number of cuts which couldn't be optimized at all, opt. stopped because of imp. constraints */
unsigned long pUnsynthesizedImp [ 9 ] ; /* -> per cut size */
unsigned long nUnsynthesizedRL ; /* number of cuts which couldn't be optimized at all, opt. stopped because of resource limits */
unsigned long pUnsynthesizedRL [ 9 ] ; /* -> per cut size */
unsigned long nSynthesizedTrivial ; /* number of cuts which could be synthesized trivially (n < 2) */
unsigned long pSynthesizedTrivial [ 9 ] ; /* -> per cut size */
unsigned long nSynthesizedImp ; /* number of cuts which could be synthesized, opt. stopped because of imp. constraints */
unsigned long pSynthesizedImp [ 9 ] ; /* -> per cut size */
unsigned long nSynthesizedRL ; /* number of cuts which could be synthesized, opt. stopped because of resource limits */
unsigned long pSynthesizedRL [ 9 ] ; /* -> per cut size */
unsigned long nCacheHits ; /* number of cache hits */
unsigned long pCacheHits [ 9 ] ; /* -> per cut size */
2016-08-21 18:13:57 +02:00
unsigned long nSatCalls ; /* number of total SAT calls */
unsigned long nUnsatCalls ; /* number of total UNSAT calls */
unsigned long nUndefCalls ; /* number of total UNDEF calls */
abctime timeExact ; /* Exact synthesis runtime */
abctime timeSat ; /* SAT runtime */
abctime timeSatSat ; /* SAT runtime (sat instance) */
abctime timeSatUnsat ; /* SAT runtime (unsat instance) */
abctime timeSatUndef ; /* SAT runtime (undef instance) */
abctime timeInstance ; /* creating instance runtime */
abctime timeTotal ; /* all runtime */
2016-07-31 12:24:02 +02:00
} ;
static Ses_Store_t * s_pSesStore = NULL ;
2016-07-16 16:51:58 +02:00
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
2016-07-31 12:24:02 +02:00
static int Abc_NormalizeArrivalTimes ( int * pArrTimeProfile , int nVars , int * maxNormalized )
2016-07-16 16:51:58 +02:00
{
2016-07-30 13:34:39 +02:00
int * p = pArrTimeProfile , * pEnd = pArrTimeProfile + nVars ;
2016-07-28 20:37:09 +02:00
int delta = * p ;
while ( + + p < pEnd )
if ( * p < delta )
delta = * p ;
* maxNormalized = 0 ;
2016-07-30 13:34:39 +02:00
p = pArrTimeProfile ;
2016-07-28 20:37:09 +02:00
while ( p < pEnd )
{
* p - = delta ;
if ( * p > * maxNormalized )
* maxNormalized = * p ;
+ + p ;
}
* maxNormalized + = 1 ;
return delta ;
}
2016-08-04 18:51:35 +02:00
static inline Ses_Store_t * Ses_StoreAlloc ( int nBTLimit , int fMakeAIG , int fVerbose )
2016-07-31 13:08:14 +02:00
{
Ses_Store_t * pStore = ABC_CALLOC ( Ses_Store_t , 1 ) ;
2016-08-09 10:53:58 +02:00
pStore - > fMakeAIG = fMakeAIG ;
pStore - > fVerbose = fVerbose ;
pStore - > nBTLimit = nBTLimit ;
2016-08-02 11:25:16 +02:00
memset ( pStore - > pEntries , 0 , SES_STORE_TABLE_SIZE ) ;
2016-07-31 13:08:14 +02:00
2016-08-21 19:28:55 +02:00
pStore - > pSat = sat_solver_new ( ) ;
2016-07-31 13:08:14 +02:00
return pStore ;
}
static inline void Ses_StoreClean ( Ses_Store_t * pStore )
{
int i ;
Ses_TruthEntry_t * pTEntry , * pTEntry2 ;
Ses_TimesEntry_t * pTiEntry , * pTiEntry2 ;
for ( i = 0 ; i < SES_STORE_TABLE_SIZE ; + + i )
if ( pStore - > pEntries [ i ] )
{
pTEntry = pStore - > pEntries [ i ] ;
while ( pTEntry )
{
pTiEntry = pTEntry - > head ;
while ( pTiEntry )
{
ABC_FREE ( pTiEntry - > pNetwork ) ;
pTiEntry2 = pTiEntry ;
pTiEntry = pTiEntry - > next ;
ABC_FREE ( pTiEntry2 ) ;
}
pTEntry2 = pTEntry ;
pTEntry = pTEntry - > next ;
ABC_FREE ( pTEntry2 ) ;
}
}
2016-08-21 19:28:55 +02:00
sat_solver_delete ( pStore - > pSat ) ;
2016-07-31 13:08:14 +02:00
ABC_FREE ( pStore ) ;
}
2016-08-02 11:25:16 +02:00
static inline int Ses_StoreTableHash ( word * pTruth , int nVars )
2016-07-31 12:24:02 +02:00
{
static int s_Primes [ 4 ] = { 1291 , 1699 , 1999 , 2357 } ;
int i ;
unsigned uHash = 0 ;
2016-08-16 08:20:28 +02:00
for ( i = 0 ; i < Abc_TtWordNum ( nVars ) ; + + i )
2016-07-31 12:24:02 +02:00
uHash ^ = pTruth [ i ] * s_Primes [ i & 0xf ] ;
return ( int ) ( uHash % SES_STORE_TABLE_SIZE ) ;
}
2016-08-02 11:25:16 +02:00
static inline int Ses_StoreTruthEqual ( Ses_TruthEntry_t * pEntry , word * pTruth , int nVars )
2016-07-31 12:24:02 +02:00
{
int i ;
2016-08-02 11:25:16 +02:00
if ( pEntry - > nVars ! = nVars )
return 0 ;
2016-08-16 08:20:28 +02:00
for ( i = 0 ; i < Abc_TtWordNum ( nVars ) ; + + i )
2016-08-02 11:25:16 +02:00
if ( pEntry - > pTruth [ i ] ! = pTruth [ i ] )
2016-07-31 12:24:02 +02:00
return 0 ;
return 1 ;
}
2016-08-02 11:25:16 +02:00
static inline void Ses_StoreTruthCopy ( Ses_TruthEntry_t * pEntry , word * pTruthSrc , int nVars )
2016-07-31 12:24:02 +02:00
{
int i ;
2016-08-02 11:25:16 +02:00
pEntry - > nVars = nVars ;
2016-08-16 08:20:28 +02:00
for ( i = 0 ; i < Abc_TtWordNum ( nVars ) ; + + i )
2016-08-02 11:25:16 +02:00
pEntry - > pTruth [ i ] = pTruthSrc [ i ] ;
2016-07-31 12:24:02 +02:00
}
2016-08-02 11:25:16 +02:00
static inline int Ses_StoreTimesEqual ( int * pTimes1 , int * pTimes2 , int nVars )
2016-07-31 12:24:02 +02:00
{
int i ;
2016-08-02 11:25:16 +02:00
for ( i = 0 ; i < nVars ; + + i )
2016-07-31 12:24:02 +02:00
if ( pTimes1 [ i ] ! = pTimes2 [ i ] )
return 0 ;
return 1 ;
}
2016-08-02 11:25:16 +02:00
static inline void Ses_StoreTimesCopy ( int * pTimesDest , int * pTimesSrc , int nVars )
2016-07-31 12:24:02 +02:00
{
int i ;
2016-08-02 11:25:16 +02:00
for ( i = 0 ; i < nVars ; + + i )
2016-07-31 12:24:02 +02:00
pTimesDest [ i ] = pTimesSrc [ i ] ;
}
2016-08-22 10:57:38 +02:00
static inline void Ses_StorePrintEntry ( Ses_TruthEntry_t * pEntry , Ses_TimesEntry_t * pTiEntry )
{
int i ;
printf ( " f = " ) ;
Abc_TtPrintHexRev ( stdout , pEntry - > pTruth , pEntry - > nVars ) ;
printf ( " , n = %d " , pEntry - > nVars ) ;
printf ( " , arrival = " ) ;
for ( i = 0 ; i < pEntry - > nVars ; + + i )
printf ( " %d " , pTiEntry - > pArrTimeProfile [ i ] ) ;
printf ( " \n " ) ;
}
2016-08-24 15:03:52 +02:00
static inline void Ses_StorePrintDebugEntry ( Ses_Store_t * pStore , word * pTruth , int nVars , int * pNormalArrTime , int nMaxDepth , char * pSol )
2016-08-22 10:57:38 +02:00
{
int l ;
fprintf ( pStore - > pDebugEntries , " abc -c \" exact -v -C %d " , pStore - > nBTLimit ) ;
if ( s_pSesStore - > fMakeAIG ) fprintf ( pStore - > pDebugEntries , " -a " ) ;
fprintf ( pStore - > pDebugEntries , " -D %d -A " , nMaxDepth ) ;
for ( l = 0 ; l < nVars ; + + l )
fprintf ( pStore - > pDebugEntries , " %c%d " , ( l = = 0 ? ' ' : ' , ' ) , pNormalArrTime [ l ] ) ;
fprintf ( pStore - > pDebugEntries , " " ) ;
Abc_TtPrintHexRev ( pStore - > pDebugEntries , pTruth , nVars ) ;
2016-08-24 15:03:52 +02:00
fprintf ( pStore - > pDebugEntries , " \" # " ) ;
if ( ! pSol )
fprintf ( pStore - > pDebugEntries , " no " ) ;
fprintf ( pStore - > pDebugEntries , " solution found before \n " ) ;
2016-08-22 10:57:38 +02:00
}
2016-08-24 09:29:02 +02:00
static void Abc_ExactNormalizeArrivalTimesForNetwork ( int nVars , int * pArrTimeProfile , char * pSol )
{
int nGates , i , j , k , nMax ;
Vec_Int_t * vLevels ;
nGates = pSol [ ABC_EXACT_SOL_NGATES ] ;
/* printf( "NORMALIZE\n" ); */
/* printf( " #vars = %d\n", nVars ); */
/* printf( " #gates = %d\n", nGates ); */
vLevels = Vec_IntAllocArrayCopy ( pArrTimeProfile , nVars ) ;
/* compute level of each gate based on arrival time profile (to compute depth) */
for ( i = 0 ; i < nGates ; + + i )
{
j = pSol [ 3 + i * 4 + 2 ] ;
k = pSol [ 3 + i * 4 + 3 ] ;
Vec_IntPush ( vLevels , Abc_MaxInt ( Vec_IntEntry ( vLevels , j ) , Vec_IntEntry ( vLevels , k ) ) + 1 ) ;
/* printf( " gate %d = (%d,%d)\n", nVars + i, j, k ); */
}
/* Vec_IntPrint( vLevels ); */
/* reset all levels except for the last one */
for ( i = 0 ; i < nVars + nGates - 1 ; + + i )
Vec_IntSetEntry ( vLevels , i , Vec_IntEntry ( vLevels , nVars + nGates - 1 ) ) ;
/* Vec_IntPrint( vLevels ); */
/* compute levels from top to bottom */
for ( i = nGates - 1 ; i > = 0 ; - - i )
{
j = pSol [ 3 + i * 4 + 2 ] ;
k = pSol [ 3 + i * 4 + 3 ] ;
Vec_IntSetEntry ( vLevels , j , Abc_MinInt ( Vec_IntEntry ( vLevels , j ) , Vec_IntEntry ( vLevels , nVars + i ) - 1 ) ) ;
Vec_IntSetEntry ( vLevels , k , Abc_MinInt ( Vec_IntEntry ( vLevels , k ) , Vec_IntEntry ( vLevels , nVars + i ) - 1 ) ) ;
}
/* Vec_IntPrint( vLevels ); */
/* normalize arrival times */
Abc_NormalizeArrivalTimes ( Vec_IntArray ( vLevels ) , nVars , & nMax ) ;
memcpy ( pArrTimeProfile , Vec_IntArray ( vLevels ) , sizeof ( int ) * nVars ) ;
/* printf( " nMax = %d\n", nMax ); */
/* Vec_IntPrint( vLevels ); */
Vec_IntFree ( vLevels ) ;
}
2016-08-08 12:59:21 +02:00
// pArrTimeProfile is normalized
2016-07-31 12:24:02 +02:00
// returns 1 if and only if a new TimesEntry has been created
2016-08-22 10:57:38 +02:00
int Ses_StoreAddEntry ( Ses_Store_t * pStore , word * pTruth , int nVars , int * pArrTimeProfile , char * pSol , int fResLimit )
2016-07-31 12:24:02 +02:00
{
2016-08-08 10:59:29 +02:00
int key , fAdded ;
2016-07-31 12:24:02 +02:00
Ses_TruthEntry_t * pTEntry ;
Ses_TimesEntry_t * pTiEntry ;
2016-08-24 09:29:02 +02:00
if ( pSol )
Abc_ExactNormalizeArrivalTimesForNetwork ( nVars , pArrTimeProfile , pSol ) ;
2016-08-02 11:25:16 +02:00
key = Ses_StoreTableHash ( pTruth , nVars ) ;
2016-07-31 12:24:02 +02:00
pTEntry = pStore - > pEntries [ key ] ;
/* does truth table already exist? */
while ( pTEntry )
{
2016-08-02 11:25:16 +02:00
if ( Ses_StoreTruthEqual ( pTEntry , pTruth , nVars ) )
2016-07-31 12:24:02 +02:00
break ;
else
pTEntry = pTEntry - > next ;
}
/* entry does not yet exist, so create new one and enqueue */
if ( ! pTEntry )
{
pTEntry = ABC_CALLOC ( Ses_TruthEntry_t , 1 ) ;
2016-08-02 11:25:16 +02:00
Ses_StoreTruthCopy ( pTEntry , pTruth , nVars ) ;
2016-07-31 12:24:02 +02:00
pTEntry - > next = pStore - > pEntries [ key ] ;
pStore - > pEntries [ key ] = pTEntry ;
}
/* does arrival time already exist? */
pTiEntry = pTEntry - > head ;
while ( pTiEntry )
{
2016-08-02 11:25:16 +02:00
if ( Ses_StoreTimesEqual ( pArrTimeProfile , pTiEntry - > pArrTimeProfile , nVars ) )
2016-07-31 12:24:02 +02:00
break ;
else
pTiEntry = pTiEntry - > next ;
}
/* entry does not yet exist, so create new one and enqueue */
if ( ! pTiEntry )
{
pTiEntry = ABC_CALLOC ( Ses_TimesEntry_t , 1 ) ;
2016-08-02 11:25:16 +02:00
Ses_StoreTimesCopy ( pTiEntry - > pArrTimeProfile , pArrTimeProfile , nVars ) ;
2016-07-31 12:24:02 +02:00
pTiEntry - > pNetwork = pSol ;
2016-08-22 10:57:38 +02:00
pTiEntry - > fResLimit = fResLimit ;
2016-07-31 12:24:02 +02:00
pTiEntry - > next = pTEntry - > head ;
pTEntry - > head = pTiEntry ;
/* item has been added */
2016-07-31 13:08:14 +02:00
fAdded = 1 ;
2016-08-04 18:51:35 +02:00
pStore - > nEntriesCount + + ;
2016-08-08 12:59:21 +02:00
if ( pSol )
pStore - > nValidEntriesCount + + ;
2016-07-31 12:24:02 +02:00
}
else
2016-08-09 10:53:58 +02:00
{
assert ( 0 ) ;
2016-07-31 12:24:02 +02:00
/* item was already present */
2016-07-31 13:08:14 +02:00
fAdded = 0 ;
2016-08-09 10:53:58 +02:00
}
2016-07-31 13:08:14 +02:00
2016-08-22 10:57:38 +02:00
/* statistics */
if ( pSol )
{
if ( fResLimit )
{
s_pSesStore - > nSynthesizedRL + + ;
s_pSesStore - > pSynthesizedRL [ nVars ] + + ;
}
else
{
s_pSesStore - > nSynthesizedImp + + ;
s_pSesStore - > pSynthesizedImp [ nVars ] + + ;
}
}
else
{
if ( fResLimit )
{
s_pSesStore - > nUnsynthesizedRL + + ;
s_pSesStore - > pUnsynthesizedRL [ nVars ] + + ;
}
else
{
s_pSesStore - > nUnsynthesizedImp + + ;
s_pSesStore - > pUnsynthesizedImp [ nVars ] + + ;
}
}
2016-07-31 13:08:14 +02:00
return fAdded ;
2016-07-31 12:24:02 +02:00
}
2016-08-08 12:59:21 +02:00
// pArrTimeProfile is normalized
// returns 1 if entry was in store, pSol may still be 0 if it couldn't be computed
2016-08-24 09:29:02 +02:00
int Ses_StoreGetEntrySimple ( Ses_Store_t * pStore , word * pTruth , int nVars , int * pArrTimeProfile , char * * pSol )
2016-07-31 12:47:09 +02:00
{
2016-08-08 10:59:29 +02:00
int key ;
2016-07-31 12:47:09 +02:00
Ses_TruthEntry_t * pTEntry ;
Ses_TimesEntry_t * pTiEntry ;
2016-08-02 11:25:16 +02:00
key = Ses_StoreTableHash ( pTruth , nVars ) ;
2016-07-31 12:47:09 +02:00
pTEntry = pStore - > pEntries [ key ] ;
/* find truth table entry */
while ( pTEntry )
{
2016-08-02 11:25:16 +02:00
if ( Ses_StoreTruthEqual ( pTEntry , pTruth , nVars ) )
2016-07-31 12:47:09 +02:00
break ;
else
pTEntry = pTEntry - > next ;
}
/* no entry found? */
if ( ! pTEntry )
return 0 ;
/* find times entry */
pTiEntry = pTEntry - > head ;
while ( pTiEntry )
{
2016-08-02 11:25:16 +02:00
if ( Ses_StoreTimesEqual ( pArrTimeProfile , pTiEntry - > pArrTimeProfile , nVars ) )
2016-07-31 12:47:09 +02:00
break ;
else
pTiEntry = pTiEntry - > next ;
}
/* no entry found? */
if ( ! pTiEntry )
return 0 ;
2016-08-08 12:59:21 +02:00
* pSol = pTiEntry - > pNetwork ;
return 1 ;
2016-07-31 12:47:09 +02:00
}
2016-07-31 12:24:02 +02:00
2016-08-24 09:29:02 +02:00
int Ses_StoreGetEntry ( Ses_Store_t * pStore , word * pTruth , int nVars , int * pArrTimeProfile , char * * pSol )
{
int key ;
Ses_TruthEntry_t * pTEntry ;
Ses_TimesEntry_t * pTiEntry ;
int pTimes [ 8 ] ;
key = Ses_StoreTableHash ( pTruth , nVars ) ;
pTEntry = pStore - > pEntries [ key ] ;
/* find truth table entry */
while ( pTEntry )
{
if ( Ses_StoreTruthEqual ( pTEntry , pTruth , nVars ) )
break ;
else
pTEntry = pTEntry - > next ;
}
/* no entry found? */
if ( ! pTEntry )
return 0 ;
/* find times entry */
pTiEntry = pTEntry - > head ;
while ( pTiEntry )
{
/* found after normalization wrt. to network */
if ( pTiEntry - > pNetwork )
{
memcpy ( pTimes , pArrTimeProfile , sizeof ( int ) * nVars ) ;
Abc_ExactNormalizeArrivalTimesForNetwork ( nVars , pTimes , pTiEntry - > pNetwork ) ;
if ( Ses_StoreTimesEqual ( pTimes , pTiEntry - > pArrTimeProfile , nVars ) )
break ;
}
/* found for non synthesized network */
else if ( Ses_StoreTimesEqual ( pArrTimeProfile , pTiEntry - > pArrTimeProfile , nVars ) )
break ;
else
pTiEntry = pTiEntry - > next ;
}
/* no entry found? */
if ( ! pTiEntry )
return 0 ;
* pSol = pTiEntry - > pNetwork ;
return 1 ;
}
2016-08-22 10:57:38 +02:00
static void Ses_StoreWrite ( Ses_Store_t * pStore , const char * pFilename , int fSynthImp , int fSynthRL , int fUnsynthImp , int fUnsynthRL )
2016-08-04 18:51:35 +02:00
{
int i ;
2016-08-22 10:57:38 +02:00
char zero = ' \0 ' ;
unsigned long nEntries = 0 ;
2016-08-04 18:51:35 +02:00
Ses_TruthEntry_t * pTEntry ;
Ses_TimesEntry_t * pTiEntry ;
FILE * pFile ;
pFile = fopen ( pFilename , " wb " ) ;
if ( pFile = = NULL )
{
printf ( " cannot open file \" %s \" for writing \n " , pFilename ) ;
return ;
}
2016-08-22 10:57:38 +02:00
if ( fSynthImp ) nEntries + = pStore - > nSynthesizedImp ;
if ( fSynthRL ) nEntries + = pStore - > nSynthesizedRL ;
if ( fUnsynthImp ) nEntries + = pStore - > nUnsynthesizedImp ;
if ( fUnsynthRL ) nEntries + = pStore - > nUnsynthesizedRL ;
fwrite ( & nEntries , sizeof ( unsigned long ) , 1 , pFile ) ;
2016-08-04 18:51:35 +02:00
for ( i = 0 ; i < SES_STORE_TABLE_SIZE ; + + i )
if ( pStore - > pEntries [ i ] )
{
pTEntry = pStore - > pEntries [ i ] ;
while ( pTEntry )
{
pTiEntry = pTEntry - > head ;
while ( pTiEntry )
{
2016-08-22 10:57:38 +02:00
if ( pStore - > fVeryVerbose & & ! pTiEntry - > pNetwork & & pTiEntry - > fResLimit )
Ses_StorePrintEntry ( pTEntry , pTiEntry ) ;
if ( ! fSynthImp & & pTiEntry - > pNetwork & & ! pTiEntry - > fResLimit ) { pTiEntry = pTiEntry - > next ; continue ; }
if ( ! fSynthRL & & pTiEntry - > pNetwork & & pTiEntry - > fResLimit ) { pTiEntry = pTiEntry - > next ; continue ; }
if ( ! fUnsynthImp & & ! pTiEntry - > pNetwork & & ! pTiEntry - > fResLimit ) { pTiEntry = pTiEntry - > next ; continue ; }
if ( ! fUnsynthRL & & ! pTiEntry - > pNetwork & & pTiEntry - > fResLimit ) { pTiEntry = pTiEntry - > next ; continue ; }
fwrite ( pTEntry - > pTruth , sizeof ( word ) , 4 , pFile ) ;
fwrite ( & pTEntry - > nVars , sizeof ( int ) , 1 , pFile ) ;
fwrite ( pTiEntry - > pArrTimeProfile , sizeof ( int ) , 8 , pFile ) ;
fwrite ( & pTiEntry - > fResLimit , sizeof ( int ) , 1 , pFile ) ;
2016-08-08 12:59:21 +02:00
if ( pTiEntry - > pNetwork )
{
fwrite ( pTiEntry - > pNetwork , sizeof ( char ) , 3 + 4 * pTiEntry - > pNetwork [ ABC_EXACT_SOL_NGATES ] + 2 + pTiEntry - > pNetwork [ ABC_EXACT_SOL_NVARS ] , pFile ) ;
}
2016-08-22 10:57:38 +02:00
else
{
fwrite ( & zero , sizeof ( char ) , 1 , pFile ) ;
fwrite ( & zero , sizeof ( char ) , 1 , pFile ) ;
fwrite ( & zero , sizeof ( char ) , 1 , pFile ) ;
}
2016-08-04 18:51:35 +02:00
pTiEntry = pTiEntry - > next ;
}
pTEntry = pTEntry - > next ;
}
}
fclose ( pFile ) ;
}
2016-08-22 10:57:38 +02:00
static void Ses_StoreRead ( Ses_Store_t * pStore , const char * pFilename , int fSynthImp , int fSynthRL , int fUnsynthImp , int fUnsynthRL )
2016-08-04 18:51:35 +02:00
{
2016-08-22 10:57:38 +02:00
int i ;
unsigned long nEntries ;
2016-08-04 18:51:35 +02:00
word pTruth [ 4 ] ;
2016-08-22 10:57:38 +02:00
int nVars , fResLimit ;
2016-08-04 18:51:35 +02:00
int pArrTimeProfile [ 8 ] ;
char pHeader [ 3 ] ;
char * pNetwork ;
FILE * pFile ;
2016-08-06 05:45:56 +02:00
int value ;
2016-08-04 18:51:35 +02:00
pFile = fopen ( pFilename , " rb " ) ;
if ( pFile = = NULL )
{
printf ( " cannot open file \" %s \" for reading \n " , pFilename ) ;
return ;
}
2016-08-22 10:57:38 +02:00
value = fread ( & nEntries , sizeof ( unsigned long ) , 1 , pFile ) ;
2016-08-04 18:51:35 +02:00
for ( i = 0 ; i < nEntries ; + + i )
{
2016-08-06 05:45:56 +02:00
value = fread ( pTruth , sizeof ( word ) , 4 , pFile ) ;
value = fread ( & nVars , sizeof ( int ) , 1 , pFile ) ;
value = fread ( pArrTimeProfile , sizeof ( int ) , 8 , pFile ) ;
2016-08-22 10:57:38 +02:00
value = fread ( & fResLimit , sizeof ( int ) , 1 , pFile ) ;
2016-08-06 05:45:56 +02:00
value = fread ( pHeader , sizeof ( char ) , 3 , pFile ) ;
2016-08-04 18:51:35 +02:00
2016-08-22 10:57:38 +02:00
if ( pHeader [ 0 ] = = ' \0 ' )
pNetwork = NULL ;
else
{
pNetwork = ABC_CALLOC ( char , 3 + 4 * pHeader [ ABC_EXACT_SOL_NGATES ] + 2 + pHeader [ ABC_EXACT_SOL_NVARS ] ) ;
pNetwork [ 0 ] = pHeader [ 0 ] ;
pNetwork [ 1 ] = pHeader [ 1 ] ;
pNetwork [ 2 ] = pHeader [ 2 ] ;
value = fread ( pNetwork + 3 , sizeof ( char ) , 4 * pHeader [ ABC_EXACT_SOL_NGATES ] + 2 + pHeader [ ABC_EXACT_SOL_NVARS ] , pFile ) ;
}
2016-08-04 18:51:35 +02:00
2016-08-22 10:57:38 +02:00
if ( ! fSynthImp & & pNetwork & & ! fResLimit ) continue ;
if ( ! fSynthRL & & pNetwork & & fResLimit ) continue ;
if ( ! fUnsynthImp & & ! pNetwork & & ! fResLimit ) continue ;
if ( ! fUnsynthRL & & ! pNetwork & & fResLimit ) continue ;
2016-08-04 18:51:35 +02:00
2016-08-22 10:57:38 +02:00
Ses_StoreAddEntry ( pStore , pTruth , nVars , pArrTimeProfile , pNetwork , fResLimit ) ;
2016-08-04 18:51:35 +02:00
}
fclose ( pFile ) ;
2016-08-22 10:57:38 +02:00
printf ( " read %lu entries from file \n " , nEntries ) ;
2016-08-04 18:51:35 +02:00
}
2016-08-24 15:03:52 +02:00
// computes top decomposition of variables wrt. to AND and OR
static inline void Ses_ManComputeTopDec ( Ses_Man_t * pSes )
{
int l , i , mask = ~ 0 ;
word * pVar ;
int fAnd , fAndC , fOr , fOrC ;
if ( pSes - > nSpecVars < 6u )
mask = Abc_Tt6Mask ( 1u < < pSes - > nSpecVars ) ;
for ( l = 0 ; l < pSes - > nSpecVars ; + + l )
{
pVar = & s_Truths8 [ l < < 2 ] ;
fAnd = fAndC = fOr = fOrC = 1 ;
for ( i = 0 ; i < pSes - > nSpecWords ; + + i )
{
fAnd & = ( pVar [ i ] & pSes - > pSpec [ i ] & mask ) ! = ( pSes - > pSpec [ i ] & mask ) ;
fAndC & = ( ~ pVar [ i ] & pSes - > pSpec [ i ] & mask ) ! = ( pSes - > pSpec [ i ] & mask ) ;
fOr & = ( pVar [ i ] & pSes - > pSpec [ i ] & mask ) ! = ( pVar [ i ] & mask ) ;
fOrC & = ( ~ pVar [ i ] & pSes - > pSpec [ i ] & mask ) ! = ( ~ pVar [ i ] & mask ) ;
}
pSes - > pDecVars | = ( fAnd | fAndC | fOr | fOrC ) < < l ;
}
}
2016-08-08 18:50:19 +02:00
static inline Ses_Man_t * Ses_ManAlloc ( word * pTruth , int nVars , int nFunc , int nMaxDepth , int * pArrTimeProfile , int fMakeAIG , int nBTLimit , int fVerbose )
2016-07-28 20:37:09 +02:00
{
int h , i ;
2016-07-16 16:51:58 +02:00
Ses_Man_t * p = ABC_CALLOC ( Ses_Man_t , 1 ) ;
p - > pSat = NULL ;
p - > bSpecInv = 0 ;
for ( h = 0 ; h < nFunc ; + + h )
2016-07-28 20:37:09 +02:00
if ( pTruth [ h < < 2 ] & 1 )
2016-07-16 16:51:58 +02:00
{
2016-07-28 20:37:09 +02:00
for ( i = 0 ; i < 4 ; + + i )
pTruth [ ( h < < 2 ) + i ] = ~ pTruth [ ( h < < 2 ) + i ] ;
2016-07-16 16:51:58 +02:00
p - > bSpecInv | = ( 1 < < h ) ;
}
2016-08-08 18:50:19 +02:00
p - > pSpec = pTruth ;
p - > nSpecVars = nVars ;
p - > nSpecFunc = nFunc ;
2016-08-22 10:57:38 +02:00
p - > nSpecWords = Abc_TtWordNum ( nVars ) ;
2016-08-08 18:50:19 +02:00
p - > nRows = ( 1 < < nVars ) - 1 ;
p - > nMaxDepth = nMaxDepth ;
2016-07-30 13:34:39 +02:00
p - > pArrTimeProfile = nMaxDepth > = 0 ? pArrTimeProfile : NULL ;
if ( p - > pArrTimeProfile )
2016-07-31 12:24:02 +02:00
p - > nArrTimeDelta = Abc_NormalizeArrivalTimes ( p - > pArrTimeProfile , nVars , & p - > nArrTimeMax ) ;
2016-07-28 20:37:09 +02:00
else
2016-07-30 13:34:39 +02:00
p - > nArrTimeDelta = p - > nArrTimeMax = 0 ;
2016-08-08 18:50:19 +02:00
p - > fMakeAIG = fMakeAIG ;
p - > nBTLimit = nBTLimit ;
p - > fVerbose = fVerbose ;
p - > fVeryVerbose = 0 ;
p - > fExtractVerbose = 0 ;
2016-08-08 18:52:11 +02:00
p - > fSatVerbose = 0 ;
2016-07-16 16:51:58 +02:00
2016-08-24 15:03:52 +02:00
if ( p - > nSpecFunc = = 1 )
Ses_ManComputeTopDec ( p ) ;
2016-07-16 16:51:58 +02:00
return p ;
}
2016-08-21 19:28:55 +02:00
static inline void Ses_ManCleanLight ( Ses_Man_t * pSes )
2016-07-16 16:51:58 +02:00
{
2016-07-28 20:37:09 +02:00
int h , i ;
2016-07-16 16:51:58 +02:00
for ( h = 0 ; h < pSes - > nSpecFunc ; + + h )
if ( ( pSes - > bSpecInv > > h ) & 1 )
2016-07-28 20:37:09 +02:00
for ( i = 0 ; i < 4 ; + + i )
pSes - > pSpec [ ( h < < 2 ) + i ] = ~ ( pSes - > pSpec [ ( h < < 2 ) + i ] ) ;
2016-07-30 13:34:39 +02:00
if ( pSes - > pArrTimeProfile )
2016-07-28 20:37:09 +02:00
for ( i = 0 ; i < pSes - > nSpecVars ; + + i )
2016-07-30 13:34:39 +02:00
pSes - > pArrTimeProfile [ i ] + = pSes - > nArrTimeDelta ;
2016-07-16 16:51:58 +02:00
2016-08-21 19:28:55 +02:00
ABC_FREE ( pSes ) ;
}
static inline void Ses_ManClean ( Ses_Man_t * pSes )
{
2016-07-16 16:51:58 +02:00
if ( pSes - > pSat )
sat_solver_delete ( pSes - > pSat ) ;
2016-08-21 19:28:55 +02:00
Ses_ManCleanLight ( pSes ) ;
2016-07-16 16:51:58 +02:00
}
/**Function*************************************************************
Synopsis [ Access variables based on indexes . ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static inline int Ses_ManSimVar ( Ses_Man_t * pSes , int i , int t )
{
assert ( i < pSes - > nGates ) ;
assert ( t < pSes - > nRows ) ;
return pSes - > nRows * i + t ;
}
static inline int Ses_ManOutputVar ( Ses_Man_t * pSes , int h , int i )
{
assert ( h < pSes - > nSpecFunc ) ;
assert ( i < pSes - > nGates ) ;
return pSes - > nOutputOffset + pSes - > nGates * h + i ;
}
static inline int Ses_ManGateVar ( Ses_Man_t * pSes , int i , int p , int q )
{
assert ( i < pSes - > nGates ) ;
assert ( p < 2 ) ;
assert ( q < 2 ) ;
assert ( p > 0 | | q > 0 ) ;
return pSes - > nGateOffset + i * 3 + ( p < < 1 ) + q - 1 ;
}
static inline int Ses_ManSelectVar ( Ses_Man_t * pSes , int i , int j , int k )
{
int a ;
int offset ;
assert ( i < pSes - > nGates ) ;
assert ( k < pSes - > nSpecVars + i ) ;
assert ( j < k ) ;
offset = pSes - > nSelectOffset ;
for ( a = pSes - > nSpecVars ; a < pSes - > nSpecVars + i ; + + a )
offset + = a * ( a - 1 ) / 2 ;
return offset + ( - j * ( 1 + j - 2 * ( pSes - > nSpecVars + i ) ) ) / 2 + ( k - j - 1 ) ;
}
2016-07-23 22:13:07 +02:00
static inline int Ses_ManDepthVar ( Ses_Man_t * pSes , int i , int j )
{
assert ( i < pSes - > nGates ) ;
2016-07-30 13:34:39 +02:00
assert ( j < = pSes - > nArrTimeMax + i ) ;
2016-07-23 22:13:07 +02:00
2016-07-30 13:34:39 +02:00
return pSes - > nDepthOffset + i * pSes - > nArrTimeMax + ( ( i * ( i + 1 ) ) / 2 ) + j ;
2016-07-23 22:13:07 +02:00
}
2016-07-16 16:51:58 +02:00
/**Function*************************************************************
Synopsis [ Setup variables to find network with nGates gates . ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void Ses_ManCreateVars ( Ses_Man_t * pSes , int nGates )
{
int i ;
2016-08-08 12:59:21 +02:00
if ( pSes - > fSatVerbose )
2016-07-16 16:51:58 +02:00
{
printf ( " create variables for network with %d functions over %d variables and %d gates \n " , pSes - > nSpecFunc , pSes - > nSpecVars , nGates ) ;
}
pSes - > nGates = nGates ;
pSes - > nSimVars = nGates * pSes - > nRows ;
pSes - > nOutputVars = pSes - > nSpecFunc * nGates ;
pSes - > nGateVars = nGates * 3 ;
pSes - > nSelectVars = 0 ;
for ( i = pSes - > nSpecVars ; i < pSes - > nSpecVars + nGates ; + + i )
pSes - > nSelectVars + = ( i * ( i - 1 ) ) / 2 ;
2016-07-30 13:34:39 +02:00
pSes - > nDepthVars = pSes - > nMaxDepth > 0 ? nGates * pSes - > nArrTimeMax + ( nGates * ( nGates + 1 ) ) / 2 : 0 ;
2016-07-16 16:51:58 +02:00
pSes - > nOutputOffset = pSes - > nSimVars ;
pSes - > nGateOffset = pSes - > nSimVars + pSes - > nOutputVars ;
pSes - > nSelectOffset = pSes - > nSimVars + pSes - > nOutputVars + pSes - > nGateVars ;
2016-07-23 22:13:07 +02:00
pSes - > nDepthOffset = pSes - > nSimVars + pSes - > nOutputVars + pSes - > nGateVars + pSes - > nSelectVars ;
2016-07-16 16:51:58 +02:00
2016-08-21 19:28:55 +02:00
/* if we already have a SAT solver, then restart it (this saves a lot of time) */
2016-07-16 16:51:58 +02:00
if ( pSes - > pSat )
2016-08-21 19:28:55 +02:00
sat_solver_restart ( pSes - > pSat ) ;
else
pSes - > pSat = sat_solver_new ( ) ;
2016-07-23 22:13:07 +02:00
sat_solver_setnvars ( pSes - > pSat , pSes - > nSimVars + pSes - > nOutputVars + pSes - > nGateVars + pSes - > nSelectVars + pSes - > nDepthVars ) ;
2016-07-16 16:51:58 +02:00
}
/**Function*************************************************************
Synopsis [ Create clauses . ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static inline void Ses_ManCreateMainClause ( Ses_Man_t * pSes , int t , int i , int j , int k , int a , int b , int c )
{
2016-08-21 19:28:55 +02:00
int pLits [ 5 ] , ctr = 0 ;
2016-07-16 16:51:58 +02:00
pLits [ ctr + + ] = Abc_Var2Lit ( Ses_ManSelectVar ( pSes , i , j , k ) , 1 ) ;
pLits [ ctr + + ] = Abc_Var2Lit ( Ses_ManSimVar ( pSes , i , t ) , a ) ;
if ( j < pSes - > nSpecVars )
{
2016-08-21 18:13:57 +02:00
if ( ( ( ( t + 1 ) & ( 1 < < j ) ) ? 1 : 0 ) ! = b )
2016-07-16 16:51:58 +02:00
return ;
}
else
pLits [ ctr + + ] = Abc_Var2Lit ( Ses_ManSimVar ( pSes , j - pSes - > nSpecVars , t ) , b ) ;
if ( k < pSes - > nSpecVars )
{
2016-08-21 18:13:57 +02:00
if ( ( ( ( t + 1 ) & ( 1 < < k ) ) ? 1 : 0 ) ! = c )
2016-07-16 16:51:58 +02:00
return ;
}
else
pLits [ ctr + + ] = Abc_Var2Lit ( Ses_ManSimVar ( pSes , k - pSes - > nSpecVars , t ) , c ) ;
if ( b > 0 | | c > 0 )
pLits [ ctr + + ] = Abc_Var2Lit ( Ses_ManGateVar ( pSes , i , b , c ) , 1 - a ) ;
2016-08-21 19:28:55 +02:00
sat_solver_addclause ( pSes - > pSat , pLits , pLits + ctr ) ;
2016-07-16 16:51:58 +02:00
}
2016-08-04 14:22:31 +02:00
static int Ses_ManCreateClauses ( Ses_Man_t * pSes )
2016-07-16 16:51:58 +02:00
{
extern int Extra_TruthVarsSymm ( unsigned * pTruth , int nVars , int iVar0 , int iVar1 ) ;
2016-08-24 09:29:02 +02:00
int h , i , j , k , t , ii , jj , kk , p , q ;
2016-07-23 22:13:07 +02:00
int pLits [ 3 ] ;
2016-08-24 15:03:52 +02:00
Vec_Int_t * vLits = NULL ;
2016-07-16 16:51:58 +02:00
for ( t = 0 ; t < pSes - > nRows ; + + t )
for ( i = 0 ; i < pSes - > nGates ; + + i )
{
/* main clauses */
for ( j = 0 ; j < pSes - > nSpecVars + i ; + + j )
for ( k = j + 1 ; k < pSes - > nSpecVars + i ; + + k )
{
Ses_ManCreateMainClause ( pSes , t , i , j , k , 0 , 0 , 1 ) ;
Ses_ManCreateMainClause ( pSes , t , i , j , k , 0 , 1 , 0 ) ;
Ses_ManCreateMainClause ( pSes , t , i , j , k , 0 , 1 , 1 ) ;
Ses_ManCreateMainClause ( pSes , t , i , j , k , 1 , 0 , 0 ) ;
Ses_ManCreateMainClause ( pSes , t , i , j , k , 1 , 0 , 1 ) ;
Ses_ManCreateMainClause ( pSes , t , i , j , k , 1 , 1 , 0 ) ;
Ses_ManCreateMainClause ( pSes , t , i , j , k , 1 , 1 , 1 ) ;
}
/* output clauses */
2016-08-24 15:03:52 +02:00
if ( pSes - > nSpecFunc ! = 1 )
for ( h = 0 ; h < pSes - > nSpecFunc ; + + h )
{
pLits [ 0 ] = Abc_Var2Lit ( Ses_ManOutputVar ( pSes , h , i ) , 1 ) ;
pLits [ 1 ] = Abc_Var2Lit ( Ses_ManSimVar ( pSes , i , t ) , 1 - Abc_TtGetBit ( & pSes - > pSpec [ h < < 2 ] , t + 1 ) ) ;
if ( ! sat_solver_addclause ( pSes - > pSat , pLits , pLits + 2 ) )
return 0 ;
}
2016-07-16 16:51:58 +02:00
}
2016-08-22 10:57:38 +02:00
/* if there is only one output, we know it must point to the last gate */
if ( pSes - > nSpecFunc = = 1 )
2016-07-16 16:51:58 +02:00
{
2016-08-22 10:57:38 +02:00
for ( i = 0 ; i < pSes - > nGates - 1 ; + + i )
{
pLits [ 0 ] = Abc_Var2Lit ( Ses_ManOutputVar ( pSes , 0 , i ) , 1 ) ;
if ( ! sat_solver_addclause ( pSes - > pSat , pLits , pLits + 1 ) )
{
Vec_IntFree ( vLits ) ;
return 0 ;
}
}
pLits [ 0 ] = Abc_Var2Lit ( Ses_ManOutputVar ( pSes , 0 , pSes - > nGates - 1 ) , 0 ) ;
if ( ! sat_solver_addclause ( pSes - > pSat , pLits , pLits + 1 ) )
{
Vec_IntFree ( vLits ) ;
return 0 ;
}
2016-08-24 15:03:52 +02:00
for ( t = 0 ; t < pSes - > nRows ; + + t )
{
pLits [ 0 ] = Abc_Var2Lit ( Ses_ManSimVar ( pSes , pSes - > nGates - 1 , t ) , 1 - Abc_TtGetBit ( pSes - > pSpec , t + 1 ) ) ;
if ( ! sat_solver_addclause ( pSes - > pSat , pLits , pLits + 1 ) )
return 0 ;
}
vLits = Vec_IntAlloc ( 0u ) ;
2016-08-22 10:57:38 +02:00
}
else
{
2016-08-24 15:03:52 +02:00
vLits = Vec_IntAlloc ( 0u ) ;
2016-08-22 10:57:38 +02:00
/* some output is selected */
for ( h = 0 ; h < pSes - > nSpecFunc ; + + h )
{
Vec_IntGrowResize ( vLits , pSes - > nGates ) ;
for ( i = 0 ; i < pSes - > nGates ; + + i )
Vec_IntSetEntry ( vLits , i , Abc_Var2Lit ( Ses_ManOutputVar ( pSes , h , i ) , 0 ) ) ;
sat_solver_addclause ( pSes - > pSat , Vec_IntArray ( vLits ) , Vec_IntArray ( vLits ) + pSes - > nGates ) ;
}
2016-07-16 16:51:58 +02:00
}
/* each gate has two operands */
for ( i = 0 ; i < pSes - > nGates ; + + i )
{
2016-08-21 19:28:55 +02:00
Vec_IntGrowResize ( vLits , ( ( pSes - > nSpecVars + i ) * ( pSes - > nSpecVars + i - 1 ) ) / 2 ) ;
jj = 0 ;
2016-07-16 16:51:58 +02:00
for ( j = 0 ; j < pSes - > nSpecVars + i ; + + j )
for ( k = j + 1 ; k < pSes - > nSpecVars + i ; + + k )
2016-08-21 19:28:55 +02:00
Vec_IntSetEntry ( vLits , jj + + , Abc_Var2Lit ( Ses_ManSelectVar ( pSes , i , j , k ) , 0 ) ) ;
sat_solver_addclause ( pSes - > pSat , Vec_IntArray ( vLits ) , Vec_IntArray ( vLits ) + jj ) ;
2016-07-16 16:51:58 +02:00
}
2016-08-24 09:29:02 +02:00
/* gate decomposition (makes it worse) */
/* if ( fDecVariable >= 0 && pSes->nGates >= 2 ) */
/* { */
/* pLits[0] = Abc_Var2Lit( Ses_ManSelectVar( pSes, pSes->nGates - 1, fDecVariable, pSes->nSpecVars + pSes->nGates - 2 ), 0 ); */
/* if ( !sat_solver_addclause( pSes->pSat, pLits, pLits + 1 ) ) */
/* { */
/* Vec_IntFree( vLits ); */
/* return 0; */
/* } */
/* for ( k = 1; k < pSes->nSpecVars + pSes->nGates - 1; ++k ) */
/* for ( j = 0; j < k; ++j ) */
/* if ( j != fDecVariable || k != pSes->nSpecVars + pSes->nGates - 2 ) */
/* { */
/* pLits[0] = Abc_Var2Lit( Ses_ManSelectVar( pSes, pSes->nGates - 1, j, k ), 1 ); */
/* if ( !sat_solver_addclause( pSes->pSat, pLits, pLits + 1 ) ) */
/* { */
/* Vec_IntFree( vLits ); */
/* return 0; */
/* } */
/* } */
/* } */
2016-07-28 20:37:09 +02:00
/* only AIG */
if ( pSes - > fMakeAIG )
{
for ( i = 0 ; i < pSes - > nGates ; + + i )
{
/* not 2 ones */
pLits [ 0 ] = Abc_Var2Lit ( Ses_ManGateVar ( pSes , i , 0 , 1 ) , 1 ) ;
pLits [ 1 ] = Abc_Var2Lit ( Ses_ManGateVar ( pSes , i , 1 , 0 ) , 1 ) ;
pLits [ 2 ] = Abc_Var2Lit ( Ses_ManGateVar ( pSes , i , 1 , 1 ) , 0 ) ;
2016-08-21 19:28:55 +02:00
sat_solver_addclause ( pSes - > pSat , pLits , pLits + 3 ) ;
2016-07-28 20:37:09 +02:00
pLits [ 0 ] = Abc_Var2Lit ( Ses_ManGateVar ( pSes , i , 0 , 1 ) , 1 ) ;
pLits [ 1 ] = Abc_Var2Lit ( Ses_ManGateVar ( pSes , i , 1 , 0 ) , 0 ) ;
pLits [ 2 ] = Abc_Var2Lit ( Ses_ManGateVar ( pSes , i , 1 , 1 ) , 1 ) ;
2016-08-21 19:28:55 +02:00
sat_solver_addclause ( pSes - > pSat , pLits , pLits + 3 ) ;
2016-07-28 20:37:09 +02:00
pLits [ 0 ] = Abc_Var2Lit ( Ses_ManGateVar ( pSes , i , 0 , 1 ) , 0 ) ;
pLits [ 1 ] = Abc_Var2Lit ( Ses_ManGateVar ( pSes , i , 1 , 0 ) , 1 ) ;
pLits [ 2 ] = Abc_Var2Lit ( Ses_ManGateVar ( pSes , i , 1 , 1 ) , 1 ) ;
2016-08-21 19:28:55 +02:00
sat_solver_addclause ( pSes - > pSat , pLits , pLits + 3 ) ;
2016-07-28 20:37:09 +02:00
}
}
2016-07-16 16:51:58 +02:00
/* EXTRA clauses: use gate i at least once */
2016-08-21 19:28:55 +02:00
Vec_IntGrowResize ( vLits , pSes - > nSpecFunc + pSes - > nGates * ( pSes - > nSpecVars + pSes - > nGates - 2 ) ) ;
2016-07-16 16:51:58 +02:00
for ( i = 0 ; i < pSes - > nGates ; + + i )
{
2016-08-21 19:28:55 +02:00
jj = 0 ;
2016-07-16 16:51:58 +02:00
for ( h = 0 ; h < pSes - > nSpecFunc ; + + h )
2016-08-21 19:28:55 +02:00
Vec_IntSetEntry ( vLits , jj + + , Abc_Var2Lit ( Ses_ManOutputVar ( pSes , h , i ) , 0 ) ) ;
2016-07-16 16:51:58 +02:00
for ( ii = i + 1 ; ii < pSes - > nGates ; + + ii )
{
for ( j = 0 ; j < pSes - > nSpecVars + i ; + + j )
2016-08-21 19:28:55 +02:00
Vec_IntSetEntry ( vLits , jj + + , Abc_Var2Lit ( Ses_ManSelectVar ( pSes , ii , j , pSes - > nSpecVars + i ) , 0 ) ) ;
2016-07-16 16:51:58 +02:00
for ( j = pSes - > nSpecVars + i + 1 ; j < pSes - > nSpecVars + ii ; + + j )
2016-08-21 19:28:55 +02:00
Vec_IntSetEntry ( vLits , jj + + , Abc_Var2Lit ( Ses_ManSelectVar ( pSes , ii , pSes - > nSpecVars + i , j ) , 0 ) ) ;
2016-07-16 16:51:58 +02:00
}
2016-08-21 19:28:55 +02:00
sat_solver_addclause ( pSes - > pSat , Vec_IntArray ( vLits ) , Vec_IntArray ( vLits ) + jj ) ;
2016-07-16 16:51:58 +02:00
}
2016-08-21 19:28:55 +02:00
Vec_IntFree ( vLits ) ;
2016-07-16 16:51:58 +02:00
/* EXTRA clauses: co-lexicographic order */
for ( i = 0 ; i < pSes - > nGates - 1 ; + + i )
{
for ( k = 2 ; k < pSes - > nSpecVars + i ; + + k )
{
for ( j = 1 ; j < k ; + + j )
for ( jj = 0 ; jj < j ; + + jj )
{
pLits [ 0 ] = Abc_Var2Lit ( Ses_ManSelectVar ( pSes , i , j , k ) , 1 ) ;
pLits [ 1 ] = Abc_Var2Lit ( Ses_ManSelectVar ( pSes , i + 1 , jj , k ) , 1 ) ;
}
for ( j = 0 ; j < k ; + + j )
for ( kk = 1 ; kk < k ; + + kk )
for ( jj = 0 ; jj < kk ; + + jj )
{
pLits [ 0 ] = Abc_Var2Lit ( Ses_ManSelectVar ( pSes , i , j , k ) , 1 ) ;
pLits [ 1 ] = Abc_Var2Lit ( Ses_ManSelectVar ( pSes , i + 1 , jj , kk ) , 1 ) ;
}
}
}
/* EXTRA clauses: symmetric variables */
2016-08-08 10:59:29 +02:00
if ( pSes - > nMaxDepth = = - 1 & & pSes - > nSpecFunc = = 1 ) /* only check if there is one output function */
2016-07-16 16:51:58 +02:00
for ( q = 1 ; q < pSes - > nSpecVars ; + + q )
for ( p = 0 ; p < q ; + + p )
2016-07-28 20:37:09 +02:00
if ( Extra_TruthVarsSymm ( ( unsigned * ) ( & pSes - > pSpec [ h < < 2 ] ) , pSes - > nSpecVars , p , q ) )
2016-07-16 16:51:58 +02:00
{
if ( pSes - > fVeryVerbose )
printf ( " variables %d and %d are symmetric \n " , p , q ) ;
for ( i = 0 ; i < pSes - > nGates ; + + i )
for ( j = 0 ; j < q ; + + j )
{
if ( j = = p ) continue ;
vLits = Vec_IntAlloc ( 0 ) ;
Vec_IntPush ( vLits , Abc_Var2Lit ( Ses_ManSelectVar ( pSes , i , j , q ) , 1 ) ) ;
for ( ii = 0 ; ii < i ; + + ii )
for ( kk = 1 ; kk < pSes - > nSpecVars + ii ; + + kk )
for ( jj = 0 ; jj < kk ; + + jj )
if ( jj = = p | | kk = = p )
Vec_IntPush ( vLits , Abc_Var2Lit ( Ses_ManSelectVar ( pSes , ii , jj , kk ) , 0 ) ) ;
2016-08-21 19:28:55 +02:00
sat_solver_addclause ( pSes - > pSat , Vec_IntArray ( vLits ) , Vec_IntLimit ( vLits ) ) ;
2016-07-16 16:51:58 +02:00
Vec_IntFree ( vLits ) ;
}
}
2016-07-23 22:13:07 +02:00
2016-08-24 09:29:02 +02:00
return 1 ;
}
2016-07-23 22:13:07 +02:00
2016-08-24 09:29:02 +02:00
static int Ses_ManCreateDepthClauses ( Ses_Man_t * pSes )
{
int i , j , k , jj , kk , d , h ;
int pLits [ 3 ] ;
2016-07-28 20:37:09 +02:00
2016-08-24 09:29:02 +02:00
for ( i = 0 ; i < pSes - > nGates ; + + i )
{
/* propagate depths from children */
for ( k = 1 ; k < i ; + + k )
for ( j = 0 ; j < k ; + + j )
2016-07-28 20:37:09 +02:00
{
2016-08-24 09:29:02 +02:00
pLits [ 0 ] = Abc_Var2Lit ( Ses_ManSelectVar ( pSes , i , pSes - > nSpecVars + j , pSes - > nSpecVars + k ) , 1 ) ;
for ( jj = 0 ; jj < = pSes - > nArrTimeMax + j ; + + jj )
{
pLits [ 1 ] = Abc_Var2Lit ( Ses_ManDepthVar ( pSes , j , jj ) , 1 ) ;
pLits [ 2 ] = Abc_Var2Lit ( Ses_ManDepthVar ( pSes , i , jj + 1 ) , 0 ) ;
sat_solver_addclause ( pSes - > pSat , pLits , pLits + 3 ) ;
}
2016-07-28 20:37:09 +02:00
}
2016-07-23 22:13:07 +02:00
2016-08-24 09:29:02 +02:00
for ( k = 0 ; k < i ; + + k )
for ( j = 0 ; j < pSes - > nSpecVars + k ; + + j )
2016-07-23 22:13:07 +02:00
{
2016-08-24 09:29:02 +02:00
pLits [ 0 ] = Abc_Var2Lit ( Ses_ManSelectVar ( pSes , i , j , pSes - > nSpecVars + k ) , 1 ) ;
for ( kk = 0 ; kk < = pSes - > nArrTimeMax + k ; + + kk )
{
pLits [ 1 ] = Abc_Var2Lit ( Ses_ManDepthVar ( pSes , k , kk ) , 1 ) ;
pLits [ 2 ] = Abc_Var2Lit ( Ses_ManDepthVar ( pSes , i , kk + 1 ) , 0 ) ;
sat_solver_addclause ( pSes - > pSat , pLits , pLits + 3 ) ;
}
2016-07-23 22:13:07 +02:00
}
2016-08-24 09:29:02 +02:00
/* propagate depths from arrival times at PIs */
if ( pSes - > pArrTimeProfile )
{
for ( k = 1 ; k < pSes - > nSpecVars + i ; + + k )
for ( j = 0 ; j < ( ( k < pSes - > nSpecVars ) ? k : pSes - > nSpecVars ) ; + + j )
2016-07-23 22:13:07 +02:00
{
2016-08-24 09:29:02 +02:00
d = pSes - > pArrTimeProfile [ j ] ;
if ( k < pSes - > nSpecVars & & pSes - > pArrTimeProfile [ k ] > d )
d = pSes - > pArrTimeProfile [ k ] ;
pLits [ 0 ] = Abc_Var2Lit ( Ses_ManSelectVar ( pSes , i , j , k ) , 1 ) ;
pLits [ 1 ] = Abc_Var2Lit ( Ses_ManDepthVar ( pSes , i , d ) , 0 ) ;
sat_solver_addclause ( pSes - > pSat , pLits , pLits + 2 ) ;
2016-07-23 22:13:07 +02:00
}
}
2016-08-24 09:29:02 +02:00
else
{
/* arrival times are 0 */
pLits [ 0 ] = Abc_Var2Lit ( Ses_ManDepthVar ( pSes , i , 0 ) , 0 ) ;
sat_solver_addclause ( pSes - > pSat , pLits , pLits + 1 ) ;
}
/* reverse order encoding of depth variables */
for ( j = 1 ; j < = pSes - > nArrTimeMax + i ; + + j )
{
pLits [ 0 ] = Abc_Var2Lit ( Ses_ManDepthVar ( pSes , i , j ) , 1 ) ;
pLits [ 1 ] = Abc_Var2Lit ( Ses_ManDepthVar ( pSes , i , j - 1 ) , 0 ) ;
sat_solver_addclause ( pSes - > pSat , pLits , pLits + 2 ) ;
}
/* constrain maximum depth */
if ( pSes - > nMaxDepth < pSes - > nArrTimeMax + i )
for ( h = 0 ; h < pSes - > nSpecFunc ; + + h )
{
pLits [ 0 ] = Abc_Var2Lit ( Ses_ManOutputVar ( pSes , h , i ) , 1 ) ;
pLits [ 1 ] = Abc_Var2Lit ( Ses_ManDepthVar ( pSes , i , pSes - > nMaxDepth ) , 1 ) ;
if ( ! sat_solver_addclause ( pSes - > pSat , pLits , pLits + 2 ) )
return 0 ;
}
2016-07-23 22:13:07 +02:00
}
2016-08-04 14:22:31 +02:00
return 1 ;
2016-07-16 16:51:58 +02:00
}
/**Function*************************************************************
Synopsis [ Solve . ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static inline int Ses_ManSolve ( Ses_Man_t * pSes )
{
int status ;
abctime timeStart , timeDelta ;
2016-08-08 12:59:21 +02:00
if ( pSes - > fSatVerbose )
2016-07-28 20:37:09 +02:00
{
printf ( " solve SAT instance with %d clauses and %d variables \n " , sat_solver_nclauses ( pSes - > pSat ) , sat_solver_nvars ( pSes - > pSat ) ) ;
}
2016-07-16 16:51:58 +02:00
timeStart = Abc_Clock ( ) ;
2016-07-28 20:37:09 +02:00
status = sat_solver_solve ( pSes - > pSat , NULL , NULL , pSes - > nBTLimit , 0 , 0 , 0 ) ;
2016-07-16 16:51:58 +02:00
timeDelta = Abc_Clock ( ) - timeStart ;
2016-08-24 15:03:52 +02:00
if ( pSes - > fSatVerbose )
Sat_SolverPrintStats ( stdout , pSes - > pSat ) ;
2016-07-16 16:51:58 +02:00
pSes - > timeSat + = timeDelta ;
if ( status = = l_True )
{
2016-08-21 18:13:57 +02:00
pSes - > nSatCalls + + ;
2016-07-16 16:51:58 +02:00
pSes - > timeSatSat + = timeDelta ;
return 1 ;
}
else if ( status = = l_False )
{
2016-08-21 18:13:57 +02:00
pSes - > nUnsatCalls + + ;
2016-07-16 16:51:58 +02:00
pSes - > timeSatUnsat + = timeDelta ;
return 0 ;
}
else
{
2016-08-21 18:13:57 +02:00
pSes - > nUndefCalls + + ;
pSes - > timeSatUndef + = timeDelta ;
2016-08-08 12:59:21 +02:00
if ( pSes - > fSatVerbose )
2016-07-16 16:51:58 +02:00
{
2016-07-28 20:37:09 +02:00
printf ( " resource limit reached \n " ) ;
2016-07-16 16:51:58 +02:00
}
2016-07-28 20:37:09 +02:00
return 2 ;
2016-07-16 16:51:58 +02:00
}
}
/**Function*************************************************************
Synopsis [ Extract solution . ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2016-07-30 13:34:39 +02:00
// char is an array of short integers that stores the synthesized network
// using the following format
2016-07-30 14:40:12 +02:00
// | nvars | nfunc | ngates | gate[1] | ... | gate[ngates] | func[1] | .. | func[nfunc] |
// nvars: integer with number of variables
// nfunc: integer with number of functions
// ngates: integer with number of gates
// gate[i]: | op | nfanin | fanin[1] | ... | fanin[nfanin] |
// op: integer of gate's truth table (divided by 2, because gate is normal)
// nfanin[i]: integer with number of fanins
// fanin: integer to primary input or other gate
// func[i]: | fanin | delay | pin[1] | ... | pin[nvars] |
// fanin: integer as literal to some gate (not primary input), can be complemented
// delay: maximum delay to output (taking arrival times into account, not normalized) or 0 if not specified
// pin[i]: pin to pin delay to input i or 0 if not specified or if there is no connection to input i
// NOTE: since outputs can only point to gates, delay and pin-to-pin times cannot be 0
2016-07-30 13:34:39 +02:00
static char * Ses_ManExtractSolution ( Ses_Man_t * pSes )
2016-07-16 16:51:58 +02:00
{
2016-07-30 14:40:12 +02:00
int nSol , h , i , j , k , l , aj , ak , d , nOp ;
2016-07-30 13:34:39 +02:00
char * pSol , * p ;
2016-08-06 05:45:56 +02:00
int * pPerm = NULL ; /* will be a 2d array [i][l] where is is gate id and l is PI id */
2016-07-30 13:34:39 +02:00
/* compute length of solution, for now all gates have 2 inputs */
2016-07-30 14:40:12 +02:00
nSol = 3 + pSes - > nGates * 4 + pSes - > nSpecFunc * ( 2 + pSes - > nSpecVars ) ;
2016-07-30 13:34:39 +02:00
p = pSol = ABC_CALLOC ( char , nSol ) ;
/* header */
* p + + = pSes - > nSpecVars ;
* p + + = pSes - > nSpecFunc ;
* p + + = pSes - > nGates ;
/* gates */
for ( i = 0 ; i < pSes - > nGates ; + + i )
{
nOp = sat_solver_var_value ( pSes - > pSat , Ses_ManGateVar ( pSes , i , 0 , 1 ) ) ;
nOp | = sat_solver_var_value ( pSes - > pSat , Ses_ManGateVar ( pSes , i , 1 , 0 ) ) < < 1 ;
nOp | = sat_solver_var_value ( pSes - > pSat , Ses_ManGateVar ( pSes , i , 1 , 1 ) ) < < 2 ;
* p + + = nOp ;
* p + + = 2 ;
2016-08-08 12:59:21 +02:00
if ( pSes - > fExtractVerbose )
2016-08-02 13:24:21 +02:00
printf ( " add gate %d with operation %d " , pSes - > nSpecVars + i , nOp ) ;
2016-07-30 13:34:39 +02:00
for ( k = 0 ; k < pSes - > nSpecVars + i ; + + k )
for ( j = 0 ; j < k ; + + j )
if ( sat_solver_var_value ( pSes - > pSat , Ses_ManSelectVar ( pSes , i , j , k ) ) )
{
2016-08-08 12:59:21 +02:00
if ( pSes - > fExtractVerbose )
2016-08-02 13:24:21 +02:00
printf ( " and operands %d and %d " , j , k ) ;
2016-07-30 13:34:39 +02:00
* p + + = j ;
* p + + = k ;
2016-08-24 09:29:02 +02:00
k = pSes - > nSpecVars + i ;
2016-07-30 13:34:39 +02:00
break ;
}
2016-08-08 12:59:21 +02:00
if ( pSes - > fExtractVerbose )
2016-08-02 13:24:21 +02:00
{
if ( pSes - > nMaxDepth > 0 )
{
printf ( " and depth vector " ) ;
for ( j = 0 ; j < = pSes - > nArrTimeMax + i ; + + j )
printf ( " %d " , sat_solver_var_value ( pSes - > pSat , Ses_ManDepthVar ( pSes , i , j ) ) ) ;
}
printf ( " \n " ) ;
}
2016-07-30 13:34:39 +02:00
}
2016-07-30 14:40:12 +02:00
/* pin-to-pin delay */
if ( pSes - > nMaxDepth ! = - 1 )
{
pPerm = ABC_CALLOC ( int , pSes - > nGates * pSes - > nSpecVars ) ;
for ( i = 0 ; i < pSes - > nGates ; + + i )
{
/* since all gates are binary for now */
j = pSol [ 3 + i * 4 + 2 ] ;
2016-08-02 13:24:21 +02:00
k = pSol [ 3 + i * 4 + 3 ] ;
2016-07-30 14:40:12 +02:00
for ( l = 0 ; l < pSes - > nSpecVars ; + + l )
{
/* pin-to-pin delay to input l of child nodes */
2016-08-02 13:24:21 +02:00
aj = j < pSes - > nSpecVars ? 0 : pPerm [ ( j - pSes - > nSpecVars ) * pSes - > nSpecVars + l ] ;
ak = k < pSes - > nSpecVars ? 0 : pPerm [ ( k - pSes - > nSpecVars ) * pSes - > nSpecVars + l ] ;
2016-07-30 14:40:12 +02:00
if ( aj = = 0 & & ak = = 0 )
2016-08-02 13:24:21 +02:00
pPerm [ i * pSes - > nSpecVars + l ] = ( l = = j | | l = = k ) ? 1 : 0 ;
2016-07-30 14:40:12 +02:00
else
2016-08-02 13:24:21 +02:00
pPerm [ i * pSes - > nSpecVars + l ] = Abc_MaxInt ( aj , ak ) + 1 ;
2016-07-30 14:40:12 +02:00
}
}
}
2016-07-30 13:34:39 +02:00
/* outputs */
for ( h = 0 ; h < pSes - > nSpecFunc ; + + h )
for ( i = 0 ; i < pSes - > nGates ; + + i )
if ( sat_solver_var_value ( pSes - > pSat , Ses_ManOutputVar ( pSes , h , i ) ) )
2016-07-30 14:40:12 +02:00
{
2016-07-30 13:34:39 +02:00
* p + + = Abc_Var2Lit ( i , ( pSes - > bSpecInv > > h ) & 1 ) ;
2016-07-30 14:40:12 +02:00
d = 0 ;
if ( pSes - > nMaxDepth ! = - 1 )
2016-08-08 10:59:29 +02:00
for ( l = 0 ; l < pSes - > nSpecVars ; + + l )
2016-08-15 16:20:30 +02:00
{
if ( pSes - > pArrTimeProfile )
d = Abc_MaxInt ( d , pSes - > pArrTimeProfile [ l ] + pPerm [ i * pSes - > nSpecVars + l ] ) ;
else
d = Abc_MaxInt ( d , pPerm [ i * pSes - > nSpecVars + l ] ) ;
}
2016-08-08 10:59:29 +02:00
* p + + = d ;
2016-08-15 16:20:30 +02:00
if ( pSes - > pArrTimeProfile & & pSes - > fExtractVerbose )
2016-08-24 09:29:02 +02:00
printf ( " output %d points to gate %d and has normalized delay %d (nArrTimeDelta = %d) \n " , h , pSes - > nSpecVars + i , d , pSes - > nArrTimeDelta ) ;
2016-08-02 13:24:21 +02:00
for ( l = 0 ; l < pSes - > nSpecVars ; + + l )
{
d = ( pSes - > nMaxDepth ! = - 1 ) ? pPerm [ i * pSes - > nSpecVars + l ] : 0 ;
2016-08-15 16:20:30 +02:00
if ( pSes - > pArrTimeProfile & & pSes - > fExtractVerbose )
2016-08-08 10:59:29 +02:00
printf ( " pin-to-pin arrival time from input %d is %d (pArrTimeProfile = %d) \n " , l , d , pSes - > pArrTimeProfile [ l ] ) ;
2016-08-02 13:24:21 +02:00
* p + + = d ;
}
2016-07-30 14:40:12 +02:00
}
/* pin-to-pin delays */
if ( pSes - > nMaxDepth ! = - 1 )
ABC_FREE ( pPerm ) ;
2016-07-30 13:34:39 +02:00
/* have we used all the fields? */
assert ( ( p - pSol ) = = nSol ) ;
return pSol ;
}
static Abc_Ntk_t * Ses_ManExtractNtk ( char const * pSol )
{
int h , i ;
char const * p ;
2016-07-16 16:51:58 +02:00
Abc_Ntk_t * pNtk ;
Abc_Obj_t * pObj ;
Vec_Ptr_t * pGates , * vNames ;
char pGateTruth [ 5 ] ;
char * pSopCover ;
pNtk = Abc_NtkAlloc ( ABC_NTK_LOGIC , ABC_FUNC_SOP , 1 ) ;
pNtk - > pName = Extra_UtilStrsav ( " exact " ) ;
2016-07-30 13:34:39 +02:00
pGates = Vec_PtrAlloc ( pSol [ ABC_EXACT_SOL_NVARS ] + pSol [ ABC_EXACT_SOL_NGATES ] ) ;
2016-07-16 16:51:58 +02:00
pGateTruth [ 3 ] = ' 0 ' ;
pGateTruth [ 4 ] = ' \0 ' ;
2016-07-30 13:34:39 +02:00
vNames = Abc_NodeGetFakeNames ( pSol [ ABC_EXACT_SOL_NVARS ] + pSol [ ABC_EXACT_SOL_NFUNC ] ) ;
2016-07-16 16:51:58 +02:00
/* primary inputs */
Vec_PtrPush ( pNtk - > vObjs , NULL ) ;
2016-07-30 13:34:39 +02:00
for ( i = 0 ; i < pSol [ ABC_EXACT_SOL_NVARS ] ; + + i )
2016-07-16 16:51:58 +02:00
{
pObj = Abc_NtkCreatePi ( pNtk ) ;
Abc_ObjAssignName ( pObj , ( char * ) Vec_PtrEntry ( vNames , i ) , NULL ) ;
Vec_PtrPush ( pGates , pObj ) ;
}
/* gates */
2016-07-30 13:34:39 +02:00
p = pSol + 3 ;
for ( i = 0 ; i < pSol [ ABC_EXACT_SOL_NGATES ] ; + + i )
2016-07-16 16:51:58 +02:00
{
2016-07-30 13:34:39 +02:00
pGateTruth [ 2 ] = ' 0 ' + ( * p & 1 ) ;
pGateTruth [ 1 ] = ' 0 ' + ( ( * p > > 1 ) & 1 ) ;
pGateTruth [ 0 ] = ' 0 ' + ( ( * p > > 2 ) & 1 ) ;
+ + p ;
2016-07-16 16:51:58 +02:00
2016-07-30 13:34:39 +02:00
assert ( * p = = 2 ) ; /* binary gate */
+ + p ;
2016-07-16 16:51:58 +02:00
pSopCover = Abc_SopFromTruthBin ( pGateTruth ) ;
pObj = Abc_NtkCreateNode ( pNtk ) ;
pObj - > pData = Abc_SopRegister ( ( Mem_Flex_t * ) pNtk - > pManFunc , pSopCover ) ;
Vec_PtrPush ( pGates , pObj ) ;
ABC_FREE ( pSopCover ) ;
2016-07-30 13:34:39 +02:00
Abc_ObjAddFanin ( pObj , ( Abc_Obj_t * ) Vec_PtrEntry ( pGates , * p + + ) ) ;
Abc_ObjAddFanin ( pObj , ( Abc_Obj_t * ) Vec_PtrEntry ( pGates , * p + + ) ) ;
2016-07-16 16:51:58 +02:00
}
/* outputs */
2016-07-30 14:40:12 +02:00
for ( h = 0 ; h < pSol [ ABC_EXACT_SOL_NFUNC ] ; + + h )
2016-07-16 16:51:58 +02:00
{
pObj = Abc_NtkCreatePo ( pNtk ) ;
2016-07-30 13:34:39 +02:00
Abc_ObjAssignName ( pObj , ( char * ) Vec_PtrEntry ( vNames , pSol [ ABC_EXACT_SOL_NVARS ] + h ) , NULL ) ;
if ( Abc_LitIsCompl ( * p ) )
Abc_ObjAddFanin ( pObj , Abc_NtkCreateNodeInv ( pNtk , ( Abc_Obj_t * ) Vec_PtrEntry ( pGates , pSol [ ABC_EXACT_SOL_NVARS ] + Abc_Lit2Var ( * p ) ) ) ) ;
else
Abc_ObjAddFanin ( pObj , ( Abc_Obj_t * ) Vec_PtrEntry ( pGates , pSol [ ABC_EXACT_SOL_NVARS ] + Abc_Lit2Var ( * p ) ) ) ;
2016-07-30 14:40:12 +02:00
p + = ( 2 + pSol [ ABC_EXACT_SOL_NVARS ] ) ;
2016-07-16 16:51:58 +02:00
}
Abc_NodeFreeNames ( vNames ) ;
Vec_PtrFree ( pGates ) ;
if ( ! Abc_NtkCheck ( pNtk ) )
printf ( " Ses_ManExtractSolution(): Network check has failed. \n " ) ;
return pNtk ;
}
2016-07-30 13:34:39 +02:00
static Gia_Man_t * Ses_ManExtractGia ( char const * pSol )
2016-07-28 20:37:09 +02:00
{
2016-07-30 13:34:39 +02:00
int h , i ;
char const * p ;
2016-07-28 20:37:09 +02:00
Gia_Man_t * pGia ;
Vec_Int_t * pGates ;
Vec_Ptr_t * vNames ;
int nObj , nChild1 , nChild2 , fChild1Comp , fChild2Comp ;
2016-07-30 13:34:39 +02:00
pGia = Gia_ManStart ( pSol [ ABC_EXACT_SOL_NVARS ] + pSol [ ABC_EXACT_SOL_NGATES ] + pSol [ ABC_EXACT_SOL_NFUNC ] + 1 ) ;
2016-07-28 20:37:09 +02:00
pGia - > nConstrs = 0 ;
pGia - > pName = Extra_UtilStrsav ( " exact " ) ;
2016-07-30 13:34:39 +02:00
pGates = Vec_IntAlloc ( pSol [ ABC_EXACT_SOL_NVARS ] + pSol [ ABC_EXACT_SOL_NGATES ] ) ;
vNames = Abc_NodeGetFakeNames ( pSol [ ABC_EXACT_SOL_NVARS ] + pSol [ ABC_EXACT_SOL_NFUNC ] ) ;
2016-07-28 20:37:09 +02:00
/* primary inputs */
2016-07-30 13:34:39 +02:00
pGia - > vNamesIn = Vec_PtrStart ( pSol [ ABC_EXACT_SOL_NVARS ] ) ;
for ( i = 0 ; i < pSol [ ABC_EXACT_SOL_NVARS ] ; + + i )
2016-07-28 20:37:09 +02:00
{
nObj = Gia_ManAppendCi ( pGia ) ;
Vec_IntPush ( pGates , nObj ) ;
2016-08-19 13:24:29 +02:00
Vec_PtrSetEntry ( pGia - > vNamesIn , i , Extra_UtilStrsav ( ( const char * ) Vec_PtrEntry ( vNames , i ) ) ) ;
2016-07-28 20:37:09 +02:00
}
/* gates */
2016-07-30 13:34:39 +02:00
p = pSol + 3 ;
for ( i = 0 ; i < pSol [ ABC_EXACT_SOL_NGATES ] ; + + i )
2016-07-28 20:37:09 +02:00
{
2016-07-30 13:34:39 +02:00
assert ( p [ 1 ] = = 2 ) ;
nChild1 = Vec_IntEntry ( pGates , p [ 2 ] ) ;
nChild2 = Vec_IntEntry ( pGates , p [ 3 ] ) ;
fChild1Comp = fChild2Comp = 0 ;
2016-07-28 20:37:09 +02:00
2016-07-30 13:34:39 +02:00
if ( * p & 1 )
{
nChild1 = Abc_LitNot ( nChild1 ) ;
fChild1Comp = 1 ;
}
if ( ( * p > > 1 ) & 1 )
{
nChild2 = Abc_LitNot ( nChild2 ) ;
fChild2Comp = 1 ;
}
nObj = Gia_ManAppendAnd ( pGia , nChild1 , nChild2 ) ;
if ( fChild1Comp & & fChild2Comp )
{
assert ( ( * p > > 2 ) & 1 ) ;
nObj = Abc_LitNot ( nObj ) ;
}
2016-07-28 20:37:09 +02:00
2016-07-30 13:34:39 +02:00
Vec_IntPush ( pGates , nObj ) ;
2016-07-28 20:37:09 +02:00
2016-07-30 13:34:39 +02:00
p + = 4 ;
2016-07-28 20:37:09 +02:00
}
/* outputs */
2016-07-30 13:34:39 +02:00
pGia - > vNamesOut = Vec_PtrStart ( pSol [ ABC_EXACT_SOL_NFUNC ] ) ;
2016-07-30 14:40:12 +02:00
for ( h = 0 ; h < pSol [ ABC_EXACT_SOL_NFUNC ] ; + + h )
2016-07-28 20:37:09 +02:00
{
2016-07-30 13:34:39 +02:00
nObj = Vec_IntEntry ( pGates , pSol [ ABC_EXACT_SOL_NVARS ] + Abc_Lit2Var ( * p ) ) ;
if ( Abc_LitIsCompl ( * p ) )
nObj = Abc_LitNot ( nObj ) ;
Gia_ManAppendCo ( pGia , nObj ) ;
2016-08-19 13:24:29 +02:00
Vec_PtrSetEntry ( pGia - > vNamesOut , h , Extra_UtilStrsav ( ( const char * ) Vec_PtrEntry ( vNames , pSol [ ABC_EXACT_SOL_NVARS ] + h ) ) ) ;
2016-07-30 14:40:12 +02:00
p + = ( 2 + pSol [ ABC_EXACT_SOL_NVARS ] ) ;
2016-07-28 20:37:09 +02:00
}
Abc_NodeFreeNames ( vNames ) ;
Vec_IntFree ( pGates ) ;
return pGia ;
}
2016-07-16 16:51:58 +02:00
/**Function*************************************************************
Synopsis [ Debug . ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void Ses_ManPrintRuntime ( Ses_Man_t * pSes )
{
printf ( " Runtime breakdown: \n " ) ;
2016-08-22 10:57:38 +02:00
ABC_PRTP ( " Sat " , pSes - > timeSat , pSes - > timeTotal ) ;
ABC_PRTP ( " Sat " , pSes - > timeSatSat , pSes - > timeTotal ) ;
ABC_PRTP ( " Unsat " , pSes - > timeSatUnsat , pSes - > timeTotal ) ;
ABC_PRTP ( " Undef " , pSes - > timeSatUndef , pSes - > timeTotal ) ;
ABC_PRTP ( " Instance " , pSes - > timeInstance , pSes - > timeTotal ) ;
ABC_PRTP ( " ALL " , pSes - > timeTotal , pSes - > timeTotal ) ;
2016-07-16 16:51:58 +02:00
}
2016-07-28 20:37:09 +02:00
static inline void Ses_ManPrintFuncs ( Ses_Man_t * pSes )
{
int h ;
printf ( " find optimum circuit for %d %d-variable functions: \n " , pSes - > nSpecFunc , pSes - > nSpecVars ) ;
for ( h = 0 ; h < pSes - > nSpecFunc ; + + h )
{
printf ( " func %d: " , h + 1 ) ;
Abc_TtPrintHexRev ( stdout , & pSes - > pSpec [ h > > 2 ] , pSes - > nSpecVars ) ;
printf ( " \n " ) ;
}
2016-08-08 18:50:19 +02:00
if ( pSes - > nMaxDepth ! = - 1 )
{
printf ( " max depth = %d \n " , pSes - > nMaxDepth ) ;
if ( pSes - > pArrTimeProfile )
{
printf ( " arrival times = " ) ;
for ( h = 0 ; h < pSes - > nSpecVars ; + + h )
printf ( " %d " , pSes - > pArrTimeProfile [ h ] ) ;
printf ( " \n " ) ;
}
}
2016-07-28 20:37:09 +02:00
}
2016-07-16 16:51:58 +02:00
static inline void Ses_ManPrintVars ( Ses_Man_t * pSes )
{
int h , i , j , k , p , q , t ;
for ( i = 0 ; i < pSes - > nGates ; + + i )
for ( t = 0 ; t < pSes - > nRows ; + + t )
printf ( " x(%d, %d) : %d \n " , i , t , Ses_ManSimVar ( pSes , i , t ) ) ;
for ( h = 0 ; h < pSes - > nSpecFunc ; + + h )
for ( i = 0 ; i < pSes - > nGates ; + + i )
printf ( " h(%d, %d) : %d \n " , h , i , Ses_ManOutputVar ( pSes , h , i ) ) ;
for ( i = 0 ; i < pSes - > nGates ; + + i )
for ( p = 0 ; p < = 1 ; + + p )
for ( q = 0 ; q < = 1 ; + + q )
{
if ( p = = 0 & & q = = 0 ) { continue ; }
printf ( " f(%d, %d, %d) : %d \n " , i , p , q , Ses_ManGateVar ( pSes , i , p , q ) ) ;
}
for ( i = 0 ; i < pSes - > nGates ; + + i )
for ( j = 0 ; j < pSes - > nSpecVars + i ; + + j )
for ( k = j + 1 ; k < pSes - > nSpecVars + i ; + + k )
printf ( " s(%d, %d, %d) : %d \n " , i , j , k , Ses_ManSelectVar ( pSes , i , j , k ) ) ;
2016-07-23 22:13:07 +02:00
if ( pSes - > nMaxDepth > 0 )
for ( i = 0 ; i < pSes - > nGates ; + + i )
for ( j = 0 ; j < = i ; + + j )
printf ( " d(%d, %d) : %d \n " , i , j , Ses_ManDepthVar ( pSes , i , j ) ) ;
}
/**Function*************************************************************
Synopsis [ Synthesis algorithm . ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2016-08-24 09:29:02 +02:00
// returns 0, if current max depth and arrival times are not consistent
static int Ses_CheckDepthConsistency ( Ses_Man_t * pSes )
2016-07-23 22:13:07 +02:00
{
2016-08-24 09:29:02 +02:00
int l , i , mask = ~ 0 ;
2016-08-22 10:57:38 +02:00
int fMaxGatesLevel2 = 1 ;
2016-07-23 22:13:07 +02:00
2016-08-24 09:29:02 +02:00
pSes - > fDecStructure = 0 ;
for ( l = 0 ; l < pSes - > nSpecVars ; + + l )
2016-08-22 10:57:38 +02:00
{
2016-08-24 09:29:02 +02:00
if ( pSes - > pArrTimeProfile [ l ] > = pSes - > nMaxDepth )
2016-08-22 10:57:38 +02:00
{
2016-08-24 15:03:52 +02:00
if ( pSes - > fReasonVerbose )
2016-08-24 09:29:02 +02:00
printf ( " give up due to impossible arrival time (depth = %d, input = %d, arrival time = %d) " , pSes - > nMaxDepth , l , pSes - > pArrTimeProfile [ l ] ) ;
return 0 ;
}
else if ( pSes - > nSpecFunc = = 1 & & pSes - > fMakeAIG & & pSes - > pArrTimeProfile [ l ] + 1 = = pSes - > nMaxDepth )
{
if ( ( pSes - > fDecStructure = = 1 & & pSes - > nSpecVars > 2 ) | | pSes - > fDecStructure = = 2 )
2016-08-22 10:57:38 +02:00
{
2016-08-24 15:03:52 +02:00
if ( pSes - > fReasonVerbose )
2016-08-24 09:29:02 +02:00
printf ( " give up due to impossible decomposition (depth = %d, input = %d, arrival time = %d) " , pSes - > nMaxDepth , l , pSes - > pArrTimeProfile [ l ] ) ;
2016-08-22 10:57:38 +02:00
return 0 ;
}
2016-08-24 09:29:02 +02:00
pSes - > fDecStructure + + ;
if ( pSes - > nSpecVars < 6u )
mask = Abc_Tt6Mask ( 1u < < pSes - > nSpecVars ) ;
/* A subset B <=> A and B = A */
2016-08-24 15:03:52 +02:00
if ( ! ( ( pSes - > pDecVars > > l ) & 1 ) )
{
if ( pSes - > fReasonVerbose )
printf ( " give up due to impossible decomposition (depth = %d, input = %d, arrival time = %d) " , pSes - > nMaxDepth , l , pSes - > pArrTimeProfile [ l ] ) ;
return 0 ;
}
2016-08-24 09:29:02 +02:00
}
}
2016-08-22 10:57:38 +02:00
2016-08-24 09:29:02 +02:00
/* check if depth's match with structure at second level from top */
if ( pSes - > fDecStructure )
fMaxGatesLevel2 = ( pSes - > nSpecVars = = 3 ) ? 2 : 1 ;
else
fMaxGatesLevel2 = ( pSes - > nSpecVars = = 4 ) ? 4 : 3 ;
2016-08-22 10:57:38 +02:00
2016-08-24 09:29:02 +02:00
i = 0 ;
for ( l = 0 ; l < pSes - > nSpecVars ; + + l )
if ( pSes - > pArrTimeProfile [ l ] + 2 = = pSes - > nMaxDepth )
if ( + + i > fMaxGatesLevel2 )
{
2016-08-24 15:03:52 +02:00
if ( pSes - > fReasonVerbose )
2016-08-24 09:29:02 +02:00
printf ( " give up due to impossible decomposition at second level (depth = %d, input = %d, arrival time = %d) " , pSes - > nMaxDepth , l , pSes - > pArrTimeProfile [ l ] ) ;
return 0 ;
2016-08-22 10:57:38 +02:00
}
2016-08-24 09:29:02 +02:00
/* check if depth's match with structure at third level from top */
if ( pSes - > nSpecVars > 4 & & pSes - > fDecStructure & & i = = 1 ) /* we have f = AND(x_i, AND(x_j, g)) (x_i and x_j may be complemented) */
{
2016-08-22 10:57:38 +02:00
i = 0 ;
for ( l = 0 ; l < pSes - > nSpecVars ; + + l )
2016-08-24 09:29:02 +02:00
if ( pSes - > pArrTimeProfile [ l ] + 3 = = pSes - > nMaxDepth )
if ( + + i > 1 )
2016-08-22 10:57:38 +02:00
{
2016-08-24 15:03:52 +02:00
if ( pSes - > fReasonVerbose )
2016-08-24 09:29:02 +02:00
printf ( " give up due to impossible decomposition at third level (depth = %d, input = %d, arrival time = %d) " , pSes - > nMaxDepth , l , pSes - > pArrTimeProfile [ l ] ) ;
2016-08-22 10:57:38 +02:00
return 0 ;
}
}
2016-08-24 09:29:02 +02:00
return 1 ;
}
// returns 0, if current max depth and #gates are not consistent
static int Ses_CheckGatesConsistency ( Ses_Man_t * pSes , int nGates )
{
/* give up if number of gates is impossible for given depth */
if ( pSes - > nMaxDepth ! = - 1 & & nGates > = ( 1 < < pSes - > nMaxDepth ) )
{
2016-08-24 15:03:52 +02:00
if ( pSes - > fReasonVerbose )
2016-08-24 09:29:02 +02:00
printf ( " give up due to impossible depth (depth = %d, gates = %d) " , pSes - > nMaxDepth , nGates ) ;
return 0 ;
}
if ( pSes - > fDecStructure & & nGates > = ( 1 < < ( pSes - > nMaxDepth - 1 ) ) + 1 )
{
2016-08-24 15:03:52 +02:00
if ( pSes - > fReasonVerbose )
2016-08-24 09:29:02 +02:00
printf ( " give up due to impossible depth in AND-dec structure (depth = %d, gates = %d) " , pSes - > nMaxDepth , nGates ) ;
return 0 ;
}
/* give up if number of gates gets practically too large */
if ( nGates > = ( 1 < < pSes - > nSpecVars ) )
{
2016-08-24 15:03:52 +02:00
if ( pSes - > fReasonVerbose )
2016-08-24 09:29:02 +02:00
printf ( " give up due to impossible number of gates " ) ;
return 0 ;
}
return 1 ;
}
static void Abc_ExactCopyDepthAndArrivalTimes ( int nVars , int nDepthFrom , int * nDepthTo , int * pTimesFrom , int * pTimesTo )
{
int l ;
* nDepthTo = nDepthFrom ;
for ( l = 0 ; l < nVars ; + + l )
pTimesTo [ l ] = pTimesFrom [ l ] ;
}
static void Ses_ManStoreDepthAndArrivalTimes ( Ses_Man_t * pSes )
{
if ( pSes - > nMaxDepth = = - 1 ) return ;
Abc_ExactCopyDepthAndArrivalTimes ( pSes - > nSpecVars , pSes - > nMaxDepth , & pSes - > nMaxDepthTmp , pSes - > pArrTimeProfile , pSes - > pArrTimeProfileTmp ) ;
}
static void Ses_ManRestoreDepthAndArrivalTimes ( Ses_Man_t * pSes )
{
if ( pSes - > nMaxDepth = = - 1 ) return ;
Abc_ExactCopyDepthAndArrivalTimes ( pSes - > nSpecVars , pSes - > nMaxDepthTmp , & pSes - > nMaxDepth , pSes - > pArrTimeProfileTmp , pSes - > pArrTimeProfile ) ;
}
static void Abc_ExactAdjustDepthAndArrivalTimes ( int nVars , int nGates , int nDepthFrom , int * nDepthTo , int * pTimesFrom , int * pTimesTo , int nTimesMax )
{
int l ;
* nDepthTo = Abc_MinInt ( nDepthFrom , nGates ) ;
for ( l = 0 ; l < nVars ; + + l )
pTimesTo [ l ] = Abc_MinInt ( pTimesFrom [ l ] , Abc_MaxInt ( 0 , nGates - 1 - nTimesMax + pTimesFrom [ l ] ) ) ;
}
static void Ses_AdjustDepthAndArrivalTimes ( Ses_Man_t * pSes , int nGates )
{
Abc_ExactAdjustDepthAndArrivalTimes ( pSes - > nSpecVars , nGates , pSes - > nMaxDepthTmp , & pSes - > nMaxDepth , pSes - > pArrTimeProfileTmp , pSes - > pArrTimeProfile , pSes - > nArrTimeMax - 1 ) ;
}
static int Ses_ManFindMinimumSize ( Ses_Man_t * pSes )
{
2016-08-24 15:03:52 +02:00
int nGates = pSes - > nStartGates , f , fRes , fSat ;
2016-08-24 09:29:02 +02:00
abctime timeStart ;
2016-08-09 10:53:58 +02:00
/* store whether call was unsuccessful due to resource limit and not due to impossible constraint */
pSes - > fHitResLimit = 0 ;
2016-08-24 09:29:02 +02:00
/* do the arrival times allow for a network? */
if ( pSes - > nMaxDepth ! = - 1 & & ! Ses_CheckDepthConsistency ( pSes ) )
return 0 ;
//Ses_ManStoreDepthAndArrivalTimes( pSes );
2016-07-23 22:13:07 +02:00
while ( true )
{
+ + nGates ;
2016-07-28 20:37:09 +02:00
2016-08-24 09:29:02 +02:00
//Ses_AdjustDepthAndArrivalTimes( pSes, nGates );
2016-08-22 10:57:38 +02:00
2016-08-24 09:29:02 +02:00
/* do #gates and max depth allow for a network? */
if ( ! Ses_CheckGatesConsistency ( pSes , nGates ) )
2016-08-22 10:57:38 +02:00
{
2016-08-24 09:29:02 +02:00
fRes = 0 ;
break ;
2016-08-15 16:20:30 +02:00
}
2016-07-28 20:37:09 +02:00
2016-08-24 09:29:02 +02:00
/* solve */
timeStart = Abc_Clock ( ) ;
Ses_ManCreateVars ( pSes , nGates ) ;
f = Ses_ManCreateDepthClauses ( pSes ) ;
pSes - > timeInstance + = ( Abc_Clock ( ) - timeStart ) ;
if ( ! f ) continue ; /* proven UNSAT while creating clauses */
/* first solve */
fSat = Ses_ManSolve ( pSes ) ;
if ( fSat = = 0 )
continue ; /* UNSAT, continue with next # of gates */
else if ( fSat = = 2 )
2016-08-15 16:20:30 +02:00
{
2016-08-24 09:29:02 +02:00
pSes - > fHitResLimit = 1 ;
fRes = 0 ;
break ;
2016-08-15 16:20:30 +02:00
}
2016-08-08 18:50:19 +02:00
2016-08-21 18:13:57 +02:00
timeStart = Abc_Clock ( ) ;
f = Ses_ManCreateClauses ( pSes ) ;
pSes - > timeInstance + = ( Abc_Clock ( ) - timeStart ) ;
2016-08-24 09:29:02 +02:00
if ( ! f ) continue ; /* proven UNSAT while creating clauses */
2016-07-23 22:13:07 +02:00
2016-08-24 09:29:02 +02:00
fSat = Ses_ManSolve ( pSes ) ;
if ( fSat = = 1 )
{
fRes = 1 ;
break ;
}
else if ( fSat = = 2 )
2016-07-23 22:13:07 +02:00
{
2016-08-09 10:53:58 +02:00
pSes - > fHitResLimit = 1 ;
2016-08-24 09:29:02 +02:00
fRes = 0 ;
break ;
2016-07-23 22:13:07 +02:00
}
2016-08-24 09:29:02 +02:00
/* UNSAT => continue */
2016-07-23 22:13:07 +02:00
}
2016-07-28 20:37:09 +02:00
2016-08-24 09:29:02 +02:00
//Ses_ManRestoreDepthAndArrivalTimes( pSes );
return fRes ;
2016-07-16 16:51:58 +02:00
}
/**Function*************************************************************
Synopsis [ Find minimum size networks with a SAT solver . ]
2016-07-28 20:37:09 +02:00
Description [ If nMaxDepth is - 1 , then depth constraints are ignored .
2016-07-30 13:34:39 +02:00
If nMaxDepth is not - 1 , one can set pArrTimeProfile which should have the length of nVars .
One can ignore pArrTimeProfile by setting it to NULL . ]
2016-07-16 16:51:58 +02:00
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2016-08-08 18:50:19 +02:00
Abc_Ntk_t * Abc_NtkFindExact ( word * pTruth , int nVars , int nFunc , int nMaxDepth , int * pArrTimeProfile , int nBTLimit , int fVerbose )
2016-07-16 16:51:58 +02:00
{
Ses_Man_t * pSes ;
2016-07-30 13:34:39 +02:00
char * pSol ;
2016-07-28 20:37:09 +02:00
Abc_Ntk_t * pNtk = NULL ;
abctime timeStart ;
2016-07-16 16:51:58 +02:00
/* some checks */
2016-07-28 20:37:09 +02:00
assert ( nVars > = 2 & & nVars < = 8 ) ;
timeStart = Abc_Clock ( ) ;
2016-07-16 16:51:58 +02:00
2016-08-08 18:50:19 +02:00
pSes = Ses_ManAlloc ( pTruth , nVars , nFunc , nMaxDepth , pArrTimeProfile , 0 , nBTLimit , fVerbose ) ;
2016-07-16 16:51:58 +02:00
if ( fVerbose )
2016-07-28 20:37:09 +02:00
Ses_ManPrintFuncs ( pSes ) ;
if ( Ses_ManFindMinimumSize ( pSes ) )
2016-07-30 13:34:39 +02:00
{
pSol = Ses_ManExtractSolution ( pSes ) ;
pNtk = Ses_ManExtractNtk ( pSol ) ;
ABC_FREE ( pSol ) ;
}
2016-07-28 20:37:09 +02:00
pSes - > timeTotal = Abc_Clock ( ) - timeStart ;
if ( fVerbose )
Ses_ManPrintRuntime ( pSes ) ;
/* cleanup */
Ses_ManClean ( pSes ) ;
return pNtk ;
}
2016-08-08 18:50:19 +02:00
Gia_Man_t * Gia_ManFindExact ( word * pTruth , int nVars , int nFunc , int nMaxDepth , int * pArrTimeProfile , int nBTLimit , int fVerbose )
2016-07-28 20:37:09 +02:00
{
Ses_Man_t * pSes ;
2016-07-30 13:34:39 +02:00
char * pSol ;
2016-07-28 20:37:09 +02:00
Gia_Man_t * pGia = NULL ;
abctime timeStart ;
/* some checks */
assert ( nVars > = 2 & & nVars < = 8 ) ;
timeStart = Abc_Clock ( ) ;
2016-07-16 16:51:58 +02:00
2016-08-08 18:50:19 +02:00
pSes = Ses_ManAlloc ( pTruth , nVars , nFunc , nMaxDepth , pArrTimeProfile , 1 , nBTLimit , fVerbose ) ;
2016-08-22 10:57:38 +02:00
pSes - > fVeryVerbose = 1 ;
2016-08-24 09:29:02 +02:00
pSes - > fExtractVerbose = 1 ;
2016-08-22 10:57:38 +02:00
pSes - > fSatVerbose = 1 ;
2016-07-28 20:37:09 +02:00
if ( fVerbose )
Ses_ManPrintFuncs ( pSes ) ;
if ( Ses_ManFindMinimumSize ( pSes ) )
2016-07-30 13:34:39 +02:00
{
pSol = Ses_ManExtractSolution ( pSes ) ;
pGia = Ses_ManExtractGia ( pSol ) ;
ABC_FREE ( pSol ) ;
}
2016-07-28 20:37:09 +02:00
pSes - > timeTotal = Abc_Clock ( ) - timeStart ;
2016-07-16 16:51:58 +02:00
if ( fVerbose )
Ses_ManPrintRuntime ( pSes ) ;
/* cleanup */
Ses_ManClean ( pSes ) ;
2016-07-28 20:37:09 +02:00
return pGia ;
}
/**Function*************************************************************
Synopsis [ Some test cases . ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
Abc_Ntk_t * Abc_NtkFromTruthTable ( word * pTruth , int nVars )
{
Abc_Ntk_t * pNtk ;
Mem_Flex_t * pMan ;
char * pSopCover ;
pMan = Mem_FlexStart ( ) ;
pSopCover = Abc_SopCreateFromTruth ( pMan , nVars , ( unsigned * ) pTruth ) ;
pNtk = Abc_NtkCreateWithNode ( pSopCover ) ;
Abc_NtkShortNames ( pNtk ) ;
Mem_FlexStop ( pMan , 0 ) ;
2016-07-16 16:51:58 +02:00
return pNtk ;
}
2016-07-28 20:37:09 +02:00
void Abc_ExactTestSingleOutput ( int fVerbose )
{
extern void Abc_NtkCecSat ( Abc_Ntk_t * pNtk1 , Abc_Ntk_t * pNtk2 , int nConfLimit , int nInsLimit ) ;
word pTruth [ 4 ] = { 0xcafe , 0 , 0 , 0 } ;
Abc_Ntk_t * pNtk , * pNtk2 , * pNtk3 , * pNtk4 ;
2016-07-30 13:34:39 +02:00
int pArrTimeProfile [ 4 ] = { 6 , 2 , 8 , 5 } ;
2016-07-28 20:37:09 +02:00
pNtk = Abc_NtkFromTruthTable ( pTruth , 4 ) ;
2016-08-08 18:50:19 +02:00
pNtk2 = Abc_NtkFindExact ( pTruth , 4 , 1 , - 1 , NULL , 0 , fVerbose ) ;
2016-07-28 20:37:09 +02:00
Abc_NtkShortNames ( pNtk2 ) ;
Abc_NtkCecSat ( pNtk , pNtk2 , 10000 , 0 ) ;
assert ( pNtk2 ) ;
assert ( Abc_NtkNodeNum ( pNtk2 ) = = 6 ) ;
Abc_NtkDelete ( pNtk2 ) ;
2016-08-08 18:50:19 +02:00
pNtk3 = Abc_NtkFindExact ( pTruth , 4 , 1 , 3 , NULL , 0 , fVerbose ) ;
2016-07-28 20:37:09 +02:00
Abc_NtkShortNames ( pNtk3 ) ;
Abc_NtkCecSat ( pNtk , pNtk3 , 10000 , 0 ) ;
assert ( pNtk3 ) ;
assert ( Abc_NtkLevel ( pNtk3 ) < = 3 ) ;
Abc_NtkDelete ( pNtk3 ) ;
2016-08-08 18:50:19 +02:00
pNtk4 = Abc_NtkFindExact ( pTruth , 4 , 1 , 9 , pArrTimeProfile , 50000 , fVerbose ) ;
2016-07-28 20:37:09 +02:00
Abc_NtkShortNames ( pNtk4 ) ;
Abc_NtkCecSat ( pNtk , pNtk4 , 10000 , 0 ) ;
assert ( pNtk4 ) ;
assert ( Abc_NtkLevel ( pNtk4 ) < = 9 ) ;
Abc_NtkDelete ( pNtk4 ) ;
2016-08-08 18:50:19 +02:00
assert ( ! Abc_NtkFindExact ( pTruth , 4 , 1 , 2 , NULL , 50000 , fVerbose ) ) ;
2016-07-28 20:37:09 +02:00
2016-08-08 18:50:19 +02:00
assert ( ! Abc_NtkFindExact ( pTruth , 4 , 1 , 8 , pArrTimeProfile , 50000 , fVerbose ) ) ;
2016-07-28 20:37:09 +02:00
Abc_NtkDelete ( pNtk ) ;
}
void Abc_ExactTestSingleOutputAIG ( int fVerbose )
{
word pTruth [ 4 ] = { 0xcafe , 0 , 0 , 0 } ;
Abc_Ntk_t * pNtk ;
Gia_Man_t * pGia , * pGia2 , * pGia3 , * pGia4 , * pMiter ;
Cec_ParCec_t ParsCec , * pPars = & ParsCec ;
2016-07-30 13:34:39 +02:00
int pArrTimeProfile [ 4 ] = { 6 , 2 , 8 , 5 } ;
2016-07-28 20:37:09 +02:00
Cec_ManCecSetDefaultParams ( pPars ) ;
pNtk = Abc_NtkFromTruthTable ( pTruth , 4 ) ;
Abc_NtkToAig ( pNtk ) ;
pGia = Abc_NtkAigToGia ( pNtk , 1 ) ;
2016-08-08 18:50:19 +02:00
pGia2 = Gia_ManFindExact ( pTruth , 4 , 1 , - 1 , NULL , 0 , fVerbose ) ;
2016-07-28 20:37:09 +02:00
pMiter = Gia_ManMiter ( pGia , pGia2 , 0 , 1 , 0 , 0 , 1 ) ;
assert ( pMiter ) ;
Cec_ManVerify ( pMiter , pPars ) ;
Gia_ManStop ( pMiter ) ;
2016-08-08 18:50:19 +02:00
pGia3 = Gia_ManFindExact ( pTruth , 4 , 1 , 3 , NULL , 0 , fVerbose ) ;
2016-07-28 20:37:09 +02:00
pMiter = Gia_ManMiter ( pGia , pGia3 , 0 , 1 , 0 , 0 , 1 ) ;
assert ( pMiter ) ;
Cec_ManVerify ( pMiter , pPars ) ;
Gia_ManStop ( pMiter ) ;
2016-08-08 18:50:19 +02:00
pGia4 = Gia_ManFindExact ( pTruth , 4 , 1 , 9 , pArrTimeProfile , 50000 , fVerbose ) ;
2016-07-28 20:37:09 +02:00
pMiter = Gia_ManMiter ( pGia , pGia4 , 0 , 1 , 0 , 0 , 1 ) ;
assert ( pMiter ) ;
Cec_ManVerify ( pMiter , pPars ) ;
Gia_ManStop ( pMiter ) ;
2016-08-08 18:50:19 +02:00
assert ( ! Gia_ManFindExact ( pTruth , 4 , 1 , 2 , NULL , 50000 , fVerbose ) ) ;
2016-07-28 20:37:09 +02:00
2016-08-08 18:50:19 +02:00
assert ( ! Gia_ManFindExact ( pTruth , 4 , 1 , 8 , pArrTimeProfile , 50000 , fVerbose ) ) ;
2016-07-28 20:37:09 +02:00
Gia_ManStop ( pGia ) ;
Gia_ManStop ( pGia2 ) ;
Gia_ManStop ( pGia3 ) ;
Gia_ManStop ( pGia4 ) ;
}
void Abc_ExactTest ( int fVerbose )
{
Abc_ExactTestSingleOutput ( fVerbose ) ;
Abc_ExactTestSingleOutputAIG ( fVerbose ) ;
printf ( " \n " ) ;
}
2016-07-16 16:51:58 +02:00
2016-07-30 01:03:42 +02:00
/**Function*************************************************************
Synopsis [ APIs for integraging with the mapper . ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
// may need to have a static pointer to the SAT-based synthesis engine and/or loaded library
// this procedure should return 1, if the engine/library are available, and 0 otherwise
int Abc_ExactIsRunning ( )
{
2016-07-31 12:24:02 +02:00
return s_pSesStore ! = NULL ;
2016-07-30 01:03:42 +02:00
}
// this procedure returns the number of inputs of the library
// for example, somebody may try to map into 10-cuts while the library only contains 8-functions
int Abc_ExactInputNum ( )
{
2016-08-02 11:25:16 +02:00
return 8 ;
}
// start exact store manager
2016-08-08 12:59:21 +02:00
void Abc_ExactStart ( int nBTLimit , int fMakeAIG , int fVerbose , int fVeryVerbose , const char * pFilename )
2016-08-02 11:25:16 +02:00
{
if ( ! s_pSesStore )
2016-08-04 18:51:35 +02:00
{
s_pSesStore = Ses_StoreAlloc ( nBTLimit , fMakeAIG , fVerbose ) ;
2016-08-08 12:59:21 +02:00
s_pSesStore - > fVeryVerbose = fVeryVerbose ;
2016-08-04 18:51:35 +02:00
if ( pFilename )
2016-08-22 10:57:38 +02:00
Ses_StoreRead ( s_pSesStore , pFilename , 1 , 0 , 0 , 0 ) ;
if ( s_pSesStore - > fVeryVerbose )
{
s_pSesStore - > pDebugEntries = fopen ( " bms.debug " , " w " ) ;
}
2016-08-04 18:51:35 +02:00
}
2016-08-02 11:25:16 +02:00
else
2016-08-04 14:22:31 +02:00
printf ( " BMS manager already started \n " ) ;
2016-08-02 11:25:16 +02:00
}
// stop exact store manager
2016-08-04 18:51:35 +02:00
void Abc_ExactStop ( const char * pFilename )
2016-08-02 11:25:16 +02:00
{
if ( s_pSesStore )
2016-08-04 18:51:35 +02:00
{
if ( pFilename )
2016-08-22 10:57:38 +02:00
Ses_StoreWrite ( s_pSesStore , pFilename , 1 , 0 , 0 , 0 ) ;
if ( s_pSesStore - > pDebugEntries )
fclose ( s_pSesStore - > pDebugEntries ) ;
2016-08-02 11:25:16 +02:00
Ses_StoreClean ( s_pSesStore ) ;
2016-08-04 18:51:35 +02:00
}
2016-08-02 11:25:16 +02:00
else
2016-08-04 14:22:31 +02:00
printf ( " BMS manager has not been started \n " ) ;
}
// show statistics about store manager
void Abc_ExactStats ( )
{
int i ;
if ( ! s_pSesStore )
{
printf ( " BMS manager has not been started \n " ) ;
return ;
}
2016-08-09 10:53:58 +02:00
printf ( " ------------------------------------------------------------------------------------------------------------------------------- \n " ) ;
printf ( " 0 1 2 3 4 5 6 7 8 total \n " ) ;
printf ( " ------------------------------------------------------------------------------------------------------------------------------- \n " ) ;
2016-08-04 14:22:31 +02:00
printf ( " number of considered cuts : " ) ;
2016-08-09 10:53:58 +02:00
for ( i = 0 ; i < 9 ; + + i )
printf ( " %10lu " , s_pSesStore - > pCutCount [ i ] ) ;
printf ( " %10lu \n " , s_pSesStore - > nCutCount ) ;
printf ( " - trivial : " ) ;
for ( i = 0 ; i < 9 ; + + i )
printf ( " %10lu " , s_pSesStore - > pSynthesizedTrivial [ i ] ) ;
printf ( " %10lu \n " , s_pSesStore - > nSynthesizedTrivial ) ;
printf ( " - synth (imp) : " ) ;
for ( i = 0 ; i < 9 ; + + i )
printf ( " %10lu " , s_pSesStore - > pSynthesizedImp [ i ] ) ;
printf ( " %10lu \n " , s_pSesStore - > nSynthesizedImp ) ;
printf ( " - synth (res) : " ) ;
for ( i = 0 ; i < 9 ; + + i )
printf ( " %10lu " , s_pSesStore - > pSynthesizedRL [ i ] ) ;
printf ( " %10lu \n " , s_pSesStore - > nSynthesizedRL ) ;
printf ( " - not synth (imp) : " ) ;
for ( i = 0 ; i < 9 ; + + i )
printf ( " %10lu " , s_pSesStore - > pUnsynthesizedImp [ i ] ) ;
printf ( " %10lu \n " , s_pSesStore - > nUnsynthesizedImp ) ;
printf ( " - not synth (res) : " ) ;
for ( i = 0 ; i < 9 ; + + i )
printf ( " %10lu " , s_pSesStore - > pUnsynthesizedRL [ i ] ) ;
printf ( " %10lu \n " , s_pSesStore - > nUnsynthesizedRL ) ;
printf ( " - cache hits : " ) ;
for ( i = 0 ; i < 9 ; + + i )
printf ( " %10lu " , s_pSesStore - > pCacheHits [ i ] ) ;
printf ( " %10lu \n " , s_pSesStore - > nCacheHits ) ;
printf ( " ------------------------------------------------------------------------------------------------------------------------------- \n " ) ;
2016-08-04 18:51:35 +02:00
printf ( " number of entries : %d \n " , s_pSesStore - > nEntriesCount ) ;
2016-08-08 12:59:21 +02:00
printf ( " number of valid entries : %d \n " , s_pSesStore - > nValidEntriesCount ) ;
2016-08-09 10:53:58 +02:00
printf ( " number of invalid entries : %d \n " , s_pSesStore - > nEntriesCount - s_pSesStore - > nValidEntriesCount ) ;
2016-08-21 18:13:57 +02:00
printf ( " ------------------------------------------------------------------------------------------------------------------------------- \n " ) ;
printf ( " number of SAT calls : %lu \n " , s_pSesStore - > nSatCalls ) ;
printf ( " number of UNSAT calls : %lu \n " , s_pSesStore - > nUnsatCalls ) ;
printf ( " number of UNDEF calls : %lu \n " , s_pSesStore - > nUndefCalls ) ;
printf ( " ------------------------------------------------------------------------------------------------------------------------------- \n " ) ;
printf ( " Runtime breakdown: \n " ) ;
ABC_PRTP ( " Exact " , s_pSesStore - > timeExact , s_pSesStore - > timeTotal ) ;
ABC_PRTP ( " Sat " , s_pSesStore - > timeSat , s_pSesStore - > timeTotal ) ;
ABC_PRTP ( " Sat " , s_pSesStore - > timeSatSat , s_pSesStore - > timeTotal ) ;
ABC_PRTP ( " Unsat " , s_pSesStore - > timeSatUnsat , s_pSesStore - > timeTotal ) ;
ABC_PRTP ( " Undef " , s_pSesStore - > timeSatUndef , s_pSesStore - > timeTotal ) ;
ABC_PRTP ( " Instance " , s_pSesStore - > timeInstance , s_pSesStore - > timeTotal ) ;
ABC_PRTP ( " Other " , s_pSesStore - > timeTotal - s_pSesStore - > timeExact , s_pSesStore - > timeTotal ) ;
ABC_PRTP ( " ALL " , s_pSesStore - > timeTotal , s_pSesStore - > timeTotal ) ;
2016-07-30 01:03:42 +02:00
}
2016-07-30 01:34:47 +02:00
// this procedure takes TT and input arrival times (pArrTimeProfile) and return the smallest output arrival time;
// it also returns the pin-to-pin delays (pPerm) between each cut leaf and the cut output and the cut area cost (Cost)
// the area cost should not exceed 2048, if the cut is implementable; otherwise, it should be ABC_INFINITY
2016-07-31 22:31:57 +02:00
int Abc_ExactDelayCost ( word * pTruth , int nVars , int * pArrTimeProfile , char * pPerm , int * Cost , int AigLevel )
2016-07-30 01:03:42 +02:00
{
2016-08-24 09:29:02 +02:00
int i , nMaxArrival , nDelta , l ;
2016-08-04 14:22:31 +02:00
Ses_Man_t * pSes = NULL ;
2016-07-30 15:21:57 +02:00
char * pSol = NULL , * p ;
2016-08-21 18:13:57 +02:00
int pNormalArrTime [ 8 ] ;
2016-08-22 10:57:38 +02:00
int Delay = ABC_INFINITY , nMaxDepth , fResLimit ;
2016-08-21 18:13:57 +02:00
abctime timeStart = Abc_Clock ( ) , timeStartExact ;
2016-07-30 15:01:59 +02:00
/* some checks */
2016-08-06 05:43:45 +02:00
if ( nVars < 0 | | nVars > 8 )
2016-08-04 14:22:31 +02:00
{
printf ( " invalid truth table size %d \n " , nVars ) ;
assert ( 0 ) ;
}
2016-07-30 15:01:59 +02:00
2016-08-09 10:53:58 +02:00
/* statistics */
s_pSesStore - > nCutCount + + ;
s_pSesStore - > pCutCount [ nVars ] + + ;
2016-08-06 05:43:45 +02:00
if ( nVars = = 0 )
{
2016-08-09 10:53:58 +02:00
s_pSesStore - > nSynthesizedTrivial + + ;
s_pSesStore - > pSynthesizedTrivial [ 0 ] + + ;
2016-08-06 05:43:45 +02:00
* Cost = 0 ;
2016-08-21 18:13:57 +02:00
s_pSesStore - > timeTotal + = ( Abc_Clock ( ) - timeStart ) ;
2016-08-06 05:43:45 +02:00
return 0 ;
}
if ( nVars = = 1 )
{
2016-08-09 10:53:58 +02:00
s_pSesStore - > nSynthesizedTrivial + + ;
s_pSesStore - > pSynthesizedTrivial [ 1 ] + + ;
2016-08-06 05:43:45 +02:00
* Cost = 0 ;
pPerm [ 0 ] = ( char ) 0 ;
2016-08-21 18:13:57 +02:00
s_pSesStore - > timeTotal + = ( Abc_Clock ( ) - timeStart ) ;
2016-08-06 05:43:45 +02:00
return pArrTimeProfile [ 0 ] ;
}
2016-08-21 18:13:57 +02:00
for ( l = 0 ; l < nVars ; + + l )
pNormalArrTime [ l ] = pArrTimeProfile [ l ] ;
2016-08-24 09:29:02 +02:00
nDelta = Abc_NormalizeArrivalTimes ( pNormalArrTime , nVars , & nMaxArrival ) ;
2016-08-08 10:59:29 +02:00
2016-08-08 12:59:21 +02:00
* Cost = ABC_INFINITY ;
2016-08-21 18:13:57 +02:00
if ( Ses_StoreGetEntry ( s_pSesStore , pTruth , nVars , pNormalArrTime , & pSol ) )
2016-08-04 14:22:31 +02:00
{
2016-08-09 10:53:58 +02:00
s_pSesStore - > nCacheHits + + ;
s_pSesStore - > pCacheHits [ nVars ] + + ;
2016-08-04 14:22:31 +02:00
}
else
{
2016-08-24 15:03:52 +02:00
if ( s_pSesStore - > fVeryVerbose )
{
printf ( ANSI_COLOR_CYAN ) ;
Abc_TtPrintHexRev ( stdout , pTruth , nVars ) ;
printf ( ANSI_COLOR_RESET ) ;
printf ( " [%d " , pNormalArrTime [ 0 ] ) ;
for ( l = 1 ; l < nVars ; + + l )
printf ( " %d " , pNormalArrTime [ l ] ) ;
printf ( " ]@%d: " , AigLevel ) ;
fflush ( stdout ) ;
}
2016-08-21 18:13:57 +02:00
nMaxDepth = pNormalArrTime [ 0 ] ;
2016-08-04 14:22:31 +02:00
for ( i = 1 ; i < nVars ; + + i )
2016-08-21 18:13:57 +02:00
nMaxDepth = Abc_MaxInt ( nMaxDepth , pNormalArrTime [ i ] ) ;
2016-08-08 12:59:21 +02:00
nMaxDepth + = nVars + 1 ;
2016-08-15 16:20:30 +02:00
if ( AigLevel ! = - 1 )
2016-08-24 09:29:02 +02:00
nMaxDepth = Abc_MinInt ( AigLevel - nDelta , nMaxDepth + nVars + 1 ) ;
2016-07-30 15:01:59 +02:00
2016-08-21 18:13:57 +02:00
timeStartExact = Abc_Clock ( ) ;
2016-07-30 15:01:59 +02:00
2016-08-21 18:13:57 +02:00
pSes = Ses_ManAlloc ( pTruth , nVars , 1 /* nSpecFunc */ , nMaxDepth , pNormalArrTime , s_pSesStore - > fMakeAIG , s_pSesStore - > nBTLimit , s_pSesStore - > fVerbose ) ;
2016-08-08 12:59:21 +02:00
pSes - > fVeryVerbose = s_pSesStore - > fVeryVerbose ;
2016-08-21 19:28:55 +02:00
pSes - > pSat = s_pSesStore - > pSat ;
2016-08-24 15:03:52 +02:00
pSes - > nStartGates = nVars - 2 ;
2016-08-04 14:22:31 +02:00
2016-08-08 12:59:21 +02:00
while ( pSes - > nMaxDepth ) /* there is improvement */
2016-07-30 15:21:57 +02:00
{
2016-08-08 12:59:21 +02:00
if ( s_pSesStore - > fVeryVerbose )
{
2016-08-24 15:03:52 +02:00
printf ( " %d " , pSes - > nMaxDepth ) ;
2016-08-08 12:59:21 +02:00
fflush ( stdout ) ;
}
2016-08-04 14:22:31 +02:00
if ( Ses_ManFindMinimumSize ( pSes ) )
{
2016-08-08 12:59:21 +02:00
if ( s_pSesStore - > fVeryVerbose )
2016-08-24 15:03:52 +02:00
{
if ( pSes - > nMaxDepth > = 10 ) printf ( " \b " ) ;
printf ( " \b " ANSI_COLOR_GREEN " %d " ANSI_COLOR_RESET , pSes - > nMaxDepth ) ;
}
2016-08-04 14:22:31 +02:00
if ( pSol )
ABC_FREE ( pSol ) ;
pSol = Ses_ManExtractSolution ( pSes ) ;
pSes - > nMaxDepth - - ;
}
else
2016-08-08 12:59:21 +02:00
{
if ( s_pSesStore - > fVeryVerbose )
2016-08-24 15:03:52 +02:00
{
if ( pSes - > nMaxDepth > = 10 ) printf ( " \b " ) ;
printf ( " \b %s%d " ANSI_COLOR_RESET , pSes - > fHitResLimit ? ANSI_COLOR_RED : ANSI_COLOR_YELLOW , pSes - > nMaxDepth ) ;
}
2016-08-04 14:22:31 +02:00
break ;
2016-08-08 12:59:21 +02:00
}
2016-07-30 15:21:57 +02:00
}
2016-08-04 14:22:31 +02:00
2016-08-24 15:03:52 +02:00
if ( s_pSesStore - > fVeryVerbose )
printf ( " \n " ) ;
2016-08-22 10:57:38 +02:00
/* log unsuccessful case for debugging */
if ( s_pSesStore - > pDebugEntries & & pSes - > fHitResLimit )
2016-08-24 15:03:52 +02:00
Ses_StorePrintDebugEntry ( s_pSesStore , pTruth , nVars , pNormalArrTime , pSes - > nMaxDepth , pSol ) ;
2016-08-22 10:57:38 +02:00
2016-08-21 18:13:57 +02:00
pSes - > timeTotal = Abc_Clock ( ) - timeStartExact ;
/* statistics */
s_pSesStore - > nSatCalls + = pSes - > nSatCalls ;
s_pSesStore - > nUnsatCalls + = pSes - > nUnsatCalls ;
s_pSesStore - > nUndefCalls + = pSes - > nUndefCalls ;
s_pSesStore - > timeSat + = pSes - > timeSat ;
s_pSesStore - > timeSatSat + = pSes - > timeSatSat ;
s_pSesStore - > timeSatUnsat + = pSes - > timeSatUnsat ;
s_pSesStore - > timeSatUndef + = pSes - > timeSatUndef ;
s_pSesStore - > timeInstance + = pSes - > timeInstance ;
s_pSesStore - > timeExact + = pSes - > timeTotal ;
2016-08-04 14:22:31 +02:00
2016-08-22 10:57:38 +02:00
/* cleanup (we need to clean before adding since pTruth may have been modified by pSes) */
fResLimit = pSes - > fHitResLimit ;
2016-08-21 19:28:55 +02:00
Ses_ManCleanLight ( pSes ) ;
2016-08-08 12:59:21 +02:00
/* store solution */
2016-08-22 10:57:38 +02:00
Ses_StoreAddEntry ( s_pSesStore , pTruth , nVars , pNormalArrTime , pSol , fResLimit ) ;
2016-07-30 15:21:57 +02:00
}
2016-07-30 15:01:59 +02:00
2016-07-30 15:21:57 +02:00
if ( pSol )
{
2016-07-30 15:01:59 +02:00
* Cost = pSol [ ABC_EXACT_SOL_NGATES ] ;
2016-08-02 13:24:21 +02:00
p = pSol + 3 + 4 * pSol [ ABC_EXACT_SOL_NGATES ] + 1 ;
2016-07-30 15:01:59 +02:00
Delay = * p + + ;
for ( l = 0 ; l < nVars ; + + l )
pPerm [ l ] = * p + + ;
}
2016-08-15 16:20:30 +02:00
if ( pSol )
{
int Delay2 = 0 ;
for ( l = 0 ; l < nVars ; + + l )
{
//printf( "%d ", pPerm[l] );
Delay2 = Abc_MaxInt ( Delay2 , pArrTimeProfile [ l ] + pPerm [ l ] ) ;
}
//printf( " output arrival = %d recomputed = %d\n", Delay, Delay2 );
2016-08-21 18:13:57 +02:00
//if ( Delay != Delay2 )
//{
// printf( "^--- BUG!\n" );
// assert( 0 );
//}
s_pSesStore - > timeTotal + = ( Abc_Clock ( ) - timeStart ) ;
return Delay2 ;
2016-08-15 16:20:30 +02:00
}
2016-08-21 18:13:57 +02:00
else
2016-08-15 16:20:30 +02:00
{
assert ( * Cost = = ABC_INFINITY ) ;
2016-08-21 18:13:57 +02:00
s_pSesStore - > timeTotal + = ( Abc_Clock ( ) - timeStart ) ;
return ABC_INFINITY ;
}
2016-07-30 01:03:42 +02:00
}
2016-07-31 12:47:09 +02:00
// this procedure returns a new node whose output in terms of the given fanins
2016-07-30 01:03:42 +02:00
// has the smallest possible arrival time (in agreement with the above Abc_ExactDelayCost)
2016-08-06 05:43:45 +02:00
Abc_Obj_t * Abc_ExactBuildNode ( word * pTruth , int nVars , int * pArrTimeProfile , Abc_Obj_t * * pFanins , Abc_Ntk_t * pNtk )
2016-07-30 01:03:42 +02:00
{
2016-08-08 12:59:21 +02:00
char * pSol = NULL ;
2016-08-21 18:13:57 +02:00
int i , j , nMaxArrival ;
int pNormalArrTime [ 8 ] ;
2016-07-31 12:47:09 +02:00
char const * p ;
Abc_Obj_t * pObj ;
Vec_Ptr_t * pGates ;
char pGateTruth [ 5 ] ;
char * pSopCover ;
2016-08-21 18:13:57 +02:00
abctime timeStart = Abc_Clock ( ) ;
2016-07-31 12:47:09 +02:00
2016-08-06 05:43:45 +02:00
if ( nVars = = 0 )
2016-08-21 18:13:57 +02:00
{
s_pSesStore - > timeTotal + = ( Abc_Clock ( ) - timeStart ) ;
2016-08-06 05:43:45 +02:00
return ( pTruth [ 0 ] & 1 ) ? Abc_NtkCreateNodeConst1 ( pNtk ) : Abc_NtkCreateNodeConst0 ( pNtk ) ;
2016-08-21 18:13:57 +02:00
}
2016-08-06 05:43:45 +02:00
if ( nVars = = 1 )
2016-08-21 18:13:57 +02:00
{
s_pSesStore - > timeTotal + = ( Abc_Clock ( ) - timeStart ) ;
2016-08-06 05:43:45 +02:00
return ( pTruth [ 0 ] & 1 ) ? Abc_NtkCreateNodeInv ( pNtk , pFanins [ 0 ] ) : Abc_NtkCreateNodeBuf ( pNtk , pFanins [ 0 ] ) ;
2016-08-21 18:13:57 +02:00
}
2016-07-31 12:47:09 +02:00
2016-08-21 18:13:57 +02:00
for ( i = 0 ; i < nVars ; + + i )
pNormalArrTime [ i ] = pArrTimeProfile [ i ] ;
Abc_NormalizeArrivalTimes ( pNormalArrTime , nVars , & nMaxArrival ) ;
2016-08-24 09:29:02 +02:00
assert ( Ses_StoreGetEntry ( s_pSesStore , pTruth , nVars , pNormalArrTime , & pSol ) ) ;
2016-07-31 12:47:09 +02:00
if ( ! pSol )
2016-08-21 18:13:57 +02:00
{
s_pSesStore - > timeTotal + = ( Abc_Clock ( ) - timeStart ) ;
2016-07-31 12:47:09 +02:00
return NULL ;
2016-08-21 18:13:57 +02:00
}
2016-07-31 12:47:09 +02:00
assert ( pSol [ ABC_EXACT_SOL_NVARS ] = = nVars ) ;
assert ( pSol [ ABC_EXACT_SOL_NFUNC ] = = 1 ) ;
pGates = Vec_PtrAlloc ( nVars + pSol [ ABC_EXACT_SOL_NGATES ] ) ;
pGateTruth [ 3 ] = ' 0 ' ;
pGateTruth [ 4 ] = ' \0 ' ;
/* primary inputs */
for ( i = 0 ; i < nVars ; + + i )
{
2016-08-09 10:53:58 +02:00
assert ( pFanins [ i ] ) ;
2016-07-31 12:47:09 +02:00
Vec_PtrPush ( pGates , pFanins [ i ] ) ;
}
/* gates */
p = pSol + 3 ;
for ( i = 0 ; i < pSol [ ABC_EXACT_SOL_NGATES ] ; + + i )
{
pGateTruth [ 2 ] = ' 0 ' + ( * p & 1 ) ;
pGateTruth [ 1 ] = ' 0 ' + ( ( * p > > 1 ) & 1 ) ;
pGateTruth [ 0 ] = ' 0 ' + ( ( * p > > 2 ) & 1 ) ;
+ + p ;
assert ( * p = = 2 ) ; /* binary gate */
+ + p ;
2016-08-04 14:22:31 +02:00
/* invert truth table if we are last gate and inverted */
if ( i + 1 = = pSol [ ABC_EXACT_SOL_NGATES ] & & Abc_LitIsCompl ( * ( p + 2 ) ) )
for ( j = 0 ; j < 4 ; + + j )
pGateTruth [ j ] = ( pGateTruth [ j ] = = ' 0 ' ) ? ' 1 ' : ' 0 ' ;
2016-07-31 12:47:09 +02:00
pSopCover = Abc_SopFromTruthBin ( pGateTruth ) ;
pObj = Abc_NtkCreateNode ( pNtk ) ;
2016-08-09 10:53:58 +02:00
assert ( pObj ) ;
2016-07-31 12:47:09 +02:00
pObj - > pData = Abc_SopRegister ( ( Mem_Flex_t * ) pNtk - > pManFunc , pSopCover ) ;
Vec_PtrPush ( pGates , pObj ) ;
ABC_FREE ( pSopCover ) ;
Abc_ObjAddFanin ( pObj , ( Abc_Obj_t * ) Vec_PtrEntry ( pGates , * p + + ) ) ;
Abc_ObjAddFanin ( pObj , ( Abc_Obj_t * ) Vec_PtrEntry ( pGates , * p + + ) ) ;
}
/* output */
2016-08-04 14:22:31 +02:00
pObj = ( Abc_Obj_t * ) Vec_PtrEntry ( pGates , nVars + Abc_Lit2Var ( * p ) ) ;
2016-07-31 12:47:09 +02:00
Vec_PtrFree ( pGates ) ;
2016-08-21 18:13:57 +02:00
s_pSesStore - > timeTotal + = ( Abc_Clock ( ) - timeStart ) ;
2016-07-31 12:47:09 +02:00
return pObj ;
2016-07-30 01:03:42 +02:00
}
2016-08-02 11:25:16 +02:00
void Abc_ExactStoreTest ( int fVerbose )
{
int i ;
word pTruth [ 4 ] = { 0xcafe , 0 , 0 , 0 } ;
int pArrTimeProfile [ 4 ] = { 6 , 2 , 8 , 5 } ;
Abc_Ntk_t * pNtk ;
Abc_Obj_t * pFanins [ 4 ] ;
Vec_Ptr_t * vNames ;
2016-08-06 05:47:53 +02:00
char pPerm [ 4 ] ;
int Cost ;
2016-08-02 11:25:16 +02:00
pNtk = Abc_NtkAlloc ( ABC_NTK_LOGIC , ABC_FUNC_SOP , 1 ) ;
pNtk - > pName = Extra_UtilStrsav ( " exact " ) ;
vNames = Abc_NodeGetFakeNames ( 4u ) ;
/* primary inputs */
Vec_PtrPush ( pNtk - > vObjs , NULL ) ;
for ( i = 0 ; i < 4 ; + + i )
{
pFanins [ i ] = Abc_NtkCreatePi ( pNtk ) ;
Abc_ObjAssignName ( pFanins [ i ] , ( char * ) Vec_PtrEntry ( vNames , i ) , NULL ) ;
}
Abc_NodeFreeNames ( vNames ) ;
2016-08-08 12:59:21 +02:00
Abc_ExactStart ( 10000 , 1 , fVerbose , 0 , NULL ) ;
2016-08-02 11:25:16 +02:00
2016-08-06 05:43:45 +02:00
assert ( ! Abc_ExactBuildNode ( pTruth , 4 , pArrTimeProfile , pFanins , pNtk ) ) ;
2016-08-02 11:25:16 +02:00
2016-08-02 13:24:21 +02:00
assert ( Abc_ExactDelayCost ( pTruth , 4 , pArrTimeProfile , pPerm , & Cost , 12 ) = = 1 ) ;
2016-08-06 05:43:45 +02:00
assert ( Abc_ExactBuildNode ( pTruth , 4 , pArrTimeProfile , pFanins , pNtk ) ) ;
2016-08-02 13:24:21 +02:00
( * pArrTimeProfile ) + + ;
2016-08-06 05:43:45 +02:00
assert ( ! Abc_ExactBuildNode ( pTruth , 4 , pArrTimeProfile , pFanins , pNtk ) ) ;
2016-08-02 13:24:21 +02:00
( * pArrTimeProfile ) - - ;
2016-08-02 11:25:16 +02:00
2016-08-04 18:51:35 +02:00
Abc_ExactStop ( NULL ) ;
2016-08-03 15:23:34 +02:00
Abc_NtkDelete ( pNtk ) ;
2016-08-02 11:25:16 +02:00
}
2016-07-16 16:51:58 +02:00
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END