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
ace34099
Commit
ace34099
authored
Mar 22, 2014
by
Alan Mishchenko
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Experiments with mapping.
parent
c86a13f0
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
1170 additions
and
371 deletions
+1170
-371
abclib.dsp
+4
-0
src/aig/gia/gia.h
+1
-0
src/aig/gia/giaCut.h
+0
-349
src/aig/gia/giaKf.c
+959
-0
src/aig/gia/module.make
+1
-0
src/base/abci/abc.c
+172
-0
src/map/if/ifCache.c
+0
-22
src/misc/vec/vecFlt.h
+17
-0
src/misc/vec/vecInt.h
+16
-0
No files found.
abclib.dsp
View file @
ace34099
...
...
@@ -3763,6 +3763,10 @@ SOURCE=.\src\aig\gia\giaJf.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\gia\giaKf.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\gia\giaMan.c
# End Source File
# Begin Source File
...
...
src/aig/gia/gia.h
View file @
ace34099
...
...
@@ -262,6 +262,7 @@ struct Jf_Par_t_
int
fVeryVerbose
;
int
nLutSizeMax
;
int
nCutNumMax
;
int
nProcNumMax
;
word
Delay
;
word
Area
;
word
Edge
;
...
...
src/aig/gia/giaCut.h
deleted
100644 → 0
View file @
c86a13f0
/**CFile****************************************************************
FileName [giaCut.h]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Scalable AIG package.]
Synopsis [Cut computation.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: giaCut.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#ifndef ABC__aig__gia__giaAig_h
#define ABC__aig__gia__giaAig_h
////////////////////////////////////////////////////////////////////////
/// INCLUDES ///
////////////////////////////////////////////////////////////////////////
#include "gia.h"
ABC_NAMESPACE_HEADER_START
////////////////////////////////////////////////////////////////////////
/// PARAMETERS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// BASIC TYPES ///
////////////////////////////////////////////////////////////////////////
#define GIA_CUT_LEAF_MAX 8
#define GIA_CUT_WORD_MAX ((GIA_CUT_LEAF_MAX > 6) ? 1 << (GIA_CUT_LEAF_MAX-6) : 1)
#define GIA_CUT_NUM_MAX 16
typedef
struct
Gia_Cut_t_
Gia_Cut_t
;
struct
Gia_Cut_t_
{
word
Sign
;
// signature
int
Id
;
// cut ID
int
iFunc
;
// function
int
iNext
;
// next cut
int
iFan0
;
// left child
int
iFan1
;
// right child
int
nLeaves
;
// number of leaves
int
pLeaves
[
GIA_CUT_LEAF_MAX
];
// cut
int
pCompls
[
GIA_CUT_LEAF_MAX
];
// polarity
};
static
inline
int
Gia_CutSize
(
int
*
pCut
)
{
return
pCut
[
0
]
&
0xF
;
}
// 4 bits
#define Gia_ObjForEachCut( pList, pCut, i, AddOn ) for ( i = 0, pCut = pList + 1; i < pList[0]; i++, pCut += Gia_CutSize(pCut) + AddOn )
////////////////////////////////////////////////////////////////////////
/// MACRO DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
// loads cuts from storage
static
inline
int
Gia_ObjLoadCuts
(
Gia_Cut_t
*
pCutsI
,
int
*
pCuts
,
int
AddOn
)
{
Gia_Cut_t
*
pCutsICur
;
int
i
,
k
,
Lit
,
*
pCut
;
assert
(
AddOn
==
1
||
AddOn
==
2
);
Gia_ObjForEachCut
(
pCuts
,
pCut
,
i
,
AddOn
)
{
pCutsICur
=
pCutsI
+
i
;
pCutsICur
->
Id
=
i
;
pCutsICur
->
Sign
=
0
;
pCutsICur
->
iFunc
=
(
AddOn
==
1
)
?
-
1
:
pCut
[
pCut
[
0
]
+
1
];
pCutsICur
->
nLeaves
=
pCut
[
0
];
for
(
k
=
0
;
k
<
pCut
[
0
];
k
++
)
{
Lit
=
pCut
[
k
+
1
];
pCutsICur
->
pCompls
[
k
]
=
Abc_LitIsCompl
(
Lit
);
pCutsICur
->
pLeaves
[
k
]
=
Abc_Lit2Var
(
Lit
);
pCutsICur
->
Sign
|=
1
<<
(
Abc_Lit2Var
(
Lit
)
&
0x3F
);
}
}
return
i
;
}
static
inline
int
Gia_CutId
(
Gia_Cut_t
*
pCutsOut
,
Gia_Cut_t
*
pCut
)
{
return
pCut
-
pCutsOut
;
}
static
inline
void
Gia_CutInsert
(
Gia_Cut_t
*
pCutsOut
,
Gia_Cut_t
*
pCut
)
// inserts cut into the list
{
int
*
pPlace
=
&
pCutsOut
[
pCut
->
nLeaves
].
iNext
;
pCut
->
iNext
=
*
pPlace
;
*
pPlace
=
pCut
-
pCutsOut
;
}
static
inline
void
Gia_CutRemove
(
int
*
pPlace
,
Gia_Cut_t
*
pCut
)
// removes cut from the list
{
*
pPlace
=
pCut
->
iNext
;
}
static
inline
word
Gia_CutGetSign
(
Gia_Cut_t
*
pCut
)
{
word
Sign
=
0
;
int
i
;
for
(
i
=
0
;
i
<
pCut
->
nLeaves
;
i
++
)
Sign
|=
((
word
)
1
)
<<
(
pCut
->
pLeaves
[
i
]
&
0x3F
);
return
Sign
;
}
static
inline
int
Gia_CutCountBits
(
word
i
)
{
i
=
i
-
((
i
>>
1
)
&
0x5555555555555555
);
i
=
(
i
&
0x3333333333333333
)
+
((
i
>>
2
)
&
0x3333333333333333
);
i
=
((
i
+
(
i
>>
4
))
&
0x0F0F0F0F0F0F0F0F
);
return
(
i
*
(
0x0101010101010101
))
>>
56
;
}
static
inline
int
Gia_CutIsContainedOrder
(
Gia_Cut_t
*
pBase
,
Gia_Cut_t
*
pCut
)
// check if pCut is contained pBase
{
int
i
,
k
;
if
(
pBase
->
nLeaves
==
pCut
->
nLeaves
)
{
for
(
i
=
1
;
i
<=
pCut
->
nLeaves
;
i
++
)
if
(
pBase
->
pLeaves
[
i
]
!=
pCut
->
pLeaves
[
i
]
)
return
0
;
return
1
;
}
assert
(
pBase
->
nLeaves
>
pCut
->
nLeaves
);
for
(
i
=
k
=
1
;
i
<=
pBase
->
nLeaves
;
i
++
)
{
if
(
pBase
->
pLeaves
[
i
]
>
pCut
->
pLeaves
[
k
]
)
return
0
;
if
(
pBase
->
pLeaves
[
i
]
==
pCut
->
pLeaves
[
k
]
)
{
if
(
k
++
==
pCut
->
nLeaves
)
return
1
;
}
}
return
0
;
}
// check if the given cut is contained in previous cuts
static
inline
int
Gia_ObjCheckContainInPrev
(
Gia_Cut_t
*
pCutsOut
,
Gia_Cut_t
*
pCut
)
{
Gia_Cut_t
*
pPrev
;
for
(
pPrev
=
pCutsOut
;
pPrev
->
iNext
;
pPrev
=
pCutsOut
+
pPrev
->
iNext
)
{
if
(
pPrev
->
iFunc
==
-
2
)
// skip sentinels
continue
;
if
(
pPrev
->
nLeaves
>
pCut
->
nLeaves
)
// stop when we reached bigger cuts
return
0
;
if
(
(
pCut
->
Sign
&
pPrev
->
Sign
)
!=
pPrev
->
Sign
)
continue
;
if
(
Gia_CutIsContainedOrder
(
pPrev
,
pCut
)
)
return
1
;
}
assert
(
0
);
return
1
;
}
// check if the given cut contains following cuts
static
inline
void
Gia_ObjCheckContainsNext
(
Gia_Cut_t
*
pCutsOut
,
Gia_Cut_t
*
pCut
,
int
**
ppPlace
)
{
Gia_Cut_t
*
pNext
;
int
*
pPlace
=
&
pCut
->
iNext
;
while
(
*
pPlace
)
{
pNext
=
pCutsOut
+
pNext
->
iNext
;
if
(
pNext
->
iFunc
==
-
2
)
// skip sentinels
continue
;
assert
(
pNext
!=
pCut
&&
pNext
->
nLeaves
>=
pCut
->
nLeaves
);
if
(
(
pNext
->
Sign
&
pCut
->
Sign
)
!=
pCut
->
Sign
)
continue
;
if
(
!
Gia_CutIsContainedOrder
(
pCut
,
pNext
)
)
{
pPlace
=
&
pNext
->
iNext
;
continue
;
}
// shift the pointer
if
(
*
ppPlace
==
&
pNext
->
iNext
)
*
ppPlace
=
pPlace
;
// remove pNext
Gia_CutRemove
(
pPlace
,
pNext
);
}
}
static
inline
int
Gia_ObjMergeCutsOrder
(
Gia_Cut_t
*
pCut
,
Gia_Cut_t
*
pCut0
,
Gia_Cut_t
*
pCut1
,
int
LutSize
)
{
int
nSize0
=
pCut0
->
nLeaves
;
int
nSize1
=
pCut1
->
nLeaves
;
int
*
pC0
=
pCut0
->
pLeaves
;
int
*
pC1
=
pCut1
->
pLeaves
;
int
*
pC
=
pCut
->
pLeaves
;
int
i
,
k
,
c
,
s
;
// the case of the largest cut sizes
if
(
nSize0
==
LutSize
&&
nSize1
==
LutSize
)
{
for
(
i
=
0
;
i
<
nSize0
;
i
++
)
{
if
(
pC0
[
i
]
!=
pC1
[
i
]
)
return
0
;
pC
[
i
]
=
pC0
[
i
];
}
pCut
->
nLeaves
=
LutSize
;
return
1
;
}
// compare two cuts with different numbers
i
=
k
=
c
=
s
=
0
;
while
(
1
)
{
if
(
c
==
LutSize
)
return
0
;
if
(
pC0
[
i
]
<
pC1
[
k
]
)
{
pC
[
c
++
]
=
pC0
[
i
++
];
if
(
i
>=
nSize0
)
goto
FlushCut1
;
}
else
if
(
pC0
[
i
]
>
pC1
[
k
]
)
{
pC
[
c
++
]
=
pC1
[
k
++
];
if
(
k
>=
nSize1
)
goto
FlushCut0
;
}
else
{
pC
[
c
++
]
=
pC0
[
i
++
];
k
++
;
if
(
i
>=
nSize0
)
goto
FlushCut1
;
if
(
k
>=
nSize1
)
goto
FlushCut0
;
}
}
FlushCut0:
if
(
c
+
nSize0
>
LutSize
+
i
)
return
0
;
while
(
i
<
nSize0
)
pC
[
c
++
]
=
pC0
[
i
++
];
pCut
->
nLeaves
=
c
;
return
1
;
FlushCut1:
if
(
c
+
nSize1
>
LutSize
+
k
)
return
0
;
while
(
k
<
nSize1
)
pC
[
c
++
]
=
pC1
[
k
++
];
pCut
->
nLeaves
=
c
;
return
1
;
}
static
inline
int
Gia_ObjCombineCuts
(
Gia_Cut_t
*
pCutsOut
,
Gia_Cut_t
*
pCut
,
Gia_Cut_t
*
pCut0
,
Gia_Cut_t
*
pCut1
,
int
LutSize
)
{
if
(
!
Gia_ObjMergeCutsOrder
(
pCut
,
pCut0
,
pCut1
,
LutSize
)
)
return
0
;
pCut
->
Sign
=
pCut0
->
Sign
|
pCut1
->
Sign
;
if
(
!
Gia_ObjCheckContainInPrev
(
pCutsOut
,
pCut
)
)
return
0
;
Gia_CutInsert
(
pCutsOut
,
pCut
);
pCut
->
Id
=
pCut
-
pCutsOut
;
pCut
->
iFan0
=
pCut0
->
Id
;
pCut
->
iFan1
=
pCut1
->
Id
;
pCut
->
iFunc
=
-
1
;
return
1
;
}
int
Gia_TtComputeForCut
(
Vec_Mem_t
*
vTtMem
,
int
iFuncLit0
,
int
iFuncLit1
,
Gia_Cut_t
*
pCut0
,
Gia_Cut_t
*
pCut1
,
Gia_Cut_t
*
pCut
,
int
LutSize
)
{
word
uTruth
[
GIA_CUT_WORD_MAX
],
uTruth0
[
GIA_CUT_WORD_MAX
],
uTruth1
[
GIA_CUT_WORD_MAX
];
int
fCompl
,
truthId
;
int
nWords
=
Abc_Truth6WordNum
(
LutSize
);
word
*
pTruth0
=
Vec_MemReadEntry
(
vTtMem
,
Abc_Lit2Var
(
iFuncLit0
));
word
*
pTruth1
=
Vec_MemReadEntry
(
vTtMem
,
Abc_Lit2Var
(
iFuncLit1
));
Abc_TtCopy
(
uTruth0
,
pTruth0
,
nWords
,
Abc_LitIsCompl
(
iFuncLit0
)
);
Abc_TtCopy
(
uTruth1
,
pTruth1
,
nWords
,
Abc_LitIsCompl
(
iFuncLit1
)
);
Abc_TtStretch
(
uTruth0
,
LutSize
,
pCut0
->
pLeaves
,
pCut0
->
nLeaves
,
pCut
->
pLeaves
,
pCut
->
nLeaves
);
Abc_TtStretch
(
uTruth1
,
LutSize
,
pCut1
->
pLeaves
,
pCut1
->
nLeaves
,
pCut
->
pLeaves
,
pCut
->
nLeaves
);
fCompl
=
(
int
)(
uTruth0
[
0
]
&
uTruth1
[
0
]
&
1
);
Abc_TtAnd
(
uTruth
,
uTruth0
,
uTruth1
,
nWords
,
fCompl
);
pCut
->
nLeaves
=
Abc_TtMinBase
(
uTruth
,
pCut
->
pLeaves
,
pCut
->
nLeaves
,
LutSize
);
assert
(
(
uTruth
[
0
]
&
1
)
==
0
);
truthId
=
Vec_MemHashInsert
(
vTtMem
,
uTruth
);
return
Abc_Var2Lit
(
truthId
,
fCompl
);
}
// Gia_Cut_t pCutsOut[GIA_CUT_LEAF_MAX + 2 + GIA_CUT_NUM_MAX * GIA_CUT_NUM_MAX]; // LutSize+1 placeholders + CutNum ^ 2 + 1
static
inline
int
Gia_ObjComputeCuts
(
Gia_Cut_t
*
pCutsOut
,
int
*
pCuts0
,
int
*
pCuts1
,
Vec_Mem_t
*
vTtMem
,
int
AddOn
,
int
nLutSize
,
int
nCutNum
,
int
fCompl0
,
int
fCompl1
)
{
Gia_Cut_t
*
pCut
;
Gia_Cut_t
pCuts0i
[
GIA_CUT_NUM_MAX
];
Gia_Cut_t
pCuts1i
[
GIA_CUT_NUM_MAX
];
int
i
,
nCuts0i
=
Gia_ObjLoadCuts
(
pCuts0i
,
pCuts0
,
AddOn
);
int
k
,
nCuts1i
=
Gia_ObjLoadCuts
(
pCuts1i
,
pCuts1
,
AddOn
);
int
*
pPlace
,
c
=
GIA_CUT_NUM_MAX
+
1
;
assert
(
nCuts0i
<=
GIA_CUT_NUM_MAX
);
assert
(
nCuts1i
<=
GIA_CUT_NUM_MAX
);
// prepare cuts
for
(
i
=
0
;
i
<=
GIA_CUT_NUM_MAX
;
i
++
)
{
pCut
=
pCutsOut
+
i
;
pCut
->
nLeaves
=
i
;
pCut
->
iNext
=
i
+
1
;
pCut
->
iFunc
=
-
2
;
pCut
->
Id
=
i
;
}
pCut
->
iNext
=
0
;
// enumerate pairs
for
(
i
=
0
;
i
<
nCuts0i
;
i
++
)
for
(
k
=
0
;
k
<
nCuts1i
;
k
++
)
if
(
Gia_CutCountBits
(
pCuts0i
[
i
].
Sign
|
pCuts1i
[
k
].
Sign
)
<=
nLutSize
)
Gia_ObjCombineCuts
(
pCutsOut
,
pCutsOut
+
c
++
,
pCuts0i
+
i
,
pCuts1i
+
k
,
nLutSize
);
assert
(
c
<=
GIA_CUT_LEAF_MAX
+
2
+
GIA_CUT_NUM_MAX
*
GIA_CUT_NUM_MAX
);
// check containment for cuts
for
(
pPlace
=
&
pCutsOut
->
iNext
;
*
pPlace
;
pPlace
=
&
pCut
->
iNext
)
{
pCut
=
pCutsOut
+
*
pPlace
;
if
(
pCut
->
iFunc
==
-
2
)
continue
;
// compute truth table
if
(
AddOn
==
2
)
{
Gia_Cut_t
*
pCut0
=
pCuts0i
+
pCut
->
iFan0
;
Gia_Cut_t
*
pCut1
=
pCuts1i
+
pCut
->
iFan1
;
int
iLit0
=
Abc_LitNotCond
(
pCut0
->
iFunc
,
fCompl0
);
int
iLit1
=
Abc_LitNotCond
(
pCut1
->
iFunc
,
fCompl1
);
int
nLeavesOld
=
pCut
->
nLeaves
;
pCut
->
iFunc
=
Gia_TtComputeForCut
(
vTtMem
,
iLit0
,
iLit1
,
pCut0
,
pCut1
,
pCut
,
nLutSize
);
// if size has changed, move the cut closer
if
(
nLeavesOld
!=
pCut
->
nLeaves
)
{
Gia_CutRemove
(
pPlace
,
pCut
);
Gia_CutInsert
(
pCutsOut
,
pCut
);
pCut
->
Sign
=
Gia_CutGetSign
(
pCut
);
}
}
// check containment after this cut
Gia_ObjCheckContainsNext
(
pCutsOut
,
pCut
,
&
pPlace
);
}
}
ABC_NAMESPACE_HEADER_END
#endif
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
src/aig/gia/giaKf.c
0 → 100644
View file @
ace34099
/**CFile****************************************************************
FileName [giaCutt.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Scalable AIG package.]
Synopsis [Cut computation.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: giaCutt.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "gia.h"
#include "misc/vec/vecSet.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
#define KF_PROC_MAX 8
#define KF_LEAF_MAX 8
#define KF_WORD_MAX ((KF_LEAF_MAX > 6) ? 1 << (KF_LEAF_MAX-6) : 1)
#define KF_LOG_TABLE 8
#define KF_NUM_MAX 16
#define KF_ADD_ON1 2 // offset in cut storage for each node (cut count; best cut)
#define KF_ADD_ON2 4 // offset in cut storage for each cut (leaf count; function, cut delay; cut area)
typedef
struct
Kf_Cut_t_
Kf_Cut_t
;
typedef
struct
Kf_Set_t_
Kf_Set_t
;
typedef
struct
Kf_Man_t_
Kf_Man_t
;
struct
Kf_Cut_t_
{
word
Sign
;
// signature
int
Polar
;
// polarity
int
Delay
;
// delay
float
Area
;
// area
int
iFunc
;
// function
int
iNext
;
// next cut
int
nLeaves
;
// number of leaves
int
pLeaves
[
KF_LEAF_MAX
];
};
struct
Kf_Set_t_
{
Kf_Man_t
*
pMan
;
// manager
unsigned
short
nLutSize
;
// lut size
unsigned
short
nCutNum
;
// cut count
int
nCuts0
;
// fanin0 cut count
int
nCuts1
;
// fanin1 cut count
int
nCuts
;
// resulting cut count
int
nTEntries
;
// hash table entries
int
TableMask
;
// hash table mask
int
pTable
[
1
<<
KF_LOG_TABLE
];
int
pValue
[
1
<<
KF_LOG_TABLE
];
int
pPlace
[
KF_LEAF_MAX
];
int
pList
[
KF_LEAF_MAX
];
Kf_Cut_t
pCuts0
[
KF_NUM_MAX
];
Kf_Cut_t
pCuts1
[
KF_NUM_MAX
];
Kf_Cut_t
pCutsR
[
KF_NUM_MAX
*
KF_NUM_MAX
];
Kf_Cut_t
*
ppCuts
[
KF_NUM_MAX
];
word
CutCount
[
4
];
// statistics
};
struct
Kf_Man_t_
{
Gia_Man_t
*
pGia
;
// user's manager
Jf_Par_t
*
pPars
;
// user's parameters
Vec_Set_t
pMem
;
// cut storage
Vec_Int_t
vCuts
;
// node params
Vec_Int_t
vTime
;
// node params
Vec_Flt_t
vArea
;
// node params
Vec_Flt_t
vRefs
;
// node params
Vec_Int_t
*
vTemp
;
// temporary
abctime
clkStart
;
// starting time
Kf_Set_t
pSett
[
KF_PROC_MAX
];
};
static
inline
int
Kf_SetCutId
(
Kf_Set_t
*
p
,
Kf_Cut_t
*
pCut
)
{
return
pCut
-
p
->
pCutsR
;
}
static
inline
Kf_Cut_t
*
Kf_SetCut
(
Kf_Set_t
*
p
,
int
i
)
{
return
i
>=
0
?
p
->
pCutsR
+
i
:
NULL
;
}
static
inline
int
Kf_ObjTime
(
Kf_Man_t
*
p
,
int
i
)
{
return
Vec_IntEntry
(
&
p
->
vTime
,
i
);
}
static
inline
float
Kf_ObjArea
(
Kf_Man_t
*
p
,
int
i
)
{
return
Vec_FltEntry
(
&
p
->
vArea
,
i
);
}
static
inline
float
Kf_ObjRefs
(
Kf_Man_t
*
p
,
int
i
)
{
return
Vec_FltEntry
(
&
p
->
vRefs
,
i
);
}
static
inline
void
Kf_ObjSetCuts
(
Kf_Man_t
*
p
,
int
i
,
Vec_Int_t
*
vVec
)
{
Vec_IntWriteEntry
(
&
p
->
vCuts
,
i
,
Vec_SetAppend
(
&
p
->
pMem
,
Vec_IntArray
(
vVec
),
Vec_IntSize
(
vVec
)));
}
static
inline
int
*
Kf_ObjCuts
(
Kf_Man_t
*
p
,
int
i
)
{
return
(
int
*
)
Vec_SetEntry
(
&
p
->
pMem
,
Vec_IntEntry
(
&
p
->
vCuts
,
i
));
}
static
inline
int
*
Kf_ObjCuts0
(
Kf_Man_t
*
p
,
int
i
)
{
return
Kf_ObjCuts
(
p
,
Gia_ObjFaninId0
(
Gia_ManObj
(
p
->
pGia
,
i
),
i
));
}
static
inline
int
*
Kf_ObjCuts1
(
Kf_Man_t
*
p
,
int
i
)
{
return
Kf_ObjCuts
(
p
,
Gia_ObjFaninId1
(
Gia_ManObj
(
p
->
pGia
,
i
),
i
));
}
static
inline
int
*
Kf_ObjCutBest
(
Kf_Man_t
*
p
,
int
i
)
{
int
*
pCuts
=
Kf_ObjCuts
(
p
,
i
);
return
pCuts
+
pCuts
[
1
];
}
#define Kf_ObjForEachCutInt( pList, pCut, i ) for ( i = 0, pCut = pList + KF_ADD_ON1; i < pList[0]; i++, pCut += pCut[0] + KF_ADD_ON2 )
#define Kf_ListForEachCutt( p, iList, pCut ) for ( pCut = Kf_SetCut(p, p->pList[iList]); pCut; pCut = Kf_SetCut(p, pCut->iNext) )
#define Kf_ListForEachCuttP( p, iList, pCut, pPlace ) for ( pPlace = p->pList+iList, pCut = Kf_SetCut(p, *pPlace); pCut; pCut = Kf_SetCut(p, *pPlace) )
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static
inline
int
Kf_SetLoadCuts
(
Kf_Cut_t
*
pCuts
,
int
*
pIntCuts
)
{
Kf_Cut_t
*
pCut
;
int
k
,
*
pIntCut
,
nCuts
=
0
;
Kf_ObjForEachCutInt
(
pIntCuts
,
pIntCut
,
nCuts
)
{
pCut
=
pCuts
+
nCuts
;
pCut
->
Sign
=
0
;
pCut
->
Polar
=
0
;
pCut
->
iFunc
=
pIntCut
[
pIntCut
[
0
]
+
1
];
pCut
->
Delay
=
pIntCut
[
pIntCut
[
0
]
+
2
];
pCut
->
Area
=
Abc_Int2Float
(
pIntCut
[
pIntCut
[
0
]
+
3
]);
pCut
->
nLeaves
=
pIntCut
[
0
];
for
(
k
=
0
;
k
<
pIntCut
[
0
];
k
++
)
{
pCut
->
pLeaves
[
k
]
=
Abc_Lit2Var
(
pIntCut
[
k
+
1
]);
pCut
->
Sign
|=
((
word
)
1
)
<<
(
pCut
->
pLeaves
[
k
]
&
0x3F
);
if
(
Abc_LitIsCompl
(
pIntCut
[
k
+
1
])
)
pCut
->
Polar
|=
(
1
<<
k
);
}
}
return
nCuts
;
}
static
inline
void
Kf_SetPrepare
(
Kf_Set_t
*
p
,
int
*
pCuts0
,
int
*
pCuts1
)
{
int
i
;
// prepare hash table
for
(
i
=
0
;
i
<=
p
->
TableMask
;
i
++
)
assert
(
p
->
pTable
[
i
]
==
0
);
// prepare cut storage
for
(
i
=
0
;
i
<=
p
->
nLutSize
;
i
++
)
p
->
pList
[
i
]
=
-
1
;
// transfer cuts
p
->
nCuts0
=
Kf_SetLoadCuts
(
p
->
pCuts0
,
pCuts0
);
p
->
nCuts1
=
Kf_SetLoadCuts
(
p
->
pCuts1
,
pCuts1
);
p
->
nCuts
=
0
;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static
inline
void
Kf_ManStoreStart
(
Vec_Int_t
*
vTemp
,
int
nCuts
)
{
Vec_IntClear
(
vTemp
);
Vec_IntPush
(
vTemp
,
nCuts
);
// cut count
Vec_IntPush
(
vTemp
,
-
1
);
// best offset
}
static
inline
void
Kf_ManStoreAddUnit
(
Vec_Int_t
*
vTemp
,
int
iObj
,
int
Time
,
float
Area
)
{
Vec_IntAddToEntry
(
vTemp
,
0
,
1
);
Vec_IntPush
(
vTemp
,
1
);
// cut size
Vec_IntPush
(
vTemp
,
Abc_Var2Lit
(
iObj
,
0
)
);
// leaf
Vec_IntPush
(
vTemp
,
2
);
// function
Vec_IntPush
(
vTemp
,
Time
);
// delay
Vec_IntPush
(
vTemp
,
Abc_Float2Int
(
Area
)
);
// area
}
static
inline
void
Kf_ManSaveResults
(
Kf_Cut_t
**
ppCuts
,
int
nCuts
,
Kf_Cut_t
*
pCutBest
,
Vec_Int_t
*
vTemp
)
{
int
i
,
k
;
assert
(
nCuts
>
0
&&
nCuts
<
KF_NUM_MAX
);
Kf_ManStoreStart
(
vTemp
,
nCuts
);
for
(
i
=
0
;
i
<
nCuts
;
i
++
)
{
if
(
ppCuts
[
i
]
==
pCutBest
)
Vec_IntWriteEntry
(
vTemp
,
1
,
Vec_IntSize
(
vTemp
)
);
Vec_IntPush
(
vTemp
,
ppCuts
[
i
]
->
nLeaves
);
// Vec_IntPushArray( vTemp, ppCuts[i]->pLeaves, ppCuts[i]->nLeaves );
for
(
k
=
0
;
k
<
ppCuts
[
i
]
->
nLeaves
;
k
++
)
Vec_IntPush
(
vTemp
,
Abc_Var2Lit
(
ppCuts
[
i
]
->
pLeaves
[
k
],
0
)
);
Vec_IntPush
(
vTemp
,
ppCuts
[
i
]
->
iFunc
);
Vec_IntPush
(
vTemp
,
ppCuts
[
i
]
->
Delay
);
Vec_IntPush
(
vTemp
,
Abc_Float2Int
(
ppCuts
[
i
]
->
Area
)
);
}
assert
(
Vec_IntEntry
(
vTemp
,
1
)
>
0
);
}
static
inline
int
Kf_SetCompareCuts
(
Kf_Cut_t
*
p1
,
Kf_Cut_t
*
p2
)
{
if
(
p1
==
NULL
||
p2
==
NULL
)
return
(
p1
!=
NULL
)
-
(
p2
!=
NULL
);
if
(
p1
->
nLeaves
!=
p2
->
nLeaves
)
return
p1
->
nLeaves
-
p2
->
nLeaves
;
return
memcmp
(
p1
->
pLeaves
,
p2
->
pLeaves
,
sizeof
(
int
)
*
p1
->
nLeaves
);
}
static
inline
void
Kf_SetAddToList
(
Kf_Set_t
*
p
,
Kf_Cut_t
*
pCut
,
int
fSort
)
{
if
(
!
fSort
)
pCut
->
iNext
=
p
->
pList
[
pCut
->
nLeaves
],
p
->
pList
[
pCut
->
nLeaves
]
=
Kf_SetCutId
(
p
,
pCut
);
else
{
int
Value
,
*
pPlace
;
Kf_Cut_t
*
pTemp
;
Vec_IntSelectSort
(
pCut
->
pLeaves
,
pCut
->
nLeaves
);
Kf_ListForEachCuttP
(
p
,
pCut
->
nLeaves
,
pTemp
,
pPlace
)
{
if
(
(
Value
=
Kf_SetCompareCuts
(
pTemp
,
pCut
))
>
0
)
break
;
assert
(
Value
<
0
);
pPlace
=
&
pTemp
->
iNext
;
}
pCut
->
iNext
=
*
pPlace
,
*
pPlace
=
Kf_SetCutId
(
p
,
pCut
);
}
}
static
inline
int
Kf_CutCompare
(
Kf_Cut_t
*
pCut0
,
Kf_Cut_t
*
pCut1
,
int
fArea
)
{
if
(
fArea
)
{
if
(
pCut0
->
Area
<
pCut1
->
Area
)
return
-
1
;
if
(
pCut0
->
Area
>
pCut1
->
Area
)
return
1
;
if
(
pCut0
->
Delay
<
pCut1
->
Delay
)
return
-
1
;
if
(
pCut0
->
Delay
>
pCut1
->
Delay
)
return
1
;
if
(
pCut0
->
nLeaves
<
pCut1
->
nLeaves
)
return
-
1
;
if
(
pCut0
->
nLeaves
>
pCut1
->
nLeaves
)
return
1
;
}
else
{
if
(
pCut0
->
Delay
<
pCut1
->
Delay
)
return
-
1
;
if
(
pCut0
->
Delay
>
pCut1
->
Delay
)
return
1
;
if
(
pCut0
->
nLeaves
<
pCut1
->
nLeaves
)
return
-
1
;
if
(
pCut0
->
nLeaves
>
pCut1
->
nLeaves
)
return
1
;
if
(
pCut0
->
Area
<
pCut1
->
Area
)
return
-
1
;
if
(
pCut0
->
Area
>
pCut1
->
Area
)
return
1
;
}
return
0
;
}
static
inline
int
Kf_SetStoreAddOne
(
Kf_Set_t
*
p
,
int
nCuts
,
int
nCutNum
,
Kf_Cut_t
*
pCut
,
int
fArea
)
{
int
i
;
p
->
ppCuts
[
nCuts
]
=
pCut
;
if
(
nCuts
==
0
)
return
1
;
for
(
i
=
nCuts
;
i
>
0
;
i
--
)
if
(
Kf_CutCompare
(
p
->
ppCuts
[
i
-
1
],
p
->
ppCuts
[
i
],
fArea
)
>
0
)
ABC_SWAP
(
Kf_Cut_t
*
,
p
->
ppCuts
[
i
-
1
],
p
->
ppCuts
[
i
]
)
else
break
;
return
Abc_MinInt
(
nCuts
+
1
,
nCutNum
);
}
static
inline
Kf_Cut_t
*
Kf_SetSelectBest
(
Kf_Set_t
*
p
,
int
fArea
,
int
fSort
)
{
// int fArea = p->pMan->pPars->fArea;
Kf_Cut_t
*
pCut
,
*
pCutBest
;
int
i
,
nCuts
=
0
;
for
(
i
=
0
;
i
<=
p
->
nLutSize
;
i
++
)
Kf_ListForEachCutt
(
p
,
i
,
pCut
)
nCuts
=
Kf_SetStoreAddOne
(
p
,
nCuts
,
p
->
nCutNum
-
1
,
pCut
,
fArea
);
assert
(
nCuts
>
0
&&
nCuts
<
p
->
nCutNum
);
p
->
nCuts
=
nCuts
;
if
(
!
fSort
)
return
p
->
ppCuts
[
0
];
// sort by size in the reverse order
pCutBest
=
p
->
ppCuts
[
0
];
for
(
i
=
0
;
i
<=
p
->
nLutSize
;
i
++
)
p
->
pList
[
i
]
=
-
1
;
for
(
i
=
0
;
i
<
nCuts
;
i
++
)
Kf_SetAddToList
(
p
,
p
->
ppCuts
[
i
],
0
);
p
->
nCuts
=
0
;
for
(
i
=
p
->
nLutSize
;
i
>=
0
;
i
--
)
Kf_ListForEachCutt
(
p
,
i
,
pCut
)
p
->
ppCuts
[
p
->
nCuts
++
]
=
pCut
;
assert
(
p
->
nCuts
==
nCuts
);
return
pCutBest
;
}
/**Function*************************************************************
Synopsis [Hash table.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static
inline
int
Kf_HashLookup
(
Kf_Set_t
*
p
,
int
i
)
{
int
k
;
assert
(
i
>
0
);
for
(
k
=
i
&
p
->
TableMask
;
p
->
pTable
[
k
];
k
=
(
k
+
1
)
&
p
->
TableMask
)
if
(
p
->
pTable
[
k
]
==
i
)
return
-
1
;
return
k
;
}
static
inline
int
Kf_HashFindOrAdd
(
Kf_Set_t
*
p
,
int
i
)
{
int
k
=
Kf_HashLookup
(
p
,
i
);
if
(
k
==
-
1
)
return
0
;
if
(
p
->
nTEntries
==
p
->
nLutSize
)
return
1
;
assert
(
p
->
pTable
[
k
]
==
0
);
p
->
pTable
[
k
]
=
i
;
p
->
pPlace
[
p
->
nTEntries
]
=
k
;
p
->
pValue
[
k
]
=
p
->
nTEntries
++
;
return
0
;
}
static
inline
void
Kf_HashPopulate
(
Kf_Set_t
*
p
,
Kf_Cut_t
*
pCut
)
{
int
i
;
assert
(
p
->
nTEntries
==
0
);
for
(
i
=
0
;
i
<
pCut
->
nLeaves
;
i
++
)
Kf_HashFindOrAdd
(
p
,
pCut
->
pLeaves
[
i
]
);
assert
(
p
->
nTEntries
==
pCut
->
nLeaves
);
}
static
inline
void
Kf_HashCleanup
(
Kf_Set_t
*
p
,
int
iStart
)
{
int
i
;
for
(
i
=
iStart
;
i
<
p
->
nTEntries
;
i
++
)
p
->
pPlace
[
i
]
=
0
;
p
->
nTEntries
=
iStart
;
}
/**Function*************************************************************
Synopsis [Cut merging with arbitary order.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
// returns 1 if the cut in hash table is dominated by the given one
static
inline
int
Kf_SetCutDominatedByThis
(
Kf_Set_t
*
p
,
Kf_Cut_t
*
pCut
)
{
int
i
;
for
(
i
=
0
;
i
<
pCut
->
nLeaves
;
i
++
)
if
(
Kf_HashLookup
(
p
,
pCut
->
pLeaves
[
i
])
>=
0
)
return
0
;
return
1
;
}
static
inline
int
Kf_SetRemoveDuplicates
(
Kf_Set_t
*
p
,
int
nLeaves
,
word
Sign
)
{
Kf_Cut_t
*
pCut
;
Kf_ListForEachCutt
(
p
,
nLeaves
,
pCut
)
if
(
pCut
->
Sign
==
Sign
&&
Kf_SetCutDominatedByThis
(
p
,
pCut
)
)
return
1
;
return
0
;
}
static
inline
void
Kf_SetFilter
(
Kf_Set_t
*
p
)
{
Kf_Cut_t
*
pCut0
,
*
pCut1
;
int
i
,
k
,
*
pPlace
;
assert
(
p
->
nCuts
>
0
);
for
(
i
=
0
;
i
<=
p
->
nLutSize
;
i
++
)
Kf_ListForEachCuttP
(
p
,
i
,
pCut0
,
pPlace
)
{
Kf_HashPopulate
(
p
,
pCut0
);
for
(
k
=
0
;
k
<
pCut0
->
nLeaves
;
k
++
)
Kf_ListForEachCutt
(
p
,
k
,
pCut1
)
if
(
(
pCut0
->
Sign
&
pCut1
->
Sign
)
==
pCut1
->
Sign
&&
Kf_SetCutDominatedByThis
(
p
,
pCut1
)
)
{
k
=
pCut0
->
nLeaves
+
1
;
p
->
nCuts
--
;
break
;
}
if
(
k
==
pCut0
->
nLeaves
+
1
)
// remove pCut0
*
pPlace
=
pCut0
->
iNext
;
else
pPlace
=
&
pCut0
->
iNext
;
Kf_HashCleanup
(
p
,
0
);
}
assert
(
p
->
nCuts
>
0
);
}
static
inline
void
Kf_SetMergePairs
(
Kf_Set_t
*
p
,
Kf_Cut_t
*
pCut0
,
Kf_Cut_t
*
pCuts
,
int
nCuts
,
int
fArea
)
{
Kf_Cut_t
*
pCut1
,
*
pCutR
;
int
i
;
Kf_HashPopulate
(
p
,
pCut0
);
for
(
pCut1
=
pCuts
;
pCut1
<
pCuts
+
nCuts
;
pCut1
++
)
{
Kf_HashCleanup
(
p
,
pCut0
->
nLeaves
);
for
(
i
=
0
;
i
<
pCut1
->
nLeaves
;
i
++
)
if
(
Kf_HashFindOrAdd
(
p
,
pCut1
->
pLeaves
[
i
])
)
break
;
if
(
i
<
pCut1
->
nLeaves
)
continue
;
if
(
Kf_SetRemoveDuplicates
(
p
,
p
->
nTEntries
,
pCut0
->
Sign
|
pCut1
->
Sign
)
)
continue
;
// create new cut
pCutR
=
p
->
pCutsR
+
p
->
nCuts
++
;
pCutR
->
nLeaves
=
p
->
nTEntries
;
for
(
i
=
0
;
i
<
p
->
nTEntries
;
i
++
)
pCutR
->
pLeaves
[
i
]
=
p
->
pTable
[
p
->
pPlace
[
i
]];
pCutR
->
Sign
=
pCut0
->
Sign
|
pCut1
->
Sign
;
pCutR
->
Delay
=
Abc_MaxInt
(
pCut0
->
Delay
,
pCut1
->
Delay
);
pCutR
->
Area
=
pCut0
->
Area
+
pCut1
->
Area
;
// add new cut
Kf_SetAddToList
(
p
,
pCutR
,
0
);
}
Kf_HashCleanup
(
p
,
0
);
}
static
inline
Kf_Cut_t
*
Kf_SetMerge
(
Kf_Set_t
*
p
,
int
*
pCuts0
,
int
*
pCuts1
,
int
fArea
,
int
fCutMin
)
{
int
c0
,
c1
;
Kf_SetPrepare
(
p
,
pCuts0
,
pCuts1
);
for
(
c0
=
c1
=
0
;
c0
<
p
->
nCuts0
&&
c1
<
p
->
nCuts1
;
)
{
if
(
p
->
pCuts0
[
c0
].
nLeaves
>=
p
->
pCuts1
[
c1
].
nLeaves
)
Kf_SetMergePairs
(
p
,
p
->
pCuts0
+
c0
++
,
p
->
pCuts1
+
c1
,
p
->
nCuts1
-
c1
,
fArea
);
else
Kf_SetMergePairs
(
p
,
p
->
pCuts1
+
c1
++
,
p
->
pCuts0
+
c0
,
p
->
nCuts0
-
c0
,
fArea
);
}
Kf_SetFilter
(
p
);
p
->
CutCount
[
3
]
+=
Abc_MinInt
(
p
->
nCuts
,
p
->
nCutNum
);
return
Kf_SetSelectBest
(
p
,
fArea
,
1
);
}
/**Function*************************************************************
Synopsis [Cut merging with fixed order.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static
inline
int
Kf_SetCountBits
(
word
i
)
{
i
=
i
-
((
i
>>
1
)
&
0x5555555555555555
);
i
=
(
i
&
0x3333333333333333
)
+
((
i
>>
2
)
&
0x3333333333333333
);
i
=
((
i
+
(
i
>>
4
))
&
0x0F0F0F0F0F0F0F0F
);
return
(
i
*
(
0x0101010101010101
))
>>
56
;
}
static
inline
word
Kf_SetCutGetSign
(
Kf_Cut_t
*
p
)
{
word
Sign
=
0
;
int
i
;
for
(
i
=
0
;
i
<
p
->
nLeaves
;
i
++
)
Sign
|=
((
word
)
1
)
<<
(
p
->
pLeaves
[
i
]
&
0x3F
);
return
Sign
;
}
static
inline
int
Kf_SetCutIsContainedOrder
(
Kf_Cut_t
*
pBase
,
Kf_Cut_t
*
pCut
)
// check if pCut is contained in pBase
{
int
nSizeB
=
pBase
->
nLeaves
;
int
nSizeC
=
pCut
->
nLeaves
;
int
i
,
k
;
if
(
nSizeB
==
nSizeC
)
{
for
(
i
=
0
;
i
<
nSizeB
;
i
++
)
if
(
pBase
->
pLeaves
[
i
]
!=
pCut
->
pLeaves
[
i
]
)
return
0
;
return
1
;
}
assert
(
nSizeB
>
nSizeC
);
for
(
i
=
k
=
0
;
i
<
nSizeB
;
i
++
)
{
if
(
pBase
->
pLeaves
[
i
]
>
pCut
->
pLeaves
[
k
]
)
return
0
;
if
(
pBase
->
pLeaves
[
i
]
==
pCut
->
pLeaves
[
k
]
)
{
if
(
k
++
==
nSizeC
)
return
1
;
}
}
return
0
;
}
static
inline
int
Kf_SetMergeOrder
(
Kf_Cut_t
*
pCut0
,
Kf_Cut_t
*
pCut1
,
Kf_Cut_t
*
pCut
,
int
nLutSize
)
{
int
nSize0
=
pCut0
->
nLeaves
;
int
nSize1
=
pCut1
->
nLeaves
;
int
*
pC0
=
pCut0
->
pLeaves
;
int
*
pC1
=
pCut1
->
pLeaves
;
int
*
pC
=
pCut
->
pLeaves
;
int
i
,
k
,
c
;
// the case of the largest cut sizes
if
(
nSize0
==
nLutSize
&&
nSize1
==
nLutSize
)
{
for
(
i
=
0
;
i
<
nSize0
;
i
++
)
{
if
(
pC0
[
i
]
!=
pC1
[
i
]
)
return
0
;
pC
[
i
]
=
pC0
[
i
];
}
pCut
->
nLeaves
=
nLutSize
;
return
1
;
}
// compare two cuts with different numbers
i
=
k
=
c
=
0
;
while
(
1
)
{
if
(
c
==
nLutSize
)
return
0
;
if
(
pC0
[
i
]
<
pC1
[
k
]
)
{
pC
[
c
++
]
=
pC0
[
i
++
];
if
(
i
>=
nSize0
)
goto
FlushCut1
;
}
else
if
(
pC0
[
i
]
>
pC1
[
k
]
)
{
pC
[
c
++
]
=
pC1
[
k
++
];
if
(
k
>=
nSize1
)
goto
FlushCut0
;
}
else
{
pC
[
c
++
]
=
pC0
[
i
++
];
k
++
;
if
(
i
>=
nSize0
)
goto
FlushCut1
;
if
(
k
>=
nSize1
)
goto
FlushCut0
;
}
}
FlushCut0:
if
(
c
+
nSize0
>
nLutSize
+
i
)
return
0
;
while
(
i
<
nSize0
)
pC
[
c
++
]
=
pC0
[
i
++
];
pCut
->
nLeaves
=
c
;
return
1
;
FlushCut1:
if
(
c
+
nSize1
>
nLutSize
+
k
)
return
0
;
while
(
k
<
nSize1
)
pC
[
c
++
]
=
pC1
[
k
++
];
pCut
->
nLeaves
=
c
;
return
1
;
}
static
inline
int
Kf_SetRemoveDuplicates2
(
Kf_Set_t
*
p
,
Kf_Cut_t
*
pCutNew
)
{
Kf_Cut_t
*
pCut
;
Kf_ListForEachCutt
(
p
,
pCutNew
->
nLeaves
,
pCut
)
if
(
pCut
->
Sign
==
pCutNew
->
Sign
&&
Kf_SetCutIsContainedOrder
(
pCut
,
pCutNew
)
)
return
1
;
return
0
;
}
static
inline
void
Kf_SetFilter2
(
Kf_Set_t
*
p
)
{
Kf_Cut_t
*
pCut0
,
*
pCut1
;
int
i
,
k
,
*
pPlace
;
assert
(
p
->
nCuts
>
0
);
for
(
i
=
0
;
i
<=
p
->
nLutSize
;
i
++
)
Kf_ListForEachCuttP
(
p
,
i
,
pCut0
,
pPlace
)
{
for
(
k
=
0
;
k
<
pCut0
->
nLeaves
;
k
++
)
Kf_ListForEachCutt
(
p
,
k
,
pCut1
)
if
(
(
pCut0
->
Sign
&
pCut1
->
Sign
)
==
pCut1
->
Sign
&&
Kf_SetCutIsContainedOrder
(
pCut0
,
pCut1
)
)
{
k
=
pCut0
->
nLeaves
+
1
;
p
->
nCuts
--
;
break
;
}
if
(
k
==
pCut0
->
nLeaves
+
1
)
// remove pCut0
*
pPlace
=
pCut0
->
iNext
;
else
pPlace
=
&
pCut0
->
iNext
;
}
assert
(
p
->
nCuts
>
0
);
}
/*
int Kf_SetComputeTruth( Kf_Man_t * p, int iFuncLit0, int iFuncLit1, int * pCut0, int * pCut1, int * pCutOut )
{
word uTruth[JF_WORD_MAX], uTruth0[JF_WORD_MAX], uTruth1[JF_WORD_MAX];
int fCompl, truthId;
int LutSize = p->pPars->nLutSize;
int nWords = Abc_Truth6WordNum(p->pPars->nLutSize);
word * pTruth0 = Vec_MemReadEntry(p->vTtMem, Abc_Lit2Var(iFuncLit0));
word * pTruth1 = Vec_MemReadEntry(p->vTtMem, Abc_Lit2Var(iFuncLit1));
Abc_TtCopy( uTruth0, pTruth0, nWords, Abc_LitIsCompl(iFuncLit0) );
Abc_TtCopy( uTruth1, pTruth1, nWords, Abc_LitIsCompl(iFuncLit1) );
Abc_TtStretch( uTruth0, LutSize, pCut0 + 1, Kf_CutSize(pCut0), pCutOut + 1, Kf_CutSize(pCutOut) );
Abc_TtStretch( uTruth1, LutSize, pCut1 + 1, Kf_CutSize(pCut1), pCutOut + 1, Kf_CutSize(pCutOut) );
fCompl = (int)(uTruth0[0] & uTruth1[0] & 1);
Abc_TtAnd( uTruth, uTruth0, uTruth1, nWords, fCompl );
pCutOut[0] = Abc_TtMinBase( uTruth, pCutOut + 1, pCutOut[0], LutSize );
assert( (uTruth[0] & 1) == 0 );
truthId = Vec_MemHashInsert(p->vTtMem, uTruth);
return Abc_Var2Lit( truthId, fCompl );
}
*/
static
inline
Kf_Cut_t
*
Kf_SetMerge2
(
Kf_Set_t
*
p
,
int
*
pCuts0
,
int
*
pCuts1
,
int
fArea
,
int
fCutMin
)
{
Kf_Cut_t
*
pCut0
,
*
pCut1
,
*
pCutR
;
Kf_SetPrepare
(
p
,
pCuts0
,
pCuts1
);
p
->
CutCount
[
0
]
+=
p
->
nCuts0
*
p
->
nCuts1
;
for
(
pCut0
=
p
->
pCuts0
;
pCut0
<
p
->
pCuts0
+
p
->
nCuts0
;
pCut0
++
)
for
(
pCut1
=
p
->
pCuts1
;
pCut1
<
p
->
pCuts1
+
p
->
nCuts1
;
pCut1
++
)
{
if
(
Kf_SetCountBits
(
pCut0
->
Sign
|
pCut1
->
Sign
)
>
p
->
nLutSize
)
continue
;
p
->
CutCount
[
1
]
++
;
pCutR
=
p
->
pCutsR
+
p
->
nCuts
;
if
(
!
Kf_SetMergeOrder
(
pCut0
,
pCut1
,
pCutR
,
p
->
nLutSize
)
)
continue
;
p
->
CutCount
[
2
]
++
;
pCutR
->
Sign
=
pCut0
->
Sign
|
pCut1
->
Sign
;
if
(
Kf_SetRemoveDuplicates2
(
p
,
pCutR
)
)
continue
;
p
->
nCuts
++
;
if
(
fCutMin
)
{
int
nOldSupp
=
pCutR
->
nLeaves
;
// pCutR->iFunc = Kf_SetComputeTruth( p, pCut0->iFunc, pCut1->iFunc, pCut0, pCut1, pCutR );
assert
(
pCutR
->
nLeaves
<=
nOldSupp
);
if
(
pCutR
->
nLeaves
<
nOldSupp
)
pCutR
->
Sign
=
Kf_SetCutGetSign
(
pCutR
);
// delay and area are inaccurate
}
assert
(
pCutR
->
nLeaves
>
1
);
pCutR
->
Delay
=
Abc_MaxInt
(
pCut0
->
Delay
,
pCut1
->
Delay
);
pCutR
->
Area
=
pCut0
->
Area
+
pCut1
->
Area
;
// add new cut
Kf_SetAddToList
(
p
,
pCutR
,
0
);
}
Kf_SetFilter2
(
p
);
p
->
CutCount
[
3
]
+=
Abc_MinInt
(
p
->
nCuts
,
p
->
nCutNum
-
1
);
return
Kf_SetSelectBest
(
p
,
fArea
,
0
);
}
/**Function*************************************************************
Synopsis [Cut operations.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static
inline
int
Kf_CutSize
(
int
*
pCut
)
{
return
pCut
[
0
];
}
static
inline
int
Kf_CutFunc
(
int
*
pCut
)
{
return
pCut
[
pCut
[
0
]
+
1
];
}
static
inline
int
Kf_CutLeaf
(
int
*
pCut
,
int
i
)
{
assert
(
i
);
return
Abc_Lit2Var
(
pCut
[
i
]);
}
static
inline
int
Kf_CutTime
(
Kf_Man_t
*
p
,
int
*
pCut
)
{
int
i
,
Time
=
0
;
for
(
i
=
1
;
i
<=
Kf_CutSize
(
pCut
);
i
++
)
Time
=
Abc_MaxInt
(
Time
,
Kf_ObjTime
(
p
,
Kf_CutLeaf
(
pCut
,
i
))
);
return
Time
+
1
;
}
static
inline
void
Kf_CutRef
(
Kf_Man_t
*
p
,
int
*
pCut
)
{
int
i
;
for
(
i
=
1
;
i
<=
Kf_CutSize
(
pCut
);
i
++
)
Gia_ObjRefIncId
(
p
->
pGia
,
Kf_CutLeaf
(
pCut
,
i
)
);
}
static
inline
void
Kf_CutDeref
(
Kf_Man_t
*
p
,
int
*
pCut
)
{
int
i
;
for
(
i
=
1
;
i
<=
Kf_CutSize
(
pCut
);
i
++
)
Gia_ObjRefDecId
(
p
->
pGia
,
Kf_CutLeaf
(
pCut
,
i
)
);
}
static
inline
void
Kf_CutPrint
(
int
*
pCut
)
{
int
i
;
printf
(
"%d {"
,
Kf_CutSize
(
pCut
)
);
for
(
i
=
1
;
i
<=
Kf_CutSize
(
pCut
);
i
++
)
printf
(
" %d"
,
Kf_CutLeaf
(
pCut
,
i
)
);
printf
(
" } Func = %d
\n
"
,
Kf_CutFunc
(
pCut
)
);
}
static
inline
void
Gia_CutPrintSetPrint
(
int
*
pCuts
)
{
int
i
,
*
pCut
;
Kf_ObjForEachCutInt
(
pCuts
,
pCut
,
i
)
Kf_CutPrint
(
pCut
);
printf
(
"
\n
"
);
}
/**Function*************************************************************
Synopsis [Computing delay/area.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int
Kf_ManComputeDelay
(
Kf_Man_t
*
p
,
int
fEval
)
{
Gia_Obj_t
*
pObj
;
int
i
,
Delay
=
0
;
if
(
fEval
)
{
Gia_ManForEachAnd
(
p
->
pGia
,
pObj
,
i
)
if
(
Gia_ObjRefNum
(
p
->
pGia
,
pObj
)
>
0
)
Vec_IntWriteEntry
(
&
p
->
vTime
,
i
,
Kf_CutTime
(
p
,
Kf_ObjCutBest
(
p
,
i
))
);
}
Gia_ManForEachCoDriver
(
p
->
pGia
,
pObj
,
i
)
{
assert
(
Gia_ObjRefNum
(
p
->
pGia
,
pObj
)
>
0
);
Delay
=
Abc_MaxInt
(
Delay
,
Kf_ObjTime
(
p
,
Gia_ObjId
(
p
->
pGia
,
pObj
))
);
}
return
Delay
;
}
int
Kf_ManComputeRefs
(
Kf_Man_t
*
p
)
{
Gia_Obj_t
*
pObj
;
float
nRefsNew
;
int
i
,
*
pCut
;
float
*
pRefs
=
Vec_FltArray
(
&
p
->
vRefs
);
float
*
pFlow
=
Vec_FltArray
(
&
p
->
vArea
);
assert
(
p
->
pGia
->
pRefs
!=
NULL
);
memset
(
p
->
pGia
->
pRefs
,
0
,
sizeof
(
int
)
*
Gia_ManObjNum
(
p
->
pGia
)
);
p
->
pPars
->
Area
=
p
->
pPars
->
Edge
=
0
;
Gia_ManForEachObjReverse
(
p
->
pGia
,
pObj
,
i
)
{
if
(
Gia_ObjIsCo
(
pObj
)
||
Gia_ObjIsBuf
(
pObj
)
)
Gia_ObjRefInc
(
p
->
pGia
,
Gia_ObjFanin0
(
pObj
)
);
else
if
(
Gia_ObjIsAnd
(
pObj
)
&&
Gia_ObjRefNum
(
p
->
pGia
,
pObj
)
>
0
)
{
pCut
=
Kf_ObjCutBest
(
p
,
i
);
Kf_CutRef
(
p
,
pCut
);
p
->
pPars
->
Edge
+=
Kf_CutSize
(
pCut
);
p
->
pPars
->
Area
++
;
}
}
// blend references and normalize flow
for
(
i
=
0
;
i
<
Gia_ManObjNum
(
p
->
pGia
);
i
++
)
{
if
(
p
->
pPars
->
fOptEdge
)
nRefsNew
=
Abc_MaxFloat
(
1
,
0
.
8
*
pRefs
[
i
]
+
0
.
2
*
p
->
pGia
->
pRefs
[
i
]
);
else
nRefsNew
=
Abc_MaxFloat
(
1
,
0
.
2
*
pRefs
[
i
]
+
0
.
8
*
p
->
pGia
->
pRefs
[
i
]
);
pFlow
[
i
]
=
pFlow
[
i
]
*
pRefs
[
i
]
/
nRefsNew
;
pRefs
[
i
]
=
nRefsNew
;
assert
(
pFlow
[
i
]
>=
0
);
}
// compute delay
p
->
pPars
->
Delay
=
Kf_ManComputeDelay
(
p
,
1
);
return
p
->
pPars
->
Area
;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
Kf_ManPrintStats
(
Kf_Man_t
*
p
,
char
*
pTitle
)
{
if
(
!
p
->
pPars
->
fVerbose
)
return
;
printf
(
"%s : "
,
pTitle
);
printf
(
"Level =%6lu "
,
p
->
pPars
->
Delay
);
printf
(
"Area =%9lu "
,
p
->
pPars
->
Area
);
printf
(
"Edge =%9lu "
,
p
->
pPars
->
Edge
);
Abc_PrintTime
(
1
,
"Time"
,
Abc_Clock
()
-
p
->
clkStart
);
fflush
(
stdout
);
}
void
Kf_ManComputeMapping
(
Kf_Man_t
*
p
)
{
Kf_Cut_t
*
pCutBest
;
Gia_Obj_t
*
pObj
;
int
i
;
if
(
p
->
pPars
->
fVerbose
)
{
printf
(
"Aig: CI = %d CO = %d AND = %d "
,
Gia_ManCiNum
(
p
->
pGia
),
Gia_ManCoNum
(
p
->
pGia
),
Gia_ManAndNum
(
p
->
pGia
)
);
printf
(
"LutSize = %d CutMax = %d Rounds = %d
\n
"
,
p
->
pPars
->
nLutSize
,
p
->
pPars
->
nCutNum
,
p
->
pPars
->
nRounds
);
printf
(
"Computing cuts...
\r
"
);
fflush
(
stdout
);
}
Gia_ManForEachObj
(
p
->
pGia
,
pObj
,
i
)
{
if
(
Gia_ObjIsCi
(
pObj
)
)
{
Kf_ManStoreStart
(
p
->
vTemp
,
0
);
Kf_ManStoreAddUnit
(
p
->
vTemp
,
i
,
0
,
0
);
assert
(
Vec_IntSize
(
p
->
vTemp
)
==
1
+
KF_ADD_ON1
+
KF_ADD_ON2
);
Kf_ObjSetCuts
(
p
,
i
,
p
->
vTemp
);
}
else
if
(
Gia_ObjIsAnd
(
pObj
)
)
{
pCutBest
=
Kf_SetMerge2
(
p
->
pSett
,
Kf_ObjCuts0
(
p
,
i
),
Kf_ObjCuts1
(
p
,
i
),
p
->
pPars
->
fAreaOnly
,
p
->
pPars
->
fCutMin
);
// pCutBest = Kf_SetMerge( p->pSett, Kf_ObjCuts0(p, i), Kf_ObjCuts1(p, i), p->pPars->fAreaOnly, p->pPars->fCutMin );
Kf_ManSaveResults
(
p
->
pSett
->
ppCuts
,
p
->
pSett
->
nCuts
,
pCutBest
,
p
->
vTemp
);
Vec_IntWriteEntry
(
&
p
->
vTime
,
i
,
pCutBest
->
Delay
+
1
);
Vec_FltWriteEntry
(
&
p
->
vArea
,
i
,
(
pCutBest
->
Area
+
1
)
/
Kf_ObjRefs
(
p
,
i
)
);
if
(
pCutBest
->
nLeaves
>
1
)
Kf_ManStoreAddUnit
(
p
->
vTemp
,
i
,
Kf_ObjTime
(
p
,
i
),
Kf_ObjArea
(
p
,
i
)
);
Kf_ObjSetCuts
(
p
,
i
,
p
->
vTemp
);
// Gia_CutPrintSetPrint( Kf_ObjCuts(p, i) );
}
}
Kf_ManComputeRefs
(
p
);
if
(
p
->
pPars
->
fVerbose
)
{
printf
(
"CutPair = %lu "
,
p
->
pSett
->
CutCount
[
0
]
);
printf
(
"Merge = %lu "
,
p
->
pSett
->
CutCount
[
1
]
);
printf
(
"Eval = %lu "
,
p
->
pSett
->
CutCount
[
2
]
);
printf
(
"Cut = %lu "
,
p
->
pSett
->
CutCount
[
3
]
);
Abc_PrintTime
(
1
,
"Time"
,
Abc_Clock
()
-
p
->
clkStart
);
printf
(
"Memory: "
);
printf
(
"Gia = %.2f MB "
,
Gia_ManMemory
(
p
->
pGia
)
/
(
1
<<
20
)
);
printf
(
"Man = %.2f MB "
,
4
.
0
*
sizeof
(
int
)
*
Gia_ManObjNum
(
p
->
pGia
)
/
(
1
<<
20
)
);
printf
(
"Cuts = %.2f MB "
,
Vec_ReportMemory
(
&
p
->
pMem
)
/
(
1
<<
20
)
);
printf
(
"Set = %.2f KB "
,
1
.
0
*
sizeof
(
Kf_Set_t
)
/
(
1
<<
10
)
);
printf
(
"
\n
"
);
fflush
(
stdout
);
Kf_ManPrintStats
(
p
,
"Start"
);
}
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
Kf_ManSetInitRefs
(
Gia_Man_t
*
p
,
Vec_Flt_t
*
vRefs
)
{
Gia_Obj_t
*
pObj
,
*
pCtrl
,
*
pData0
,
*
pData1
;
int
i
;
Vec_FltFill
(
vRefs
,
Gia_ManObjNum
(
p
),
0
);
Gia_ManForEachAnd
(
p
,
pObj
,
i
)
{
Vec_FltAddToEntry
(
vRefs
,
Gia_ObjFaninId0
(
pObj
,
i
),
1
);
Vec_FltAddToEntry
(
vRefs
,
Gia_ObjFaninId1
(
pObj
,
i
),
1
);
if
(
!
Gia_ObjIsMuxType
(
pObj
)
)
continue
;
// discount XOR/MUX
pCtrl
=
Gia_ObjRecognizeMux
(
pObj
,
&
pData1
,
&
pData0
);
Vec_FltAddToEntry
(
vRefs
,
Gia_ObjId
(
p
,
Gia_Regular
(
pCtrl
)),
-
1
);
if
(
Gia_Regular
(
pData0
)
==
Gia_Regular
(
pData1
)
)
Vec_FltAddToEntry
(
vRefs
,
Gia_ObjId
(
p
,
Gia_Regular
(
pData0
)),
-
1
);
}
Gia_ManForEachCo
(
p
,
pObj
,
i
)
Vec_FltAddToEntry
(
vRefs
,
Gia_ObjFaninId0
(
pObj
,
Gia_ObjId
(
p
,
pObj
)),
1
);
for
(
i
=
0
;
i
<
Gia_ManObjNum
(
p
);
i
++
)
Vec_FltUpdateEntry
(
vRefs
,
i
,
1
);
}
Kf_Man_t
*
Kf_ManAlloc
(
Gia_Man_t
*
pGia
,
Jf_Par_t
*
pPars
)
{
Kf_Man_t
*
p
;
int
i
;
assert
(
pPars
->
nLutSizeMax
<=
KF_LEAF_MAX
);
assert
(
pPars
->
nCutNumMax
<=
KF_NUM_MAX
);
assert
(
pPars
->
nProcNumMax
<=
KF_PROC_MAX
);
Vec_IntFreeP
(
&
pGia
->
vMapping
);
p
=
ABC_CALLOC
(
Kf_Man_t
,
1
);
p
->
clkStart
=
Abc_Clock
();
p
->
pGia
=
pGia
;
p
->
pPars
=
pPars
;
Vec_SetAlloc_
(
&
p
->
pMem
,
20
);
Vec_IntFill
(
&
p
->
vCuts
,
Gia_ManObjNum
(
pGia
),
0
);
Vec_IntFill
(
&
p
->
vTime
,
Gia_ManObjNum
(
pGia
),
0
);
Vec_FltFill
(
&
p
->
vArea
,
Gia_ManObjNum
(
pGia
),
0
);
Kf_ManSetInitRefs
(
pGia
,
&
p
->
vRefs
);
p
->
vTemp
=
Vec_IntAlloc
(
1000
);
pGia
->
pRefs
=
ABC_CALLOC
(
int
,
Gia_ManObjNum
(
pGia
)
);
// prepare cut sets
for
(
i
=
0
;
i
<
pPars
->
nProcNumMax
;
i
++
)
{
(
p
->
pSett
+
i
)
->
pMan
=
p
;
(
p
->
pSett
+
i
)
->
nLutSize
=
(
unsigned
short
)
pPars
->
nLutSize
;
(
p
->
pSett
+
i
)
->
nCutNum
=
(
unsigned
short
)
pPars
->
nCutNum
;
(
p
->
pSett
+
i
)
->
TableMask
=
(
1
<<
KF_LOG_TABLE
)
-
1
;
}
return
p
;
}
void
Kf_ManFree
(
Kf_Man_t
*
p
)
{
ABC_FREE
(
p
->
pGia
->
pRefs
);
ABC_FREE
(
p
->
vCuts
.
pArray
);
ABC_FREE
(
p
->
vTime
.
pArray
);
ABC_FREE
(
p
->
vArea
.
pArray
);
ABC_FREE
(
p
->
vRefs
.
pArray
);
Vec_IntFreeP
(
&
p
->
vTemp
);
Vec_SetFree_
(
&
p
->
pMem
);
ABC_FREE
(
p
);
}
Gia_Man_t
*
Kf_ManDerive
(
Kf_Man_t
*
p
)
{
Vec_Int_t
*
vMapping
;
Gia_Obj_t
*
pObj
;
int
i
,
k
,
*
pCut
;
assert
(
!
p
->
pPars
->
fCutMin
);
vMapping
=
Vec_IntAlloc
(
Gia_ManObjNum
(
p
->
pGia
)
+
(
int
)
p
->
pPars
->
Edge
+
(
int
)
p
->
pPars
->
Area
*
2
);
Vec_IntFill
(
vMapping
,
Gia_ManObjNum
(
p
->
pGia
),
0
);
Gia_ManForEachAnd
(
p
->
pGia
,
pObj
,
i
)
{
if
(
Gia_ObjIsBuf
(
pObj
)
||
Gia_ObjRefNum
(
p
->
pGia
,
pObj
)
==
0
)
continue
;
pCut
=
Kf_ObjCutBest
(
p
,
i
);
Vec_IntWriteEntry
(
vMapping
,
i
,
Vec_IntSize
(
vMapping
)
);
Vec_IntPush
(
vMapping
,
Kf_CutSize
(
pCut
)
);
for
(
k
=
1
;
k
<=
Kf_CutSize
(
pCut
);
k
++
)
Vec_IntPush
(
vMapping
,
Kf_CutLeaf
(
pCut
,
k
)
);
Vec_IntPush
(
vMapping
,
i
);
}
assert
(
Vec_IntCap
(
vMapping
)
==
16
||
Vec_IntSize
(
vMapping
)
==
Vec_IntCap
(
vMapping
)
);
p
->
pGia
->
vMapping
=
vMapping
;
// Gia_ManMappingVerify( p->pGia );
return
p
->
pGia
;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
Kf_ManSetDefaultPars
(
Jf_Par_t
*
pPars
)
{
memset
(
pPars
,
0
,
sizeof
(
Jf_Par_t
)
);
pPars
->
nLutSize
=
6
;
pPars
->
nCutNum
=
8
;
pPars
->
nRounds
=
1
;
pPars
->
nVerbLimit
=
5
;
pPars
->
DelayTarget
=
-
1
;
pPars
->
fAreaOnly
=
1
;
pPars
->
fOptEdge
=
1
;
pPars
->
fCoarsen
=
0
;
pPars
->
fCutMin
=
0
;
pPars
->
fFuncDsd
=
0
;
pPars
->
fGenCnf
=
0
;
pPars
->
fPureAig
=
0
;
pPars
->
fVerbose
=
0
;
pPars
->
fVeryVerbose
=
0
;
pPars
->
nLutSizeMax
=
KF_LEAF_MAX
;
pPars
->
nCutNumMax
=
KF_NUM_MAX
;
pPars
->
nProcNumMax
=
1
;
}
Gia_Man_t
*
Kf_ManPerformMapping
(
Gia_Man_t
*
pGia
,
Jf_Par_t
*
pPars
)
{
Kf_Man_t
*
p
;
Gia_Man_t
*
pNew
;
p
=
Kf_ManAlloc
(
pGia
,
pPars
);
Kf_ManComputeMapping
(
p
);
pNew
=
Kf_ManDerive
(
p
);
Kf_ManFree
(
p
);
return
pNew
;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END
src/aig/gia/module.make
View file @
ace34099
...
...
@@ -31,6 +31,7 @@ SRC += src/aig/gia/giaAig.c \
src/aig/gia/giaIso.c
\
src/aig/gia/giaIso2.c
\
src/aig/gia/giaJf.c
\
src/aig/gia/giaKf.c
\
src/aig/gia/giaMan.c
\
src/aig/gia/giaMem.c
\
src/aig/gia/giaMfs.c
\
...
...
src/base/abci/abc.c
View file @
ace34099
...
...
@@ -374,6 +374,7 @@ static int Abc_CommandAbc9If ( Abc_Frame_t * pAbc, int argc, cha
static
int
Abc_CommandAbc9Iff
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
);
static
int
Abc_CommandAbc9If2
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
);
static
int
Abc_CommandAbc9Jf
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
);
static
int
Abc_CommandAbc9Kf
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
);
static
int
Abc_CommandAbc9Struct
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
);
static
int
Abc_CommandAbc9Trace
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
);
static
int
Abc_CommandAbc9Speedup
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
);
...
...
@@ -940,6 +941,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd
(
pAbc
,
"ABC9"
,
"&iff"
,
Abc_CommandAbc9Iff
,
0
);
Cmd_CommandAdd
(
pAbc
,
"ABC9"
,
"&if2"
,
Abc_CommandAbc9If2
,
0
);
Cmd_CommandAdd
(
pAbc
,
"ABC9"
,
"&jf"
,
Abc_CommandAbc9Jf
,
0
);
Cmd_CommandAdd
(
pAbc
,
"ABC9"
,
"&kf"
,
Abc_CommandAbc9Kf
,
0
);
Cmd_CommandAdd
(
pAbc
,
"ABC9"
,
"&struct"
,
Abc_CommandAbc9Struct
,
0
);
Cmd_CommandAdd
(
pAbc
,
"ABC9"
,
"&trace"
,
Abc_CommandAbc9Trace
,
0
);
Cmd_CommandAdd
(
pAbc
,
"ABC9"
,
"&speedup"
,
Abc_CommandAbc9Speedup
,
0
);
...
...
@@ -30347,6 +30349,176 @@ usage:
return
1
;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int
Abc_CommandAbc9Kf
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
)
{
extern
void
Kf_ManSetDefaultPars
(
Jf_Par_t
*
pPars
);
extern
Gia_Man_t
*
Kf_ManPerformMapping
(
Gia_Man_t
*
pGia
,
Jf_Par_t
*
pPars
);
char
Buffer
[
200
];
Jf_Par_t
Pars
,
*
pPars
=
&
Pars
;
Gia_Man_t
*
pNew
;
int
c
;
Kf_ManSetDefaultPars
(
pPars
);
Extra_UtilGetoptReset
();
while
(
(
c
=
Extra_UtilGetopt
(
argc
,
argv
,
"KCRDWPaekmdcgvwh"
)
)
!=
EOF
)
{
switch
(
c
)
{
case
'K'
:
if
(
globalUtilOptind
>=
argc
)
{
Abc_Print
(
-
1
,
"Command line switch
\"
-K
\"
should be followed by a positive integer.
\n
"
);
goto
usage
;
}
pPars
->
nLutSize
=
atoi
(
argv
[
globalUtilOptind
]);
globalUtilOptind
++
;
if
(
pPars
->
nLutSize
<
2
||
pPars
->
nLutSize
>
pPars
->
nLutSizeMax
)
{
Abc_Print
(
-
1
,
"LUT size %d is not supported.
\n
"
,
pPars
->
nLutSize
);
goto
usage
;
}
break
;
case
'C'
:
if
(
globalUtilOptind
>=
argc
)
{
Abc_Print
(
-
1
,
"Command line switch
\"
-C
\"
should be followed by a positive integer.
\n
"
);
goto
usage
;
}
pPars
->
nCutNum
=
atoi
(
argv
[
globalUtilOptind
]);
globalUtilOptind
++
;
if
(
pPars
->
nCutNum
<
1
||
pPars
->
nCutNum
>
pPars
->
nCutNumMax
)
{
Abc_Print
(
-
1
,
"This number of cuts (%d) is not supported.
\n
"
,
pPars
->
nCutNum
);
goto
usage
;
}
break
;
case
'R'
:
if
(
globalUtilOptind
>=
argc
)
{
Abc_Print
(
-
1
,
"Command line switch
\"
-R
\"
should be followed by a positive integer.
\n
"
);
goto
usage
;
}
pPars
->
nRounds
=
atoi
(
argv
[
globalUtilOptind
]);
globalUtilOptind
++
;
if
(
pPars
->
nRounds
<
0
)
goto
usage
;
break
;
case
'D'
:
if
(
globalUtilOptind
>=
argc
)
{
Abc_Print
(
-
1
,
"Command line switch
\"
-D
\"
should be followed by a floating point number.
\n
"
);
goto
usage
;
}
pPars
->
DelayTarget
=
atoi
(
argv
[
globalUtilOptind
]);
globalUtilOptind
++
;
if
(
pPars
->
DelayTarget
<=
0
.
0
)
goto
usage
;
break
;
case
'W'
:
if
(
globalUtilOptind
>=
argc
)
{
Abc_Print
(
-
1
,
"Command line switch
\"
-W
\"
should be followed by a positive integer.
\n
"
);
goto
usage
;
}
pPars
->
nVerbLimit
=
atoi
(
argv
[
globalUtilOptind
]);
globalUtilOptind
++
;
if
(
pPars
->
nVerbLimit
<
0
)
goto
usage
;
break
;
case
'P'
:
if
(
globalUtilOptind
>=
argc
)
{
Abc_Print
(
-
1
,
"Command line switch
\"
-P
\"
should be followed by a positive integer.
\n
"
);
goto
usage
;
}
pPars
->
nProcNumMax
=
atoi
(
argv
[
globalUtilOptind
]);
globalUtilOptind
++
;
if
(
pPars
->
nProcNumMax
<
0
)
goto
usage
;
break
;
case
'a'
:
pPars
->
fAreaOnly
^=
1
;
break
;
case
'e'
:
pPars
->
fOptEdge
^=
1
;
break
;
case
'k'
:
pPars
->
fCoarsen
^=
1
;
break
;
case
'm'
:
pPars
->
fCutMin
^=
1
;
break
;
case
'd'
:
pPars
->
fFuncDsd
^=
1
;
break
;
case
'c'
:
pPars
->
fGenCnf
^=
1
;
break
;
case
'g'
:
pPars
->
fPureAig
^=
1
;
break
;
case
'v'
:
pPars
->
fVerbose
^=
1
;
break
;
case
'w'
:
pPars
->
fVeryVerbose
^=
1
;
break
;
case
'h'
:
default:
goto
usage
;
}
}
if
(
pAbc
->
pGia
==
NULL
)
{
Abc_Print
(
-
1
,
"Empty GIA network.
\n
"
);
return
1
;
}
pNew
=
Kf_ManPerformMapping
(
pAbc
->
pGia
,
pPars
);
if
(
pNew
==
NULL
)
{
Abc_Print
(
-
1
,
"Abc_CommandAbc9Kf(): Mapping into LUTs has failed.
\n
"
);
return
1
;
}
Abc_FrameUpdateGia
(
pAbc
,
pNew
);
return
0
;
usage:
if
(
pPars
->
DelayTarget
==
-
1
)
sprintf
(
Buffer
,
"best possible"
);
else
sprintf
(
Buffer
,
"%d"
,
pPars
->
DelayTarget
);
Abc_Print
(
-
2
,
"usage: &kf [-KCRDWP num] [-akmdcgvwh]
\n
"
);
Abc_Print
(
-
2
,
"
\t
performs technology mapping of the network
\n
"
);
Abc_Print
(
-
2
,
"
\t
-K num : LUT size for the mapping (2 <= K <= %d) [default = %d]
\n
"
,
pPars
->
nLutSizeMax
,
pPars
->
nLutSize
);
Abc_Print
(
-
2
,
"
\t
-C num : the max number of priority cuts (1 <= C <= %d) [default = %d]
\n
"
,
pPars
->
nCutNumMax
,
pPars
->
nCutNum
);
Abc_Print
(
-
2
,
"
\t
-R num : the number of mapping rounds [default = %d]
\n
"
,
pPars
->
nRounds
);
Abc_Print
(
-
2
,
"
\t
-D num : sets the delay constraint for the mapping [default = %s]
\n
"
,
Buffer
);
Abc_Print
(
-
2
,
"
\t
-W num : min frequency when printing functions with
\"
-w
\"
[default = %d]
\n
"
,
pPars
->
nVerbLimit
);
Abc_Print
(
-
2
,
"
\t
-P num : the number of cut computation processes [default = %d]
\n
"
,
pPars
->
nProcNumMax
);
Abc_Print
(
-
2
,
"
\t
-a : toggles area-oriented mapping [default = %s]
\n
"
,
pPars
->
fAreaOnly
?
"yes"
:
"no"
);
Abc_Print
(
-
2
,
"
\t
-e : toggles edge vs node minimization [default = %s]
\n
"
,
pPars
->
fOptEdge
?
"yes"
:
"no"
);
Abc_Print
(
-
2
,
"
\t
-k : toggles coarsening the subject graph [default = %s]
\n
"
,
pPars
->
fCoarsen
?
"yes"
:
"no"
);
Abc_Print
(
-
2
,
"
\t
-m : toggles cut minimization [default = %s]
\n
"
,
pPars
->
fCutMin
?
"yes"
:
"no"
);
Abc_Print
(
-
2
,
"
\t
-d : toggles using DSD to represent cut functions [default = %s]
\n
"
,
pPars
->
fFuncDsd
?
"yes"
:
"no"
);
Abc_Print
(
-
2
,
"
\t
-c : toggles mapping for CNF generation [default = %s]
\n
"
,
pPars
->
fGenCnf
?
"yes"
:
"no"
);
Abc_Print
(
-
2
,
"
\t
-g : toggles generating AIG without mapping [default = %s]
\n
"
,
pPars
->
fPureAig
?
"yes"
:
"no"
);
Abc_Print
(
-
2
,
"
\t
-v : toggles verbose output [default = %s]
\n
"
,
pPars
->
fVerbose
?
"yes"
:
"no"
);
Abc_Print
(
-
2
,
"
\t
-w : toggles very verbose output [default = %s]
\n
"
,
pPars
->
fVeryVerbose
?
"yes"
:
"no"
);
Abc_Print
(
-
2
,
"
\t
-h : prints the command usage
\n
"
);
return
1
;
}
/**Function*************************************************************
src/map/if/ifCache.c
View file @
ace34099
...
...
@@ -54,28 +54,6 @@ void If_ManCacheRecord( If_Man_t * p, int iDsd0, int iDsd1, int nShared, int iDs
Vec_IntPush
(
p
->
vCutData
,
iDsd
);
// printf( "%6d %6d %6d %6d\n", iDsd0, iDsd1, nShared, iDsd );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static
inline
int
Vec_IntCountUnique
(
Vec_Int_t
*
p
)
{
int
i
,
Count
=
0
,
Max
=
Vec_IntFindMax
(
p
);
unsigned
char
*
pPres
=
ABC_CALLOC
(
unsigned
char
,
Max
+
1
);
for
(
i
=
0
;
i
<
p
->
nSize
;
i
++
)
if
(
pPres
[
p
->
pArray
[
i
]]
==
0
)
pPres
[
p
->
pArray
[
i
]]
=
1
,
Count
++
;
ABC_FREE
(
pPres
);
return
Count
;
}
/**Function*************************************************************
...
...
src/misc/vec/vecFlt.h
View file @
ace34099
...
...
@@ -395,6 +395,23 @@ static inline void Vec_FltAddToEntry( Vec_Flt_t * p, int i, float Addition )
SeeAlso []
***********************************************************************/
static
inline
void
Vec_FltUpdateEntry
(
Vec_Flt_t
*
p
,
int
i
,
float
Value
)
{
if
(
Vec_FltEntry
(
p
,
i
)
<
Value
)
Vec_FltWriteEntry
(
p
,
i
,
Value
);
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static
inline
float
Vec_FltEntryLast
(
Vec_Flt_t
*
p
)
{
return
p
->
pArray
[
p
->
nSize
-
1
];
...
...
src/misc/vec/vecInt.h
View file @
ace34099
...
...
@@ -695,6 +695,12 @@ static inline void Vec_IntPush( Vec_Int_t * p, int Entry )
}
p
->
pArray
[
p
->
nSize
++
]
=
Entry
;
}
static
inline
void
Vec_IntPushArray
(
Vec_Int_t
*
p
,
int
*
pEntries
,
int
nEntries
)
{
int
i
;
for
(
i
=
0
;
i
<
nEntries
;
i
++
)
Vec_IntPush
(
p
,
pEntries
[
i
]
);
}
/**Function*************************************************************
...
...
@@ -1293,6 +1299,16 @@ static inline int Vec_IntCheckUniqueSmall( Vec_Int_t * p )
return
0
;
return
1
;
}
static
inline
int
Vec_IntCountUnique
(
Vec_Int_t
*
p
)
{
int
i
,
Count
=
0
,
Max
=
Vec_IntFindMax
(
p
);
unsigned
char
*
pPres
=
ABC_CALLOC
(
unsigned
char
,
Max
+
1
);
for
(
i
=
0
;
i
<
p
->
nSize
;
i
++
)
if
(
pPres
[
p
->
pArray
[
i
]]
==
0
)
pPres
[
p
->
pArray
[
i
]]
=
1
,
Count
++
;
ABC_FREE
(
pPres
);
return
Count
;
}
/**Function*************************************************************
...
...
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