Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
A
abc
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lvzhengyang
abc
Commits
7d7ce3ec
Commit
7d7ce3ec
authored
Dec 28, 2017
by
Alan Mishchenko
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
New exact synthesis command 'allexact'.
parent
c3dccf30
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
1340 additions
and
15 deletions
+1340
-15
abclib.dsp
+4
-0
src/base/abci/abc.c
+170
-1
src/sat/bmc/bmc.h
+19
-8
src/sat/bmc/bmcMaj.c
+21
-3
src/sat/bmc/bmcMaj2.c
+21
-3
src/sat/bmc/bmcMaj3.c
+1098
-0
src/sat/bmc/module.make
+1
-0
src/sat/glucose/Glucose.cpp
+6
-0
No files found.
abclib.dsp
View file @
7d7ce3ec
...
...
@@ -2031,6 +2031,10 @@ SOURCE=.\src\sat\bmc\bmcMaj2.c
# End Source File
# Begin Source File
SOURCE=.\src\sat\bmc\bmcMaj3.c
# End Source File
# Begin Source File
SOURCE=.\src\sat\bmc\bmcMaxi.c
# End Source File
# Begin Source File
...
...
src/base/abci/abc.c
View file @
7d7ce3ec
...
...
@@ -152,6 +152,7 @@ static int Abc_CommandBmsPs ( Abc_Frame_t * pAbc, int argc, cha
static
int
Abc_CommandMajExact
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
);
static
int
Abc_CommandTwoExact
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
);
static
int
Abc_CommandLutExact
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
);
static
int
Abc_CommandAllExact
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
);
static
int
Abc_CommandLogic
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
);
static
int
Abc_CommandComb
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
);
...
...
@@ -821,6 +822,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd
(
pAbc
,
"Exact synthesis"
,
"majexact"
,
Abc_CommandMajExact
,
0
);
Cmd_CommandAdd
(
pAbc
,
"Exact synthesis"
,
"twoexact"
,
Abc_CommandTwoExact
,
0
);
Cmd_CommandAdd
(
pAbc
,
"Exact synthesis"
,
"lutexact"
,
Abc_CommandLutExact
,
0
);
Cmd_CommandAdd
(
pAbc
,
"Exact synthesis"
,
"allexact"
,
Abc_CommandAllExact
,
0
);
Cmd_CommandAdd
(
pAbc
,
"Various"
,
"logic"
,
Abc_CommandLogic
,
1
);
Cmd_CommandAdd
(
pAbc
,
"Various"
,
"comb"
,
Abc_CommandComb
,
1
);
...
...
@@ -8385,7 +8387,7 @@ int Abc_CommandLutExact( Abc_Frame_t * pAbc, int argc, char ** argv )
usage:
Abc_Print
(
-
2
,
"usage: lutexact [-INK <num>] [-aogvh] <hex>
\n
"
);
Abc_Print
(
-
2
,
"
\t
exact synthesis of
multi-input function using two
-input gates
\n
"
);
Abc_Print
(
-
2
,
"
\t
exact synthesis of
I-input function using N K
-input gates
\n
"
);
Abc_Print
(
-
2
,
"
\t
-I <num> : the number of input variables [default = %d]
\n
"
,
pPars
->
nVars
);
Abc_Print
(
-
2
,
"
\t
-N <num> : the number of K-input nodes [default = %d]
\n
"
,
pPars
->
nNodes
);
Abc_Print
(
-
2
,
"
\t
-K <num> : the number of node fanins [default = %d]
\n
"
,
pPars
->
nLutSize
);
...
...
@@ -8409,6 +8411,173 @@ usage:
SeeAlso []
***********************************************************************/
int
Abc_CommandAllExact
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
)
{
extern
void
Zyx_ManExactSynthesis
(
Bmc_EsPar_t
*
pPars
);
int
c
;
Bmc_EsPar_t
Pars
,
*
pPars
=
&
Pars
;
Bmc_EsParSetDefault
(
pPars
);
Extra_UtilGetoptReset
();
while
(
(
c
=
Extra_UtilGetopt
(
argc
,
argv
,
"MINKaoegvh"
)
)
!=
EOF
)
{
switch
(
c
)
{
case
'M'
:
if
(
globalUtilOptind
>=
argc
)
{
Abc_Print
(
-
1
,
"Command line switch
\"
-M
\"
should be followed by an integer.
\n
"
);
goto
usage
;
}
pPars
->
nMajSupp
=
atoi
(
argv
[
globalUtilOptind
]);
globalUtilOptind
++
;
if
(
pPars
->
nMajSupp
<
0
)
goto
usage
;
break
;
case
'I'
:
if
(
globalUtilOptind
>=
argc
)
{
Abc_Print
(
-
1
,
"Command line switch
\"
-I
\"
should be followed by an integer.
\n
"
);
goto
usage
;
}
pPars
->
nVars
=
atoi
(
argv
[
globalUtilOptind
]);
globalUtilOptind
++
;
if
(
pPars
->
nVars
<
0
)
goto
usage
;
break
;
case
'N'
:
if
(
globalUtilOptind
>=
argc
)
{
Abc_Print
(
-
1
,
"Command line switch
\"
-N
\"
should be followed by an integer.
\n
"
);
goto
usage
;
}
pPars
->
nNodes
=
atoi
(
argv
[
globalUtilOptind
]);
globalUtilOptind
++
;
if
(
pPars
->
nNodes
<
0
)
goto
usage
;
break
;
case
'K'
:
if
(
globalUtilOptind
>=
argc
)
{
Abc_Print
(
-
1
,
"Command line switch
\"
-K
\"
should be followed by an integer.
\n
"
);
goto
usage
;
}
pPars
->
nLutSize
=
atoi
(
argv
[
globalUtilOptind
]);
globalUtilOptind
++
;
if
(
pPars
->
nLutSize
<
0
)
goto
usage
;
break
;
case
'a'
:
pPars
->
fOnlyAnd
^=
1
;
break
;
case
'o'
:
pPars
->
fOrderNodes
^=
1
;
break
;
case
'e'
:
pPars
->
fGenAll
^=
1
;
break
;
case
'g'
:
pPars
->
fGlucose
^=
1
;
break
;
case
'v'
:
pPars
->
fVerbose
^=
1
;
break
;
case
'h'
:
goto
usage
;
default:
goto
usage
;
}
}
if
(
pPars
->
nMajSupp
>
0
)
{
if
(
pPars
->
nMajSupp
!=
5
&&
pPars
->
nMajSupp
!=
7
&&
pPars
->
nMajSupp
!=
9
)
{
Abc_Print
(
-
1
,
"Currently only support majority with 5, 7 or 9 inputs.
\n
"
);
return
1
;
}
pPars
->
nVars
=
pPars
->
nMajSupp
;
pPars
->
nLutSize
=
3
;
pPars
->
fMajority
=
1
;
if
(
pPars
->
nNodes
==
0
)
{
if
(
pPars
->
nMajSupp
==
5
)
pPars
->
nNodes
=
4
;
if
(
pPars
->
nMajSupp
==
7
)
pPars
->
nNodes
=
7
;
if
(
pPars
->
nMajSupp
==
9
)
pPars
->
nNodes
=
10
;
}
}
else
{
if
(
pPars
->
nVars
==
0
)
{
Abc_Print
(
-
1
,
"The number of variables (-I num) needs to be specified on the command line.
\n
"
);
return
1
;
}
if
(
pPars
->
nNodes
==
0
)
{
Abc_Print
(
-
1
,
"The number of nodes (-N num) needs to be specified on the command line.
\n
"
);
return
1
;
}
if
(
argc
==
globalUtilOptind
+
1
)
pPars
->
pTtStr
=
argv
[
globalUtilOptind
];
if
(
pPars
->
pTtStr
==
NULL
)
{
Abc_Print
(
-
1
,
"Truth table should be given on the command line.
\n
"
);
return
1
;
}
if
(
(
1
<<
(
pPars
->
nVars
-
2
))
!=
(
int
)
strlen
(
pPars
->
pTtStr
)
)
{
Abc_Print
(
-
1
,
"Truth table is expected to have %d hex digits (instead of %d).
\n
"
,
(
1
<<
(
pPars
->
nVars
-
2
)),
strlen
(
pPars
->
pTtStr
)
);
return
1
;
}
}
if
(
pPars
->
nVars
>
pPars
->
nNodes
*
(
pPars
->
nLutSize
-
1
)
+
1
)
{
Abc_Print
(
-
1
,
"Function with %d variales cannot be implemented with %d %d-input LUTs.
\n
"
,
pPars
->
nVars
,
pPars
->
nNodes
,
pPars
->
nLutSize
);
return
1
;
}
if
(
pPars
->
nVars
>
10
)
{
Abc_Print
(
-
1
,
"Function should not have more than 10 inputs.
\n
"
);
return
1
;
}
if
(
pPars
->
nLutSize
>
6
)
{
Abc_Print
(
-
1
,
"Node size should not be more than 6 inputs.
\n
"
);
return
1
;
}
Zyx_ManExactSynthesis
(
pPars
);
return
0
;
usage:
Abc_Print
(
-
2
,
"usage: allexact [-MIKN <num>] [-aoevh] <hex>
\n
"
);
Abc_Print
(
-
2
,
"
\t
exact synthesis of I-input function using N K-input gates
\n
"
);
Abc_Print
(
-
2
,
"
\t
-M <num> : the majority support size (overrides -I and -K) [default = %d]
\n
"
,
pPars
->
nMajSupp
);
Abc_Print
(
-
2
,
"
\t
-I <num> : the number of input variables [default = %d]
\n
"
,
pPars
->
nVars
);
Abc_Print
(
-
2
,
"
\t
-K <num> : the number of node fanins [default = %d]
\n
"
,
pPars
->
nLutSize
);
Abc_Print
(
-
2
,
"
\t
-N <num> : the number of K-input nodes [default = %d]
\n
"
,
pPars
->
nNodes
);
Abc_Print
(
-
2
,
"
\t
-a : toggle using only AND-gates when K = 2 [default = %s]
\n
"
,
pPars
->
fOnlyAnd
?
"yes"
:
"no"
);
Abc_Print
(
-
2
,
"
\t
-o : toggle using node ordering by fanins [default = %s]
\n
"
,
pPars
->
fOrderNodes
?
"yes"
:
"no"
);
Abc_Print
(
-
2
,
"
\t
-e : toggle enumerating all solutions [default = %s]
\n
"
,
pPars
->
fGenAll
?
"yes"
:
"no"
);
// Abc_Print( -2, "\t-g : toggle using Glucose 3.0 by Gilles Audemard and Laurent Simon [default = %s]\n", pPars->fGlucose ? "yes" : "no" );
Abc_Print
(
-
2
,
"
\t
-v : toggle verbose printout [default = %s]
\n
"
,
pPars
->
fVerbose
?
"yes"
:
"no"
);
Abc_Print
(
-
2
,
"
\t
-h : print the command usage
\n
"
);
Abc_Print
(
-
2
,
"
\t
<hex> : truth table in hex notation
\n
"
);
return
1
;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int
Abc_CommandLogic
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
)
{
Abc_Ntk_t
*
pNtk
,
*
pNtkRes
;
src/sat/bmc/bmc.h
View file @
7d7ce3ec
...
...
@@ -50,8 +50,13 @@ struct Bmc_EsPar_t_
int
nVars
;
int
nNodes
;
int
nLutSize
;
int
fGlucose
;
int
nMajSupp
;
int
fMajority
;
int
fEnumSols
;
int
fOnlyAnd
;
int
fGlucose
;
int
fOrderNodes
;
int
fGenAll
;
int
fFewerVars
;
int
fVerbose
;
char
*
pTtStr
;
...
...
@@ -59,13 +64,19 @@ struct Bmc_EsPar_t_
static
inline
void
Bmc_EsParSetDefault
(
Bmc_EsPar_t
*
pPars
)
{
pPars
->
nVars
=
5
;
// when first GC happens (4096) (degree of 2)
pPars
->
nNodes
=
4
;
// when each next GC happens (5)
pPars
->
nLutSize
=
3
;
// log difference compared to unique table
pPars
->
fGlucose
=
0
;
// minimum gain when reodering is not performed
pPars
->
fOnlyAnd
=
0
;
// minimum gain when reodering is not performed
pPars
->
fFewerVars
=
0
;
// minimum gain when reodering is not performed
pPars
->
fVerbose
=
1
;
// verbose output
memset
(
pPars
,
0
,
sizeof
(
Bmc_EsPar_t
)
);
pPars
->
nVars
=
0
;
pPars
->
nNodes
=
0
;
pPars
->
nLutSize
=
2
;
pPars
->
nMajSupp
=
0
;
pPars
->
fMajority
=
0
;
pPars
->
fEnumSols
=
0
;
pPars
->
fOnlyAnd
=
0
;
pPars
->
fGlucose
=
0
;
pPars
->
fOrderNodes
=
0
;
pPars
->
fGenAll
=
0
;
pPars
->
fFewerVars
=
0
;
pPars
->
fVerbose
=
1
;
}
...
...
src/sat/bmc/bmcMaj.c
View file @
7d7ce3ec
...
...
@@ -184,6 +184,7 @@ static inline int Maj_ManFindFanin( Maj_Man_t * p, int i, int k )
}
static
inline
int
Maj_ManEval
(
Maj_Man_t
*
p
)
{
int
fUseMiddle
=
1
;
static
int
Flag
=
0
;
int
i
,
k
,
iMint
;
word
*
pFanins
[
3
];
for
(
i
=
p
->
nVars
+
2
;
i
<
p
->
nObjs
;
i
++
)
...
...
@@ -192,10 +193,27 @@ static inline int Maj_ManEval( Maj_Man_t * p )
pFanins
[
k
]
=
Maj_ManTruth
(
p
,
Maj_ManFindFanin
(
p
,
i
,
k
)
);
Abc_TtMaj
(
Maj_ManTruth
(
p
,
i
),
pFanins
[
0
],
pFanins
[
1
],
pFanins
[
2
],
p
->
nWords
);
}
if
(
Flag
&&
p
->
nVars
>=
6
)
iMint
=
Abc_TtFindLastDiffBit
(
Maj_ManTruth
(
p
,
p
->
nObjs
-
1
),
Maj_ManTruth
(
p
,
p
->
nObjs
),
p
->
nVars
);
if
(
fUseMiddle
)
{
iMint
=
-
1
;
for
(
i
=
0
;
i
<
(
1
<<
p
->
nVars
);
i
++
)
{
int
nOnes
=
Abc_TtBitCount16
(
i
);
if
(
nOnes
<
p
->
nVars
/
2
||
nOnes
>
p
->
nVars
/
2
+
1
)
continue
;
if
(
Abc_TtGetBit
(
Maj_ManTruth
(
p
,
p
->
nObjs
),
i
)
==
Abc_TtGetBit
(
Maj_ManTruth
(
p
,
p
->
nObjs
-
1
),
i
)
)
continue
;
iMint
=
i
;
break
;
}
}
else
iMint
=
Abc_TtFindFirstDiffBit
(
Maj_ManTruth
(
p
,
p
->
nObjs
-
1
),
Maj_ManTruth
(
p
,
p
->
nObjs
),
p
->
nVars
);
{
if
(
Flag
&&
p
->
nVars
>=
6
)
iMint
=
Abc_TtFindLastDiffBit
(
Maj_ManTruth
(
p
,
p
->
nObjs
-
1
),
Maj_ManTruth
(
p
,
p
->
nObjs
),
p
->
nVars
);
else
iMint
=
Abc_TtFindFirstDiffBit
(
Maj_ManTruth
(
p
,
p
->
nObjs
-
1
),
Maj_ManTruth
(
p
,
p
->
nObjs
),
p
->
nVars
);
}
//Flag ^= 1;
assert
(
iMint
<
(
1
<<
p
->
nVars
)
);
return
iMint
;
...
...
src/sat/bmc/bmcMaj2.c
View file @
7d7ce3ec
...
...
@@ -280,6 +280,7 @@ static inline int Maj_ManFindFanin( Maj_Man_t * p, int i, int k )
}
static
inline
int
Maj_ManEval
(
Maj_Man_t
*
p
)
{
int
fUseMiddle
=
1
;
static
int
Flag
=
0
;
int
i
,
k
,
iMint
;
word
*
pFanins
[
3
];
for
(
i
=
p
->
nVars
+
2
;
i
<
p
->
nObjs
;
i
++
)
...
...
@@ -288,10 +289,27 @@ static inline int Maj_ManEval( Maj_Man_t * p )
pFanins
[
k
]
=
Maj_ManTruth
(
p
,
Maj_ManFindFanin
(
p
,
i
,
k
)
);
Abc_TtMaj
(
Maj_ManTruth
(
p
,
i
),
pFanins
[
0
],
pFanins
[
1
],
pFanins
[
2
],
p
->
nWords
);
}
if
(
Flag
&&
p
->
nVars
>=
6
)
iMint
=
Abc_TtFindLastDiffBit
(
Maj_ManTruth
(
p
,
p
->
nObjs
-
1
),
Maj_ManTruth
(
p
,
p
->
nObjs
),
p
->
nVars
);
if
(
fUseMiddle
)
{
iMint
=
-
1
;
for
(
i
=
0
;
i
<
(
1
<<
p
->
nVars
);
i
++
)
{
int
nOnes
=
Abc_TtBitCount16
(
i
);
if
(
nOnes
<
p
->
nVars
/
2
||
nOnes
>
p
->
nVars
/
2
+
1
)
continue
;
if
(
Abc_TtGetBit
(
Maj_ManTruth
(
p
,
p
->
nObjs
),
i
)
==
Abc_TtGetBit
(
Maj_ManTruth
(
p
,
p
->
nObjs
-
1
),
i
)
)
continue
;
iMint
=
i
;
break
;
}
}
else
iMint
=
Abc_TtFindFirstDiffBit
(
Maj_ManTruth
(
p
,
p
->
nObjs
-
1
),
Maj_ManTruth
(
p
,
p
->
nObjs
),
p
->
nVars
);
{
if
(
Flag
&&
p
->
nVars
>=
6
)
iMint
=
Abc_TtFindLastDiffBit
(
Maj_ManTruth
(
p
,
p
->
nObjs
-
1
),
Maj_ManTruth
(
p
,
p
->
nObjs
),
p
->
nVars
);
else
iMint
=
Abc_TtFindFirstDiffBit
(
Maj_ManTruth
(
p
,
p
->
nObjs
-
1
),
Maj_ManTruth
(
p
,
p
->
nObjs
),
p
->
nVars
);
}
//Flag ^= 1;
assert
(
iMint
<
(
1
<<
p
->
nVars
)
);
return
iMint
;
...
...
src/sat/bmc/bmcMaj3.c
0 → 100644
View file @
7d7ce3ec
/**CFile****************************************************************
FileName [bmcMaj3.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [SAT-based bounded model checking.]
Synopsis [Majority gate synthesis.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: bmcMaj3.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "bmc.h"
#include "misc/extra/extra.h"
#include "misc/util/utilTruth.h"
#include "sat/glucose/AbcGlucose.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
#define MAJ3_OBJS 32 // nVars + nNodes
typedef
struct
Maj3_Man_t_
Maj3_Man_t
;
struct
Maj3_Man_t_
{
int
nVars
;
// inputs
int
nNodes
;
// internal nodes
int
nObjs
;
// total objects (nVars inputs, nNodes internal nodes)
int
nWords
;
// the truth table size in 64-bit words
int
iVar
;
// the next available SAT variable
Vec_Wrd_t
*
vInfo
;
// nVars + nNodes + 1
Vec_Int_t
*
vLevels
;
// distriction of nodes by levels
int
VarMarks
[
MAJ3_OBJS
][
MAJ3_OBJS
];
// variable marks
int
ObjVals
[
MAJ3_OBJS
];
// object values
int
pLits
[
2
][
MAJ3_OBJS
];
// neg, pos literals
int
nLits
[
3
];
// neg, pos, fixed literal
bmcg_sat_solver
*
pSat
;
// SAT solver
};
static
inline
word
*
Maj3_ManTruth
(
Maj3_Man_t
*
p
,
int
v
)
{
return
Vec_WrdEntryP
(
p
->
vInfo
,
p
->
nWords
*
v
);
}
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static
inline
int
Maj3_ManValue
(
int
iMint
,
int
nVars
)
{
int
k
,
Count
=
0
;
for
(
k
=
0
;
k
<
nVars
;
k
++
)
Count
+=
(
iMint
>>
k
)
&
1
;
return
(
int
)(
Count
>
nVars
/
2
);
}
Vec_Wrd_t
*
Maj3_ManTruthTables
(
Maj3_Man_t
*
p
)
{
Vec_Wrd_t
*
vInfo
=
p
->
vInfo
=
Vec_WrdStart
(
p
->
nWords
*
(
p
->
nObjs
+
1
)
);
int
i
,
nMints
=
Abc_MaxInt
(
64
,
1
<<
p
->
nVars
);
for
(
i
=
0
;
i
<
p
->
nVars
;
i
++
)
Abc_TtIthVar
(
Maj3_ManTruth
(
p
,
i
),
i
,
p
->
nVars
);
for
(
i
=
0
;
i
<
nMints
;
i
++
)
if
(
Maj3_ManValue
(
i
,
p
->
nVars
)
)
Abc_TtSetBit
(
Maj3_ManTruth
(
p
,
p
->
nObjs
),
i
);
//Dau_DsdPrintFromTruth( Maj3_ManTruth(p, p->nObjs), p->nVars );
return
vInfo
;
}
void
Maj3_ManFirstAndLevel
(
Vec_Int_t
*
vLevels
,
int
Firsts
[
MAJ3_OBJS
],
int
Levels
[
MAJ3_OBJS
],
int
nVars
,
int
nObjs
)
{
int
i
,
k
,
Entry
,
Obj
=
0
;
Firsts
[
0
]
=
Obj
;
for
(
k
=
0
;
k
<
nVars
;
k
++
)
Levels
[
Obj
++
]
=
0
;
Vec_IntReverseOrder
(
vLevels
);
Vec_IntForEachEntry
(
vLevels
,
Entry
,
i
)
{
Firsts
[
i
+
1
]
=
Obj
;
for
(
k
=
0
;
k
<
Entry
;
k
++
)
Levels
[
Obj
++
]
=
i
+
1
;
}
Vec_IntReverseOrder
(
vLevels
);
assert
(
Obj
==
nObjs
);
}
int
Maj3_ManMarkup
(
Maj3_Man_t
*
p
)
{
int
nSatVars
=
2
;
// SAT variable counter
int
nLevels
=
Vec_IntSize
(
p
->
vLevels
);
int
nSecond
=
Vec_IntEntry
(
p
->
vLevels
,
1
);
int
i
,
k
,
Firsts
[
MAJ3_OBJS
],
Levels
[
MAJ3_OBJS
];
assert
(
Vec_IntEntry
(
p
->
vLevels
,
0
)
==
1
);
assert
(
p
->
nObjs
<=
MAJ3_OBJS
);
assert
(
p
->
nNodes
==
Vec_IntSum
(
p
->
vLevels
)
);
Maj3_ManFirstAndLevel
(
p
->
vLevels
,
Firsts
,
Levels
,
p
->
nVars
,
p
->
nObjs
);
// create map
for
(
i
=
0
;
i
<
p
->
nObjs
;
i
++
)
for
(
k
=
0
;
k
<
p
->
nObjs
;
k
++
)
p
->
VarMarks
[
i
][
k
]
=
-
1
;
for
(
k
=
0
;
k
<
3
;
k
++
)
// first node
p
->
VarMarks
[
p
->
nVars
][
k
]
=
1
;
for
(
k
=
0
;
k
<
nSecond
;
k
++
)
// top node
p
->
VarMarks
[
p
->
nObjs
-
1
][
p
->
nObjs
-
2
-
k
]
=
1
;
for
(
k
=
2
;
k
<
nLevels
;
k
++
)
// cascade
p
->
VarMarks
[
Firsts
[
k
]][
Firsts
[
k
-
1
]]
=
1
;
for
(
i
=
p
->
nVars
+
1
;
i
<
(
nSecond
==
3
?
p
->
nObjs
-
1
:
p
->
nObjs
);
i
++
)
for
(
k
=
0
;
k
<
Firsts
[
Levels
[
i
]];
k
++
)
if
(
p
->
VarMarks
[
i
][
k
]
==
-
1
)
p
->
VarMarks
[
i
][
k
]
=
nSatVars
++
;
//printf( "The number of variables is %d.\n", nSatVars );
return
nSatVars
;
}
void
Maj3_ManVarMapPrint
(
Maj3_Man_t
*
p
)
{
int
i
,
k
,
Firsts
[
MAJ3_OBJS
],
Levels
[
MAJ3_OBJS
];
Maj3_ManFirstAndLevel
(
p
->
vLevels
,
Firsts
,
Levels
,
p
->
nVars
,
p
->
nObjs
);
// print
printf
(
"Variable map for problem with %d inputs, %d nodes and %d levels: "
,
p
->
nVars
,
p
->
nNodes
,
Vec_IntSize
(
p
->
vLevels
)
);
Vec_IntPrint
(
p
->
vLevels
);
printf
(
" "
);
printf
(
" "
);
for
(
i
=
0
;
i
<
p
->
nObjs
;
i
++
)
printf
(
"%3d "
,
i
);
printf
(
"
\n
"
);
for
(
i
=
p
->
nObjs
-
1
;
i
>=
p
->
nVars
;
i
--
)
{
printf
(
" %2d "
,
i
);
printf
(
" %2d "
,
Levels
[
i
]
);
for
(
k
=
0
;
k
<
p
->
nObjs
;
k
++
)
if
(
p
->
VarMarks
[
i
][
k
]
==
-
1
)
printf
(
" . "
);
else
if
(
p
->
VarMarks
[
i
][
k
]
==
1
)
printf
(
" + "
);
else
printf
(
"%3d%c "
,
p
->
VarMarks
[
i
][
k
],
bmcg_sat_solver_read_cex_varvalue
(
p
->
pSat
,
p
->
VarMarks
[
i
][
k
])
?
'+'
:
' '
);
printf
(
"
\n
"
);
}
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static
inline
int
Maj3_ManFindFanin
(
Maj3_Man_t
*
p
,
int
i
,
int
*
pFanins
)
{
int
f
,
nFanins
=
0
;
p
->
nLits
[
0
]
=
p
->
nLits
[
1
]
=
p
->
nLits
[
2
]
=
0
;
for
(
f
=
0
;
f
<
i
;
f
++
)
{
if
(
p
->
VarMarks
[
i
][
f
]
<
0
)
continue
;
assert
(
p
->
VarMarks
[
i
][
f
]
>
0
);
if
(
p
->
VarMarks
[
i
][
f
]
==
1
)
// fixed
{
p
->
nLits
[
2
]
++
;
pFanins
[
nFanins
++
]
=
f
;
}
else
if
(
bmcg_sat_solver_read_cex_varvalue
(
p
->
pSat
,
p
->
VarMarks
[
i
][
f
])
)
// pos
{
p
->
pLits
[
1
][
p
->
nLits
[
1
]
++
]
=
Abc_Var2Lit
(
p
->
VarMarks
[
i
][
f
],
1
);
pFanins
[
nFanins
++
]
=
f
;
}
else
// neg
p
->
pLits
[
0
][
p
->
nLits
[
0
]
++
]
=
Abc_Var2Lit
(
p
->
VarMarks
[
i
][
f
],
0
);
}
return
nFanins
;
}
static
inline
void
Maj3_ManPrintSolution
(
Maj3_Man_t
*
p
)
{
int
i
,
k
,
iVar
,
nFanins
,
pFanins
[
MAJ3_OBJS
];
printf
(
"Realization of %d-input majority using %d MAJ3 gates:
\n
"
,
p
->
nVars
,
p
->
nNodes
);
// for ( i = p->nVars; i < p->nObjs; i++ )
for
(
i
=
p
->
nObjs
-
1
;
i
>=
p
->
nVars
;
i
--
)
{
printf
(
"%02d = MAJ("
,
i
);
nFanins
=
Maj3_ManFindFanin
(
p
,
i
,
pFanins
);
assert
(
nFanins
==
3
);
for
(
k
=
0
;
k
<
3
;
k
++
)
{
iVar
=
pFanins
[
k
];
if
(
iVar
>=
0
&&
iVar
<
p
->
nVars
)
printf
(
" %c"
,
'a'
+
iVar
);
else
printf
(
" %02d"
,
iVar
);
}
printf
(
" )
\n
"
);
}
}
static
inline
int
Maj3_ManEval
(
Maj3_Man_t
*
p
)
{
int
fUseMiddle
=
1
;
static
int
Flag
=
0
;
int
i
,
k
,
iMint
,
pFanins
[
3
];
word
*
pFaninsW
[
3
];
for
(
i
=
p
->
nVars
;
i
<
p
->
nObjs
;
i
++
)
{
int
nFanins
=
Maj3_ManFindFanin
(
p
,
i
,
pFanins
);
assert
(
nFanins
==
3
);
for
(
k
=
0
;
k
<
3
;
k
++
)
pFaninsW
[
k
]
=
Maj3_ManTruth
(
p
,
pFanins
[
k
]
);
Abc_TtMaj
(
Maj3_ManTruth
(
p
,
i
),
pFaninsW
[
0
],
pFaninsW
[
1
],
pFaninsW
[
2
],
p
->
nWords
);
}
if
(
fUseMiddle
)
{
iMint
=
-
1
;
for
(
i
=
0
;
i
<
(
1
<<
p
->
nVars
);
i
++
)
{
int
nOnes
=
Abc_TtBitCount16
(
i
);
if
(
nOnes
<
p
->
nVars
/
2
||
nOnes
>
p
->
nVars
/
2
+
1
)
continue
;
if
(
Abc_TtGetBit
(
Maj3_ManTruth
(
p
,
p
->
nObjs
),
i
)
==
Abc_TtGetBit
(
Maj3_ManTruth
(
p
,
p
->
nObjs
-
1
),
i
)
)
continue
;
iMint
=
i
;
break
;
}
}
else
{
if
(
Flag
&&
p
->
nVars
>=
6
)
iMint
=
Abc_TtFindLastDiffBit
(
Maj3_ManTruth
(
p
,
p
->
nObjs
-
1
),
Maj3_ManTruth
(
p
,
p
->
nObjs
),
p
->
nVars
);
else
iMint
=
Abc_TtFindFirstDiffBit
(
Maj3_ManTruth
(
p
,
p
->
nObjs
-
1
),
Maj3_ManTruth
(
p
,
p
->
nObjs
),
p
->
nVars
);
}
//Flag ^= 1;
assert
(
iMint
<
(
1
<<
p
->
nVars
)
);
return
iMint
;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
Maj3_PrintClause
(
int
*
pLits
,
int
nLits
)
{
int
i
;
for
(
i
=
0
;
i
<
nLits
;
i
++
)
printf
(
"%c%d "
,
Abc_LitIsCompl
(
pLits
[
i
])
?
'-'
:
'+'
,
Abc_Lit2Var
(
pLits
[
i
])
);
printf
(
"
\n
"
);
}
int
Maj3_ManAddCnfStart
(
Maj3_Man_t
*
p
)
{
int
i
,
k
,
status
,
nLits
,
pLits
[
MAJ3_OBJS
];
// nodes have at least one fanin
//printf( "Fanin clauses:\n" );
for
(
i
=
p
->
nVars
;
i
<
p
->
nObjs
;
i
++
)
{
// check if it is already connected
int
Count
=
0
;
for
(
k
=
0
;
k
<
p
->
nObjs
;
k
++
)
Count
+=
p
->
VarMarks
[
i
][
k
]
==
1
;
assert
(
Count
<=
3
);
if
(
Count
==
3
)
continue
;
// collect connections
nLits
=
0
;
for
(
k
=
0
;
k
<
p
->
nObjs
;
k
++
)
if
(
p
->
VarMarks
[
i
][
k
]
>
1
)
pLits
[
nLits
++
]
=
Abc_Var2Lit
(
p
->
VarMarks
[
i
][
k
],
0
);
//Maj3_PrintClause( pLits, nLits );
assert
(
nLits
>
0
);
if
(
nLits
>
0
&&
!
bmcg_sat_solver_addclause
(
p
->
pSat
,
pLits
,
nLits
)
)
assert
(
0
);
}
// nodes have at least one fanout
//printf( "Fanout clauses:\n" );
for
(
k
=
0
;
k
<
p
->
nObjs
-
1
;
k
++
)
{
// check if it is already connected
int
Count
=
0
;
for
(
i
=
0
;
i
<
p
->
nObjs
;
i
++
)
Count
+=
p
->
VarMarks
[
i
][
k
]
==
1
;
assert
(
Count
<=
3
);
if
(
Count
>
0
)
continue
;
// collect connections
nLits
=
0
;
for
(
i
=
0
;
i
<
p
->
nObjs
;
i
++
)
if
(
p
->
VarMarks
[
i
][
k
]
>
1
)
pLits
[
nLits
++
]
=
Abc_Var2Lit
(
p
->
VarMarks
[
i
][
k
],
0
);
//Maj3_PrintClause( pLits, nLits );
//assert( nLits > 0 );
if
(
nLits
>
0
&&
!
bmcg_sat_solver_addclause
(
p
->
pSat
,
pLits
,
nLits
)
)
assert
(
0
);
}
status
=
bmcg_sat_solver_solve
(
p
->
pSat
,
NULL
,
0
);
assert
(
status
==
GLUCOSE_SAT
);
Maj3_ManVarMapPrint
(
p
);
return
1
;
}
int
Maj3_ManAddCnf
(
Maj3_Man_t
*
p
,
int
iMint
)
{
// input values
int
i
,
k
,
j
,
n
,
*
pVals
=
p
->
ObjVals
;
for
(
i
=
0
;
i
<
p
->
nVars
;
i
++
)
pVals
[
i
]
=
(
iMint
>>
i
)
&
1
;
// first node value
pVals
[
p
->
nVars
]
=
(
pVals
[
0
]
&&
pVals
[
1
])
||
(
pVals
[
0
]
&&
pVals
[
2
])
||
(
pVals
[
1
]
&&
pVals
[
2
]);
// last node value
pVals
[
p
->
nObjs
-
1
]
=
Maj3_ManValue
(
iMint
,
p
->
nVars
);
// intermediate node values
for
(
i
=
p
->
nVars
+
1
;
i
<
p
->
nObjs
-
1
;
i
++
)
pVals
[
i
]
=
p
->
iVar
++
;
//printf( "Adding clauses for minterm %d.\n", iMint );
bmcg_sat_solver_set_nvars
(
p
->
pSat
,
p
->
iVar
);
for
(
n
=
0
;
n
<
2
;
n
++
)
for
(
i
=
p
->
nVars
+
1
;
i
<
p
->
nObjs
;
i
++
)
{
//printf( "\nNode %d. Phase %d.\n", i, n );
for
(
k
=
0
;
k
<
p
->
nObjs
;
k
++
)
if
(
p
->
VarMarks
[
i
][
k
]
>=
1
)
{
// add first input
int
pLits
[
5
],
nLits
=
0
;
if
(
pVals
[
k
]
==
!
n
)
continue
;
if
(
pVals
[
k
]
>
1
)
pLits
[
nLits
++
]
=
Abc_Var2Lit
(
pVals
[
k
],
n
);
if
(
p
->
VarMarks
[
i
][
k
]
>
1
)
pLits
[
nLits
++
]
=
Abc_Var2Lit
(
p
->
VarMarks
[
i
][
k
],
1
);
for
(
j
=
k
+
1
;
j
<
p
->
nObjs
;
j
++
)
if
(
p
->
VarMarks
[
i
][
j
]
>=
1
)
{
// add second input
int
nLits2
=
nLits
;
if
(
pVals
[
j
]
==
!
n
)
continue
;
if
(
pVals
[
j
]
>
1
)
pLits
[
nLits2
++
]
=
Abc_Var2Lit
(
pVals
[
j
],
n
);
if
(
p
->
VarMarks
[
i
][
j
]
>
1
)
pLits
[
nLits2
++
]
=
Abc_Var2Lit
(
p
->
VarMarks
[
i
][
j
],
1
);
// add output
if
(
pVals
[
i
]
==
n
)
continue
;
if
(
pVals
[
i
]
>
1
)
pLits
[
nLits2
++
]
=
Abc_Var2Lit
(
pVals
[
i
],
!
n
);
assert
(
nLits2
>
0
&&
nLits2
<=
5
);
//Maj3_PrintClause( pLits, nLits2 );
if
(
!
bmcg_sat_solver_addclause
(
p
->
pSat
,
pLits
,
nLits2
)
)
return
0
;
}
}
}
return
1
;
}
int
Maj3_ManAddConstraintsLazy
(
Maj3_Man_t
*
p
)
{
int
i
,
pFanins
[
MAJ3_OBJS
],
nConstr
=
0
;
//Maj3_ManVarMapPrint( p );
for
(
i
=
p
->
nVars
+
1
;
i
<
p
->
nObjs
;
i
++
)
{
int
nFanins
=
Maj3_ManFindFanin
(
p
,
i
,
pFanins
);
if
(
nFanins
==
3
)
continue
;
//printf( "Node %d has %d fanins.\n", i, nFanins );
nConstr
++
;
if
(
nFanins
<
3
)
{
assert
(
p
->
nLits
[
0
]
>
0
);
//Maj3_PrintClause( p->pLits[0], p->nLits[0] );
if
(
!
bmcg_sat_solver_addclause
(
p
->
pSat
,
p
->
pLits
[
0
],
p
->
nLits
[
0
]
)
)
return
-
1
;
}
else
if
(
nFanins
>
3
)
{
int
nLits
=
Abc_MinInt
(
4
-
p
->
nLits
[
2
],
p
->
nLits
[
1
]);
assert
(
nLits
>
0
);
//Maj3_PrintClause( p->pLits[1], nLits );
if
(
!
bmcg_sat_solver_addclause
(
p
->
pSat
,
p
->
pLits
[
1
],
nLits
)
)
return
-
1
;
}
}
return
nConstr
;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Maj3_Man_t
*
Maj3_ManAlloc
(
int
nVars
,
int
nNodes
,
Vec_Int_t
*
vLevels
)
{
Maj3_Man_t
*
p
=
ABC_CALLOC
(
Maj3_Man_t
,
1
);
p
->
vLevels
=
vLevels
;
p
->
nVars
=
nVars
;
p
->
nNodes
=
nNodes
;
p
->
nObjs
=
nVars
+
nNodes
;
p
->
nWords
=
Abc_TtWordNum
(
nVars
);
p
->
iVar
=
Maj3_ManMarkup
(
p
);
p
->
vInfo
=
Maj3_ManTruthTables
(
p
);
p
->
pSat
=
bmcg_sat_solver_start
();
bmcg_sat_solver_set_nvars
(
p
->
pSat
,
p
->
iVar
);
Maj3_ManAddCnfStart
(
p
);
return
p
;
}
void
Maj3_ManFree
(
Maj3_Man_t
*
p
)
{
bmcg_sat_solver_stop
(
p
->
pSat
);
Vec_WrdFree
(
p
->
vInfo
);
ABC_FREE
(
p
);
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int
Maj3_ManExactSynthesis
(
int
nVars
,
int
nNodes
,
int
fVerbose
,
Vec_Int_t
*
vLevels
)
{
Maj3_Man_t
*
p
;
abctime
clkTotal
=
Abc_Clock
();
int
i
,
status
,
nLazy
,
nLazyAll
=
0
,
iMint
=
0
;
printf
(
"Running exact synthesis for %d-input majority with %d MAJ3 gates...
\n
"
,
nVars
,
nNodes
);
p
=
Maj3_ManAlloc
(
nVars
,
nNodes
,
vLevels
);
for
(
i
=
0
;
iMint
!=
-
1
;
i
++
)
{
abctime
clk
=
Abc_Clock
();
if
(
!
Maj3_ManAddCnf
(
p
,
iMint
)
)
break
;
while
(
(
status
=
bmcg_sat_solver_solve
(
p
->
pSat
,
NULL
,
0
))
==
GLUCOSE_SAT
)
{
nLazy
=
Maj3_ManAddConstraintsLazy
(
p
);
if
(
nLazy
==
-
1
)
{
printf
(
"Became UNSAT after adding lazy constraints.
\n
"
);
status
=
GLUCOSE_UNSAT
;
break
;
}
//printf( "Added %d lazy constraints.\n\n", nLazy );
if
(
nLazy
==
0
)
break
;
nLazyAll
+=
nLazy
;
}
if
(
fVerbose
)
{
printf
(
"Iter %3d : "
,
i
);
Extra_PrintBinary
(
stdout
,
(
unsigned
*
)
&
iMint
,
p
->
nVars
);
printf
(
" Var =%5d "
,
p
->
iVar
);
printf
(
"Cla =%6d "
,
bmcg_sat_solver_clausenum
(
p
->
pSat
)
);
printf
(
"Conf =%9d "
,
bmcg_sat_solver_conflictnum
(
p
->
pSat
)
);
printf
(
"Lazy =%9d "
,
nLazyAll
);
Abc_PrintTime
(
1
,
"Time"
,
Abc_Clock
()
-
clk
);
}
if
(
status
==
GLUCOSE_UNSAT
)
{
printf
(
"The problem has no solution.
\n
"
);
break
;
}
iMint
=
Maj3_ManEval
(
p
);
}
if
(
iMint
==
-
1
)
Maj3_ManPrintSolution
(
p
);
Maj3_ManFree
(
p
);
Abc_PrintTime
(
1
,
"Total runtime"
,
Abc_Clock
()
-
clkTotal
);
return
iMint
==
-
1
;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int
Maj3_ManTest
()
{
/*
int nVars = 5;
int nNodes = 4;
int fVerbose = 1;
int Levels[MAJ3_OBJS] = { 1, 2, 1 };
Vec_Int_t vLevels = { 3, 3, Levels };
*/
int
nVars
=
7
;
int
nNodes
=
7
;
int
fVerbose
=
1
;
int
Levels
[
MAJ3_OBJS
]
=
{
1
,
2
,
2
,
2
};
Vec_Int_t
vLevels
=
{
4
,
4
,
Levels
};
/*
int nVars = 9;
int nNodes = 10;
int fVerbose = 1;
int Levels[MAJ3_OBJS] = { 1, 2, 3, 2, 2 };
Vec_Int_t vLevels = { 5, 5, Levels };
*/
/*
int nVars = 9;
int nNodes = 10;
int fVerbose = 1;
int Levels[MAJ3_OBJS] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
Vec_Int_t vLevels = { 10, 10, Levels };
*/
// Maj3_Man_t * p = Maj3_ManAlloc( nVars, nNodes, &vLevels );
// Maj3_ManFree( p );
Maj3_ManExactSynthesis
(
nVars
,
nNodes
,
fVerbose
,
&
vLevels
);
return
0
;
}
typedef
struct
Zyx_Man_t_
Zyx_Man_t
;
struct
Zyx_Man_t_
{
Bmc_EsPar_t
*
pPars
;
// parameters
word
*
pTruth
;
// truth table
int
nObjs
;
// total objects (nVars inputs, nNodes internal nodes)
int
nWords
;
// the truth table size in 64-bit words
int
LutMask
;
// 1 << nLutSize
int
TopoBase
;
// (1 << nLutSize) * nObjs
int
MintBase
;
// TopoBase + nObjs * nObjs
Vec_Wrd_t
*
vInfo
;
// nVars + nNodes + 1
Vec_Int_t
*
vVarValues
;
// variable values
int
pFanins
[
MAJ3_OBJS
][
MAJ3_OBJS
];
// fanins
int
pLits
[
2
][
2
*
MAJ3_OBJS
];
// neg/pos literals
int
nLits
[
2
];
// neg/pos literal
int
Counts
[
1024
];
bmcg_sat_solver
*
pSat
;
// SAT solver
};
static
inline
word
*
Zyx_ManTruth
(
Zyx_Man_t
*
p
,
int
v
)
{
return
Vec_WrdEntryP
(
p
->
vInfo
,
p
->
nWords
*
v
);
}
static
inline
int
Zyx_FuncVar
(
Zyx_Man_t
*
p
,
int
i
,
int
m
)
{
return
(
1
<<
p
->
pPars
->
nLutSize
)
*
i
+
m
;
}
static
inline
int
Zyx_TopoVar
(
Zyx_Man_t
*
p
,
int
i
,
int
f
)
{
return
p
->
TopoBase
+
p
->
nObjs
*
i
+
f
;
}
static
inline
int
Zyx_MintVar
(
Zyx_Man_t
*
p
,
int
m
,
int
i
)
{
return
p
->
MintBase
+
p
->
nObjs
*
m
+
i
;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
Zyx_SetConstVar
(
Zyx_Man_t
*
p
,
int
Var
,
int
Value
)
{
int
iLit
=
Abc_Var2Lit
(
Var
,
!
Value
);
int
status
=
bmcg_sat_solver_addclause
(
p
->
pSat
,
&
iLit
,
1
);
assert
(
status
);
assert
(
Vec_IntEntry
(
p
->
vVarValues
,
Var
)
==
-
1
);
Vec_IntWriteEntry
(
p
->
vVarValues
,
Var
,
Value
);
//printf( "Setting var %d to value %d.\n", Var, Value );
}
void
Zyx_ManSetupVars
(
Zyx_Man_t
*
p
)
{
int
i
,
k
,
m
;
word
*
pSpec
=
p
->
pPars
->
fMajority
?
Zyx_ManTruth
(
p
,
p
->
nObjs
)
:
p
->
pTruth
;
// set unused functionality vars to 0
for
(
i
=
p
->
pPars
->
nVars
;
i
<
p
->
nObjs
;
i
++
)
Zyx_SetConstVar
(
p
,
Zyx_FuncVar
(
p
,
i
,
0
),
0
);
// set unused topology vars
for
(
i
=
p
->
pPars
->
nVars
;
i
<
p
->
nObjs
;
i
++
)
for
(
k
=
i
;
k
<
p
->
nObjs
;
k
++
)
Zyx_SetConstVar
(
p
,
Zyx_TopoVar
(
p
,
i
,
k
),
0
);
// connect topmost node
Zyx_SetConstVar
(
p
,
Zyx_TopoVar
(
p
,
p
->
nObjs
-
1
,
p
->
nObjs
-
2
),
1
);
// connect first node
if
(
p
->
pPars
->
fMajority
)
for
(
k
=
0
;
k
<
p
->
pPars
->
nVars
;
k
++
)
Zyx_SetConstVar
(
p
,
Zyx_TopoVar
(
p
,
p
->
pPars
->
nVars
,
k
),
k
<
3
);
// set minterm vars
for
(
m
=
0
;
m
<
(
1
<<
p
->
pPars
->
nVars
);
m
++
)
{
for
(
i
=
0
;
i
<
p
->
pPars
->
nVars
;
i
++
)
Zyx_SetConstVar
(
p
,
Zyx_MintVar
(
p
,
m
,
i
),
(
m
>>
i
)
&
1
);
Zyx_SetConstVar
(
p
,
Zyx_MintVar
(
p
,
m
,
p
->
nObjs
-
1
),
Abc_TtGetBit
(
pSpec
,
m
)
);
}
}
int
Zyx_ManAddCnfStart
(
Zyx_Man_t
*
p
)
{
// nodes have fanins
int
i
,
k
,
pLits
[
MAJ3_OBJS
];
//printf( "Adding initial clauses:\n" );
for
(
i
=
p
->
pPars
->
nVars
;
i
<
p
->
nObjs
;
i
++
)
{
int
nLits
=
0
;
for
(
k
=
0
;
k
<
i
;
k
++
)
pLits
[
nLits
++
]
=
Abc_Var2Lit
(
Zyx_TopoVar
(
p
,
i
,
k
),
0
);
assert
(
nLits
>
0
);
if
(
!
bmcg_sat_solver_addclause
(
p
->
pSat
,
pLits
,
nLits
)
)
return
0
;
}
// nodes have fanouts
for
(
k
=
0
;
k
<
p
->
nObjs
-
1
;
k
++
)
{
int
nLits
=
0
;
for
(
i
=
p
->
pPars
->
nVars
;
i
<
p
->
nObjs
;
i
++
)
pLits
[
nLits
++
]
=
Abc_Var2Lit
(
Zyx_TopoVar
(
p
,
i
,
k
),
0
);
assert
(
nLits
>
0
);
if
(
!
bmcg_sat_solver_addclause
(
p
->
pSat
,
pLits
,
nLits
)
)
return
0
;
}
// two input functions
if
(
p
->
pPars
->
nLutSize
!=
2
)
return
1
;
for
(
i
=
p
->
pPars
->
nVars
;
i
<
p
->
nObjs
;
i
++
)
{
for
(
k
=
0
;
k
<
3
;
k
++
)
{
pLits
[
0
]
=
Abc_Var2Lit
(
Zyx_FuncVar
(
p
,
i
,
1
),
k
==
1
);
pLits
[
1
]
=
Abc_Var2Lit
(
Zyx_FuncVar
(
p
,
i
,
2
),
k
==
2
);
pLits
[
2
]
=
Abc_Var2Lit
(
Zyx_FuncVar
(
p
,
i
,
3
),
k
!=
0
);
if
(
!
bmcg_sat_solver_addclause
(
p
->
pSat
,
pLits
,
3
)
)
return
0
;
}
if
(
p
->
pPars
->
fOnlyAnd
)
{
pLits
[
0
]
=
Abc_Var2Lit
(
Zyx_FuncVar
(
p
,
i
,
1
),
1
);
pLits
[
1
]
=
Abc_Var2Lit
(
Zyx_FuncVar
(
p
,
i
,
2
),
1
);
pLits
[
2
]
=
Abc_Var2Lit
(
Zyx_FuncVar
(
p
,
i
,
3
),
0
);
if
(
!
bmcg_sat_solver_addclause
(
p
->
pSat
,
pLits
,
3
)
)
return
0
;
}
}
return
1
;
}
void
Zyx_ManPrintVarMap
(
Zyx_Man_t
*
p
,
int
fSat
)
{
int
i
,
k
,
nTopoVars
=
0
;
printf
(
" "
);
for
(
k
=
0
;
k
<
p
->
nObjs
-
1
;
k
++
)
printf
(
"%3d "
,
k
);
printf
(
"
\n
"
);
for
(
i
=
p
->
nObjs
-
1
;
i
>=
p
->
pPars
->
nVars
;
i
--
)
{
printf
(
"%3d "
,
i
);
for
(
k
=
0
;
k
<
p
->
nObjs
-
1
;
k
++
)
{
int
iVar
=
Zyx_TopoVar
(
p
,
i
,
k
);
if
(
Vec_IntEntry
(
p
->
vVarValues
,
iVar
)
==
-
1
)
printf
(
"%3d%c "
,
iVar
,
(
fSat
&&
bmcg_sat_solver_read_cex_varvalue
(
p
->
pSat
,
iVar
))
?
'*'
:
' '
),
nTopoVars
++
;
else
printf
(
"%3d "
,
Vec_IntEntry
(
p
->
vVarValues
,
iVar
)
);
}
printf
(
"
\n
"
);
}
if
(
fSat
)
return
;
printf
(
"Using %d active functionality vars and %d active topology vars (out of %d SAT vars).
\n
"
,
p
->
pPars
->
fMajority
?
0
:
p
->
pPars
->
nNodes
*
p
->
LutMask
,
nTopoVars
,
bmcg_sat_solver_varnum
(
p
->
pSat
)
);
}
void
Zyx_PrintClause
(
int
*
pLits
,
int
nLits
)
{
int
i
;
for
(
i
=
0
;
i
<
nLits
;
i
++
)
printf
(
"%c%d "
,
Abc_LitIsCompl
(
pLits
[
i
])
?
'-'
:
'+'
,
Abc_Lit2Var
(
pLits
[
i
])
);
printf
(
"
\n
"
);
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static
inline
int
Zyx_ManValue
(
int
iMint
,
int
nVars
)
{
int
k
,
Count
=
0
;
for
(
k
=
0
;
k
<
nVars
;
k
++
)
Count
+=
(
iMint
>>
k
)
&
1
;
return
(
int
)(
Count
>
nVars
/
2
);
}
Vec_Wrd_t
*
Zyx_ManTruthTables
(
Zyx_Man_t
*
p
,
word
*
pTruth
)
{
Vec_Wrd_t
*
vInfo
=
p
->
vInfo
=
Vec_WrdStart
(
p
->
nWords
*
(
p
->
nObjs
+
1
)
);
int
i
,
nMints
=
Abc_MaxInt
(
64
,
1
<<
p
->
pPars
->
nVars
);
assert
(
p
->
pPars
->
fMajority
==
(
pTruth
==
NULL
)
);
for
(
i
=
0
;
i
<
p
->
pPars
->
nVars
;
i
++
)
Abc_TtIthVar
(
Zyx_ManTruth
(
p
,
i
),
i
,
p
->
pPars
->
nVars
);
if
(
p
->
pPars
->
fMajority
)
for
(
i
=
0
;
i
<
nMints
;
i
++
)
if
(
Zyx_ManValue
(
i
,
p
->
pPars
->
nVars
)
)
Abc_TtSetBit
(
Zyx_ManTruth
(
p
,
p
->
nObjs
),
i
);
//Dau_DsdPrintFromTruth( Zyx_ManTruth(p, p->nObjs), p->pPars->nVars );
return
vInfo
;
}
Zyx_Man_t
*
Zyx_ManAlloc
(
Bmc_EsPar_t
*
pPars
,
word
*
pTruth
)
{
Zyx_Man_t
*
p
=
ABC_CALLOC
(
Zyx_Man_t
,
1
);
p
->
pPars
=
pPars
;
p
->
pTruth
=
pTruth
;
p
->
nObjs
=
p
->
pPars
->
nVars
+
p
->
pPars
->
nNodes
;
p
->
nWords
=
Abc_TtWordNum
(
p
->
pPars
->
nVars
);
p
->
LutMask
=
(
1
<<
p
->
pPars
->
nLutSize
)
-
1
;
p
->
TopoBase
=
(
1
<<
p
->
pPars
->
nLutSize
)
*
p
->
nObjs
;
p
->
MintBase
=
p
->
TopoBase
+
p
->
nObjs
*
p
->
nObjs
;
p
->
vVarValues
=
Vec_IntStartFull
(
p
->
MintBase
+
(
1
<<
p
->
pPars
->
nVars
)
*
p
->
nObjs
);
p
->
vInfo
=
Zyx_ManTruthTables
(
p
,
pTruth
);
p
->
pSat
=
bmcg_sat_solver_start
();
bmcg_sat_solver_set_nvars
(
p
->
pSat
,
p
->
MintBase
+
(
1
<<
p
->
pPars
->
nVars
)
*
p
->
nObjs
);
Zyx_ManSetupVars
(
p
);
Zyx_ManAddCnfStart
(
p
);
Zyx_ManPrintVarMap
(
p
,
0
);
return
p
;
}
void
Zyx_ManFree
(
Zyx_Man_t
*
p
)
{
bmcg_sat_solver_stop
(
p
->
pSat
);
Vec_WrdFree
(
p
->
vInfo
);
Vec_IntFree
(
p
->
vVarValues
);
ABC_FREE
(
p
);
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int
Zyx_ManCollectFanins
(
Zyx_Man_t
*
p
,
int
i
)
{
int
k
,
Val
;
assert
(
i
>=
p
->
pPars
->
nVars
&&
i
<
p
->
nObjs
);
p
->
nLits
[
0
]
=
p
->
nLits
[
1
]
=
0
;
for
(
k
=
0
;
k
<
i
;
k
++
)
{
Val
=
bmcg_sat_solver_read_cex_varvalue
(
p
->
pSat
,
Zyx_TopoVar
(
p
,
i
,
k
));
p
->
pFanins
[
i
][
p
->
nLits
[
1
]]
=
k
;
p
->
pLits
[
Val
][
p
->
nLits
[
Val
]
++
]
=
Abc_Var2Lit
(
Zyx_TopoVar
(
p
,
i
,
k
),
Val
);
}
return
p
->
nLits
[
1
];
}
int
Zyx_ManAddCnfLazyTopo
(
Zyx_Man_t
*
p
)
{
int
i
,
k
,
j
,
nLazy
=
0
;
// fanin count
//printf( "Adding topology clauses.\n" );
for
(
i
=
p
->
pPars
->
nVars
;
i
<
p
->
nObjs
;
i
++
)
{
int
nFanins
=
Zyx_ManCollectFanins
(
p
,
i
);
if
(
nFanins
==
p
->
pPars
->
nLutSize
)
continue
;
nLazy
++
;
assert
(
nFanins
==
p
->
nLits
[
1
]
);
if
(
p
->
nLits
[
1
]
>
p
->
pPars
->
nLutSize
)
{
p
->
nLits
[
1
]
=
p
->
pPars
->
nLutSize
+
1
;
//Zyx_PrintClause( p->pLits[1], p->nLits[1] );
if
(
!
bmcg_sat_solver_addclause
(
p
->
pSat
,
p
->
pLits
[
1
],
p
->
nLits
[
1
]
)
)
return
-
1
;
}
else
// if ( p->nLits[1] < p->pPars->nLutSize )
{
//Zyx_PrintClause( p->pLits[0], p->nLits[0] );
if
(
!
bmcg_sat_solver_addclause
(
p
->
pSat
,
p
->
pLits
[
0
],
p
->
nLits
[
0
]
)
)
return
-
1
;
}
}
if
(
nLazy
||
!
p
->
pPars
->
fOrderNodes
)
return
nLazy
;
// ordering
for
(
i
=
p
->
pPars
->
nVars
+
1
;
i
<
p
->
nObjs
;
i
++
)
{
for
(
k
=
p
->
pPars
->
nLutSize
-
1
;
k
>=
0
;
k
--
)
if
(
p
->
pFanins
[
i
-
1
][
k
]
!=
p
->
pFanins
[
i
][
k
]
)
break
;
if
(
k
==
-
1
)
{
if
(
!
p
->
pPars
->
fMajority
)
{
// compare by LUT functions
}
continue
;
}
if
(
p
->
pFanins
[
i
-
1
][
k
]
<
p
->
pFanins
[
i
][
k
]
)
{
assert
(
bmcg_sat_solver_read_cex_varvalue
(
p
->
pSat
,
Zyx_TopoVar
(
p
,
i
-
1
,
p
->
pFanins
[
i
][
k
]))
==
0
);
assert
(
bmcg_sat_solver_read_cex_varvalue
(
p
->
pSat
,
Zyx_TopoVar
(
p
,
i
,
p
->
pFanins
[
i
][
k
]))
==
1
);
continue
;
}
nLazy
++
;
assert
(
bmcg_sat_solver_read_cex_varvalue
(
p
->
pSat
,
Zyx_TopoVar
(
p
,
i
-
1
,
p
->
pFanins
[
i
-
1
][
k
]))
==
1
);
assert
(
bmcg_sat_solver_read_cex_varvalue
(
p
->
pSat
,
Zyx_TopoVar
(
p
,
i
,
p
->
pFanins
[
i
-
1
][
k
]))
==
0
);
// rule out this order
p
->
nLits
[
0
]
=
0
;
for
(
j
=
p
->
pFanins
[
i
-
1
][
k
];
j
<
p
->
nObjs
-
1
;
j
++
)
{
int
ValA
=
bmcg_sat_solver_read_cex_varvalue
(
p
->
pSat
,
Zyx_TopoVar
(
p
,
i
-
1
,
j
));
int
ValB
=
bmcg_sat_solver_read_cex_varvalue
(
p
->
pSat
,
Zyx_TopoVar
(
p
,
i
,
j
));
p
->
pLits
[
0
][
p
->
nLits
[
0
]
++
]
=
Abc_Var2Lit
(
Zyx_TopoVar
(
p
,
i
-
1
,
j
),
ValA
);
p
->
pLits
[
0
][
p
->
nLits
[
0
]
++
]
=
Abc_Var2Lit
(
Zyx_TopoVar
(
p
,
i
,
j
),
ValB
);
}
//printf( "\n" );
//Zyx_ManPrintVarMap( p, 1 );
//Zyx_PrintClause( p->pLits[0], p->nLits[0] );
if
(
!
bmcg_sat_solver_addclause
(
p
->
pSat
,
p
->
pLits
[
0
],
p
->
nLits
[
0
]
)
)
return
-
1
;
//break;
}
return
nLazy
;
}
int
Zyx_ManAddCnfBlockSolution
(
Zyx_Man_t
*
p
)
{
Vec_Int_t
*
vLits
=
Vec_IntAlloc
(
100
);
int
i
,
k
;
for
(
i
=
p
->
pPars
->
nVars
;
i
<
p
->
nObjs
;
i
++
)
{
int
nFanins
=
Zyx_ManCollectFanins
(
p
,
i
);
assert
(
nFanins
==
p
->
pPars
->
nLutSize
);
for
(
k
=
0
;
k
<
p
->
pPars
->
nLutSize
;
k
++
)
Vec_IntPush
(
vLits
,
Abc_Var2Lit
(
Zyx_TopoVar
(
p
,
i
,
p
->
pFanins
[
i
][
k
]),
1
)
);
}
//Zyx_ManPrintVarMap( p, 1 );
//Zyx_PrintClause( Vec_IntArray(vLits), Vec_IntSize(vLits) );
if
(
!
bmcg_sat_solver_addclause
(
p
->
pSat
,
Vec_IntArray
(
vLits
),
Vec_IntSize
(
vLits
)
)
)
return
0
;
Vec_IntFree
(
vLits
);
return
1
;
}
int
Zyx_ManAddCnfLazyFunc
(
Zyx_Man_t
*
p
,
int
iMint
)
{
int
Sets
[
3
][
2
]
=
{{
0
,
1
},
{
0
,
2
},
{
1
,
2
}};
int
i
,
k
,
n
,
j
,
s
;
assert
(
!
p
->
pPars
->
fMajority
||
p
->
pPars
->
nLutSize
==
3
);
//printf( "Adding functionality clauses for minterm %d.\n", iMint );
p
->
Counts
[
iMint
]
++
;
for
(
i
=
p
->
pPars
->
nVars
;
i
<
p
->
nObjs
;
i
++
)
{
int
nFanins
=
Zyx_ManCollectFanins
(
p
,
i
);
assert
(
nFanins
==
p
->
pPars
->
nLutSize
);
for
(
n
=
0
;
n
<
2
;
n
++
)
{
if
(
p
->
pPars
->
fMajority
)
{
for
(
k
=
0
;
k
<
3
;
k
++
)
{
p
->
nLits
[
0
]
=
0
;
for
(
s
=
0
;
s
<
2
;
s
++
)
{
p
->
pLits
[
0
][
p
->
nLits
[
0
]
++
]
=
Abc_Var2Lit
(
Zyx_TopoVar
(
p
,
i
,
p
->
pFanins
[
i
][
Sets
[
k
][
s
]]),
1
);
p
->
pLits
[
0
][
p
->
nLits
[
0
]
++
]
=
Abc_Var2Lit
(
Zyx_MintVar
(
p
,
iMint
,
p
->
pFanins
[
i
][
Sets
[
k
][
s
]]),
n
);
}
p
->
pLits
[
0
][
p
->
nLits
[
0
]
++
]
=
Abc_Var2Lit
(
Zyx_MintVar
(
p
,
iMint
,
i
),
!
n
);
if
(
!
bmcg_sat_solver_addclause
(
p
->
pSat
,
p
->
pLits
[
0
],
p
->
nLits
[
0
]
)
)
return
0
;
}
}
else
{
for
(
k
=
0
;
k
<=
p
->
LutMask
;
k
++
)
{
p
->
nLits
[
0
]
=
0
;
p
->
pLits
[
0
][
p
->
nLits
[
0
]
++
]
=
Abc_Var2Lit
(
Zyx_FuncVar
(
p
,
i
,
k
),
n
);
for
(
j
=
0
;
j
<
p
->
pPars
->
nLutSize
;
j
++
)
{
p
->
pLits
[
0
][
p
->
nLits
[
0
]
++
]
=
Abc_Var2Lit
(
Zyx_TopoVar
(
p
,
i
,
p
->
pFanins
[
i
][
j
]),
1
);
p
->
pLits
[
0
][
p
->
nLits
[
0
]
++
]
=
Abc_Var2Lit
(
Zyx_MintVar
(
p
,
iMint
,
p
->
pFanins
[
i
][
j
]),
(
k
>>
j
)
&
1
);
}
p
->
pLits
[
0
][
p
->
nLits
[
0
]
++
]
=
Abc_Var2Lit
(
Zyx_MintVar
(
p
,
iMint
,
i
),
!
n
);
//Zyx_PrintClause( p->pLits[0], p->nLits[0] );
if
(
!
bmcg_sat_solver_addclause
(
p
->
pSat
,
p
->
pLits
[
0
],
p
->
nLits
[
0
]
)
)
return
0
;
}
}
}
}
return
1
;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static
void
Zyx_ManPrintSolution
(
Zyx_Man_t
*
p
,
int
fCompl
)
{
int
i
,
k
;
printf
(
"Realization of given %d-input function using %d %d-input %s:
\n
"
,
p
->
pPars
->
nVars
,
p
->
pPars
->
nNodes
,
p
->
pPars
->
nLutSize
,
p
->
pPars
->
fMajority
?
"MAJ-gates"
:
"LUTs"
);
for
(
i
=
p
->
nObjs
-
1
;
i
>=
p
->
pPars
->
nVars
;
i
--
)
{
printf
(
"%02d = "
,
i
);
if
(
p
->
pPars
->
fMajority
)
printf
(
"MAJ3"
);
else
{
printf
(
"%d
\'
b"
,
1
<<
p
->
pPars
->
nLutSize
);
for
(
k
=
p
->
LutMask
;
k
>=
0
;
k
--
)
printf
(
"%d"
,
bmcg_sat_solver_read_cex_varvalue
(
p
->
pSat
,
Zyx_FuncVar
(
p
,
i
,
k
))
^
(
i
==
p
->
nObjs
-
1
&&
fCompl
)
);
}
printf
(
"("
);
for
(
k
=
0
;
k
<
i
;
k
++
)
if
(
bmcg_sat_solver_read_cex_varvalue
(
p
->
pSat
,
Zyx_TopoVar
(
p
,
i
,
k
))
)
if
(
k
>=
0
&&
k
<
p
->
pPars
->
nVars
)
printf
(
" %c"
,
'a'
+
k
);
else
printf
(
" %02d"
,
k
);
printf
(
" )
\n
"
);
}
}
static
inline
int
Zyx_ManEval
(
Zyx_Man_t
*
p
)
{
static
int
Flag
=
0
;
int
i
,
k
,
j
,
iMint
;
word
*
pFaninsW
[
6
],
*
pSpec
;
for
(
i
=
p
->
pPars
->
nVars
;
i
<
p
->
nObjs
;
i
++
)
{
int
nFanins
=
Zyx_ManCollectFanins
(
p
,
i
);
assert
(
nFanins
==
p
->
pPars
->
nLutSize
);
for
(
k
=
0
;
k
<
p
->
pPars
->
nLutSize
;
k
++
)
pFaninsW
[
k
]
=
Zyx_ManTruth
(
p
,
p
->
pFanins
[
i
][
k
]
);
if
(
p
->
pPars
->
fMajority
)
Abc_TtMaj
(
Zyx_ManTruth
(
p
,
i
),
pFaninsW
[
0
],
pFaninsW
[
1
],
pFaninsW
[
2
],
p
->
nWords
);
else
{
Abc_TtConst0
(
Zyx_ManTruth
(
p
,
i
),
p
->
nWords
);
for
(
k
=
1
;
k
<=
p
->
LutMask
;
k
++
)
if
(
bmcg_sat_solver_read_cex_varvalue
(
p
->
pSat
,
Zyx_FuncVar
(
p
,
i
,
k
))
)
{
Abc_TtConst1
(
Zyx_ManTruth
(
p
,
p
->
nObjs
),
p
->
nWords
);
for
(
j
=
0
;
j
<
p
->
pPars
->
nLutSize
;
j
++
)
Abc_TtAndCompl
(
Zyx_ManTruth
(
p
,
p
->
nObjs
),
Zyx_ManTruth
(
p
,
p
->
nObjs
),
0
,
pFaninsW
[
j
],
!
((
k
>>
j
)
&
1
),
p
->
nWords
);
Abc_TtOr
(
Zyx_ManTruth
(
p
,
i
),
Zyx_ManTruth
(
p
,
i
),
Zyx_ManTruth
(
p
,
p
->
nObjs
),
p
->
nWords
);
}
}
}
pSpec
=
p
->
pPars
->
fMajority
?
Zyx_ManTruth
(
p
,
p
->
nObjs
)
:
p
->
pTruth
;
if
(
Flag
&&
p
->
pPars
->
nVars
>=
6
)
iMint
=
Abc_TtFindLastDiffBit
(
Zyx_ManTruth
(
p
,
p
->
nObjs
-
1
),
pSpec
,
p
->
pPars
->
nVars
);
else
iMint
=
Abc_TtFindFirstDiffBit
(
Zyx_ManTruth
(
p
,
p
->
nObjs
-
1
),
pSpec
,
p
->
pPars
->
nVars
);
//Flag ^= 1;
assert
(
iMint
<
(
1
<<
p
->
pPars
->
nVars
)
);
return
iMint
;
}
static
inline
void
Zyx_ManEvalStats
(
Zyx_Man_t
*
p
)
{
int
i
;
for
(
i
=
0
;
i
<
(
1
<<
p
->
pPars
->
nVars
);
i
++
)
printf
(
"%d=%d "
,
i
,
p
->
Counts
[
i
]
);
printf
(
"
\n
"
);
}
static
inline
void
Zyx_ManPrint
(
Zyx_Man_t
*
p
,
int
Iter
,
int
iMint
,
int
nLazyAll
,
abctime
clk
)
{
printf
(
"Iter %6d : "
,
Iter
);
Extra_PrintBinary
(
stdout
,
(
unsigned
*
)
&
iMint
,
p
->
pPars
->
nVars
);
printf
(
" "
);
printf
(
"Cla =%9d "
,
bmcg_sat_solver_clausenum
(
p
->
pSat
)
);
printf
(
"Lazy =%6d "
,
nLazyAll
);
printf
(
"Conf =%9d "
,
bmcg_sat_solver_conflictnum
(
p
->
pSat
)
);
Abc_PrintTime
(
1
,
"Time"
,
clk
);
//Zyx_ManEvalStats( p );
}
void
Zyx_ManExactSynthesis
(
Bmc_EsPar_t
*
pPars
)
{
int
status
,
Iter
,
iMint
=
0
,
fCompl
=
0
,
nLazyAll
=
0
,
nSols
=
0
;
abctime
clkTotal
=
Abc_Clock
(),
clk
=
Abc_Clock
();
Zyx_Man_t
*
p
;
word
pTruth
[
16
];
if
(
!
pPars
->
fMajority
)
{
Abc_TtReadHex
(
pTruth
,
pPars
->
pTtStr
);
if
(
pTruth
[
0
]
&
1
)
{
fCompl
=
1
;
Abc_TtNot
(
pTruth
,
Abc_TtWordNum
(
pPars
->
nVars
)
);
}
}
assert
(
pPars
->
nVars
<=
10
);
assert
(
pPars
->
nLutSize
<=
6
);
p
=
Zyx_ManAlloc
(
pPars
,
pPars
->
fMajority
?
NULL
:
pTruth
);
printf
(
"Running exact synthesis for %d-input function with %d %d-input %s...
\n
"
,
p
->
pPars
->
nVars
,
p
->
pPars
->
nNodes
,
p
->
pPars
->
nLutSize
,
p
->
pPars
->
fMajority
?
"MAJ-gates"
:
"LUTs"
);
for
(
Iter
=
0
;
;
Iter
++
)
{
while
(
(
status
=
bmcg_sat_solver_solve
(
p
->
pSat
,
NULL
,
0
))
==
GLUCOSE_SAT
)
{
int
nLazy
=
Zyx_ManAddCnfLazyTopo
(
p
);
if
(
nLazy
==
-
1
)
{
printf
(
"Became UNSAT after adding lazy constraints.
\n
"
);
status
=
GLUCOSE_UNSAT
;
break
;
}
//printf( "Added %d lazy constraints.\n\n", nLazy );
if
(
nLazy
==
0
)
break
;
nLazyAll
+=
nLazy
;
}
if
(
status
==
GLUCOSE_UNSAT
)
break
;
// find mismatch
iMint
=
Zyx_ManEval
(
p
);
if
(
iMint
==
-
1
)
{
if
(
pPars
->
fGenAll
)
{
nSols
++
;
if
(
pPars
->
fVerbose
)
{
Zyx_ManPrint
(
p
,
Iter
,
iMint
,
nLazyAll
,
Abc_Clock
()
-
clkTotal
);
clk
=
Abc_Clock
();
}
Zyx_ManPrintSolution
(
p
,
fCompl
);
if
(
!
Zyx_ManAddCnfBlockSolution
(
p
)
)
break
;
continue
;
}
else
break
;
}
if
(
!
Zyx_ManAddCnfLazyFunc
(
p
,
iMint
)
)
{
printf
(
"Became UNSAT after adding constraints for minterm %d
\n
"
,
iMint
);
status
=
GLUCOSE_UNSAT
;
break
;
}
status
=
bmcg_sat_solver_solve
(
p
->
pSat
,
NULL
,
0
);
if
(
pPars
->
fVerbose
&&
Iter
%
100
==
0
)
{
Zyx_ManPrint
(
p
,
Iter
,
iMint
,
nLazyAll
,
Abc_Clock
()
-
clk
);
clk
=
Abc_Clock
();
}
if
(
status
==
GLUCOSE_UNSAT
)
break
;
}
if
(
pPars
->
fVerbose
)
Zyx_ManPrint
(
p
,
Iter
,
iMint
,
nLazyAll
,
Abc_Clock
()
-
clkTotal
);
if
(
pPars
->
fGenAll
)
printf
(
"Finished enumerating %d solutions.
\n
"
,
nSols
);
else
if
(
iMint
==
-
1
)
Zyx_ManPrintSolution
(
p
,
fCompl
);
else
printf
(
"The problem has no solution.
\n
"
);
Zyx_ManFree
(
p
);
Abc_PrintTime
(
1
,
"Total runtime"
,
Abc_Clock
()
-
clkTotal
);
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END
src/sat/bmc/module.make
View file @
7d7ce3ec
...
...
@@ -24,6 +24,7 @@ SRC += src/sat/bmc/bmcBCore.c \
src/sat/bmc/bmcLoad.c
\
src/sat/bmc/bmcMaj.c
\
src/sat/bmc/bmcMaj2.c
\
src/sat/bmc/bmcMaj3.c
\
src/sat/bmc/bmcMaxi.c
\
src/sat/bmc/bmcMesh.c
\
src/sat/bmc/bmcMesh2.c
\
...
...
src/sat/glucose/Glucose.cpp
View file @
7d7ce3ec
...
...
@@ -253,6 +253,12 @@ bool Solver::addClause_(vec<Lit>& ps)
else
if
(
value
(
ps
[
i
])
!=
l_False
&&
ps
[
i
]
!=
p
)
ps
[
j
++
]
=
p
=
ps
[
i
];
ps
.
shrink
(
i
-
j
);
if
(
0
)
{
for
(
int
i
=
0
;
i
<
ps
.
size
();
i
++
)
printf
(
"%s%d "
,
(
toInt
(
ps
[
i
])
&
1
)
?
"-"
:
""
,
toInt
(
ps
[
i
])
>>
1
);
printf
(
"
\n
"
);
}
if
(
flag
&&
(
certifiedUNSAT
))
{
for
(
i
=
j
=
0
,
p
=
lit_Undef
;
i
<
ps
.
size
();
i
++
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment