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
20c46b5a
Commit
20c46b5a
authored
Oct 12, 2015
by
Alan Mishchenko
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Experiments with precomputation and matching.
parent
d25473b3
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
623 additions
and
79 deletions
+623
-79
src/base/abci/abc.c
+6
-2
src/map/mio/mio.c
+10
-6
src/map/mio/mio.h
+2
-1
src/map/mio/mioRead.c
+11
-1
src/map/mio/mioUtils.c
+8
-7
src/opt/sfm/sfmDec.c
+282
-62
src/opt/sfm/sfmInt.h
+11
-0
src/opt/sfm/sfmLib.c
+293
-0
No files found.
src/base/abci/abc.c
View file @
20c46b5a
...
...
@@ -5160,7 +5160,7 @@ int Abc_CommandMfs3( Abc_Frame_t * pAbc, int argc, char ** argv )
// set defaults
Sfm_ParSetDefault3
(
pPars
);
Extra_UtilGetoptReset
();
while
(
(
c
=
Extra_UtilGetopt
(
argc
,
argv
,
"OIFXMLCNdavwh"
)
)
!=
EOF
)
while
(
(
c
=
Extra_UtilGetopt
(
argc
,
argv
,
"OIFXMLCNda
o
vwh"
)
)
!=
EOF
)
{
switch
(
c
)
{
...
...
@@ -5258,6 +5258,9 @@ int Abc_CommandMfs3( Abc_Frame_t * pAbc, int argc, char ** argv )
case
'a'
:
pPars
->
fArea
^=
1
;
break
;
case
'o'
:
pPars
->
fRrOnly
^=
1
;
break
;
case
'v'
:
pPars
->
fVerbose
^=
1
;
break
;
...
...
@@ -5285,7 +5288,7 @@ int Abc_CommandMfs3( Abc_Frame_t * pAbc, int argc, char ** argv )
return
0
;
usage:
Abc_Print
(
-
2
,
"usage: mfs3 [-OIFXMLCN <num>] [-avwh]
\n
"
);
Abc_Print
(
-
2
,
"usage: mfs3 [-OIFXMLCN <num>] [-a
o
vwh]
\n
"
);
Abc_Print
(
-
2
,
"
\t
performs don't-care-based optimization of mapped networks
\n
"
);
Abc_Print
(
-
2
,
"
\t
-O <num> : the number of levels in the TFO cone (0 <= num) [default = %d]
\n
"
,
pPars
->
nTfoLevMax
);
Abc_Print
(
-
2
,
"
\t
-I <num> : the number of levels in the TFI cone (1 <= num) [default = %d]
\n
"
,
pPars
->
nTfiLevMax
);
...
...
@@ -5296,6 +5299,7 @@ usage:
Abc_Print
(
-
2
,
"
\t
-C <num> : the max number of conflicts in one SAT run (0 = no limit) [default = %d]
\n
"
,
pPars
->
nBTLimit
);
Abc_Print
(
-
2
,
"
\t
-N <num> : the max number of nodes to try (0 = all) [default = %d]
\n
"
,
pPars
->
nNodesMax
);
Abc_Print
(
-
2
,
"
\t
-a : toggle minimizing area or area+edges [default = %s]
\n
"
,
pPars
->
fArea
?
"area"
:
"area+edges"
);
Abc_Print
(
-
2
,
"
\t
-o : toggle using old implementation for comparison [default = %s]
\n
"
,
pPars
->
fRrOnly
?
"yes"
:
"no"
);
Abc_Print
(
-
2
,
"
\t
-v : toggle printing optimization summary [default = %s]
\n
"
,
pPars
->
fVerbose
?
"yes"
:
"no"
);
Abc_Print
(
-
2
,
"
\t
-w : toggle printing detailed stats for each node [default = %s]
\n
"
,
pPars
->
fVeryVerbose
?
"yes"
:
"no"
);
Abc_Print
(
-
2
,
"
\t
-h : print the command usage
\n
"
);
src/map/mio/mio.c
View file @
20c46b5a
...
...
@@ -443,7 +443,7 @@ int Mio_CommandWriteGenlib( Abc_Frame_t * pAbc, int argc, char **argv )
printf
(
"Error! Cannot open file
\"
%s
\"
for writing the library.
\n
"
,
pFileName
);
return
1
;
}
Mio_WriteLibrary
(
pFile
,
(
Mio_Library_t
*
)
Abc_FrameReadLibGen
(),
0
);
Mio_WriteLibrary
(
pFile
,
(
Mio_Library_t
*
)
Abc_FrameReadLibGen
(),
0
,
0
);
fclose
(
pFile
);
printf
(
"The current genlib library is written into file
\"
%s
\"
.
\n
"
,
pFileName
);
return
0
;
...
...
@@ -472,7 +472,8 @@ int Mio_CommandPrintGenlib( Abc_Frame_t * pAbc, int argc, char **argv )
{
FILE
*
pOut
,
*
pErr
;
Abc_Ntk_t
*
pNet
;
int
fVerbose
;
int
fShort
=
0
;
int
fVerbose
=
0
;
int
c
;
pNet
=
Abc_FrameReadNtk
(
pAbc
);
...
...
@@ -480,12 +481,14 @@ int Mio_CommandPrintGenlib( Abc_Frame_t * pAbc, int argc, char **argv )
pErr
=
Abc_FrameReadErr
(
pAbc
);
// set the defaults
fVerbose
=
1
;
Extra_UtilGetoptReset
();
while
(
(
c
=
Extra_UtilGetopt
(
argc
,
argv
,
"vh"
))
!=
EOF
)
while
(
(
c
=
Extra_UtilGetopt
(
argc
,
argv
,
"
s
vh"
))
!=
EOF
)
{
switch
(
c
)
{
case
's'
:
fShort
^=
1
;
break
;
case
'v'
:
fVerbose
^=
1
;
break
;
...
...
@@ -501,12 +504,13 @@ int Mio_CommandPrintGenlib( Abc_Frame_t * pAbc, int argc, char **argv )
printf
(
"Library is not available.
\n
"
);
return
1
;
}
Mio_WriteLibrary
(
stdout
,
(
Mio_Library_t
*
)
Abc_FrameReadLibGen
(),
0
);
Mio_WriteLibrary
(
stdout
,
(
Mio_Library_t
*
)
Abc_FrameReadLibGen
(),
0
,
fShort
);
return
0
;
usage:
fprintf
(
pErr
,
"
\n
usage: print_genlib [-vh]
\n
"
);
fprintf
(
pErr
,
"
\n
usage: print_genlib [-
s
vh]
\n
"
);
fprintf
(
pErr
,
"
\t
print the current genlib library
\n
"
);
fprintf
(
pErr
,
"
\t
-s : toggles writing short form [default = %s]
\n
"
,
fShort
?
"yes"
:
"no"
);
fprintf
(
pErr
,
"
\t
-v : toggles enabling of verbose output [default = %s]
\n
"
,
fVerbose
?
"yes"
:
"no"
);
fprintf
(
pErr
,
"
\t
-h : print the command usage
\n
"
);
return
1
;
...
...
src/map/mio/mio.h
View file @
20c46b5a
...
...
@@ -58,6 +58,7 @@ typedef struct Mio_Cell2_t_ Mio_Cell2_t;
struct
Mio_Cell2_t_
{
char
*
pName
;
// name
Vec_Int_t
*
vExpr
;
// expression
unsigned
Id
:
28
;
// gate ID
unsigned
nFanins
:
4
;
// gate fanins
word
Area
;
// area
...
...
@@ -177,7 +178,7 @@ extern void Mio_LibraryDelete( Mio_Library_t * pLib );
extern
void
Mio_GateDelete
(
Mio_Gate_t
*
pGate
);
extern
void
Mio_PinDelete
(
Mio_Pin_t
*
pPin
);
extern
Mio_Pin_t
*
Mio_PinDup
(
Mio_Pin_t
*
pPin
);
extern
void
Mio_WriteLibrary
(
FILE
*
pFile
,
Mio_Library_t
*
pLib
,
int
fPrintSops
);
extern
void
Mio_WriteLibrary
(
FILE
*
pFile
,
Mio_Library_t
*
pLib
,
int
fPrintSops
,
int
fShort
);
extern
Mio_Gate_t
**
Mio_CollectRoots
(
Mio_Library_t
*
pLib
,
int
nInputs
,
float
tDelay
,
int
fSkipInv
,
int
*
pnGates
,
int
fVerbose
);
extern
Mio_Cell_t
*
Mio_CollectRootsNew
(
Mio_Library_t
*
pLib
,
int
nInputs
,
int
*
pnGates
,
int
fVerbose
);
extern
Mio_Cell_t
*
Mio_CollectRootsNewDefault
(
int
nInputs
,
int
*
pnGates
,
int
fVerbose
);
...
...
src/map/mio/mioRead.c
View file @
20c46b5a
...
...
@@ -329,6 +329,16 @@ int Mio_LibraryReadInternal( Mio_Library_t * pLib, char * pBuffer, int fExtended
SeeAlso []
***********************************************************************/
char
*
Mio_LibraryCleanStr
(
char
*
p
)
{
int
i
,
k
;
char
*
pRes
=
Abc_UtilStrsav
(
p
);
for
(
i
=
k
=
0
;
pRes
[
i
];
i
++
)
if
(
pRes
[
i
]
!=
' '
&&
pRes
[
i
]
!=
'\t'
&&
pRes
[
i
]
!=
'\r'
&&
pRes
[
i
]
!=
'\n'
)
pRes
[
k
++
]
=
pRes
[
i
];
pRes
[
k
]
=
0
;
return
pRes
;
}
Mio_Gate_t
*
Mio_LibraryReadGate
(
char
**
ppToken
,
int
fExtendedFormat
)
{
Mio_Gate_t
*
pGate
;
...
...
@@ -354,7 +364,7 @@ Mio_Gate_t * Mio_LibraryReadGate( char ** ppToken, int fExtendedFormat )
// then rest of the expression
pToken
=
strtok
(
NULL
,
";"
);
pGate
->
pForm
=
chomp
(
pToken
);
pGate
->
pForm
=
Mio_LibraryCleanStr
(
pToken
);
// read the pin info
// start the linked list of pins
...
...
src/map/mio/mioUtils.c
View file @
20c46b5a
...
...
@@ -200,10 +200,10 @@ void Mio_WritePin( FILE * pFile, Mio_Pin_t * pPin, int NameLen, int fAllPins )
fprintf
(
pFile
,
"%7s "
,
pPhaseNames
[
pPin
->
Phase
]
);
fprintf
(
pFile
,
"%3d "
,
(
int
)
pPin
->
dLoadInput
);
fprintf
(
pFile
,
"%3d "
,
(
int
)
pPin
->
dLoadMax
);
fprintf
(
pFile
,
"%
6
.2f "
,
pPin
->
dDelayBlockRise
);
fprintf
(
pFile
,
"%
6
.2f "
,
pPin
->
dDelayFanoutRise
);
fprintf
(
pFile
,
"%
6
.2f "
,
pPin
->
dDelayBlockFall
);
fprintf
(
pFile
,
"%
6
.2f"
,
pPin
->
dDelayFanoutFall
);
fprintf
(
pFile
,
"%
8
.2f "
,
pPin
->
dDelayBlockRise
);
fprintf
(
pFile
,
"%
8
.2f "
,
pPin
->
dDelayFanoutRise
);
fprintf
(
pFile
,
"%
8
.2f "
,
pPin
->
dDelayBlockFall
);
fprintf
(
pFile
,
"%
8
.2f"
,
pPin
->
dDelayFanoutFall
);
}
/**Function*************************************************************
...
...
@@ -225,7 +225,7 @@ void Mio_WriteGate( FILE * pFile, Mio_Gate_t * pGate, int GateLen, int NameLen,
sprintf
(
Buffer
,
"%s=%s;"
,
pGate
->
pOutName
,
pGate
->
pForm
);
fprintf
(
pFile
,
"GATE %-*s "
,
GateLen
,
pGate
->
pName
);
fprintf
(
pFile
,
"%8.2f "
,
pGate
->
dArea
);
fprintf
(
pFile
,
"%-*s "
,
Abc_MinInt
(
NameLen
+
FormLen
+
2
,
3
0
),
Buffer
);
fprintf
(
pFile
,
"%-*s "
,
Abc_MinInt
(
NameLen
+
FormLen
+
2
,
6
0
),
Buffer
);
// print the pins
if
(
fPrintSops
)
fprintf
(
pFile
,
"%s"
,
pGate
->
pSop
?
pGate
->
pSop
:
"unspecified
\n
"
);
...
...
@@ -248,12 +248,12 @@ void Mio_WriteGate( FILE * pFile, Mio_Gate_t * pGate, int GateLen, int NameLen,
SeeAlso []
***********************************************************************/
void
Mio_WriteLibrary
(
FILE
*
pFile
,
Mio_Library_t
*
pLib
,
int
fPrintSops
)
void
Mio_WriteLibrary
(
FILE
*
pFile
,
Mio_Library_t
*
pLib
,
int
fPrintSops
,
int
fShort
)
{
Mio_Gate_t
*
pGate
;
Mio_Pin_t
*
pPin
;
int
i
,
GateLen
=
0
,
NameLen
=
0
,
FormLen
=
0
;
int
fAllPins
=
Mio_CheckGates
(
pLib
);
int
fAllPins
=
fShort
||
Mio_CheckGates
(
pLib
);
Mio_LibraryForEachGate
(
pLib
,
pGate
)
{
GateLen
=
Abc_MaxInt
(
GateLen
,
strlen
(
pGate
->
pName
)
);
...
...
@@ -631,6 +631,7 @@ static inline void Mio_CollectCopy2( Mio_Cell2_t * pCell, Mio_Gate_t * pGate )
{
Mio_Pin_t
*
pPin
;
int
k
;
pCell
->
pName
=
pGate
->
pName
;
pCell
->
vExpr
=
pGate
->
vExpr
;
pCell
->
uTruth
=
pGate
->
uTruth
;
pCell
->
Area
=
(
word
)(
MIO_NUM
*
pGate
->
dArea
);
pCell
->
nFanins
=
pGate
->
nInputs
;
...
...
src/opt/sfm/sfmDec.c
View file @
20c46b5a
...
...
@@ -22,6 +22,8 @@
#include "misc/st/st.h"
#include "map/mio/mio.h"
#include "base/abc/abc.h"
#include "misc/util/utilTruth.h"
#include "opt/dau/dau.h"
ABC_NAMESPACE_IMPL_START
...
...
@@ -30,13 +32,12 @@ ABC_NAMESPACE_IMPL_START
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
#define SFM_FAN_MAX 6
typedef
struct
Sfm_Dec_t_
Sfm_Dec_t
;
struct
Sfm_Dec_t_
{
//
parameters
//
external
Sfm_Par_t
*
pPars
;
// parameters
Sfm_Lib_t
*
pLib
;
// library
// library
Vec_Int_t
vGateSizes
;
// fanin counts
Vec_Wrd_t
vGateFuncs
;
// gate truth tables
...
...
@@ -52,6 +53,7 @@ struct Sfm_Dec_t_
int
nDivs
;
// the number of divisors
int
nMffc
;
// the number of divisors
int
iTarget
;
// target node
int
fUseLast
;
// internal switch
Vec_Int_t
vObjRoots
;
// roots of the window
Vec_Int_t
vObjGates
;
// functionality
Vec_Wec_t
vObjFanins
;
// fanin IDs
...
...
@@ -61,10 +63,11 @@ struct Sfm_Dec_t_
sat_solver
*
pSat
;
// reusable solver
Vec_Wec_t
vClauses
;
// CNF clauses for the node
Vec_Int_t
vImpls
[
2
];
// onset/offset implications
Vec_Int_t
vCounts
[
2
];
// onset/offset counters
Vec_Wrd_t
vSets
[
2
];
// onset/offset patterns
int
nPats
[
2
];
// CEX count
word
uMask
[
2
];
// mask count
word
TtElems
[
SFM_SUPP_MAX
][
SFM_WORD_MAX
];
word
*
pTtElems
[
SFM_SUPP_MAX
];
// temporary
Vec_Int_t
vTemp
;
Vec_Int_t
vTemp2
;
...
...
@@ -138,14 +141,21 @@ void Sfm_ParSetDefault3( Sfm_Par_t * pPars )
***********************************************************************/
Sfm_Dec_t
*
Sfm_DecStart
(
Sfm_Par_t
*
pPars
)
{
Sfm_Dec_t
*
p
=
ABC_CALLOC
(
Sfm_Dec_t
,
1
);
Sfm_Dec_t
*
p
=
ABC_CALLOC
(
Sfm_Dec_t
,
1
);
int
i
;
p
->
pPars
=
pPars
;
p
->
pSat
=
sat_solver_new
();
p
->
timeStart
=
Abc_Clock
();
for
(
i
=
0
;
i
<
SFM_SUPP_MAX
;
i
++
)
p
->
pTtElems
[
i
]
=
p
->
TtElems
[
i
];
Abc_TtElemInit
(
p
->
pTtElems
,
SFM_SUPP_MAX
);
p
->
pLib
=
Sfm_LibPrepare
(
pPars
->
nMffcMax
+
1
,
1
,
pPars
->
fVerbose
);
if
(
pPars
->
fVeryVerbose
)
Sfm_LibPrint
(
p
->
pLib
);
return
p
;
}
void
Sfm_DecStop
(
Sfm_Dec_t
*
p
)
{
Sfm_LibStop
(
p
->
pLib
);
// library
Vec_IntErase
(
&
p
->
vGateSizes
);
Vec_WrdErase
(
&
p
->
vGateFuncs
);
...
...
@@ -162,8 +172,6 @@ void Sfm_DecStop( Sfm_Dec_t * p )
Vec_WecErase
(
&
p
->
vClauses
);
Vec_IntErase
(
&
p
->
vImpls
[
0
]
);
Vec_IntErase
(
&
p
->
vImpls
[
1
]
);
Vec_IntErase
(
&
p
->
vCounts
[
0
]
);
Vec_IntErase
(
&
p
->
vCounts
[
1
]
);
Vec_WrdErase
(
&
p
->
vSets
[
0
]
);
Vec_WrdErase
(
&
p
->
vSets
[
1
]
);
// temporary
...
...
@@ -270,25 +278,59 @@ int Sfm_DecPrepareSolver( Sfm_Dec_t * p )
SeeAlso []
***********************************************************************/
int
Sfm_DecFindWeight
(
Sfm_Dec_t
*
p
,
int
c
,
int
iLit
)
int
Sfm_DecFindWeight
(
Sfm_Dec_t
*
p
,
int
c
,
int
iLit
,
word
Mask
)
{
int
Value
=
Vec_IntEntry
(
&
p
->
vCounts
[
!
c
],
Abc_Lit2Var
(
iLit
)
);
return
Abc_LitIsCompl
(
iLit
)
?
Value
:
p
->
nPats
[
!
c
]
-
Value
;
int
Value0
=
Abc_TtCountOnes
(
Vec_WrdEntry
(
&
p
->
vSets
[
!
c
],
Abc_Lit2Var
(
iLit
))
&
Mask
);
int
Weight0
=
Abc_LitIsCompl
(
iLit
)
?
Abc_TtCountOnes
(
p
->
uMask
[
!
c
]
&
Mask
)
-
Value0
:
Value0
;
return
Weight0
;
}
void
Sfm_DecPrint
(
Sfm_Dec_t
*
p
,
word
*
Masks
)
{
int
c
,
i
,
k
,
Entry
;
for
(
c
=
0
;
c
<
2
;
c
++
)
{
Vec_Int_t
*
vLevel
=
Vec_WecEntry
(
&
p
->
vObjFanins
,
p
->
iTarget
);
printf
(
"
\n
%s-SET of object %d (divs = %d) with gate
\"
%s
\"
and fanins: "
,
c
?
"OFF"
:
"ON"
,
p
->
iTarget
,
p
->
nDivs
,
Mio_GateReadName
((
Mio_Gate_t
*
)
Vec_PtrEntry
(
&
p
->
vGateHands
,
Vec_IntEntry
(
&
p
->
vObjGates
,
p
->
iTarget
)))
);
Vec_IntForEachEntry
(
vLevel
,
Entry
,
i
)
printf
(
"%d "
,
Entry
);
printf
(
"
\n
"
);
printf
(
"Implications: "
);
Vec_IntForEachEntry
(
&
p
->
vImpls
[
c
],
Entry
,
i
)
printf
(
"%s%d(%d) "
,
Abc_LitIsCompl
(
Entry
)
?
"!"
:
""
,
Abc_Lit2Var
(
Entry
),
Sfm_DecFindWeight
(
p
,
c
,
Entry
,
Masks
?
Masks
[
!
c
]
:
~
(
word
)
0
)
);
printf
(
"
\n
"
);
printf
(
" "
);
for
(
i
=
0
;
i
<=
p
->
iTarget
;
i
++
)
printf
(
"%d"
,
i
/
10
);
printf
(
"
\n
"
);
printf
(
" "
);
for
(
i
=
0
;
i
<=
p
->
iTarget
;
i
++
)
printf
(
"%d"
,
i
%
10
);
printf
(
"
\n
"
);
for
(
k
=
0
;
k
<
p
->
nPats
[
c
];
k
++
)
{
printf
(
"%2d : "
,
k
);
for
(
i
=
0
;
i
<=
p
->
iTarget
;
i
++
)
printf
(
"%d"
,
(
int
)((
Vec_WrdEntry
(
&
p
->
vSets
[
c
],
i
)
>>
k
)
&
1
)
);
printf
(
"
\n
"
);
}
printf
(
"
\n
"
);
}
}
int
Sfm_DecPeformDecOne
(
Sfm_Dec_t
*
p
,
int
*
pfConst
)
{
int
fVerbose
=
p
->
pPars
->
fVeryVerbose
;
int
nBTLimit
=
0
;
int
i
,
k
,
c
,
Entry
,
status
,
Lits
[
3
],
RetValue
;
int
iLitBest
=
-
1
,
iCBest
=
-
1
,
WeightBest
=
-
1
,
Weight
;
int
iLitBest
=
-
1
,
iCBest
=
-
1
,
WeightBest
=
ABC_INFINITY
,
Weight
;
*
pfConst
=
-
1
;
// check stuck-at-0/1 (on/off-set empty)
p
->
nPats
[
0
]
=
p
->
nPats
[
1
]
=
0
;
p
->
uMask
[
0
]
=
p
->
uMask
[
1
]
=
0
;
Vec_IntClear
(
&
p
->
vImpls
[
0
]
);
Vec_IntClear
(
&
p
->
vImpls
[
1
]
);
Vec_IntClear
(
&
p
->
vCounts
[
0
]
);
Vec_IntClear
(
&
p
->
vCounts
[
1
]
);
Vec_WrdClear
(
&
p
->
vSets
[
0
]
);
Vec_WrdClear
(
&
p
->
vSets
[
1
]
);
for
(
c
=
0
;
c
<
2
;
c
++
)
...
...
@@ -309,11 +351,7 @@ int Sfm_DecPeformDecOne( Sfm_Dec_t * p, int * pfConst )
assert
(
status
==
l_True
);
// record this status
for
(
i
=
0
;
i
<=
p
->
iTarget
;
i
++
)
{
Entry
=
sat_solver_var_value
(
p
->
pSat
,
i
);
Vec_IntPush
(
&
p
->
vCounts
[
c
],
Entry
);
Vec_WrdPush
(
&
p
->
vSets
[
c
],
(
word
)
Entry
);
}
Vec_WrdPush
(
&
p
->
vSets
[
c
],
(
word
)
sat_solver_var_value
(
p
->
pSat
,
i
)
);
p
->
nPats
[
c
]
++
;
p
->
uMask
[
c
]
=
1
;
}
...
...
@@ -342,10 +380,7 @@ int Sfm_DecPeformDecOne( Sfm_Dec_t * p, int * pfConst )
// record this status
for
(
k
=
0
;
k
<=
p
->
iTarget
;
k
++
)
if
(
sat_solver_var_value
(
p
->
pSat
,
k
)
)
{
Vec_IntAddToEntry
(
&
p
->
vCounts
[
c
],
k
,
1
);
*
Vec_WrdEntryP
(
&
p
->
vSets
[
c
],
k
)
|=
((
word
)
1
<<
p
->
nPats
[
c
]);
}
p
->
uMask
[
c
]
|=
((
word
)
1
<<
p
->
nPats
[
c
]
++
);
}
}
...
...
@@ -354,8 +389,8 @@ int Sfm_DecPeformDecOne( Sfm_Dec_t * p, int * pfConst )
{
Vec_IntForEachEntry
(
&
p
->
vImpls
[
c
],
Entry
,
i
)
{
Weight
=
Sfm_DecFindWeight
(
p
,
c
,
Entry
);
if
(
WeightBest
<
Weight
)
Weight
=
Sfm_DecFindWeight
(
p
,
c
,
Entry
,
(
~
(
word
)
0
)
);
if
(
WeightBest
>
Weight
)
{
WeightBest
=
Weight
;
iLitBest
=
Entry
;
...
...
@@ -363,7 +398,7 @@ int Sfm_DecPeformDecOne( Sfm_Dec_t * p, int * pfConst )
}
}
}
if
(
WeightBest
==
-
1
)
if
(
WeightBest
==
ABC_INFINITY
)
{
p
->
nNoDecs
++
;
return
-
2
;
...
...
@@ -376,43 +411,11 @@ int Sfm_DecPeformDecOne( Sfm_Dec_t * p, int * pfConst )
if
(
RetValue
==
0
)
return
-
1
;
// print the results
if
(
!
fVerbose
)
return
Abc_Var2Lit
(
iLitBest
,
iCBest
);
printf
(
"
\n
Best literal (%d; %s%d) with weight %d.
\n\n
"
,
iCBest
,
Abc_LitIsCompl
(
iLitBest
)
?
"!"
:
""
,
Abc_Lit2Var
(
iLitBest
),
WeightBest
);
for
(
c
=
0
;
c
<
2
;
c
++
)
if
(
fVerbose
)
{
Vec_Int_t
*
vLevel
=
Vec_WecEntry
(
&
p
->
vObjFanins
,
p
->
iTarget
);
printf
(
"
\n
%s-SET of object %d (divs = %d) with gate
\"
%s
\"
and fanins: "
,
c
?
"OFF"
:
"ON"
,
p
->
iTarget
,
p
->
nDivs
,
Mio_GateReadName
((
Mio_Gate_t
*
)
Vec_PtrEntry
(
&
p
->
vGateHands
,
Vec_IntEntry
(
&
p
->
vObjGates
,
p
->
iTarget
)))
);
Vec_IntForEachEntry
(
vLevel
,
Entry
,
i
)
printf
(
"%d "
,
Entry
);
printf
(
"
\n
"
);
printf
(
"Implications: "
);
Vec_IntForEachEntry
(
&
p
->
vImpls
[
c
],
Entry
,
i
)
printf
(
"%s%d(%d) "
,
Abc_LitIsCompl
(
Entry
)
?
"!"
:
""
,
Abc_Lit2Var
(
Entry
),
Sfm_DecFindWeight
(
p
,
c
,
Entry
)
);
printf
(
"
\n
"
);
printf
(
" "
);
for
(
i
=
0
;
i
<=
p
->
iTarget
;
i
++
)
printf
(
"%d"
,
i
/
10
);
printf
(
"
\n
"
);
printf
(
" "
);
for
(
i
=
0
;
i
<=
p
->
iTarget
;
i
++
)
printf
(
"%d"
,
i
%
10
);
printf
(
"
\n
"
);
for
(
k
=
0
;
k
<
p
->
nPats
[
c
];
k
++
)
{
printf
(
"%2d : "
,
k
);
for
(
i
=
0
;
i
<=
p
->
iTarget
;
i
++
)
printf
(
"%d"
,
(
int
)((
Vec_WrdEntry
(
&
p
->
vSets
[
c
],
i
)
>>
k
)
&
1
)
);
printf
(
"
\n
"
);
}
printf
(
"
\n
"
);
printf
(
"
\n
Best literal (%d; %s%d) with weight %d.
\n\n
"
,
iCBest
,
Abc_LitIsCompl
(
iLitBest
)
?
"!"
:
""
,
Abc_Lit2Var
(
iLitBest
),
WeightBest
);
Sfm_DecPrint
(
p
,
NULL
);
}
return
Abc_Var2Lit
(
iLitBest
,
iCBest
);
}
...
...
@@ -507,6 +510,216 @@ int Sfm_DecPeformDec( Sfm_Dec_t * p )
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int
Sfm_DecCombineDec
(
Sfm_Dec_t
*
p
,
word
*
pTruth0
,
word
*
pTruth1
,
int
*
pSupp0
,
int
*
pSupp1
,
int
nSupp0
,
int
nSupp1
,
word
*
pTruth
,
int
*
pSupp
,
int
Var
)
{
Vec_Int_t
vVec0
=
{
2
*
SFM_SUPP_MAX
,
nSupp0
,
pSupp0
};
Vec_Int_t
vVec1
=
{
2
*
SFM_SUPP_MAX
,
nSupp1
,
pSupp1
};
Vec_Int_t
vVec
=
{
2
*
SFM_SUPP_MAX
,
0
,
pSupp
};
int
nWords0
=
Abc_TtWordNum
(
nSupp0
);
int
nWords1
=
Abc_TtWordNum
(
nSupp1
);
int
nSupp
,
iSuppVar
;
// check the case of equal cofactors
if
(
nSupp0
==
nSupp1
&&
!
memcmp
(
pSupp0
,
pSupp1
,
sizeof
(
int
)
*
nSupp0
)
&&
!
memcmp
(
pTruth0
,
pTruth1
,
sizeof
(
word
)
*
nWords0
)
)
{
memcpy
(
pSupp
,
pSupp0
,
sizeof
(
int
)
*
nSupp0
);
memcpy
(
pTruth
,
pTruth0
,
sizeof
(
word
)
*
nWords0
);
return
nSupp0
;
}
// merge support variables
Vec_IntTwoMerge2Int
(
&
vVec0
,
&
vVec1
,
&
vVec
);
Vec_IntPushOrder
(
&
vVec
,
Var
);
nSupp
=
Vec_IntSize
(
&
vVec
);
if
(
nSupp
>
SFM_SUPP_MAX
)
return
-
2
;
// expand truth tables
Abc_TtStretch6
(
pTruth0
,
nSupp0
,
nSupp
);
Abc_TtStretch6
(
pTruth1
,
nSupp1
,
nSupp
);
Abc_TtExpand
(
pTruth0
,
nSupp
,
pSupp0
,
nSupp0
,
pSupp
,
nSupp
);
Abc_TtExpand
(
pTruth1
,
nSupp
,
pSupp1
,
nSupp1
,
pSupp
,
nSupp
);
// perform operation
iSuppVar
=
Vec_IntFind
(
&
vVec
,
Var
);
Abc_TtMux
(
pTruth
,
p
->
pTtElems
[
iSuppVar
],
pTruth1
,
pTruth0
,
Abc_TtWordNum
(
nSupp
)
);
return
nSupp
;
}
int
Sfm_DecPeformDec_rec
(
Sfm_Dec_t
*
p
,
word
*
pTruth
,
int
*
pSupp
,
int
*
pAssump
,
int
nAssump
,
word
Masks
[
2
],
int
fCofactor
)
{
int
nBTLimit
=
0
;
int
fVerbose
=
p
->
pPars
->
fVeryVerbose
;
int
c
,
i
,
d
,
Var
,
WeightBest
,
status
;
Vec_Int_t
vAss
=
{
SFM_SUPP_MAX
,
nAssump
,
pAssump
};
// if ( nAssump > SFM_SUPP_MAX )
if
(
nAssump
>
p
->
nMffc
)
return
-
2
;
// check constant
for
(
c
=
0
;
c
<
2
;
c
++
)
{
if
(
p
->
uMask
[
c
]
&
Masks
[
c
]
)
// there are some patterns
continue
;
p
->
nSatCalls
++
;
pAssump
[
nAssump
]
=
Abc_Var2Lit
(
p
->
iTarget
,
c
);
status
=
sat_solver_solve
(
p
->
pSat
,
pAssump
,
pAssump
+
nAssump
+
1
,
nBTLimit
,
0
,
0
,
0
);
if
(
status
==
l_Undef
)
return
-
2
;
if
(
status
==
l_False
)
{
pTruth
[
0
]
=
c
?
~
((
word
)
0
)
:
0
;
return
0
;
}
assert
(
status
==
l_True
);
if
(
p
->
nPats
[
c
]
==
64
)
return
-
2
;
//continue;
for
(
i
=
0
;
i
<=
p
->
iTarget
;
i
++
)
if
(
sat_solver_var_value
(
p
->
pSat
,
i
)
)
*
Vec_WrdEntryP
(
&
p
->
vSets
[
c
],
i
)
|=
((
word
)
1
<<
p
->
nPats
[
c
]);
p
->
uMask
[
c
]
|=
((
word
)
1
<<
p
->
nPats
[
c
]
++
);
}
// check implications
Vec_IntClear
(
&
p
->
vImpls
[
0
]
);
Vec_IntClear
(
&
p
->
vImpls
[
1
]
);
for
(
d
=
0
;
d
<
p
->
nDivs
;
d
++
)
{
int
Impls
[
2
]
=
{
-
1
,
-
1
};
for
(
c
=
0
;
c
<
2
;
c
++
)
{
word
MaskAll
=
p
->
uMask
[
c
]
&
Masks
[
c
];
word
MaskCur
=
Vec_WrdEntry
(
&
p
->
vSets
[
c
],
d
)
&
Masks
[
c
];
assert
(
MaskAll
);
if
(
MaskCur
!=
0
&&
MaskCur
!=
MaskAll
)
// has both ones and zeros
continue
;
pAssump
[
nAssump
]
=
Abc_Var2Lit
(
p
->
iTarget
,
c
);
pAssump
[
nAssump
+
1
]
=
Abc_Var2Lit
(
d
,
MaskCur
!=
0
);
p
->
nSatCalls
++
;
status
=
sat_solver_solve
(
p
->
pSat
,
pAssump
,
pAssump
+
nAssump
+
2
,
nBTLimit
,
0
,
0
,
0
);
if
(
status
==
l_Undef
)
return
-
2
;
if
(
status
==
l_False
)
{
Impls
[
c
]
=
Abc_LitNot
(
pAssump
[
nAssump
+
1
]);
Vec_IntPush
(
&
p
->
vImpls
[
c
],
Abc_LitNot
(
pAssump
[
nAssump
+
1
])
);
continue
;
}
assert
(
status
==
l_True
);
if
(
p
->
nPats
[
c
]
==
64
)
return
-
2
;
//continue;
// record this status
for
(
i
=
0
;
i
<=
p
->
iTarget
;
i
++
)
if
(
sat_solver_var_value
(
p
->
pSat
,
i
)
)
*
Vec_WrdEntryP
(
&
p
->
vSets
[
c
],
i
)
|=
((
word
)
1
<<
p
->
nPats
[
c
]);
p
->
uMask
[
c
]
|=
((
word
)
1
<<
p
->
nPats
[
c
]
++
);
}
if
(
Impls
[
0
]
==
-
1
||
Impls
[
1
]
==
-
1
||
Impls
[
0
]
==
Impls
[
1
]
)
continue
;
assert
(
Abc_Lit2Var
(
Impls
[
0
])
==
Abc_Lit2Var
(
Impls
[
1
])
);
// found buffer/inverter
pTruth
[
0
]
=
Abc_LitIsCompl
(
Impls
[
0
])
?
~
p
->
pTtElems
[
0
][
0
]
:
p
->
pTtElems
[
0
][
0
];
pSupp
[
0
]
=
Abc_Lit2Var
(
Impls
[
0
]);
return
1
;
}
// find the best cofactoring variable
Var
=
-
1
,
WeightBest
=
ABC_INFINITY
;
for
(
c
=
0
;
c
<
2
;
c
++
)
{
int
iLit
,
Weight
;
Vec_IntForEachEntry
(
&
p
->
vImpls
[
c
],
iLit
,
i
)
{
Weight
=
Sfm_DecFindWeight
(
p
,
c
,
iLit
,
Masks
[
!
c
]
);
if
(
WeightBest
>
Weight
)
{
WeightBest
=
Weight
;
Var
=
Abc_Lit2Var
(
iLit
);
}
}
}
if
(
Var
==
-
1
&&
fCofactor
)
{
if
(
p
->
fUseLast
)
Var
=
p
->
nDivs
-
1
;
else
Var
=
p
->
nDivs
-
2
;
fCofactor
=
0
;
}
// printf( "Assumptions: " );
// Vec_IntPrint( &vAss );
// Sfm_DecPrint( p, Masks );
//printf( "Best var %d with weight %d.\n", Var, WeightBest );
// cofactor the problem
if
(
Var
>=
0
)
{
word
uTruth
[
2
][
SFM_WORD_MAX
],
MasksNext
[
2
];
int
Supp
[
2
][
2
*
SFM_SUPP_MAX
],
nSupp
[
2
],
nSuppAll
;
//if ( Abc_TtCountOnes(
for
(
i
=
0
;
i
<
2
;
i
++
)
{
for
(
c
=
0
;
c
<
2
;
c
++
)
{
word
MaskVar
=
Vec_WrdEntry
(
&
p
->
vSets
[
c
],
Var
);
MasksNext
[
c
]
=
Masks
[
c
]
&
(
i
?
MaskVar
|
~
p
->
uMask
[
c
]
:
~
MaskVar
);
}
pAssump
[
nAssump
]
=
Abc_Var2Lit
(
Var
,
!
i
);
nSupp
[
i
]
=
Sfm_DecPeformDec_rec
(
p
,
uTruth
[
i
],
Supp
[
i
],
pAssump
,
nAssump
+
1
,
MasksNext
,
fCofactor
);
if
(
nSupp
[
i
]
==
-
2
)
return
-
2
;
}
// combine solutions
nSuppAll
=
Sfm_DecCombineDec
(
p
,
uTruth
[
0
],
uTruth
[
1
],
Supp
[
0
],
Supp
[
1
],
nSupp
[
0
],
nSupp
[
1
],
pTruth
,
pSupp
,
Var
);
//if ( nSuppAll > p->nMffc )
// return -2;
return
nSuppAll
;
}
return
-
2
;
}
int
Sfm_DecPeformDec2Int
(
Sfm_Dec_t
*
p
)
{
word
uTruth
[
SFM_WORD_MAX
];
word
Masks
[
2
]
=
{
~
((
word
)
0
),
~
((
word
)
0
)
};
int
pAssump
[
2
*
SFM_SUPP_MAX
];
int
pSupp
[
2
*
SFM_SUPP_MAX
],
nSupp
;
p
->
nPats
[
0
]
=
p
->
nPats
[
1
]
=
0
;
p
->
uMask
[
0
]
=
p
->
uMask
[
1
]
=
0
;
Vec_WrdFill
(
&
p
->
vSets
[
0
],
p
->
iTarget
+
1
,
0
);
Vec_WrdFill
(
&
p
->
vSets
[
1
],
p
->
iTarget
+
1
,
0
);
nSupp
=
Sfm_DecPeformDec_rec
(
p
,
uTruth
,
pSupp
,
pAssump
,
0
,
Masks
,
1
);
//printf( "%d %d ", p->nPats[0], p->nPats[1] );
// printf( "Node %4d : ", p->iTarget );
// printf( "MFFC %2d ", p->nMffc );
if
(
nSupp
==
-
2
)
{
// printf( "NO DEC.\n" );
p
->
nNoDecs
++
;
return
-
2
;
}
// transform truth table
Dau_DsdPrintFromTruth
(
uTruth
,
nSupp
);
return
-
1
;
}
int
Sfm_DecPeformDec2
(
Sfm_Dec_t
*
p
)
{
p
->
fUseLast
=
1
;
Sfm_DecPeformDec2Int
(
p
);
// p->fUseLast = 0;
// Sfm_DecPeformDec2Int( p );
// printf( "\n" );
//Sfm_LibImplement( p->pLib, uTruth, pSupp, nSupp, &p->vObjGates, &p->vObjFanins );
return
-
1
;
}
/**Function*************************************************************
Synopsis [Incremental level update.]
Description []
...
...
@@ -790,8 +1003,8 @@ void Abc_NtkPerformMfs3( Abc_Ntk_t * pNtk, Sfm_Par_t * pPars )
Sfm_Dec_t
*
p
=
Sfm_DecStart
(
pPars
);
Abc_Obj_t
*
pObj
;
abctime
clk
;
int
i
,
Limit
,
RetValue
,
Count
=
0
,
nStop
=
Abc_NtkObjNumMax
(
pNtk
);
//int iNode =
2341;//8;//70;
int
i
=
0
,
Limit
,
RetValue
,
Count
=
0
,
nStop
=
Abc_NtkObjNumMax
(
pNtk
);
int
iNode
=
70
;
//
2341;//8;//70;
printf
(
"Running remapping with parameters: "
);
printf
(
"TFO = %d. "
,
pPars
->
nTfoLevMax
);
printf
(
"TFI = %d. "
,
pPars
->
nTfiLevMax
);
...
...
@@ -844,10 +1057,17 @@ p->timeCnf += Abc_Clock() - clk;
if
(
!
RetValue
)
continue
;
clk
=
Abc_Clock
();
if
(
pPars
->
fRrOnly
)
RetValue
=
Sfm_DecPeformDec
(
p
);
else
RetValue
=
Sfm_DecPeformDec2
(
p
);
p
->
timeSat
+=
Abc_Clock
()
-
clk
;
if
(
RetValue
==
-
1
)
//break;
if
(
RetValue
<
0
)
continue
;
if
(
pPars
->
fRrOnly
)
Sfm_DecInsert
(
pNtk
,
pObj
,
Limit
,
&
p
->
vObjGates
,
&
p
->
vObjFanins
,
&
p
->
vObjMap
,
&
p
->
vGateHands
);
if
(
pPars
->
fVeryVerbose
)
printf
(
"This was modification %d
\n
"
,
Count
);
...
...
src/opt/sfm/sfmInt.h
View file @
20c46b5a
...
...
@@ -45,10 +45,16 @@ ABC_NAMESPACE_HEADER_START
#define SFM_SAT_UNDEC 0x1234567812345678
#define SFM_SAT_SAT 0x8765432187654321
#define SFM_SUPP_MAX 6
#define SFM_WORD_MAX ((SFM_SUPP_MAX>6) ? (1<<(SFM_SUPP_MAX-6)) : 1)
////////////////////////////////////////////////////////////////////////
/// BASIC TYPES ///
////////////////////////////////////////////////////////////////////////
typedef
struct
Sfm_Fun_t_
Sfm_Fun_t
;
typedef
struct
Sfm_Lib_t_
Sfm_Lib_t
;
struct
Sfm_Ntk_t_
{
// parameters
...
...
@@ -182,6 +188,11 @@ extern int Sfm_TruthToCnf( word Truth, int nVars, Vec_Int_t * vCover, V
extern
Vec_Wec_t
*
Sfm_CreateCnf
(
Sfm_Ntk_t
*
p
);
extern
void
Sfm_TranslateCnf
(
Vec_Wec_t
*
vRes
,
Vec_Str_t
*
vCnf
,
Vec_Int_t
*
vFaninMap
,
int
iPivotVar
);
/*=== sfmCore.c ==========================================================*/
/*=== sfmLib.c ==========================================================*/
extern
Sfm_Lib_t
*
Sfm_LibPrepare
(
int
nVars
,
int
fTwo
,
int
fVerbose
);
extern
void
Sfm_LibPrint
(
Sfm_Lib_t
*
p
);
extern
void
Sfm_LibStop
(
Sfm_Lib_t
*
p
);
extern
int
Sfm_LibImplement
(
Sfm_Lib_t
*
p
,
word
uTruth
,
int
*
pFanins
,
int
nFanins
,
Vec_Int_t
*
vGates
,
Vec_Wec_t
*
vFanins
);
/*=== sfmNtk.c ==========================================================*/
extern
Sfm_Ntk_t
*
Sfm_ConstructNetwork
(
Vec_Wec_t
*
vFanins
,
int
nPis
,
int
nPos
);
extern
void
Sfm_NtkPrepare
(
Sfm_Ntk_t
*
p
);
...
...
src/opt/sfm/sfmLib.c
View file @
20c46b5a
...
...
@@ -21,6 +21,11 @@
#include "sfmInt.h"
#include "misc/st/st.h"
#include "map/mio/mio.h"
#include "misc/vec/vecMem.h"
#include "misc/util/utilTruth.h"
#include "misc/extra/extra.h"
#include "map/mio/exp.h"
#include "opt/dau/dau.h"
ABC_NAMESPACE_IMPL_START
...
...
@@ -29,6 +34,31 @@ ABC_NAMESPACE_IMPL_START
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
struct
Sfm_Fun_t_
{
int
Next
;
// next function in the list
int
Area
;
// area of this function
char
pFansT
[
8
];
// top gate ID, followed by fanin perm
char
pFansB
[
8
];
// bottom gate ID, followed by fanin perm
};
struct
Sfm_Lib_t_
{
Mio_Cell2_t
*
pCells
;
// library gates
int
nCells
;
// library gate count
int
nObjs
;
// object count
int
nObjsAlloc
;
// object count
Sfm_Fun_t
*
pObjs
;
// objects
Vec_Mem_t
*
vTtMem
;
// truth tables
Vec_Int_t
vLists
;
// lists of funcs for each truth table
Vec_Int_t
vCounts
;
// counters of functions for each truth table
};
static
inline
Sfm_Fun_t
*
Sfm_LibFun
(
Sfm_Lib_t
*
p
,
int
i
)
{
return
i
==
-
1
?
NULL
:
p
->
pObjs
+
i
;
}
#define Sfm_LibForEachSuper( p, pObj, Func ) \
for ( pObj = Sfm_LibFun(p, Vec_IntEntry(&p->vLists, Func)); pObj; pObj = Sfm_LibFun(p, pObj->Next) )
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
...
...
@@ -93,6 +123,269 @@ void Sfm_LibPreprocess( Mio_Library_t * pLib, Vec_Int_t * vGateSizes, Vec_Wrd_t
Sfm_DecCreateCnf
(
vGateSizes
,
vGateFuncs
,
vGateCnfs
);
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Sfm_Lib_t
*
Sfm_LibStart
(
int
nVars
)
{
Sfm_Lib_t
*
p
=
ABC_CALLOC
(
Sfm_Lib_t
,
1
);
p
->
vTtMem
=
Vec_MemAllocForTT
(
nVars
,
0
);
Vec_IntGrow
(
&
p
->
vLists
,
(
1
<<
16
)
);
Vec_IntGrow
(
&
p
->
vCounts
,
(
1
<<
16
)
);
Vec_IntFill
(
&
p
->
vLists
,
2
,
-
1
);
Vec_IntFill
(
&
p
->
vCounts
,
2
,
-
1
);
p
->
nObjsAlloc
=
(
1
<<
16
);
p
->
pObjs
=
ABC_CALLOC
(
Sfm_Fun_t
,
p
->
nObjsAlloc
);
return
p
;
}
void
Sfm_LibStop
(
Sfm_Lib_t
*
p
)
{
Vec_MemHashFree
(
p
->
vTtMem
);
Vec_MemFree
(
p
->
vTtMem
);
Vec_IntErase
(
&
p
->
vLists
);
Vec_IntErase
(
&
p
->
vCounts
);
ABC_FREE
(
p
->
pCells
);
ABC_FREE
(
p
->
pObjs
);
ABC_FREE
(
p
);
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
word
Sfm_LibTruthTwo
(
Mio_Cell2_t
*
pCellBot
,
Mio_Cell2_t
*
pCellTop
,
int
InTop
)
{
word
uTruthBot
=
Exp_Truth6
(
pCellBot
->
nFanins
,
pCellBot
->
vExpr
,
NULL
);
word
uFanins
[
6
];
int
i
,
k
;
assert
(
InTop
>=
0
&&
InTop
<
(
int
)
pCellTop
->
nFanins
);
for
(
i
=
0
,
k
=
pCellBot
->
nFanins
;
i
<
(
int
)
pCellTop
->
nFanins
;
i
++
)
uFanins
[
i
]
=
(
i
==
InTop
)
?
uTruthBot
:
s_Truths6
[
k
++
];
assert
(
(
int
)
pCellBot
->
nFanins
+
(
int
)
pCellTop
->
nFanins
==
k
+
1
);
uTruthBot
=
Exp_Truth6
(
pCellTop
->
nFanins
,
pCellTop
->
vExpr
,
uFanins
);
return
uTruthBot
;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
Sfm_LibPrepareAdd
(
Sfm_Lib_t
*
p
,
word
uTruth
,
int
*
Perm
,
int
nFanins
,
Mio_Cell2_t
*
pCellBot
,
Mio_Cell2_t
*
pCellTop
,
int
InTop
)
{
Sfm_Fun_t
*
pObj
;
int
Area
=
(
int
)(
pCellBot
->
Area
/
1000
)
+
(
pCellTop
?
(
int
)(
pCellTop
->
Area
/
1000
)
:
0
);
int
i
,
k
,
iFunc
=
Vec_MemHashInsert
(
p
->
vTtMem
,
&
uTruth
);
if
(
iFunc
==
Vec_IntSize
(
&
p
->
vLists
)
)
{
Vec_IntPush
(
&
p
->
vLists
,
-
1
);
Vec_IntPush
(
&
p
->
vCounts
,
0
);
}
assert
(
pCellBot
!=
NULL
);
// iterate through the supergates of this truth table
Sfm_LibForEachSuper
(
p
,
pObj
,
iFunc
)
{
if
(
Area
>=
pObj
->
Area
)
return
;
}
// create new object
if
(
p
->
nObjs
==
p
->
nObjsAlloc
)
{
int
nObjsAlloc
=
2
*
p
->
nObjsAlloc
;
p
->
pObjs
=
ABC_REALLOC
(
Sfm_Fun_t
,
p
->
pObjs
,
nObjsAlloc
);
memset
(
p
->
pObjs
+
p
->
nObjsAlloc
,
0
,
sizeof
(
Sfm_Fun_t
)
*
p
->
nObjsAlloc
);
p
->
nObjsAlloc
=
nObjsAlloc
;
}
pObj
=
p
->
pObjs
+
p
->
nObjs
;
pObj
->
Area
=
Area
;
pObj
->
Next
=
Vec_IntEntry
(
&
p
->
vLists
,
iFunc
);
Vec_IntWriteEntry
(
&
p
->
vLists
,
iFunc
,
p
->
nObjs
++
);
Vec_IntAddToEntry
(
&
p
->
vCounts
,
iFunc
,
1
);
// create gate
assert
(
pCellBot
->
Id
<
128
);
pObj
->
pFansB
[
0
]
=
(
char
)
pCellBot
->
Id
;
for
(
k
=
0
;
k
<
(
int
)
pCellBot
->
nFanins
;
k
++
)
pObj
->
pFansB
[
k
+
1
]
=
Perm
[
k
];
if
(
pCellTop
==
NULL
)
return
;
assert
(
pCellTop
->
Id
<
128
);
pObj
->
pFansT
[
0
]
=
(
char
)
pCellTop
->
Id
;
for
(
i
=
0
;
i
<
(
int
)
pCellTop
->
nFanins
;
i
++
)
pObj
->
pFansT
[
i
+
1
]
=
(
char
)(
i
==
InTop
?
16
:
Perm
[
k
++
]);
assert
(
k
==
nFanins
);
}
Sfm_Lib_t
*
Sfm_LibPrepare
(
int
nVars
,
int
fTwo
,
int
fVerbose
)
{
abctime
clk
=
Abc_Clock
();
Sfm_Lib_t
*
p
=
Sfm_LibStart
(
nVars
);
Mio_Cell2_t
*
pCell1
,
*
pCell2
,
*
pLimit
;
int
*
pPerm
[
7
],
*
Perm1
,
*
Perm2
,
Perm
[
6
];
int
nPerms
[
7
],
i
,
f
,
n
;
Vec_Int_t
*
vUseful
;
word
tTemp1
,
tCur
;
char
pRes
[
1000
];
assert
(
nVars
<=
6
);
// precompute gates
p
->
pCells
=
Mio_CollectRootsNewDefault2
(
nVars
,
&
p
->
nCells
,
0
);
pLimit
=
p
->
pCells
+
p
->
nCells
;
// find useful ones
vUseful
=
Vec_IntStart
(
p
->
nCells
);
// vUseful = Vec_IntStartFull( p->nCells );
for
(
pCell1
=
p
->
pCells
+
4
;
pCell1
<
pLimit
;
pCell1
++
)
{
word
uTruth
=
pCell1
->
uTruth
;
if
(
Dau_DsdDecompose
(
&
uTruth
,
pCell1
->
nFanins
,
0
,
0
,
pRes
)
<=
3
)
Vec_IntWriteEntry
(
vUseful
,
pCell1
-
p
->
pCells
,
1
);
else
printf
(
"Skipping gate
\"
%s
\"
with non-DSD function %s
\n
"
,
pCell1
->
pName
,
pRes
);
}
// generate permutations
for
(
i
=
2
;
i
<=
nVars
;
i
++
)
pPerm
[
i
]
=
Extra_PermSchedule
(
i
);
for
(
i
=
2
;
i
<=
nVars
;
i
++
)
nPerms
[
i
]
=
Extra_Factorial
(
i
);
// add single cells
for
(
pCell1
=
p
->
pCells
+
4
;
pCell1
<
pLimit
;
pCell1
++
)
if
(
Vec_IntEntry
(
vUseful
,
pCell1
-
p
->
pCells
)
)
{
int
nFanins
=
pCell1
->
nFanins
;
assert
(
nFanins
>=
2
&&
nFanins
<=
6
);
for
(
i
=
0
;
i
<
nFanins
;
i
++
)
Perm
[
i
]
=
i
;
// permute truth table
tCur
=
tTemp1
=
pCell1
->
uTruth
;
for
(
n
=
0
;
n
<
nPerms
[
nFanins
];
n
++
)
{
Sfm_LibPrepareAdd
(
p
,
tCur
,
Perm
,
nFanins
,
pCell1
,
NULL
,
-
1
);
// update
tCur
=
Abc_Tt6SwapAdjacent
(
tCur
,
pPerm
[
nFanins
][
n
]
);
Perm1
=
Perm
+
pPerm
[
nFanins
][
n
];
Perm2
=
Perm1
+
1
;
ABC_SWAP
(
int
,
*
Perm1
,
*
Perm2
);
}
assert
(
tTemp1
==
tCur
);
}
// add double cells
if
(
fTwo
)
for
(
pCell1
=
p
->
pCells
+
4
;
pCell1
<
pLimit
;
pCell1
++
)
if
(
Vec_IntEntry
(
vUseful
,
pCell1
-
p
->
pCells
)
)
for
(
pCell2
=
p
->
pCells
+
4
;
pCell2
<
pLimit
;
pCell2
++
)
if
(
Vec_IntEntry
(
vUseful
,
pCell2
-
p
->
pCells
)
)
if
(
(
int
)
pCell1
->
nFanins
+
(
int
)
pCell2
->
nFanins
<=
nVars
+
1
)
for
(
f
=
0
;
f
<
(
int
)
pCell2
->
nFanins
;
f
++
)
{
int
nFanins
=
pCell1
->
nFanins
+
pCell2
->
nFanins
-
1
;
assert
(
nFanins
>=
2
&&
nFanins
<=
nVars
);
for
(
i
=
0
;
i
<
nFanins
;
i
++
)
Perm
[
i
]
=
i
;
// permute truth table
tCur
=
tTemp1
=
Sfm_LibTruthTwo
(
pCell1
,
pCell2
,
f
);
for
(
n
=
0
;
n
<
nPerms
[
nFanins
];
n
++
)
{
Sfm_LibPrepareAdd
(
p
,
tCur
,
Perm
,
nFanins
,
pCell1
,
pCell2
,
f
);
// update
tCur
=
Abc_Tt6SwapAdjacent
(
tCur
,
pPerm
[
nFanins
][
n
]
);
Perm1
=
Perm
+
pPerm
[
nFanins
][
n
];
Perm2
=
Perm1
+
1
;
ABC_SWAP
(
int
,
*
Perm1
,
*
Perm2
);
}
assert
(
tTemp1
==
tCur
);
}
// cleanup
for
(
i
=
2
;
i
<=
nVars
;
i
++
)
ABC_FREE
(
pPerm
[
i
]
);
Vec_IntFree
(
vUseful
);
if
(
fVerbose
)
{
printf
(
"Library processing: Var = %d. Cells = %d. Func = %6d. Obj = %8d. Ave = %8.2f "
,
nVars
,
p
->
nCells
,
Vec_MemEntryNum
(
p
->
vTtMem
),
p
->
nObjs
,
1
.
0
*
p
->
nObjs
/
Vec_MemEntryNum
(
p
->
vTtMem
)
);
Abc_PrintTime
(
1
,
"Time"
,
Abc_Clock
()
-
clk
);
}
return
p
;
}
void
Sfm_LibPrintGate
(
Mio_Cell2_t
*
pCell
,
char
*
pFanins
,
Mio_Cell2_t
*
pCell2
,
char
*
pFanins2
)
{
int
k
;
printf
(
" %s("
,
pCell
->
pName
);
for
(
k
=
0
;
k
<
(
int
)
pCell
->
nFanins
;
k
++
)
if
(
pFanins
[
k
]
==
(
char
)
16
)
Sfm_LibPrintGate
(
pCell2
,
pFanins2
,
NULL
,
NULL
);
else
printf
(
" %c"
,
'a'
+
pFanins
[
k
]
);
printf
(
" )"
);
}
void
Sfm_LibPrintObj
(
Sfm_Lib_t
*
p
,
Sfm_Fun_t
*
pObj
)
{
Mio_Cell2_t
*
pCellB
=
p
->
pCells
+
(
int
)
pObj
->
pFansB
[
0
];
Mio_Cell2_t
*
pCellT
=
p
->
pCells
+
(
int
)
pObj
->
pFansT
[
0
];
int
nFanins
=
pCellB
->
nFanins
+
(
pCellT
==
p
->
pCells
?
0
:
pCellT
->
nFanins
);
printf
(
" Area = %6.2f Fanins = %d "
,
0
.
001
*
pObj
->
Area
,
nFanins
);
if
(
pCellT
==
p
->
pCells
)
Sfm_LibPrintGate
(
pCellB
,
pObj
->
pFansB
+
1
,
NULL
,
NULL
);
else
Sfm_LibPrintGate
(
pCellT
,
pObj
->
pFansT
+
1
,
pCellB
,
pObj
->
pFansB
+
1
);
printf
(
"
\n
"
);
}
void
Sfm_LibPrint
(
Sfm_Lib_t
*
p
)
{
word
*
pTruth
;
Sfm_Fun_t
*
pObj
;
int
iFunc
;
Vec_MemForEachEntry
(
p
->
vTtMem
,
pTruth
,
iFunc
)
{
if
(
iFunc
<
2
)
continue
;
//if ( iFunc % 10000 )
// continue;
printf
(
"%d : Count = %d "
,
iFunc
,
Vec_IntEntry
(
&
p
->
vCounts
,
iFunc
)
);
Dau_DsdPrintFromTruth
(
pTruth
,
Abc_TtSupportSize
(
pTruth
,
6
)
);
Sfm_LibForEachSuper
(
p
,
pObj
,
iFunc
)
Sfm_LibPrintObj
(
p
,
pObj
);
}
}
void
Sfm_LibTest
(
int
nVars
,
int
fTwo
,
int
fVerbose
)
{
Sfm_Lib_t
*
p
=
Sfm_LibPrepare
(
nVars
,
fTwo
,
1
);
if
(
fVerbose
)
Sfm_LibPrint
(
p
);
Sfm_LibStop
(
p
);
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int
Sfm_LibImplement
(
Sfm_Lib_t
*
p
,
word
uTruth
,
int
*
pFanins
,
int
nFanins
,
Vec_Int_t
*
vGates
,
Vec_Wec_t
*
vFanins
)
{
return
0
;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
...
...
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