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
38254947
Commit
38254947
authored
Dec 05, 2006
by
Alan Mishchenko
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Version abc61205
parent
52e5b91c
Show whitespace changes
Inline
Side-by-side
Showing
24 changed files
with
2215 additions
and
1867 deletions
+2215
-1867
abc.dsp
+14
-2
abc.rc
+0
-1
src/aig/ivy/ivyFactor.c
+481
-531
src/aig/ivy/ivyIsop.c
+0
-1
src/base/abc/abc.h
+0
-3
src/base/abci/abc.c
+106
-7
src/base/abci/abcIf.c
+37
-74
src/base/abci/abcMap.c
+2
-1
src/base/abci/abcMulti.c
+643
-0
src/base/abci/abcNtbdd.c
+0
-67
src/base/abci/abcRenode.c
+77
-563
src/base/abci/abcReorder.c
+100
-0
src/base/abci/abcVerify.c
+4
-2
src/base/abci/module.make
+2
-0
src/map/if/if.h
+42
-23
src/map/if/ifCore.c
+3
-3
src/map/if/ifCut.c
+557
-1
src/map/if/ifMan.c
+30
-11
src/map/if/ifMap.c
+14
-570
src/map/if/ifPrepro.c
+3
-3
src/map/if/ifReduce.c
+2
-2
src/map/if/ifSeq.c
+1
-1
src/map/if/ifTruth.c
+95
-0
src/map/if/module.make
+2
-1
No files found.
abc.dsp
View file @
38254947
...
@@ -262,6 +262,10 @@ SOURCE=.\src\base\abci\abcMiter.c
...
@@ -262,6 +262,10 @@ SOURCE=.\src\base\abci\abcMiter.c
# End Source File
# End Source File
# Begin Source File
# Begin Source File
SOURCE=.\src\base\abci\abcMulti.c
# End Source File
# Begin Source File
SOURCE=.\src\base\abci\abcMv.c
SOURCE=.\src\base\abci\abcMv.c
# End Source File
# End Source File
# Begin Source File
# Begin Source File
...
@@ -294,6 +298,10 @@ SOURCE=.\src\base\abci\abcRenode.c
...
@@ -294,6 +298,10 @@ SOURCE=.\src\base\abci\abcRenode.c
# End Source File
# End Source File
# Begin Source File
# Begin Source File
SOURCE=.\src\base\abci\abcReorder.c
# End Source File
# Begin Source File
SOURCE=.\src\base\abci\abcRestruct.c
SOURCE=.\src\base\abci\abcRestruct.c
# End Source File
# End Source File
# Begin Source File
# Begin Source File
...
@@ -1826,11 +1834,11 @@ SOURCE=.\src\map\if\ifMap.c
...
@@ -1826,11 +1834,11 @@ SOURCE=.\src\map\if\ifMap.c
# End Source File
# End Source File
# Begin Source File
# Begin Source File
SOURCE=.\src\map\if\if
Reduce
.c
SOURCE=.\src\map\if\if
Prepro
.c
# End Source File
# End Source File
# Begin Source File
# Begin Source File
SOURCE=.\src\map\if\if
Select
.c
SOURCE=.\src\map\if\if
Reduce
.c
# End Source File
# End Source File
# Begin Source File
# Begin Source File
...
@@ -1838,6 +1846,10 @@ SOURCE=.\src\map\if\ifSeq.c
...
@@ -1838,6 +1846,10 @@ SOURCE=.\src\map\if\ifSeq.c
# End Source File
# End Source File
# Begin Source File
# Begin Source File
SOURCE=.\src\map\if\ifTruth.c
# End Source File
# Begin Source File
SOURCE=.\src\map\if\ifUtil.c
SOURCE=.\src\map\if\ifUtil.c
# End Source File
# End Source File
# End Group
# End Group
...
...
abc.rc
View file @
38254947
...
@@ -30,7 +30,6 @@ alias fs fraig_sweep
...
@@ -30,7 +30,6 @@ alias fs fraig_sweep
alias fsto fraig_store
alias fsto fraig_store
alias fres fraig_restore
alias fres fraig_restore
alias ft fraig_trust
alias ft fraig_trust
alias mu renode -m
alias pex print_exdc -d
alias pex print_exdc -d
alias pf print_factor
alias pf print_factor
alias pfan print_fanio
alias pfan print_fanio
...
...
src/aig/ivy/ivyFactor.c
View file @
38254947
...
@@ -25,62 +25,45 @@
...
@@ -25,62 +25,45 @@
/// DECLARATIONS ///
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
extern
Dec_Edge_t
Dec_Factor32_rec
(
Dec_Graph_t
*
pFForm
,
Vec_Int_t
*
vCover
,
int
nVars
);
// ISOP computation fails if intermediate memory usage exceed this limit
extern
Dec_Edge_t
Dec_Factor32LF_rec
(
Dec_Graph_t
*
pFForm
,
Vec_Int_t
*
vCover
,
int
nVars
,
Vec_Int_t
*
vSimple
);
#define IVY_FACTOR_MEM_LIMIT 16*4096
extern
Dec_Edge_t
Dec_Factor32Trivial
(
Dec_Graph_t
*
pFForm
,
Vec_Int_t
*
vCover
,
int
nVars
);
extern
Dec_Edge_t
Dec_Factor32TrivialCube
(
Dec_Graph_t
*
pFForm
,
Vec_Int_t
*
vCover
,
int
nVars
,
Mvc_Cube_t
*
pCube
,
Vec_Int_t
*
vEdgeLits
);
extern
Dec_Edge_t
Dec_Factor32TrivialTree_rec
(
Dec_Graph_t
*
pFForm
,
Dec_Edge_t
*
peNodes
,
int
nNodes
,
int
fNodeOr
);
extern
Vec_Int_t
*
Dec_Factor32Divisor
(
Vec_Int_t
*
vCover
,
int
nVars
);
extern
void
Dec_Factor32DivisorZeroKernel
(
Vec_Int_t
*
vCover
,
int
nVars
);
extern
int
Dec_Factor32WorstLiteral
(
Vec_Int_t
*
vCover
,
int
nVars
);
extern
Vec_Int_t
*
Mvc_CoverCommonCubeCover
(
Vec_Int_t
*
vCover
);
// intermediate ISOP representation
typedef
struct
Ivy_Sop_t_
Ivy_Sop_t
;
struct
Ivy_Sop_t_
{
unsigned
*
uCubes
;
int
nCubes
;
};
static
inline
int
Ivy_CubeHasLit
(
unsigned
uCube
,
int
i
)
{
return
(
uCube
&
(
unsigned
)(
1
<<
i
))
>
0
;}
static
inline
unsigned
Ivy_CubeSetLit
(
unsigned
uCube
,
int
i
)
{
return
uCube
|
(
unsigned
)(
1
<<
i
);
}
static
inline
unsigned
Ivy_CubeXorLit
(
unsigned
uCube
,
int
i
)
{
return
uCube
^
(
unsigned
)(
1
<<
i
);
}
static
inline
unsigned
Ivy_CubeRemLit
(
unsigned
uCube
,
int
i
)
{
return
uCube
&
~
(
unsigned
)(
1
<<
i
);
}
////////////////////////////////////////////////////////////////////////
static
inline
int
Ivy_CubeContains
(
unsigned
uLarge
,
unsigned
uSmall
)
{
return
(
uLarge
&
uSmall
)
==
uSmall
;
}
/// FUNCTION DEFINITIONS ///
static
inline
unsigned
Ivy_CubeSharp
(
unsigned
uCube
,
unsigned
uPart
)
{
return
uCube
&
~
uPart
;
}
////////////////////////////////////////////////////////////////////////
static
inline
unsigned
Ivy_CubeMask
(
int
nVar
)
{
return
(
~
(
unsigned
)
0
)
>>
(
32
-
nVar
);
}
/**Function*************************************************************
static
inline
int
Ivy_CubeIsMarked
(
unsigned
uCube
)
{
return
Ivy_CubeHasLit
(
uCube
,
31
);
}
static
inline
void
Ivy_CubeMark
(
unsigned
uCube
)
{
Ivy_CubeSetLit
(
uCube
,
31
);
}
static
inline
void
Ivy_CubeUnmark
(
unsigned
uCube
)
{
Ivy_CubeRemLit
(
uCube
,
31
);
}
Synopsis [Factors the cover.]
static
inline
int
Ivy_SopCubeNum
(
Ivy_Sop_t
*
cSop
)
{
return
cSop
->
nCubes
;
}
static
inline
unsigned
Ivy_SopCube
(
Ivy_Sop_t
*
cSop
,
int
i
)
{
return
cSop
->
uCubes
[
i
];
}
static
inline
void
Ivy_SopAddCube
(
Ivy_Sop_t
*
cSop
,
unsigned
uCube
)
{
cSop
->
uCubes
[
cSop
->
nCubes
++
]
=
uCube
;
}
static
inline
void
Ivy_SopSetCube
(
Ivy_Sop_t
*
cSop
,
unsigned
uCube
,
int
i
)
{
cSop
->
uCubes
[
i
]
=
uCube
;
}
static
inline
void
Ivy_SopShrink
(
Ivy_Sop_t
*
cSop
,
int
nCubesNew
)
{
cSop
->
nCubes
=
nCubesNew
;
}
Description []
// iterators
#define Ivy_SopForEachCube( cSop, uCube, i ) \
SideEffects []
for ( i = 0; (i < Ivy_SopCubeNum(cSop)) && ((uCube) = Ivy_SopCube(cSop, i)); i++ )
#define Ivy_CubeForEachLiteral( uCube, Lit, nLits, i ) \
SeeAlso []
for ( i = 0; (i < (nLits)) && ((Lit) = Ivy_CubeHasLit(uCube, i)); i++ )
***********************************************************************/
Dec_Graph_t
*
Dec_Factor32
(
Vec_Int_t
*
vCover
,
int
nVars
)
{
Dec_Graph_t
*
pFForm
;
Dec_Edge_t
eRoot
;
// check for trivial functions
if
(
Vec_IntSize
(
vCover
)
==
0
)
return
Dec_GraphCreateConst0
();
if
(
Vec_IntSize
(
vCover
)
==
1
&&
/* tautology */
)
return
Dec_GraphCreateConst1
();
// perform CST
Mvc_CoverInverse
(
vCover
);
// CST
// start the factored form
pFForm
=
Dec_GraphCreate
(
Abc_SopGetVarNum
(
pSop
)
);
// factor the cover
eRoot
=
Dec_Factor32_rec
(
pFForm
,
vCover
,
nVars
);
// finalize the factored form
Dec_GraphSetRoot
(
pFForm
,
eRoot
);
// verify the factored form
// if ( !Dec_Factor32Verify( pSop, pFForm ) )
// printf( "Verification has failed.\n" );
// Mvc_CoverInverse( vCover ); // undo CST
return
pFForm
;
}
/**Function*************************************************************
/**Function*************************************************************
Synopsis [
Internal recursive factoring procedur
e.]
Synopsis [
Divides cover by one cub
e.]
Description []
Description []
...
@@ -89,78 +72,31 @@ Dec_Graph_t * Dec_Factor32( Vec_Int_t * vCover, int nVars )
...
@@ -89,78 +72,31 @@ Dec_Graph_t * Dec_Factor32( Vec_Int_t * vCover, int nVars )
SeeAlso []
SeeAlso []
***********************************************************************/
***********************************************************************/
Dec_Edge_t
Dec_Factor32_rec
(
Dec_Graph_t
*
pFForm
,
Vec_Int_t
*
vCover
,
int
nVars
)
void
Ivy_SopDivideByCube
(
Vec_Int_t
*
vStore
,
int
nVars
,
Ivy_Sop_t
*
cSop
,
Ivy_Sop_t
*
cDiv
,
Ivy_Sop_t
*
vQuo
,
Ivy_Sop_t
*
vRem
)
{
{
Vec_Int_t
*
vDiv
,
*
vQuo
,
*
vRem
,
*
vCom
;
unsigned
uCube
,
uDiv
;
Dec_Edge_t
eNodeDiv
,
eNodeQuo
,
eNodeRem
;
int
i
;
Dec_Edge_t
eNodeAnd
,
eNode
;
// get the only cube
assert
(
Ivy_SopCubeNum
(
cDiv
)
==
1
);
// make sure the cover contains some cubes
uDiv
=
Ivy_SopCube
(
cDiv
,
0
);
assert
(
Vec_IntSize
(
vCover
)
);
// allocate covers
vQuo
->
nCubes
=
0
;
// get the divisor
vQuo
->
uCubes
=
Vec_IntFetch
(
vStore
,
Ivy_SopCubeNum
(
cSop
)
);
vDiv
=
Dec_Factor32Divisor
(
vCover
,
nVars
);
vRem
->
nCubes
=
0
;
if
(
vDiv
==
NULL
)
vRem
->
uCubes
=
Vec_IntFetch
(
vStore
,
Ivy_SopCubeNum
(
cSop
)
);
return
Dec_Factor32Trivial
(
pFForm
,
vCover
,
nVars
);
// sort the cubes
Ivy_SopForEachCube
(
cSop
,
uCube
,
i
)
// divide the cover by the divisor
Mvc_CoverDivideInternal
(
vCover
,
nVars
,
vDiv
,
&
vQuo
,
&
vRem
);
assert
(
Vec_IntSize
(
vQuo
)
);
Vec_IntFree
(
vDiv
);
Vec_IntFree
(
vRem
);
// check the trivial case
if
(
Vec_IntSize
(
vQuo
)
==
1
)
{
eNode
=
Dec_Factor32LF_rec
(
pFForm
,
vCover
,
nVars
,
vQuo
);
Vec_IntFree
(
vQuo
);
return
eNode
;
}
// make the quotient cube free
Mvc_CoverMakeCubeFree
(
vQuo
);
// divide the cover by the quotient
Mvc_CoverDivideInternal
(
vCover
,
nVars
,
vQuo
,
&
vDiv
,
&
vRem
);
// check the trivial case
if
(
Mvc_CoverIsCubeFree
(
vDiv
)
)
{
eNodeDiv
=
Dec_Factor32_rec
(
pFForm
,
vDiv
);
eNodeQuo
=
Dec_Factor32_rec
(
pFForm
,
vQuo
);
Vec_IntFree
(
vDiv
);
Vec_IntFree
(
vQuo
);
eNodeAnd
=
Dec_GraphAddNodeAnd
(
pFForm
,
eNodeDiv
,
eNodeQuo
);
if
(
Vec_IntSize
(
vRem
)
==
0
)
{
{
Vec_IntFree
(
vRem
);
if
(
Ivy_CubeContains
(
uCube
,
uDiv
)
)
return
eNodeAnd
;
Ivy_SopAddCube
(
vQuo
,
Ivy_CubeSharp
(
uCube
,
uDiv
)
);
}
else
else
{
Ivy_SopAddCube
(
vRem
,
uCube
);
eNodeRem
=
Dec_Factor32_rec
(
pFForm
,
vRem
);
Vec_IntFree
(
vRem
);
return
Dec_GraphAddNodeOr
(
pFForm
,
eNodeAnd
,
eNodeRem
);
}
}
}
// get the common cube
vCom
=
Mvc_CoverCommonCubeCover
(
vDiv
);
Vec_IntFree
(
vDiv
);
Vec_IntFree
(
vQuo
);
Vec_IntFree
(
vRem
);
// solve the simple problem
eNode
=
Dec_Factor32LF_rec
(
pFForm
,
vCover
,
nVars
,
vCom
);
Vec_IntFree
(
vCom
);
return
eNode
;
}
}
/**Function*************************************************************
/**Function*************************************************************
Synopsis [
Internal recursive factoring procedure for the leaf cas
e.]
Synopsis [
Divides cover by one cub
e.]
Description []
Description []
...
@@ -169,101 +105,107 @@ Dec_Edge_t Dec_Factor32_rec( Dec_Graph_t * pFForm, Vec_Int_t * vCover, int nVars
...
@@ -169,101 +105,107 @@ Dec_Edge_t Dec_Factor32_rec( Dec_Graph_t * pFForm, Vec_Int_t * vCover, int nVars
SeeAlso []
SeeAlso []
***********************************************************************/
***********************************************************************/
Dec_Edge_t
Dec_Factor32LF_rec
(
Dec_Graph_t
*
pFForm
,
Vec_Int_t
*
vCover
,
int
nVars
,
Vec_Int_t
*
vSimple
)
void
Ivy_SopDivideInternal
(
Vec_Int_t
*
vStore
,
int
nVars
,
Ivy_Sop_t
*
cSop
,
Ivy_Sop_t
*
cDiv
,
Ivy_Sop_t
*
vQuo
,
Ivy_Sop_t
*
vRem
)
{
{
Dec_Man_t
*
pManDec
=
Abc_FrameReadManDec
();
unsigned
uCube
,
uCube2
,
uDiv
,
uDiv2
,
uQuo
;
Vec_Int_t
*
vEdgeLits
=
pManDec
->
vLits
;
int
i
,
i2
,
k
,
k2
;
Vec_Int_t
*
vDiv
,
*
vQuo
,
*
vRem
;
assert
(
Ivy_SopCubeNum
(
cSop
)
>=
Ivy_SopCubeNum
(
cDiv
)
);
Dec_Edge_t
eNodeDiv
,
eNodeQuo
,
eNodeRem
;
if
(
Ivy_SopCubeNum
(
cDiv
)
==
1
)
Dec_Edge_t
eNodeAnd
;
// get the most often occurring literal
vDiv
=
Mvc_CoverBestLiteralCover
(
vCover
,
nVars
,
vSimple
);
// divide the cover by the literal
Mvc_CoverDivideByLiteral
(
vCover
,
nVars
,
vDiv
,
&
vQuo
,
&
vRem
);
// get the node pointer for the literal
eNodeDiv
=
Dec_Factor32TrivialCube
(
pFForm
,
vDiv
,
Mvc_CoverReadCubeHead
(
vDiv
),
vEdgeLits
);
Vec_IntFree
(
vDiv
);
// factor the quotient and remainder
eNodeQuo
=
Dec_Factor32_rec
(
pFForm
,
vQuo
);
Vec_IntFree
(
vQuo
);
eNodeAnd
=
Dec_GraphAddNodeAnd
(
pFForm
,
eNodeDiv
,
eNodeQuo
);
if
(
Vec_IntSize
(
vRem
)
==
0
)
{
{
Vec_IntFree
(
vRem
);
Ivy_SopDivideByCube
(
cSop
,
cDiv
,
vQuo
,
vRem
);
return
eNodeAnd
;
return
;
}
}
else
// allocate quotient
vQuo
->
nCubes
=
0
;
vQuo
->
uCubes
=
Vec_IntFetch
(
vStore
,
Ivy_SopCubeNum
(
cSop
)
/
Ivy_SopCubeNum
(
cDiv
)
);
// for each cube of the cover
// it either belongs to the quotient or to the remainder
Ivy_SopForEachCube
(
cSop
,
uCube
,
i
)
{
{
eNodeRem
=
Dec_Factor32_rec
(
pFForm
,
vRem
);
// skip taken cubes
Vec_IntFree
(
vRem
);
if
(
Ivy_CubeIsMarked
(
uCube
)
)
return
Dec_GraphAddNodeOr
(
pFForm
,
eNodeAnd
,
eNodeRem
);
continue
;
// mark the cube
Ivy_SopSetCube
(
cSop
,
Ivy_CubeMark
(
uCube
),
i
);
// find a matching cube in the divisor
Ivy_SopForEachCube
(
cDiv
,
uDiv
,
k
)
if
(
Ivy_CubeContains
(
uCube
,
uDiv
)
)
break
;
// the case when the cube is not found
// (later we will add marked cubes to the remainder)
if
(
k
==
Ivy_SopCubeNum
(
cDiv
)
)
continue
;
// if the quotient cube exist, it will be
uQuo
=
Ivy_CubeSharp
(
uCube
,
uDiv
);
// try to find other cubes of the divisor
Ivy_SopForEachCube
(
cDiv
,
uDiv2
,
k2
)
{
if
(
k2
==
k
)
continue
;
// find a matching cube
Ivy_SopForEachCube
(
cSop
,
uCube2
,
i2
)
{
// skip taken cubes
if
(
Ivy_CubeIsMarked
(
uCube2
)
)
continue
;
// check if the cube can be used
if
(
Ivy_CubeContains
(
uCube2
,
uDiv2
)
&&
uQuo
==
Ivy_CubeSharp
(
uCube2
,
uDiv2
)
)
break
;
}
}
}
// the case when the cube is not found
if
(
i2
==
Ivy_SopCubeNum
(
cSop
)
)
break
;
// the case when the cube is found - mark it and keep going
/**Function*************************************************************
Ivy_SopSetCube
(
cSop
,
Ivy_CubeMark
(
uCube2
),
i2
);
}
Synopsis [Factoring the cover, which has no algebraic divisors.]
// if we did not find some cube, continue
// (later we will add marked cubes to the remainder)
Description []
if
(
k2
!=
Ivy_SopCubeNum
(
cDiv
)
)
continue
;
SideEffects []
// we found all cubes - add the quotient cube
Ivy_SopAddCube
(
vQuo
,
uQuo
);
SeeAlso []
}
// allocate remainder
***********************************************************************/
vRem
->
nCubes
=
0
;
Dec_Edge_t
Dec_Factor32Trivial
(
Dec_Graph_t
*
pFForm
,
Vec_Int_t
*
vCover
,
int
nVars
)
vRem
->
uCubes
=
Vec_IntFetch
(
vStore
,
Ivy_SopCubeNum
(
cSop
)
-
Ivy_SopCubeNum
(
vQuo
)
*
Ivy_SopCubeNum
(
cDiv
)
);
{
// finally add the remaining cubes to the remainder
Dec_Man_t
*
pManDec
=
Abc_FrameReadManDec
();
// and clean the marked cubes in the cover
Vec_Int_t
*
vEdgeCubes
=
pManDec
->
vCubes
;
Ivy_SopForEachCube
(
cSop
,
uCube
,
i
)
Vec_Int_t
*
vEdgeLits
=
pManDec
->
vLits
;
Mvc_Manager_t
*
pMem
=
pManDec
->
pMvcMem
;
Dec_Edge_t
eNode
;
Mvc_Cube_t
*
pCube
;
int
i
;
// create the factored form for each cube
Vec_IntClear
(
vEdgeCubes
);
Mvc_CoverForEachCube
(
vCover
,
pCube
)
{
{
eNode
=
Dec_Factor32TrivialCube
(
pFForm
,
vCover
,
nVars
,
pCube
,
vEdgeLits
);
if
(
!
Ivy_CubeIsMarked
(
uCube
)
)
Vec_IntPush
(
vEdgeCubes
,
Dec_EdgeToInt_
(
eNode
)
);
continue
;
Ivy_SopSetCube
(
cSop
,
Ivy_CubeUnmark
(
uCube
),
i
);
Ivy_SopAddCube
(
vRem
,
Ivy_CubeUnmark
(
uCube
)
);
}
}
// balance the factored forms
return
Dec_Factor32TrivialTree_rec
(
pFForm
,
(
Dec_Edge_t
*
)
vEdgeCubes
->
pArray
,
vEdgeCubes
->
nSize
,
1
);
}
}
/**Function*************************************************************
/**Function*************************************************************
Synopsis [
Factoring the cube
.]
Synopsis [
Derives the quotient of division by literal
.]
Description []
Description [Reduces the cover to be the equal to the result of
division of the given cover by the literal.]
SideEffects []
SideEffects []
SeeAlso []
SeeAlso []
***********************************************************************/
***********************************************************************/
Dec_Edge_t
Dec_Factor32TrivialCube
(
Dec_Graph_t
*
pFForm
,
Vec_Int_t
*
vCover
,
Mvc_Cube_t
*
pCube
,
int
nVars
,
Vec_Int_t
*
vEdgeLits
)
void
Ivy_SopDivideByLiteralQuo
(
Ivy_Sop_t
*
cSop
,
int
iLit
)
{
{
Dec_Edge_t
eNode
;
unsigned
uCube
;
int
iBit
,
Value
;
int
i
,
k
=
0
;
// create the factored form for each literal
Ivy_SopForEachCube
(
cSop
,
uCube
,
i
)
Vec_IntClear
(
vEdgeLits
);
Mvc_CubeForEachBit
(
vCover
,
pCube
,
iBit
,
Value
)
if
(
Value
)
{
{
eNode
=
Dec_EdgeCreate
(
iBit
/
2
,
iBit
%
2
);
// CST
if
(
Ivy_CubeHasLit
(
uCube
,
iLit
)
)
Vec_IntPush
(
vEdgeLits
,
Dec_EdgeToInt_
(
eNode
)
);
Ivy_SopSetCube
(
cSop
,
Ivy_CubeRemLit
(
uCube
,
iLit
),
k
++
);
}
}
// balance the factored forms
Ivy_SopShrink
(
cSop
,
k
);
return
Dec_Factor32TrivialTree_rec
(
pFForm
,
(
Dec_Edge_t
*
)
vEdgeLits
->
pArray
,
vEdgeLits
->
nSize
,
0
);
}
}
/**Function*************************************************************
/**Function*************************************************************
Synopsis [
Create the well-balanced tree of nodes.
]
Synopsis []
Description []
Description []
...
@@ -272,90 +214,71 @@ Dec_Edge_t Dec_Factor32TrivialCube( Dec_Graph_t * pFForm, Vec_Int_t * vCover, Mv
...
@@ -272,90 +214,71 @@ Dec_Edge_t Dec_Factor32TrivialCube( Dec_Graph_t * pFForm, Vec_Int_t * vCover, Mv
SeeAlso []
SeeAlso []
***********************************************************************/
***********************************************************************/
Dec_Edge_t
Dec_Factor32TrivialTree_rec
(
Dec_Graph_t
*
pFForm
,
Dec_Edge_t
*
peNodes
,
int
nNodes
,
int
fNodeOr
)
void
Ivy_SopCommonCubeCover
(
Ivy_Sop_t
*
cSop
,
Ivy_Sop_t
*
vCommon
,
Vec_Int_t
*
vStore
)
{
{
Dec_Edge_t
eNode1
,
eNode2
;
unsigned
uTemp
,
uCube
;
int
nNodes1
,
nNodes2
;
int
i
;
uCube
=
~
(
unsigned
)
0
;
if
(
nNodes
==
1
)
Ivy_SopForEachCube
(
cSop
,
uTemp
,
i
)
return
peNodes
[
0
];
uCube
&=
uTemp
;
vCommon
->
nCubes
=
0
;
// split the nodes into two parts
vCommon
->
uCubes
=
Vec_IntFetch
(
vStore
,
1
);
nNodes1
=
nNodes
/
2
;
Ivy_SopPush
(
vCommon
,
uCube
);
nNodes2
=
nNodes
-
nNodes1
;
// nNodes2 = nNodes/2;
// nNodes1 = nNodes - nNodes2;
// recursively construct the tree for the parts
eNode1
=
Dec_Factor32TrivialTree_rec
(
pFForm
,
peNodes
,
nNodes1
,
fNodeOr
);
eNode2
=
Dec_Factor32TrivialTree_rec
(
pFForm
,
peNodes
+
nNodes1
,
nNodes2
,
fNodeOr
);
if
(
fNodeOr
)
return
Dec_GraphAddNodeOr
(
pFForm
,
eNode1
,
eNode2
);
else
return
Dec_GraphAddNodeAnd
(
pFForm
,
eNode1
,
eNode2
);
}
}
/**Function*************************************************************
/**Function*************************************************************
Synopsis [
Returns the quick divisor of the cover.
]
Synopsis []
Description [Returns NULL, if there is not divisor other than
Description []
trivial.]
SideEffects []
SideEffects []
SeeAlso []
SeeAlso []
***********************************************************************/
***********************************************************************/
Vec_Int_t
*
Dec_Factor32Divisor
(
Vec_Int_t
*
vCover
,
int
nVars
)
void
Ivy_SopCreateInverse
(
Ivy_Sop_t
*
cSop
,
Vec_Int_t
*
vInput
,
int
nVars
,
Vec_Int_t
*
vStore
)
{
{
Vec_Int_t
*
pKernel
;
unsigned
uCube
,
uMask
;
if
(
Vec_IntSize
(
vCover
)
<=
1
)
int
i
;
return
NULL
;
// start the cover
// allocate the literal array and count literals
cSop
->
nCubes
=
0
;
if
(
Mvc_CoverAnyLiteral
(
vCover
,
NULL
)
==
-
1
)
cSop
->
uCubes
=
Vec_IntFetch
(
vStore
,
Vec_IntSize
(
vInput
)
);
return
NULL
;
// add the cubes
// duplicate the cover
uMask
=
Ivy_CubeMask
(
nVars
);
pKernel
=
Mvc_CoverDup
(
vCover
);
Vec_IntForEachEntry
(
vInput
,
uCube
,
i
)
// perform the kerneling
Vec_IntPush
(
cSop
,
Ivy_CubeSharp
(
uMask
,
uCube
)
);
Dec_Factor32DivisorZeroKernel
(
pKernel
);
assert
(
Vec_IntSize
(
pKernel
)
);
return
pKernel
;
}
}
/**Function*************************************************************
/**Function*************************************************************
Synopsis [
Computes a level-zero kernel.
]
Synopsis []
Description [
Modifies the cover to contain one level-zero kernel.
]
Description []
SideEffects []
SideEffects []
SeeAlso []
SeeAlso []
***********************************************************************/
***********************************************************************/
void
Dec_Factor32DivisorZeroKernel
(
Vec_Int_t
*
vCover
,
int
nVars
)
void
Ivy_SopDup
(
Ivy_Sop_t
*
cSop
,
Ivy_Sop_t
*
vCopy
,
Vec_Int_t
*
vStore
)
{
{
int
iLit
;
unsigned
uCube
;
// find any literal that occurs at least two times
int
i
;
// iLit = Mvc_CoverAnyLiteral( vCover, NULL );
// start the cover
iLit
=
Dec_Factor32WorstLiteral
(
vCover
,
NULL
);
vCopy
->
nCubes
=
0
;
// iLit = Mvc_CoverBestLiteral( vCover, NULL );
vCopy
->
uCubes
=
Vec_IntFetch
(
vStore
,
Vec_IntSize
(
cSop
)
);
if
(
iLit
==
-
1
)
// add the cubes
return
;
Ivy_SopForEachCube
(
cSop
,
uTemp
,
i
)
// derive the cube-free quotient
Ivy_SopPush
(
vCopy
,
uTemp
);
Mvc_CoverDivideByLiteralQuo
(
vCover
,
iLit
);
// the same cover
Mvc_CoverMakeCubeFree
(
vCover
);
// the same cover
// call recursively
Dec_Factor32DivisorZeroKernel
(
vCover
);
// the same cover
}
}
/**Function*************************************************************
/**Function*************************************************************
Synopsis [Find the
mo
st often occurring literal.]
Synopsis [Find the
lea
st often occurring literal.]
Description [Find the
mo
st often occurring literal among those
Description [Find the
lea
st often occurring literal among those
that occur more than once.]
that occur more than once.]
SideEffects []
SideEffects []
...
@@ -363,31 +286,26 @@ void Dec_Factor32DivisorZeroKernel( Vec_Int_t * vCover, int nVars )
...
@@ -363,31 +286,26 @@ void Dec_Factor32DivisorZeroKernel( Vec_Int_t * vCover, int nVars )
SeeAlso []
SeeAlso []
***********************************************************************/
***********************************************************************/
int
Dec_Factor32WorstLiteral
(
Vec_Int_t
*
vCover
,
int
nVar
s
)
int
Ivy_SopWorstLiteral
(
Ivy_Sop_t
*
cSop
,
int
nLit
s
)
{
{
Mvc_Cube_t
*
p
Cube
;
unsigned
u
Cube
;
int
nWord
,
nBit
;
int
nWord
,
nBit
;
int
i
,
iMin
,
nLitsMin
,
nLitsCur
;
int
i
,
k
,
iMin
,
nLitsMin
,
nLitsCur
;
int
fUseFirst
=
1
;
int
fUseFirst
=
1
;
// go through each literal
// go through each literal
iMin
=
-
1
;
iMin
=
-
1
;
nLitsMin
=
1000000
;
nLitsMin
=
1000000
;
for
(
i
=
0
;
i
<
vCover
->
nB
its
;
i
++
)
for
(
i
=
0
;
i
<
nL
its
;
i
++
)
{
{
// get the word and bit of this literal
nWord
=
Mvc_CubeWhichWord
(
i
);
nBit
=
Mvc_CubeWhichBit
(
i
);
// go through all the cubes
// go through all the cubes
nLitsCur
=
0
;
nLitsCur
=
0
;
Mvc_CoverForEachCube
(
vCover
,
pCube
)
Ivy_SopForEachCube
(
cSop
,
uCube
,
k
)
if
(
pCube
->
pData
[
nWord
]
&
(
1
<<
nBit
)
)
if
(
Ivy_CubeHasLit
(
uCube
,
i
)
)
nLitsCur
++
;
nLitsCur
++
;
// skip the literal that does not occur or occurs once
// skip the literal that does not occur or occurs once
if
(
nLitsCur
<
2
)
if
(
nLitsCur
<
2
)
continue
;
continue
;
// check if this is the best literal
// check if this is the best literal
if
(
fUseFirst
)
if
(
fUseFirst
)
{
{
...
@@ -406,69 +324,108 @@ int Dec_Factor32WorstLiteral( Vec_Int_t * vCover, int nVars )
...
@@ -406,69 +324,108 @@ int Dec_Factor32WorstLiteral( Vec_Int_t * vCover, int nVars )
}
}
}
}
}
}
if
(
nLitsMin
<
1000000
)
if
(
nLitsMin
<
1000000
)
return
iMin
;
return
iMin
;
return
-
1
;
return
-
1
;
}
}
/**Function*************************************************************
/**Function*************************************************************
Synopsis []
Synopsis [
Computes a level-zero kernel.
]
Description []
Description [
Modifies the cover to contain one level-zero kernel.
]
SideEffects []
SideEffects []
SeeAlso []
SeeAlso []
***********************************************************************/
***********************************************************************/
Vec_Int_t
*
Mvc_CoverCommonCubeCover
(
Vec_Int_t
*
vCover
)
void
Ivy_SopMakeCubeFree
(
Ivy_Sop_t
*
cSop
)
{
{
Vec_Int_t
*
vRes
;
unsigned
uMask
;
unsigned
uTemp
,
uCube
;
int
i
;
int
i
;
uCube
=
~
(
unsigned
)
0
;
assert
(
Ivy_SopCubeNum
(
cSop
)
>
0
);
Vec_IntForEachEntry
(
vCover
,
uTemp
,
i
)
// find the common cube
uCube
&=
uTemp
;
uMask
=
~
(
unsigned
)
0
;
vRes
=
Vec_IntAlloc
(
1
);
Ivy_SopForEachCube
(
cSop
,
uCube
,
i
)
Vec_IntPush
(
vRes
,
uCube
);
uMask
&=
uCube
;
return
vRes
;
if
(
uMask
==
0
)
return
;
// remove the common cube
Ivy_SopForEachCube
(
cSop
,
uCube
,
i
)
Ivy_SopSetCube
(
cSop
,
Ivy_CubeSharp
(
uCube
,
uMask
),
i
);
}
}
/**Function*************************************************************
/**Function*************************************************************
Synopsis [
Returns 1 if the support of cover2 is contained in the support of cover1
.]
Synopsis [
Computes a level-zero kernel
.]
Description []
Description [
Modifies the cover to contain one level-zero kernel.
]
SideEffects []
SideEffects []
SeeAlso []
SeeAlso []
***********************************************************************/
***********************************************************************/
int
Mvc_CoverCheckSuppContainment
(
Vec_Int_t
*
vCover1
,
Vec_Int_t
*
vCover2
)
void
Ivy_SopDivisorZeroKernel_rec
(
Ivy_Sop_t
*
cSop
,
int
nLits
)
{
{
unsigned
uTemp
,
uSupp1
,
uSupp2
;
int
iLit
;
int
i
;
// find any literal that occurs at least two times
// set the supports
iLit
=
Ivy_SopWorstLiteral
(
cSop
,
nLits
);
uSupp1
=
0
;
if
(
iLit
==
-
1
)
Vec_IntForEachEntry
(
vCover1
,
uTemp
,
i
)
return
;
uSupp1
|=
uTemp
;
// derive the cube-free quotient
uSupp2
=
0
;
Ivy_SopDivideByLiteralQuo
(
cSop
,
iLit
);
// the same cover
Vec_IntForEachEntry
(
vCover2
,
uTemp
,
i
)
Ivy_SopMakeCubeFree
(
cSop
);
// the same cover
uSupp2
|=
uTemp
;
// call recursively
// return containment
Ivy_SopDivisorZeroKernel_rec
(
cSop
);
// the same cover
return
uSupp1
&
!
uSupp2
;
// Mvc_CubeBitNotImpl( Result, vCover2->pMask, vCover1->pMask );
// return !Result;
}
}
/**Function*************************************************************
Synopsis [Returns the quick divisor of the cover.]
Description [Returns NULL, if there is not divisor other than
trivial.]
SideEffects []
SeeAlso []
***********************************************************************/
int
Ivy_SopDivisor
(
Ivy_Sop_t
*
cSop
,
int
nLits
,
Ivy_Sop_t
*
cDiv
,
Vec_Int_t
*
vStore
)
{
if
(
Ivy_SopCubeNum
(
cSop
)
<=
1
)
return
0
;
if
(
Ivy_SopWorstLiteral
(
cSop
,
nLits
)
==
-
1
)
return
0
;
// duplicate the cover
Ivy_SopDup
(
cSop
,
cDiv
,
vStore
);
// perform the kerneling
Ivy_SopDivisorZeroKernel_rec
(
cDiv
,
int
nLits
);
assert
(
Ivy_SopCubeNum
(
cDiv
)
>
0
);
return
1
;
}
extern
Dec_Edge_t
Dec_Factor32_rec
(
Dec_Graph_t
*
pFForm
,
Vec_Int_t
*
cSop
,
int
nVars
);
extern
Dec_Edge_t
Dec_Factor32LF_rec
(
Dec_Graph_t
*
pFForm
,
Vec_Int_t
*
cSop
,
int
nVars
,
Vec_Int_t
*
vSimple
);
extern
Dec_Edge_t
Dec_Factor32Trivial
(
Dec_Graph_t
*
pFForm
,
Vec_Int_t
*
cSop
,
int
nVars
);
extern
Dec_Edge_t
Dec_Factor32TrivialCube
(
Dec_Graph_t
*
pFForm
,
Vec_Int_t
*
cSop
,
int
nVars
,
unsigned
uCube
,
Vec_Int_t
*
vEdgeLits
);
extern
Dec_Edge_t
Dec_Factor32TrivialTree_rec
(
Dec_Graph_t
*
pFForm
,
Dec_Edge_t
*
peNodes
,
int
nNodes
,
int
fNodeOr
);
extern
int
Dec_Factor32Verify
(
Vec_Int_t
*
cSop
,
Dec_Graph_t
*
pFForm
)
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
/**Function*************************************************************
Synopsis []
Synopsis [
Factors the cover.
]
Description []
Description []
...
@@ -477,32 +434,44 @@ int Mvc_CoverCheckSuppContainment( Vec_Int_t * vCover1, Vec_Int_t * vCover2 )
...
@@ -477,32 +434,44 @@ int Mvc_CoverCheckSuppContainment( Vec_Int_t * vCover1, Vec_Int_t * vCover2 )
SeeAlso []
SeeAlso []
***********************************************************************/
***********************************************************************/
void
Mvc_CoverDivide
(
Vec_Int_t
*
vCover
,
Vec_Int_t
*
vDiv
,
Vec_Int_t
**
pvQuo
,
Vec_Int_t
**
pvRem
)
Dec_Graph_t
*
Dec_Factor32
(
Vec_Int_t
*
cSop
,
int
nVars
,
Vec_Int_t
*
vStore
)
{
{
// check the number of cubes
Ivy_Sop_t
cSop
,
cRes
;
if
(
Vec_IntSize
(
vCover
)
<
Vec_IntSize
(
vDiv
)
)
Ivy_Sop_t
*
pcSop
=
&
cSop
,
*
pcRes
=
&
cRes
;
{
Dec_Graph_t
*
pFForm
;
*
pvQuo
=
NULL
;
Dec_Edge_t
eRoot
;
*
pvRem
=
NULL
;
return
;
}
// make sure that support of vCover contains that of vDiv
assert
(
nVars
<
16
);
if
(
!
Mvc_CoverCheckSuppContainment
(
vCover
,
vDiv
)
)
{
*
pvQuo
=
NULL
;
*
pvRem
=
NULL
;
return
;
}
// perform the general division
// check for trivial functions
Mvc_CoverDivideInternal
(
vCover
,
vDiv
,
pvQuo
,
pvRem
);
if
(
Vec_IntSize
(
cSop
)
==
0
)
}
return
Dec_GraphCreateConst0
();
if
(
Vec_IntSize
(
cSop
)
==
1
&&
Vec_IntEntry
(
cSop
,
0
)
==
Ivy_CubeMask
(
nVars
)
)
return
Dec_GraphCreateConst1
();
// prepare memory manager
Vec_IntClear
(
vStore
);
Vec_IntGrow
(
vStore
,
IVY_FACTOR_MEM_LIMIT
);
// perform CST
Ivy_SopCreateInverse
(
cSop
,
pcSop
,
nVars
,
vStore
);
// CST
// start the factored form
pFForm
=
Dec_GraphCreate
(
nVars
);
// factor the cover
eRoot
=
Dec_Factor32_rec
(
pFForm
,
cSop
,
2
*
nVars
);
// finalize the factored form
Dec_GraphSetRoot
(
pFForm
,
eRoot
);
// verify the factored form
if
(
!
Dec_Factor32Verify
(
pSop
,
pFForm
,
nVars
)
)
printf
(
"Verification has failed.
\n
"
);
return
pFForm
;
}
/**Function*************************************************************
/**Function*************************************************************
Synopsis [
Merge the cubes inside the groups
.]
Synopsis [
Internal recursive factoring procedure
.]
Description []
Description []
...
@@ -511,185 +480,123 @@ void Mvc_CoverDivide( Vec_Int_t * vCover, Vec_Int_t * vDiv, Vec_Int_t ** pvQuo,
...
@@ -511,185 +480,123 @@ void Mvc_CoverDivide( Vec_Int_t * vCover, Vec_Int_t * vDiv, Vec_Int_t ** pvQuo,
SeeAlso []
SeeAlso []
***********************************************************************/
***********************************************************************/
void
Mvc_CoverDivideInternal
(
Vec_Int_t
*
vCover
,
Vec_Int_t
*
vDiv
,
Vec_Int_t
**
pvQuo
,
Vec_Int_t
**
pvRem
)
Dec_Edge_t
Dec_Factor32_rec
(
Dec_Graph_t
*
pFForm
,
Vec_Int_t
*
cSop
,
int
nLits
)
{
{
Vec_Int_t
*
vQuo
,
*
vRem
;
Vec_Int_t
*
cDiv
,
*
vQuo
,
*
vRem
,
*
vCom
;
Mvc_Cube_t
*
pCubeC
,
*
pCubeD
,
*
pCubeCopy
;
Dec_Edge_t
eNodeDiv
,
eNodeQuo
,
eNodeRem
;
Mvc_Cube_t
*
pCube1
,
*
pCube2
;
Dec_Edge_t
eNodeAnd
,
eNode
;
int
*
pGroups
,
nGroups
;
// the cube groups
int
nCubesC
,
nCubesD
,
nMerges
,
iCubeC
,
iCubeD
,
iMerge
;
int
fSkipG
,
GroupSize
,
g
,
c
,
RetValue
;
int
nCubes
;
// get cover sizes
// make sure the cover contains some cubes
nCubesD
=
Vec_IntSize
(
vDiv
);
assert
(
Vec_IntSize
(
cSop
)
);
nCubesC
=
Vec_IntSize
(
vCover
);
// check trivial cases
// get the divisor
if
(
nCubesD
==
1
)
cDiv
=
Ivy_SopDivisor
(
cSop
,
nLits
);
{
if
(
cDiv
==
NULL
)
if
(
Mvc_CoverIsOneLiteral
(
vDiv
)
)
return
Dec_Factor32Trivial
(
pFForm
,
cSop
,
nLits
);
Mvc_CoverDivideByLiteral
(
vCover
,
vDiv
,
pvQuo
,
pvRem
);
else
Mvc_CoverDivideByCube
(
vCover
,
vDiv
,
pvQuo
,
pvRem
);
return
;
}
// create the divisor and the remainder
// divide the cover by the divisor
vQuo
=
Mvc_CoverAlloc
(
vCover
->
pMem
,
vCover
->
nBits
);
Ivy_SopDivideInternal
(
cSop
,
nLits
,
cDiv
,
&
vQuo
,
&
vRem
);
vRem
=
Mvc_CoverAlloc
(
vCover
->
pMem
,
vCover
->
nBits
);
assert
(
Vec_IntSize
(
vQuo
)
);
// get the support of the divisor
Mvc_CoverAllocateMask
(
vDiv
);
Mvc_CoverSupport
(
vDiv
,
vDiv
->
pMask
);
// sort the cubes of the divisor
Mvc_CoverSort
(
vDiv
,
NULL
,
Mvc_CubeCompareInt
);
// sort the cubes of the cover
Mvc_CoverSort
(
vCover
,
vDiv
->
pMask
,
Mvc_CubeCompareIntOutsideAndUnderMask
);
// allocate storage for cube groups
pGroups
=
MEM_ALLOC
(
vCover
->
pMem
,
int
,
nCubesC
+
1
);
// mask contains variables in the support of Div
// split the cubes into groups using the mask
Mvc_CoverList2Array
(
vCover
);
Mvc_CoverList2Array
(
vDiv
);
pGroups
[
0
]
=
0
;
nGroups
=
1
;
for
(
c
=
1
;
c
<
nCubesC
;
c
++
)
{
// get the cubes
pCube1
=
vCover
->
pCubes
[
c
-
1
];
pCube2
=
vCover
->
pCubes
[
c
];
// compare the cubes
Mvc_CubeBitEqualOutsideMask
(
RetValue
,
pCube1
,
pCube2
,
vDiv
->
pMask
);
if
(
!
RetValue
)
pGroups
[
nGroups
++
]
=
c
;
}
// finish off the last group
pGroups
[
nGroups
]
=
nCubesC
;
// consider each group separately and decide
Vec_IntFree
(
cDiv
);
// whether it can produce a quotient cube
Vec_IntFree
(
vRem
);
nCubes
=
0
;
for
(
g
=
0
;
g
<
nGroups
;
g
++
)
// check the trivial case
{
if
(
Vec_IntSize
(
vQuo
)
==
1
)
// if the group has less than nCubesD cubes,
// there is no way it can produce the quotient cube
// copy the cubes to the remainder
GroupSize
=
pGroups
[
g
+
1
]
-
pGroups
[
g
];
if
(
GroupSize
<
nCubesD
)
{
for
(
c
=
pGroups
[
g
];
c
<
pGroups
[
g
+
1
];
c
++
)
{
{
pCubeCopy
=
Mvc_CubeDup
(
vRem
,
vCover
->
pCubes
[
c
]
);
eNode
=
Dec_Factor32LF_rec
(
pFForm
,
cSop
,
nLits
,
vQuo
);
Mvc_CoverAddCubeTail
(
vRem
,
pCubeCopy
);
Vec_IntFree
(
vQuo
);
nCubes
++
;
return
eNode
;
}
continue
;
}
}
// mark the cubes as those that should be added to the remainder
// make the quotient cube free
for
(
c
=
pGroups
[
g
];
c
<
pGroups
[
g
+
1
];
c
++
)
Ivy_SopMakeCubeFree
(
vQuo
);
Mvc_CubeSetSize
(
vCover
->
pCubes
[
c
],
1
);
// go through the cubes in the group and at the same time
// divide the cover by the quotient
// go through the cubes in the divisor
Ivy_SopDivideInternal
(
cSop
,
nLits
,
vQuo
,
&
cDiv
,
&
vRem
);
iCubeD
=
0
;
iCubeC
=
0
;
pCubeD
=
vDiv
->
pCubes
[
iCubeD
++
];
pCubeC
=
vCover
->
pCubes
[
pGroups
[
g
]
+
iCubeC
++
];
fSkipG
=
0
;
nMerges
=
0
;
while
(
1
)
// check the trivial case
if
(
Ivy_SopIsCubeFree
(
cDiv
)
)
{
{
// compare the topmost cubes in F and in D
eNodeDiv
=
Dec_Factor32_rec
(
pFForm
,
cDiv
);
RetValue
=
Mvc_CubeCompareIntUnderMask
(
pCubeC
,
pCubeD
,
vDiv
->
pMask
);
eNodeQuo
=
Dec_Factor32_rec
(
pFForm
,
vQuo
);
// cube are ordered in increasing order of their int value
Vec_IntFree
(
cDiv
);
if
(
RetValue
==
-
1
)
// pCubeC is above pCubeD
Vec_IntFree
(
vQuo
);
{
// cube in C should be added to the remainder
eNodeAnd
=
Dec_GraphAddNodeAnd
(
pFForm
,
eNodeDiv
,
eNodeQuo
);
// check that there is enough cubes in the group
if
(
Vec_IntSize
(
vRem
)
==
0
)
if
(
GroupSize
-
iCubeC
<
nCubesD
-
nMerges
)
{
{
fSkipG
=
1
;
Vec_IntFree
(
vRem
)
;
break
;
return
eNodeAnd
;
}
}
// get the next cube in the cover
else
pCubeC
=
vCover
->
pCubes
[
pGroups
[
g
]
+
iCubeC
++
];
{
continue
;
eNodeRem
=
Dec_Factor32_rec
(
pFForm
,
vRem
);
Vec_IntFree
(
vRem
);
return
Dec_GraphAddNodeOr
(
pFForm
,
eNodeAnd
,
eNodeRem
);
}
}
if
(
RetValue
==
1
)
// pCubeD is above pCubeC
{
// given cube in D does not have a corresponding cube in the cover
fSkipG
=
1
;
break
;
}
}
// mark the cube as the one that should NOT be added to the remainder
Mvc_CubeSetSize
(
pCubeC
,
0
);
// remember this merged cube
iMerge
=
iCubeC
-
1
;
nMerges
++
;
// stop if we considered the last cube of the group
if
(
iCubeD
==
nCubesD
)
break
;
// advance the cube of the divisor
// get the common cube
assert
(
iCubeD
<
nCubesD
);
vCom
=
Ivy_SopCommonCubeCover
(
cDiv
);
pCubeD
=
vDiv
->
pCubes
[
iCubeD
++
];
Vec_IntFree
(
cDiv
);
Vec_IntFree
(
vQuo
);
Vec_IntFree
(
vRem
);
// advance the cube of the group
// solve the simple problem
assert
(
pGroups
[
g
]
+
iCubeC
<
nCubesC
);
eNode
=
Dec_Factor32LF_rec
(
pFForm
,
cSop
,
nLits
,
vCom
);
pCubeC
=
vCover
->
pCubes
[
pGroups
[
g
]
+
iCubeC
++
];
Vec_IntFree
(
vCom
);
}
return
eNode
;
}
if
(
fSkipG
)
{
// the group has failed, add all the cubes to the remainder
for
(
c
=
pGroups
[
g
];
c
<
pGroups
[
g
+
1
];
c
++
)
{
pCubeCopy
=
Mvc_CubeDup
(
vRem
,
vCover
->
pCubes
[
c
]
);
Mvc_CoverAddCubeTail
(
vRem
,
pCubeCopy
);
nCubes
++
;
}
continue
;
}
// the group has worked, add left-over cubes to the remainder
/**Function*************************************************************
for
(
c
=
pGroups
[
g
];
c
<
pGroups
[
g
+
1
];
c
++
)
{
pCubeC
=
vCover
->
pCubes
[
c
];
if
(
Mvc_CubeReadSize
(
pCubeC
)
)
{
pCubeCopy
=
Mvc_CubeDup
(
vRem
,
pCubeC
);
Mvc_CoverAddCubeTail
(
vRem
,
pCubeCopy
);
nCubes
++
;
}
}
// create the quotient cube
Synopsis [Internal recursive factoring procedure for the leaf case.]
pCube1
=
Mvc_CubeAlloc
(
vQuo
);
Mvc_CubeBitSharp
(
pCube1
,
vCover
->
pCubes
[
pGroups
[
g
]
+
iMerge
],
vDiv
->
pMask
);
// add the cube to the quotient
Mvc_CoverAddCubeTail
(
vQuo
,
pCube1
);
nCubes
+=
nCubesD
;
}
assert
(
nCubes
==
nCubesC
);
// deallocate the memory
Description []
MEM_FREE
(
vCover
->
pMem
,
int
,
nCubesC
+
1
,
pGroups
);
SideEffects []
// return the results
SeeAlso []
*
pvRem
=
vRem
;
*
pvQuo
=
vQuo
;
***********************************************************************/
// Mvc_CoverVerifyDivision( vCover, vDiv, vQuo, vRem );
Dec_Edge_t
Dec_Factor32LF_rec
(
Dec_Graph_t
*
pFForm
,
Vec_Int_t
*
cSop
,
int
nLits
,
Vec_Int_t
*
vSimple
)
{
Dec_Man_t
*
pManDec
=
Abc_FrameReadManDec
();
Vec_Int_t
*
vEdgeLits
=
pManDec
->
vLits
;
Vec_Int_t
*
cDiv
,
*
vQuo
,
*
vRem
;
Dec_Edge_t
eNodeDiv
,
eNodeQuo
,
eNodeRem
;
Dec_Edge_t
eNodeAnd
;
// get the most often occurring literal
cDiv
=
Ivy_SopBestLiteralCover
(
cSop
,
nLits
,
vSimple
);
// divide the cover by the literal
Ivy_SopDivideByLiteral
(
cSop
,
nLits
,
cDiv
,
&
vQuo
,
&
vRem
);
// get the node pointer for the literal
eNodeDiv
=
Dec_Factor32TrivialCube
(
pFForm
,
cDiv
,
Ivy_SopReadCubeHead
(
cDiv
),
vEdgeLits
);
Vec_IntFree
(
cDiv
);
// factor the quotient and remainder
eNodeQuo
=
Dec_Factor32_rec
(
pFForm
,
vQuo
);
Vec_IntFree
(
vQuo
);
eNodeAnd
=
Dec_GraphAddNodeAnd
(
pFForm
,
eNodeDiv
,
eNodeQuo
);
if
(
Vec_IntSize
(
vRem
)
==
0
)
{
Vec_IntFree
(
vRem
);
return
eNodeAnd
;
}
else
{
eNodeRem
=
Dec_Factor32_rec
(
pFForm
,
vRem
);
Vec_IntFree
(
vRem
);
return
Dec_GraphAddNodeOr
(
pFForm
,
eNodeAnd
,
eNodeRem
);
}
}
}
/**Function*************************************************************
/**Function*************************************************************
Synopsis [
Divides the cover by a cube
.]
Synopsis [
Factoring the cover, which has no algebraic divisors
.]
Description []
Description []
...
@@ -698,52 +605,56 @@ void Mvc_CoverDivideInternal( Vec_Int_t * vCover, Vec_Int_t * vDiv, Vec_Int_t **
...
@@ -698,52 +605,56 @@ void Mvc_CoverDivideInternal( Vec_Int_t * vCover, Vec_Int_t * vDiv, Vec_Int_t **
SeeAlso []
SeeAlso []
***********************************************************************/
***********************************************************************/
void
Mvc_CoverDivideByCube
(
Vec_Int_t
*
vCover
,
Vec_Int_t
*
vDiv
,
Vec_Int_t
**
pvQuo
,
Vec_Int_t
**
pvRem
)
Dec_Edge_t
Dec_Factor32Trivial
(
Dec_Graph_t
*
pFForm
,
Vec_Int_t
*
cSop
,
int
nLits
)
{
{
Vec_Int_t
*
vQuo
,
*
vRem
;
Dec_Man_t
*
pManDec
=
Abc_FrameReadManDec
();
Mvc_Cube_t
*
pCubeC
,
*
pCubeD
,
*
pCubeCopy
;
Vec_Int_t
*
vEdgeCubes
=
pManDec
->
vCubes
;
int
ComvResult
;
Vec_Int_t
*
vEdgeLits
=
pManDec
->
vLits
;
Mvc_Manager_t
*
pMem
=
pManDec
->
pMvcMem
;
Dec_Edge_t
eNode
;
unsigned
uCube
;
int
i
;
// create the factored form for each cube
Vec_IntClear
(
vEdgeCubes
);
Ivy_SopForEachCube
(
cSop
,
uCube
)
{
eNode
=
Dec_Factor32TrivialCube
(
pFForm
,
cSop
,
nLits
,
uCube
,
vEdgeLits
);
Vec_IntPush
(
vEdgeCubes
,
Dec_EdgeToInt_
(
eNode
)
);
}
// balance the factored forms
return
Dec_Factor32TrivialTree_rec
(
pFForm
,
(
Dec_Edge_t
*
)
vEdgeCubes
->
pArray
,
vEdgeCubes
->
nSize
,
1
);
}
// get the only cube of D
/**Function*************************************************************
assert
(
Vec_IntSize
(
vDiv
)
==
1
);
// start the quotient and the remainder
Synopsis [Factoring the cube.]
vQuo
=
Mvc_CoverAlloc
(
vCover
->
pMem
,
vCover
->
nBits
);
vRem
=
Mvc_CoverAlloc
(
vCover
->
pMem
,
vCover
->
nBits
);
// get the first and only cube of the divisor
Description []
pCubeD
=
Mvc_CoverReadCubeHead
(
vDiv
);
// iterate through the cubes in the cover
SideEffects []
Mvc_CoverForEachCube
(
vCover
,
pCubeC
)
{
SeeAlso []
// check the containment of literals from pCubeD in pCube
Mvc_Cube2BitNotImpl
(
ComvResult
,
pCubeD
,
pCubeC
);
***********************************************************************/
if
(
!
ComvResult
)
Dec_Edge_t
Dec_Factor32TrivialCube
(
Dec_Graph_t
*
pFForm
,
Vec_Int_t
*
cSop
,
unsigned
uCube
,
int
nLits
,
Vec_Int_t
*
vEdgeLits
)
{
// this cube belongs to the quotient
{
// alloc the cube
Dec_Edge_t
eNode
;
pCubeCopy
=
Mvc_CubeAlloc
(
vQuo
);
int
iBit
,
Value
;
// clean the support of D
// create the factored form for each literal
Mvc_CubeBitSharp
(
pCubeCopy
,
pCubeC
,
pCubeD
);
Vec_IntClear
(
vEdgeLits
);
// add the cube to the quotient
Mvc_CubeForEachLit
(
cSop
,
uCube
,
iBit
,
Value
)
Mvc_CoverAddCubeTail
(
vQuo
,
pCubeCopy
);
if
(
Value
)
}
else
{
{
// copy the cube
eNode
=
Dec_EdgeCreate
(
iBit
/
2
,
iBit
%
2
);
// CST
pCubeCopy
=
Mvc_CubeDup
(
vRem
,
pCubeC
);
Vec_IntPush
(
vEdgeLits
,
Dec_EdgeToInt_
(
eNode
)
);
// add the cube to the remainder
Mvc_CoverAddCubeTail
(
vRem
,
pCubeCopy
);
}
}
}
// return the results
// balance the factored forms
*
pvRem
=
vRem
;
return
Dec_Factor32TrivialTree_rec
(
pFForm
,
(
Dec_Edge_t
*
)
vEdgeLits
->
pArray
,
vEdgeLits
->
nSize
,
0
);
*
pvQuo
=
vQuo
;
}
}
/**Function*************************************************************
/**Function*************************************************************
Synopsis [
Divides the cover by a literal
.]
Synopsis [
Create the well-balanced tree of nodes
.]
Description []
Description []
...
@@ -752,80 +663,119 @@ void Mvc_CoverDivideByCube( Vec_Int_t * vCover, Vec_Int_t * vDiv, Vec_Int_t ** p
...
@@ -752,80 +663,119 @@ void Mvc_CoverDivideByCube( Vec_Int_t * vCover, Vec_Int_t * vDiv, Vec_Int_t ** p
SeeAlso []
SeeAlso []
***********************************************************************/
***********************************************************************/
void
Mvc_CoverDivideByLiteral
(
Vec_Int_t
*
vCover
,
Vec_Int_t
*
vDiv
,
Vec_Int_t
**
pvQuo
,
Vec_Int_t
**
pvRem
)
Dec_Edge_t
Dec_Factor32TrivialTree_rec
(
Dec_Graph_t
*
pFForm
,
Dec_Edge_t
*
peNodes
,
int
nNodes
,
int
fNodeOr
)
{
{
Vec_Int_t
*
vQuo
,
*
vRem
;
Dec_Edge_t
eNode1
,
eNode2
;
Mvc_Cube_t
*
pCubeC
,
*
pCubeCopy
;
int
nNodes1
,
nNodes2
;
int
iLit
;
// get the only cube of D
if
(
nNodes
==
1
)
assert
(
Vec_IntSize
(
vDiv
)
==
1
)
;
return
peNodes
[
0
]
;
// start the quotient and the remainder
// split the nodes into two parts
vQuo
=
Mvc_CoverAlloc
(
vCover
->
pMem
,
vCover
->
nBits
);
nNodes1
=
nNodes
/
2
;
vRem
=
Mvc_CoverAlloc
(
vCover
->
pMem
,
vCover
->
nBits
);
nNodes2
=
nNodes
-
nNodes1
;
// nNodes2 = nNodes/2;
// nNodes1 = nNodes - nNodes2;
// get the first and only literal in the divisor cube
// recursively construct the tree for the parts
iLit
=
Mvc_CoverFirstCubeFirstLit
(
vDiv
);
eNode1
=
Dec_Factor32TrivialTree_rec
(
pFForm
,
peNodes
,
nNodes1
,
fNodeOr
);
eNode2
=
Dec_Factor32TrivialTree_rec
(
pFForm
,
peNodes
+
nNodes1
,
nNodes2
,
fNodeOr
);
// iterate through the cubes in the cover
if
(
fNodeOr
)
Mvc_CoverForEachCube
(
vCover
,
pCubeC
)
return
Dec_GraphAddNodeOr
(
pFForm
,
eNode1
,
eNode2
);
{
// copy the cube
pCubeCopy
=
Mvc_CubeDup
(
vCover
,
pCubeC
);
// add the cube to the quotient or to the remainder depending on the literal
if
(
Mvc_CubeBitValue
(
pCubeCopy
,
iLit
)
)
{
// remove the literal
Mvc_CubeBitRemove
(
pCubeCopy
,
iLit
);
// add the cube ot the quotient
Mvc_CoverAddCubeTail
(
vQuo
,
pCubeCopy
);
}
else
else
{
// add the cube ot the remainder
return
Dec_GraphAddNodeAnd
(
pFForm
,
eNode1
,
eNode2
);
Mvc_CoverAddCubeTail
(
vRem
,
pCubeCopy
);
}
}
// return the results
*
pvRem
=
vRem
;
*
pvQuo
=
vQuo
;
}
}
// verification using temporary BDD package
#include "cuddInt.h"
/**Function*************************************************************
/**Function*************************************************************
Synopsis [
Derives the quotient of division by literal
.]
Synopsis [
Verifies that the factoring is correct
.]
Description [Reduces the cover to be the equal to the result of
Description []
division of the given cover by the literal.]
SideEffects []
SideEffects []
SeeAlso []
SeeAlso []
***********************************************************************/
***********************************************************************/
void
Mvc_CoverDivideByLiteralQuo
(
Vec_Int_t
*
vCover
,
int
iLit
)
DdNode
*
Ivy_SopCoverToBdd
(
DdManager
*
dd
,
Vec_Int_t
*
cSop
,
int
nVars
)
{
{
Mvc_Cube_t
*
pCube
,
*
pCube2
,
*
pPrev
;
DdNode
*
bSum
,
*
bCube
,
*
bTemp
,
*
bVar
;
// delete those cubes that do not have this literal
unsigned
uCube
;
// remove this literal from other cubes
int
Value
,
v
;
pPrev
=
NULL
;
assert
(
nVars
<
16
);
Mvc_CoverForEachCubeSafe
(
vCover
,
pCube
,
pCube2
)
// start the cover
bSum
=
Cudd_ReadLogicZero
(
dd
);
Cudd_Ref
(
bSum
);
// check the logic function of the node
Vec_IntForEachEntry
(
cSop
,
uCube
,
i
)
{
{
if
(
Mvc_CubeBitValue
(
pCube
,
iLit
)
==
0
)
bCube
=
Cudd_ReadOne
(
dd
);
Cudd_Ref
(
bCube
);
{
// delete the cube from the cover
for
(
v
=
0
;
v
<
nVars
;
v
++
)
Mvc_CoverDeleteCube
(
vCover
,
pPrev
,
pCube
);
{
Mvc_CubeFree
(
vCover
,
pCube
);
Value
=
((
uCube
>>
2
*
v
)
&
3
);
// don't update the previous cube
if
(
Value
==
1
)
}
bVar
=
Cudd_Not
(
Cudd_bddIthVar
(
dd
,
v
)
);
else
if
(
Value
==
2
)
bVar
=
Cudd_bddIthVar
(
dd
,
v
);
else
else
{
// delete this literal from the cube
continue
;
Mvc_CubeBitRemove
(
pCube
,
iLit
);
bCube
=
Cudd_bddAnd
(
dd
,
bTemp
=
bCube
,
bVar
);
Cudd_Ref
(
bCube
);
// update the previous cube
Cudd_RecursiveDeref
(
dd
,
bTemp
);
pPrev
=
pCube
;
}
}
bSum
=
Cudd_bddOr
(
dd
,
bTemp
=
bSum
,
bCube
);
Cudd_Ref
(
bSum
);
Cudd_RecursiveDeref
(
dd
,
bTemp
);
Cudd_RecursiveDeref
(
dd
,
bCube
);
}
}
// complement the result if necessary
Cudd_Deref
(
bSum
);
return
bSum
;
}
/**Function*************************************************************
Synopsis [Verifies that the factoring is correct.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int
Dec_Factor32Verify
(
Vec_Int_t
*
cSop
,
Dec_Graph_t
*
pFForm
,
int
nVars
)
{
static
DdManager
*
dd
=
NULL
;
DdNode
*
bFunc1
,
*
bFunc2
;
int
RetValue
;
// get the manager
if
(
dd
==
NULL
)
dd
=
Cudd_Init
(
16
,
0
,
CUDD_UNIQUE_SLOTS
,
CUDD_CACHE_SLOTS
,
0
);
// get the functions
bFunc1
=
Ivy_SopCoverToBdd
(
dd
,
cSop
,
nVars
);
Cudd_Ref
(
bFunc1
);
bFunc2
=
Dec_GraphDeriveBdd
(
dd
,
pFForm
);
Cudd_Ref
(
bFunc2
);
//Extra_bddPrint( dd, bFunc1 ); printf("\n");
//Extra_bddPrint( dd, bFunc2 ); printf("\n");
RetValue
=
(
bFunc1
==
bFunc2
);
if
(
bFunc1
!=
bFunc2
)
{
int
s
;
Extra_bddPrint
(
dd
,
bFunc1
);
printf
(
"
\n
"
);
Extra_bddPrint
(
dd
,
bFunc2
);
printf
(
"
\n
"
);
s
=
0
;
}
Cudd_RecursiveDeref
(
dd
,
bFunc1
);
Cudd_RecursiveDeref
(
dd
,
bFunc2
);
return
RetValue
;
}
}
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
...
...
src/aig/ivy/ivyIsop.c
View file @
38254947
...
@@ -19,7 +19,6 @@
...
@@ -19,7 +19,6 @@
***********************************************************************/
***********************************************************************/
#include "ivy.h"
#include "ivy.h"
#include "mem.h"
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
/// DECLARATIONS ///
...
...
src/base/abc/abc.h
View file @
38254947
...
@@ -698,9 +698,6 @@ extern int Abc_NodeMffcLabel( Abc_Obj_t * pNode );
...
@@ -698,9 +698,6 @@ extern int Abc_NodeMffcLabel( Abc_Obj_t * pNode );
extern
void
Abc_NodeMffsConeSupp
(
Abc_Obj_t
*
pNode
,
Vec_Ptr_t
*
vCone
,
Vec_Ptr_t
*
vSupp
);
extern
void
Abc_NodeMffsConeSupp
(
Abc_Obj_t
*
pNode
,
Vec_Ptr_t
*
vCone
,
Vec_Ptr_t
*
vSupp
);
extern
int
Abc_NodeDeref_rec
(
Abc_Obj_t
*
pNode
);
extern
int
Abc_NodeDeref_rec
(
Abc_Obj_t
*
pNode
);
extern
int
Abc_NodeRef_rec
(
Abc_Obj_t
*
pNode
);
extern
int
Abc_NodeRef_rec
(
Abc_Obj_t
*
pNode
);
/*=== abcRenode.c ==========================================================*/
extern
Abc_Ntk_t
*
Abc_NtkRenode
(
Abc_Ntk_t
*
pNtk
,
int
nThresh
,
int
nFaninMax
,
int
fCnf
,
int
fMulti
,
int
fSimple
,
int
fFactor
);
extern
DdNode
*
Abc_NtkRenodeDeriveBdd
(
DdManager
*
dd
,
Abc_Obj_t
*
pNodeOld
,
Vec_Ptr_t
*
vFaninsOld
);
/*=== abcRefactor.c ==========================================================*/
/*=== abcRefactor.c ==========================================================*/
extern
int
Abc_NtkRefactor
(
Abc_Ntk_t
*
pNtk
,
int
nNodeSizeMax
,
int
nConeSizeMax
,
bool
fUpdateLevel
,
bool
fUseZeros
,
bool
fUseDcs
,
bool
fVerbose
);
extern
int
Abc_NtkRefactor
(
Abc_Ntk_t
*
pNtk
,
int
nNodeSizeMax
,
int
nConeSizeMax
,
bool
fUpdateLevel
,
bool
fUseZeros
,
bool
fUseDcs
,
bool
fVerbose
);
/*=== abcRewrite.c ==========================================================*/
/*=== abcRewrite.c ==========================================================*/
...
...
src/base/abci/abc.c
View file @
38254947
...
@@ -53,6 +53,7 @@ static int Abc_CommandShowCut ( Abc_Frame_t * pAbc, int argc, char ** arg
...
@@ -53,6 +53,7 @@ static int Abc_CommandShowCut ( Abc_Frame_t * pAbc, int argc, char ** arg
static
int
Abc_CommandCollapse
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
);
static
int
Abc_CommandCollapse
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
);
static
int
Abc_CommandStrash
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
);
static
int
Abc_CommandStrash
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
);
static
int
Abc_CommandBalance
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
);
static
int
Abc_CommandBalance
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
);
static
int
Abc_CommandMulti
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
);
static
int
Abc_CommandRenode
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
);
static
int
Abc_CommandRenode
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
);
static
int
Abc_CommandCleanup
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
);
static
int
Abc_CommandCleanup
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
);
static
int
Abc_CommandSweep
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
);
static
int
Abc_CommandSweep
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
);
...
@@ -184,6 +185,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
...
@@ -184,6 +185,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd
(
pAbc
,
"Synthesis"
,
"collapse"
,
Abc_CommandCollapse
,
1
);
Cmd_CommandAdd
(
pAbc
,
"Synthesis"
,
"collapse"
,
Abc_CommandCollapse
,
1
);
Cmd_CommandAdd
(
pAbc
,
"Synthesis"
,
"strash"
,
Abc_CommandStrash
,
1
);
Cmd_CommandAdd
(
pAbc
,
"Synthesis"
,
"strash"
,
Abc_CommandStrash
,
1
);
Cmd_CommandAdd
(
pAbc
,
"Synthesis"
,
"balance"
,
Abc_CommandBalance
,
1
);
Cmd_CommandAdd
(
pAbc
,
"Synthesis"
,
"balance"
,
Abc_CommandBalance
,
1
);
Cmd_CommandAdd
(
pAbc
,
"Synthesis"
,
"multi"
,
Abc_CommandMulti
,
1
);
Cmd_CommandAdd
(
pAbc
,
"Synthesis"
,
"renode"
,
Abc_CommandRenode
,
1
);
Cmd_CommandAdd
(
pAbc
,
"Synthesis"
,
"renode"
,
Abc_CommandRenode
,
1
);
Cmd_CommandAdd
(
pAbc
,
"Synthesis"
,
"cleanup"
,
Abc_CommandCleanup
,
1
);
Cmd_CommandAdd
(
pAbc
,
"Synthesis"
,
"cleanup"
,
Abc_CommandCleanup
,
1
);
Cmd_CommandAdd
(
pAbc
,
"Synthesis"
,
"sweep"
,
Abc_CommandSweep
,
1
);
Cmd_CommandAdd
(
pAbc
,
"Synthesis"
,
"sweep"
,
Abc_CommandSweep
,
1
);
...
@@ -1911,7 +1913,7 @@ usage:
...
@@ -1911,7 +1913,7 @@ usage:
SeeAlso []
SeeAlso []
***********************************************************************/
***********************************************************************/
int
Abc_Command
Renode
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
)
int
Abc_Command
Multi
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
)
{
{
FILE
*
pOut
,
*
pErr
;
FILE
*
pOut
,
*
pErr
;
Abc_Ntk_t
*
pNtk
,
*
pNtkRes
;
Abc_Ntk_t
*
pNtk
,
*
pNtkRes
;
...
@@ -1920,6 +1922,7 @@ int Abc_CommandRenode( Abc_Frame_t * pAbc, int argc, char ** argv )
...
@@ -1920,6 +1922,7 @@ int Abc_CommandRenode( Abc_Frame_t * pAbc, int argc, char ** argv )
int
fMulti
;
int
fMulti
;
int
fSimple
;
int
fSimple
;
int
fFactor
;
int
fFactor
;
extern
Abc_Ntk_t
*
Abc_NtkMulti
(
Abc_Ntk_t
*
pNtk
,
int
nThresh
,
int
nFaninMax
,
int
fCnf
,
int
fMulti
,
int
fSimple
,
int
fFactor
);
pNtk
=
Abc_FrameReadNtk
(
pAbc
);
pNtk
=
Abc_FrameReadNtk
(
pAbc
);
pOut
=
Abc_FrameReadOut
(
pAbc
);
pOut
=
Abc_FrameReadOut
(
pAbc
);
...
@@ -1990,7 +1993,7 @@ int Abc_CommandRenode( Abc_Frame_t * pAbc, int argc, char ** argv )
...
@@ -1990,7 +1993,7 @@ int Abc_CommandRenode( Abc_Frame_t * pAbc, int argc, char ** argv )
}
}
// get the new network
// get the new network
pNtkRes
=
Abc_Ntk
Renode
(
pNtk
,
nThresh
,
nFaninMax
,
fCnf
,
fMulti
,
fSimple
,
fFactor
);
pNtkRes
=
Abc_Ntk
Multi
(
pNtk
,
nThresh
,
nFaninMax
,
fCnf
,
fMulti
,
fSimple
,
fFactor
);
if
(
pNtkRes
==
NULL
)
if
(
pNtkRes
==
NULL
)
{
{
fprintf
(
pErr
,
"Renoding has failed.
\n
"
);
fprintf
(
pErr
,
"Renoding has failed.
\n
"
);
...
@@ -2001,7 +2004,7 @@ int Abc_CommandRenode( Abc_Frame_t * pAbc, int argc, char ** argv )
...
@@ -2001,7 +2004,7 @@ int Abc_CommandRenode( Abc_Frame_t * pAbc, int argc, char ** argv )
return
0
;
return
0
;
usage:
usage:
fprintf
(
pErr
,
"usage:
renode
[-T num] [-F num] [-msfch]
\n
"
);
fprintf
(
pErr
,
"usage:
multi
[-T num] [-F num] [-msfch]
\n
"
);
fprintf
(
pErr
,
"
\t
transforms an AIG into a logic network by creating larger nodes
\n
"
);
fprintf
(
pErr
,
"
\t
transforms an AIG into a logic network by creating larger nodes
\n
"
);
fprintf
(
pErr
,
"
\t
-F num : the maximum fanin size after renoding [default = %d]
\n
"
,
nFaninMax
);
fprintf
(
pErr
,
"
\t
-F num : the maximum fanin size after renoding [default = %d]
\n
"
,
nFaninMax
);
fprintf
(
pErr
,
"
\t
-T num : the threshold for AIG node duplication [default = %d]
\n
"
,
nThresh
);
fprintf
(
pErr
,
"
\t
-T num : the threshold for AIG node duplication [default = %d]
\n
"
,
nThresh
);
...
@@ -2027,6 +2030,95 @@ usage:
...
@@ -2027,6 +2030,95 @@ usage:
SeeAlso []
SeeAlso []
***********************************************************************/
***********************************************************************/
int
Abc_CommandRenode
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
)
{
FILE
*
pOut
,
*
pErr
;
Abc_Ntk_t
*
pNtk
,
*
pNtkRes
;
int
nFaninMax
,
c
;
int
fUseBdds
;
int
fVerbose
;
extern
Abc_Ntk_t
*
Abc_NtkRenode
(
Abc_Ntk_t
*
pNtk
,
int
nFaninMax
,
int
fUseBdds
,
int
fVerbose
);
pNtk
=
Abc_FrameReadNtk
(
pAbc
);
pOut
=
Abc_FrameReadOut
(
pAbc
);
pErr
=
Abc_FrameReadErr
(
pAbc
);
// set defaults
nFaninMax
=
8
;
fUseBdds
=
0
;
fVerbose
=
0
;
Extra_UtilGetoptReset
();
while
(
(
c
=
Extra_UtilGetopt
(
argc
,
argv
,
"Fbvh"
)
)
!=
EOF
)
{
switch
(
c
)
{
case
'F'
:
if
(
globalUtilOptind
>=
argc
)
{
fprintf
(
pErr
,
"Command line switch
\"
-F
\"
should be followed by an integer.
\n
"
);
goto
usage
;
}
nFaninMax
=
atoi
(
argv
[
globalUtilOptind
]);
globalUtilOptind
++
;
if
(
nFaninMax
<
0
)
goto
usage
;
break
;
case
'b'
:
fUseBdds
^=
1
;
break
;
case
'v'
:
fVerbose
^=
1
;
break
;
case
'h'
:
goto
usage
;
default:
goto
usage
;
}
}
if
(
pNtk
==
NULL
)
{
fprintf
(
pErr
,
"Empty network.
\n
"
);
return
1
;
}
if
(
!
Abc_NtkIsStrash
(
pNtk
)
)
{
fprintf
(
pErr
,
"Cannot renode a network that is not an AIG (run
\"
strash
\"
).
\n
"
);
return
1
;
}
// get the new network
pNtkRes
=
Abc_NtkRenode
(
pNtk
,
nFaninMax
,
fUseBdds
,
fVerbose
);
if
(
pNtkRes
==
NULL
)
{
fprintf
(
pErr
,
"Renoding has failed.
\n
"
);
return
1
;
}
// replace the current network
Abc_FrameReplaceCurrentNetwork
(
pAbc
,
pNtkRes
);
return
0
;
usage:
fprintf
(
pErr
,
"usage: renode [-F num] [-bv]
\n
"
);
fprintf
(
pErr
,
"
\t
transforms an AIG into a logic network by creating larger nodes
\n
"
);
fprintf
(
pErr
,
"
\t
-F num : the maximum fanin size after renoding [default = %d]
\n
"
,
nFaninMax
);
fprintf
(
pErr
,
"
\t
-b : toggles cost function (BDD nodes or FF literals) [default = %s]
\n
"
,
fUseBdds
?
"BDD nodes"
:
"FF literals"
);
fprintf
(
pErr
,
"
\t
-v : print verbose information [default = %s]
\n
"
,
fVerbose
?
"yes"
:
"no"
);
fprintf
(
pErr
,
"
\t
-h : print the command usage
\n
"
);
return
1
;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int
Abc_CommandCleanup
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
)
int
Abc_CommandCleanup
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
)
{
{
FILE
*
pOut
,
*
pErr
;
FILE
*
pOut
,
*
pErr
;
...
@@ -7391,19 +7483,26 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv )
...
@@ -7391,19 +7483,26 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv )
// set defaults
// set defaults
memset
(
pPars
,
0
,
sizeof
(
If_Par_t
)
);
memset
(
pPars
,
0
,
sizeof
(
If_Par_t
)
);
// user-controlable paramters
pPars
->
Mode
=
0
;
pPars
->
Mode
=
0
;
pPars
->
nLutSize
=
4
;
pPars
->
nLutSize
=
4
;
// pPars->pLutLib = Abc_FrameReadLibLut();
pPars
->
nCutsMax
=
20
;
pPars
->
nCutsMax
=
20
;
pPars
->
DelayTarget
=
-
1
;
pPars
->
fPreprocess
=
1
;
pPars
->
fPreprocess
=
1
;
pPars
->
fArea
=
0
;
pPars
->
fArea
=
0
;
pPars
->
fFancy
=
0
;
pPars
->
fFancy
=
0
;
pPars
->
fLatchPaths
=
0
;
pPars
->
fExpRed
=
1
;
pPars
->
fExpRed
=
1
;
pPars
->
fLatchPaths
=
0
;
pPars
->
fSeq
=
0
;
pPars
->
fSeq
=
0
;
pPars
->
nLatches
=
0
;
pPars
->
DelayTarget
=
-
1
;
pPars
->
fVerbose
=
0
;
pPars
->
fVerbose
=
0
;
// internal parameters
pPars
->
fTruth
=
1
;
pPars
->
nLatches
=
pNtk
?
Abc_NtkLatchNum
(
pNtk
)
:
0
;
pPars
->
pLutLib
=
NULL
;
// Abc_FrameReadLibLut();
pPars
->
pTimesArr
=
NULL
;
pPars
->
pTimesArr
=
NULL
;
pPars
->
pFuncCost
=
NULL
;
Extra_UtilGetoptReset
();
Extra_UtilGetoptReset
();
while
(
(
c
=
Extra_UtilGetopt
(
argc
,
argv
,
"MKCDpaflrsvh"
)
)
!=
EOF
)
while
(
(
c
=
Extra_UtilGetopt
(
argc
,
argv
,
"MKCDpaflrsvh"
)
)
!=
EOF
)
{
{
...
...
src/base/abci/abcIf.c
View file @
38254947
...
@@ -28,8 +28,7 @@
...
@@ -28,8 +28,7 @@
static
If_Man_t
*
Abc_NtkToIf
(
Abc_Ntk_t
*
pNtk
,
If_Par_t
*
pPars
);
static
If_Man_t
*
Abc_NtkToIf
(
Abc_Ntk_t
*
pNtk
,
If_Par_t
*
pPars
);
static
Abc_Ntk_t
*
Abc_NtkFromIf
(
If_Man_t
*
pIfMan
,
Abc_Ntk_t
*
pNtk
);
static
Abc_Ntk_t
*
Abc_NtkFromIf
(
If_Man_t
*
pIfMan
,
Abc_Ntk_t
*
pNtk
);
static
Abc_Obj_t
*
Abc_NodeFromIf_rec
(
Abc_Ntk_t
*
pNtkNew
,
If_Man_t
*
pIfMan
,
If_Obj_t
*
pIfObj
);
static
Abc_Obj_t
*
Abc_NodeFromIf_rec
(
Abc_Ntk_t
*
pNtkNew
,
If_Man_t
*
pIfMan
,
If_Obj_t
*
pIfObj
);
static
Hop_Obj_t
*
Abc_NodeIfToHop
(
Hop_Man_t
*
pHopMan
,
If_Man_t
*
pIfMan
,
If_Cut_t
*
pCut
);
static
Hop_Obj_t
*
Abc_NodeIfToHop
(
Hop_Man_t
*
pHopMan
,
If_Man_t
*
pIfMan
,
If_Obj_t
*
pIfObj
);
static
Hop_Obj_t
*
Abc_NodeIfToHop2
(
Hop_Man_t
*
pHopMan
,
If_Man_t
*
pIfMan
,
If_Obj_t
*
pIfObj
);
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
/// FUNCTION DEFINITIONS ///
...
@@ -75,7 +74,7 @@ Abc_Ntk_t * Abc_NtkIf( Abc_Ntk_t * pNtk, If_Par_t * pPars )
...
@@ -75,7 +74,7 @@ Abc_Ntk_t * Abc_NtkIf( Abc_Ntk_t * pNtk, If_Par_t * pPars )
return
NULL
;
return
NULL
;
}
}
// transform the result of mapping into
a BDD
network
// transform the result of mapping into
the new
network
pNtkNew
=
Abc_NtkFromIf
(
pIfMan
,
pNtk
);
pNtkNew
=
Abc_NtkFromIf
(
pIfMan
,
pNtk
);
if
(
pNtkNew
==
NULL
)
if
(
pNtkNew
==
NULL
)
return
NULL
;
return
NULL
;
...
@@ -163,6 +162,9 @@ Abc_Ntk_t * Abc_NtkFromIf( If_Man_t * pIfMan, Abc_Ntk_t * pNtk )
...
@@ -163,6 +162,9 @@ Abc_Ntk_t * Abc_NtkFromIf( If_Man_t * pIfMan, Abc_Ntk_t * pNtk )
Abc_Obj_t
*
pNode
,
*
pNodeNew
;
Abc_Obj_t
*
pNode
,
*
pNodeNew
;
int
i
,
nDupGates
;
int
i
,
nDupGates
;
// create the new network
// create the new network
if
(
pIfMan
->
pPars
->
fUseBdds
)
pNtkNew
=
Abc_NtkStartFrom
(
pNtk
,
ABC_NTK_LOGIC
,
ABC_FUNC_BDD
);
else
pNtkNew
=
Abc_NtkStartFrom
(
pNtk
,
ABC_NTK_LOGIC
,
ABC_FUNC_AIG
);
pNtkNew
=
Abc_NtkStartFrom
(
pNtk
,
ABC_NTK_LOGIC
,
ABC_FUNC_AIG
);
// prepare the mapping manager
// prepare the mapping manager
If_ManCleanNodeCopy
(
pIfMan
);
If_ManCleanNodeCopy
(
pIfMan
);
...
@@ -221,75 +223,37 @@ Abc_Obj_t * Abc_NodeFromIf_rec( Abc_Ntk_t * pNtkNew, If_Man_t * pIfMan, If_Obj_t
...
@@ -221,75 +223,37 @@ Abc_Obj_t * Abc_NodeFromIf_rec( Abc_Ntk_t * pNtkNew, If_Man_t * pIfMan, If_Obj_t
If_CutForEachLeaf
(
pIfMan
,
pCutBest
,
pIfLeaf
,
i
)
If_CutForEachLeaf
(
pIfMan
,
pCutBest
,
pIfLeaf
,
i
)
Abc_ObjAddFanin
(
pNodeNew
,
Abc_NodeFromIf_rec
(
pNtkNew
,
pIfMan
,
pIfLeaf
)
);
Abc_ObjAddFanin
(
pNodeNew
,
Abc_NodeFromIf_rec
(
pNtkNew
,
pIfMan
,
pIfLeaf
)
);
// derive the function of this node
// derive the function of this node
// pNodeNew->pData = Abc_NodeIfToHop( pNtkNew->pManFunc, pIfMan, pCutBest );
pNodeNew
->
pData
=
Abc_NodeIfToHop2
(
pNtkNew
->
pManFunc
,
pIfMan
,
pIfObj
);
If_ObjSetCopy
(
pIfObj
,
pNodeNew
);
return
pNodeNew
;
}
/**Function*************************************************************
Synopsis [Recursively derives the truth table for the cut.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Hop_Obj_t
*
Abc_NodeIfToHop_rec
(
Hop_Man_t
*
pHopMan
,
If_Man_t
*
pIfMan
,
If_Cut_t
*
pCut
,
Vec_Ptr_t
*
vVisited
)
{
Hop_Obj_t
*
gFunc
,
*
gFunc0
,
*
gFunc1
;
// if the cut is visited, return the result
if
(
If_CutData
(
pCut
)
)
return
If_CutData
(
pCut
);
// compute the functions of the children
gFunc0
=
Abc_NodeIfToHop_rec
(
pHopMan
,
pIfMan
,
pCut
->
pOne
,
vVisited
);
gFunc1
=
Abc_NodeIfToHop_rec
(
pHopMan
,
pIfMan
,
pCut
->
pTwo
,
vVisited
);
// get the function of the cut
gFunc
=
Hop_And
(
pHopMan
,
Hop_NotCond
(
gFunc0
,
pCut
->
fCompl0
),
Hop_NotCond
(
gFunc1
,
pCut
->
fCompl1
)
);
gFunc
=
Hop_NotCond
(
gFunc
,
pCut
->
Phase
);
assert
(
If_CutData
(
pCut
)
==
NULL
);
If_CutSetData
(
pCut
,
gFunc
);
// add this cut to the visited list
Vec_PtrPush
(
vVisited
,
pCut
);
return
gFunc
;
}
/**Function*************************************************************
Synopsis [Derives the truth table for one cut.]
Description []
if
(
pIfMan
->
pPars
->
fTruth
)
{
SideEffects []
if
(
pIfMan
->
pPars
->
fUseBdds
)
{
SeeAlso []
extern
void
Abc_NodeBddReorder
(
void
*
p
,
Abc_Obj_t
*
pNode
);
extern
DdNode
*
Kit_TruthToBdd
(
DdManager
*
dd
,
unsigned
*
pTruth
,
int
nVars
);
// transform truth table into the BDD
pNodeNew
->
pData
=
Kit_TruthToBdd
(
pNtkNew
->
pManFunc
,
If_CutTruth
(
pCutBest
),
pCutBest
->
nLimit
);
// reorder the fanins to minimize the BDD size
Abc_NodeBddReorder
(
pIfMan
->
pPars
->
pReoMan
,
pNodeNew
);
}
else
{
typedef
int
Kit_Graph_t
;
extern
Kit_Graph_t
*
Kit_TruthToGraph
(
unsigned
*
pTruth
,
int
nVars
);
extern
Hop_Obj_t
*
Dec_GraphToNetworkAig
(
Hop_Man_t
*
pMan
,
Kit_Graph_t
*
pGraph
);
// transform truth table into the decomposition tree
Kit_Graph_t
*
pGraph
=
Kit_TruthToGraph
(
If_CutTruth
(
pCutBest
),
pCutBest
->
nLimit
);
// derive the AIG for that tree
pNodeNew
->
pData
=
Dec_GraphToNetworkAig
(
pNtkNew
->
pManFunc
,
pGraph
);
Kit_GraphFree
(
pGraph
);
}
}
else
***********************************************************************/
pNodeNew
->
pData
=
Abc_NodeIfToHop
(
pNtkNew
->
pManFunc
,
pIfMan
,
pIfObj
);
Hop_Obj_t
*
Abc_NodeIfToHop
(
Hop_Man_t
*
pHopMan
,
If_Man_t
*
pIfMan
,
If_Cut_t
*
pCut
)
If_ObjSetCopy
(
pIfObj
,
pNodeNew
);
{
return
pNodeNew
;
Hop_Obj_t
*
gFunc
;
If_Obj_t
*
pLeaf
;
int
i
;
assert
(
pCut
->
nLeaves
>
1
);
// set the leaf variables
If_CutForEachLeaf
(
pIfMan
,
pCut
,
pLeaf
,
i
)
If_CutSetData
(
If_ObjCutTriv
(
pLeaf
),
Hop_IthVar
(
pHopMan
,
i
)
);
// recursively compute the function while collecting visited cuts
Vec_PtrClear
(
pIfMan
->
vTemp
);
gFunc
=
Abc_NodeIfToHop_rec
(
pHopMan
,
pIfMan
,
pCut
,
pIfMan
->
vTemp
);
// printf( "%d ", Vec_PtrSize(p->vTemp) );
// clean the cuts
If_CutForEachLeaf
(
pIfMan
,
pCut
,
pLeaf
,
i
)
If_CutSetData
(
If_ObjCutTriv
(
pLeaf
),
NULL
);
Vec_PtrForEachEntry
(
pIfMan
->
vTemp
,
pCut
,
i
)
If_CutSetData
(
pCut
,
NULL
);
return
gFunc
;
}
}
/**Function*************************************************************
/**Function*************************************************************
Synopsis [Recursively derives the truth table for the cut.]
Synopsis [Recursively derives the truth table for the cut.]
...
@@ -301,7 +265,7 @@ Hop_Obj_t * Abc_NodeIfToHop( Hop_Man_t * pHopMan, If_Man_t * pIfMan, If_Cut_t *
...
@@ -301,7 +265,7 @@ Hop_Obj_t * Abc_NodeIfToHop( Hop_Man_t * pHopMan, If_Man_t * pIfMan, If_Cut_t *
SeeAlso []
SeeAlso []
***********************************************************************/
***********************************************************************/
Hop_Obj_t
*
Abc_NodeIfToHop
2
_rec
(
Hop_Man_t
*
pHopMan
,
If_Man_t
*
pIfMan
,
If_Obj_t
*
pIfObj
,
Vec_Ptr_t
*
vVisited
)
Hop_Obj_t
*
Abc_NodeIfToHop_rec
(
Hop_Man_t
*
pHopMan
,
If_Man_t
*
pIfMan
,
If_Obj_t
*
pIfObj
,
Vec_Ptr_t
*
vVisited
)
{
{
If_Cut_t
*
pCut
;
If_Cut_t
*
pCut
;
Hop_Obj_t
*
gFunc
,
*
gFunc0
,
*
gFunc1
;
Hop_Obj_t
*
gFunc
,
*
gFunc0
,
*
gFunc1
;
...
@@ -311,11 +275,10 @@ Hop_Obj_t * Abc_NodeIfToHop2_rec( Hop_Man_t * pHopMan, If_Man_t * pIfMan, If_Obj
...
@@ -311,11 +275,10 @@ Hop_Obj_t * Abc_NodeIfToHop2_rec( Hop_Man_t * pHopMan, If_Man_t * pIfMan, If_Obj
if
(
If_CutData
(
pCut
)
)
if
(
If_CutData
(
pCut
)
)
return
If_CutData
(
pCut
);
return
If_CutData
(
pCut
);
// compute the functions of the children
// compute the functions of the children
gFunc0
=
Abc_NodeIfToHop
2
_rec
(
pHopMan
,
pIfMan
,
pIfObj
->
pFanin0
,
vVisited
);
gFunc0
=
Abc_NodeIfToHop_rec
(
pHopMan
,
pIfMan
,
pIfObj
->
pFanin0
,
vVisited
);
gFunc1
=
Abc_NodeIfToHop
2
_rec
(
pHopMan
,
pIfMan
,
pIfObj
->
pFanin1
,
vVisited
);
gFunc1
=
Abc_NodeIfToHop_rec
(
pHopMan
,
pIfMan
,
pIfObj
->
pFanin1
,
vVisited
);
// get the function of the cut
// get the function of the cut
gFunc
=
Hop_And
(
pHopMan
,
Hop_NotCond
(
gFunc0
,
pIfObj
->
fCompl0
),
Hop_NotCond
(
gFunc1
,
pIfObj
->
fCompl1
)
);
gFunc
=
Hop_And
(
pHopMan
,
Hop_NotCond
(
gFunc0
,
pIfObj
->
fCompl0
),
Hop_NotCond
(
gFunc1
,
pIfObj
->
fCompl1
)
);
gFunc
=
Hop_NotCond
(
gFunc
,
pCut
->
Phase
);
assert
(
If_CutData
(
pCut
)
==
NULL
);
assert
(
If_CutData
(
pCut
)
==
NULL
);
If_CutSetData
(
pCut
,
gFunc
);
If_CutSetData
(
pCut
,
gFunc
);
// add this cut to the visited list
// add this cut to the visited list
...
@@ -334,7 +297,7 @@ Hop_Obj_t * Abc_NodeIfToHop2_rec( Hop_Man_t * pHopMan, If_Man_t * pIfMan, If_Obj
...
@@ -334,7 +297,7 @@ Hop_Obj_t * Abc_NodeIfToHop2_rec( Hop_Man_t * pHopMan, If_Man_t * pIfMan, If_Obj
SeeAlso []
SeeAlso []
***********************************************************************/
***********************************************************************/
Hop_Obj_t
*
Abc_NodeIfToHop
2
(
Hop_Man_t
*
pHopMan
,
If_Man_t
*
pIfMan
,
If_Obj_t
*
pIfObj
)
Hop_Obj_t
*
Abc_NodeIfToHop
(
Hop_Man_t
*
pHopMan
,
If_Man_t
*
pIfMan
,
If_Obj_t
*
pIfObj
)
{
{
If_Cut_t
*
pCut
;
If_Cut_t
*
pCut
;
Hop_Obj_t
*
gFunc
;
Hop_Obj_t
*
gFunc
;
...
@@ -348,7 +311,7 @@ Hop_Obj_t * Abc_NodeIfToHop2( Hop_Man_t * pHopMan, If_Man_t * pIfMan, If_Obj_t *
...
@@ -348,7 +311,7 @@ Hop_Obj_t * Abc_NodeIfToHop2( Hop_Man_t * pHopMan, If_Man_t * pIfMan, If_Obj_t *
If_CutSetData
(
If_ObjCutTriv
(
pLeaf
),
Hop_IthVar
(
pHopMan
,
i
)
);
If_CutSetData
(
If_ObjCutTriv
(
pLeaf
),
Hop_IthVar
(
pHopMan
,
i
)
);
// recursively compute the function while collecting visited cuts
// recursively compute the function while collecting visited cuts
Vec_PtrClear
(
pIfMan
->
vTemp
);
Vec_PtrClear
(
pIfMan
->
vTemp
);
gFunc
=
Abc_NodeIfToHop
2
_rec
(
pHopMan
,
pIfMan
,
pIfObj
,
pIfMan
->
vTemp
);
gFunc
=
Abc_NodeIfToHop_rec
(
pHopMan
,
pIfMan
,
pIfObj
,
pIfMan
->
vTemp
);
// printf( "%d ", Vec_PtrSize(p->vTemp) );
// printf( "%d ", Vec_PtrSize(p->vTemp) );
// clean the cuts
// clean the cuts
If_CutForEachLeaf
(
pIfMan
,
pCut
,
pLeaf
,
i
)
If_CutForEachLeaf
(
pIfMan
,
pCut
,
pLeaf
,
i
)
...
...
src/base/abci/abcMap.c
View file @
38254947
...
@@ -469,6 +469,7 @@ Abc_Ntk_t * Abc_NtkSuperChoice( Abc_Ntk_t * pNtk )
...
@@ -469,6 +469,7 @@ Abc_Ntk_t * Abc_NtkSuperChoice( Abc_Ntk_t * pNtk )
***********************************************************************/
***********************************************************************/
Abc_Ntk_t
*
Abc_NtkFromMapSuperChoice
(
Map_Man_t
*
pMan
,
Abc_Ntk_t
*
pNtk
)
Abc_Ntk_t
*
Abc_NtkFromMapSuperChoice
(
Map_Man_t
*
pMan
,
Abc_Ntk_t
*
pNtk
)
{
{
extern
Abc_Ntk_t
*
Abc_NtkMulti
(
Abc_Ntk_t
*
pNtk
,
int
nThresh
,
int
nFaninMax
,
int
fCnf
,
int
fMulti
,
int
fSimple
,
int
fFactor
);
ProgressBar
*
pProgress
;
ProgressBar
*
pProgress
;
Abc_Ntk_t
*
pNtkNew
,
*
pNtkNew2
;
Abc_Ntk_t
*
pNtkNew
,
*
pNtkNew2
;
Abc_Obj_t
*
pNode
;
Abc_Obj_t
*
pNode
;
...
@@ -484,7 +485,7 @@ Abc_Ntk_t * Abc_NtkFromMapSuperChoice( Map_Man_t * pMan, Abc_Ntk_t * pNtk )
...
@@ -484,7 +485,7 @@ Abc_Ntk_t * Abc_NtkFromMapSuperChoice( Map_Man_t * pMan, Abc_Ntk_t * pNtk )
// duplicate the network
// duplicate the network
pNtkNew2
=
Abc_NtkDup
(
pNtk
);
pNtkNew2
=
Abc_NtkDup
(
pNtk
);
pNtkNew
=
Abc_Ntk
Renode
(
pNtkNew2
,
0
,
20
,
0
,
0
,
1
,
0
);
pNtkNew
=
Abc_Ntk
Multi
(
pNtkNew2
,
0
,
20
,
0
,
0
,
1
,
0
);
if
(
!
Abc_NtkBddToSop
(
pNtkNew
,
0
)
)
if
(
!
Abc_NtkBddToSop
(
pNtkNew
,
0
)
)
{
{
printf
(
"Abc_NtkFromMapSuperChoice(): Converting to SOPs has failed.
\n
"
);
printf
(
"Abc_NtkFromMapSuperChoice(): Converting to SOPs has failed.
\n
"
);
...
...
src/base/abci/abcMulti.c
0 → 100644
View file @
38254947
/**CFile****************************************************************
FileName [abcMulti.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Network and node package.]
Synopsis [Procedures which transform an AIG into multi-input AND-graph.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: abcMulti.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "abc.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static
void
Abc_NtkMultiInt
(
Abc_Ntk_t
*
pNtk
,
Abc_Ntk_t
*
pNtkNew
);
static
Abc_Obj_t
*
Abc_NtkMulti_rec
(
Abc_Ntk_t
*
pNtkNew
,
Abc_Obj_t
*
pNodeOld
);
static
DdNode
*
Abc_NtkMultiDeriveBdd_rec
(
DdManager
*
dd
,
Abc_Obj_t
*
pNodeOld
,
Vec_Ptr_t
*
vFanins
);
static
DdNode
*
Abc_NtkMultiDeriveBdd
(
DdManager
*
dd
,
Abc_Obj_t
*
pNodeOld
,
Vec_Ptr_t
*
vFaninsOld
);
static
void
Abc_NtkMultiSetBounds
(
Abc_Ntk_t
*
pNtk
,
int
nThresh
,
int
nFaninMax
);
static
void
Abc_NtkMultiSetBoundsCnf
(
Abc_Ntk_t
*
pNtk
);
static
void
Abc_NtkMultiSetBoundsMulti
(
Abc_Ntk_t
*
pNtk
,
int
nThresh
);
static
void
Abc_NtkMultiSetBoundsSimple
(
Abc_Ntk_t
*
pNtk
);
static
void
Abc_NtkMultiSetBoundsFactor
(
Abc_Ntk_t
*
pNtk
);
static
void
Abc_NtkMultiCone
(
Abc_Obj_t
*
pNode
,
Vec_Ptr_t
*
vCone
);
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Transforms the AIG into nodes.]
Description [Threhold is the max number of nodes duplicated at a node.]
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t
*
Abc_NtkMulti
(
Abc_Ntk_t
*
pNtk
,
int
nThresh
,
int
nFaninMax
,
int
fCnf
,
int
fMulti
,
int
fSimple
,
int
fFactor
)
{
Abc_Ntk_t
*
pNtkNew
;
assert
(
Abc_NtkIsStrash
(
pNtk
)
);
assert
(
nThresh
>=
0
);
assert
(
nFaninMax
>
1
);
// print a warning about choice nodes
if
(
Abc_NtkGetChoiceNum
(
pNtk
)
)
printf
(
"Warning: The choice nodes in the AIG are removed by renoding.
\n
"
);
// define the boundary
if
(
fCnf
)
Abc_NtkMultiSetBoundsCnf
(
pNtk
);
else
if
(
fMulti
)
Abc_NtkMultiSetBoundsMulti
(
pNtk
,
nThresh
);
else
if
(
fSimple
)
Abc_NtkMultiSetBoundsSimple
(
pNtk
);
else
if
(
fFactor
)
Abc_NtkMultiSetBoundsFactor
(
pNtk
);
else
Abc_NtkMultiSetBounds
(
pNtk
,
nThresh
,
nFaninMax
);
// perform renoding for this boundary
pNtkNew
=
Abc_NtkStartFrom
(
pNtk
,
ABC_NTK_LOGIC
,
ABC_FUNC_BDD
);
Abc_NtkMultiInt
(
pNtk
,
pNtkNew
);
Abc_NtkFinalize
(
pNtk
,
pNtkNew
);
// make the network minimum base
Abc_NtkMinimumBase
(
pNtkNew
);
// fix the problem with complemented and duplicated CO edges
Abc_NtkLogicMakeSimpleCos
(
pNtkNew
,
0
);
// report the number of CNF objects
if
(
fCnf
)
{
// int nClauses = Abc_NtkGetClauseNum(pNtkNew) + 2*Abc_NtkPoNum(pNtkNew) + 2*Abc_NtkLatchNum(pNtkNew);
// printf( "CNF variables = %d. CNF clauses = %d.\n", Abc_NtkNodeNum(pNtkNew), nClauses );
}
//printf( "Maximum fanin = %d.\n", Abc_NtkGetFaninMax(pNtkNew) );
if
(
pNtk
->
pExdc
)
pNtkNew
->
pExdc
=
Abc_NtkDup
(
pNtk
->
pExdc
);
// make sure everything is okay
if
(
!
Abc_NtkCheck
(
pNtkNew
)
)
{
printf
(
"Abc_NtkMulti: The network check has failed.
\n
"
);
Abc_NtkDelete
(
pNtkNew
);
return
NULL
;
}
return
pNtkNew
;
}
/**Function*************************************************************
Synopsis [Transforms the AIG into nodes.]
Description [Threhold is the max number of nodes duplicated at a node.]
SideEffects []
SeeAlso []
***********************************************************************/
void
Abc_NtkMultiInt
(
Abc_Ntk_t
*
pNtk
,
Abc_Ntk_t
*
pNtkNew
)
{
ProgressBar
*
pProgress
;
Abc_Obj_t
*
pNode
,
*
pConst1
,
*
pNodeNew
;
int
i
;
// set the constant node
pConst1
=
Abc_AigConst1
(
pNtk
);
if
(
Abc_ObjFanoutNum
(
pConst1
)
>
0
)
{
pNodeNew
=
Abc_NtkCreateNode
(
pNtkNew
);
pNodeNew
->
pData
=
Cudd_ReadOne
(
pNtkNew
->
pManFunc
);
Cudd_Ref
(
pNodeNew
->
pData
);
pConst1
->
pCopy
=
pNodeNew
;
}
// perform renoding for POs
pProgress
=
Extra_ProgressBarStart
(
stdout
,
Abc_NtkCoNum
(
pNtk
)
);
Abc_NtkForEachCo
(
pNtk
,
pNode
,
i
)
{
Extra_ProgressBarUpdate
(
pProgress
,
i
,
NULL
);
if
(
Abc_ObjIsCi
(
Abc_ObjFanin0
(
pNode
))
)
continue
;
Abc_NtkMulti_rec
(
pNtkNew
,
Abc_ObjFanin0
(
pNode
)
);
}
Extra_ProgressBarStop
(
pProgress
);
// clean the boundaries and data field in the old network
Abc_NtkForEachObj
(
pNtk
,
pNode
,
i
)
{
pNode
->
fMarkA
=
0
;
pNode
->
pData
=
NULL
;
}
}
/**Function*************************************************************
Synopsis [Find the best multi-input node rooted at the given node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Obj_t
*
Abc_NtkMulti_rec
(
Abc_Ntk_t
*
pNtkNew
,
Abc_Obj_t
*
pNodeOld
)
{
Vec_Ptr_t
*
vCone
;
Abc_Obj_t
*
pNodeNew
;
int
i
;
assert
(
!
Abc_ObjIsComplement
(
pNodeOld
)
);
// return if the result if known
if
(
pNodeOld
->
pCopy
)
return
pNodeOld
->
pCopy
;
assert
(
Abc_ObjIsNode
(
pNodeOld
)
);
assert
(
!
Abc_AigNodeIsConst
(
pNodeOld
)
);
assert
(
pNodeOld
->
fMarkA
);
//printf( "%d ", Abc_NodeMffcSizeSupp(pNodeOld) );
// collect the renoding cone
vCone
=
Vec_PtrAlloc
(
10
);
Abc_NtkMultiCone
(
pNodeOld
,
vCone
);
// create a new node
pNodeNew
=
Abc_NtkCreateNode
(
pNtkNew
);
for
(
i
=
0
;
i
<
vCone
->
nSize
;
i
++
)
Abc_ObjAddFanin
(
pNodeNew
,
Abc_NtkMulti_rec
(
pNtkNew
,
vCone
->
pArray
[
i
])
);
// derive the function of this node
pNodeNew
->
pData
=
Abc_NtkMultiDeriveBdd
(
pNtkNew
->
pManFunc
,
pNodeOld
,
vCone
);
Cudd_Ref
(
pNodeNew
->
pData
);
Vec_PtrFree
(
vCone
);
// remember the node
pNodeOld
->
pCopy
=
pNodeNew
;
return
pNodeOld
->
pCopy
;
}
/**Function*************************************************************
Synopsis [Derives the local BDD of the node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
DdNode
*
Abc_NtkMultiDeriveBdd
(
DdManager
*
dd
,
Abc_Obj_t
*
pNodeOld
,
Vec_Ptr_t
*
vFaninsOld
)
{
Abc_Obj_t
*
pFaninOld
;
DdNode
*
bFunc
;
int
i
;
assert
(
!
Abc_AigNodeIsConst
(
pNodeOld
)
);
assert
(
Abc_ObjIsNode
(
pNodeOld
)
);
// set the elementary BDD variables for the input nodes
for
(
i
=
0
;
i
<
vFaninsOld
->
nSize
;
i
++
)
{
pFaninOld
=
vFaninsOld
->
pArray
[
i
];
pFaninOld
->
pData
=
Cudd_bddIthVar
(
dd
,
i
);
Cudd_Ref
(
pFaninOld
->
pData
);
pFaninOld
->
fMarkC
=
1
;
}
// call the recursive BDD computation
bFunc
=
Abc_NtkMultiDeriveBdd_rec
(
dd
,
pNodeOld
,
vFaninsOld
);
Cudd_Ref
(
bFunc
);
// dereference the intermediate nodes
for
(
i
=
0
;
i
<
vFaninsOld
->
nSize
;
i
++
)
{
pFaninOld
=
vFaninsOld
->
pArray
[
i
];
Cudd_RecursiveDeref
(
dd
,
pFaninOld
->
pData
);
pFaninOld
->
fMarkC
=
0
;
}
Cudd_Deref
(
bFunc
);
return
bFunc
;
}
/**Function*************************************************************
Synopsis [Derives the local BDD of the node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
DdNode
*
Abc_NtkMultiDeriveBdd_rec
(
DdManager
*
dd
,
Abc_Obj_t
*
pNode
,
Vec_Ptr_t
*
vFanins
)
{
DdNode
*
bFunc
,
*
bFunc0
,
*
bFunc1
;
assert
(
!
Abc_ObjIsComplement
(
pNode
)
);
// if the result is available return
if
(
pNode
->
fMarkC
)
{
assert
(
pNode
->
pData
);
// network has a cycle
return
pNode
->
pData
;
}
// mark the node as visited
pNode
->
fMarkC
=
1
;
Vec_PtrPush
(
vFanins
,
pNode
);
// compute the result for both branches
bFunc0
=
Abc_NtkMultiDeriveBdd_rec
(
dd
,
Abc_ObjFanin
(
pNode
,
0
),
vFanins
);
Cudd_Ref
(
bFunc0
);
bFunc1
=
Abc_NtkMultiDeriveBdd_rec
(
dd
,
Abc_ObjFanin
(
pNode
,
1
),
vFanins
);
Cudd_Ref
(
bFunc1
);
bFunc0
=
Cudd_NotCond
(
bFunc0
,
Abc_ObjFaninC0
(
pNode
)
);
bFunc1
=
Cudd_NotCond
(
bFunc1
,
Abc_ObjFaninC1
(
pNode
)
);
// get the final result
bFunc
=
Cudd_bddAnd
(
dd
,
bFunc0
,
bFunc1
);
Cudd_Ref
(
bFunc
);
Cudd_RecursiveDeref
(
dd
,
bFunc0
);
Cudd_RecursiveDeref
(
dd
,
bFunc1
);
// set the result
pNode
->
pData
=
bFunc
;
assert
(
pNode
->
pData
);
return
bFunc
;
}
/**Function*************************************************************
Synopsis [Limits the cones to be no more than the given size.]
Description [Returns 1 if the last cone was limited. Returns 0 if no changes.]
SideEffects []
SeeAlso []
***********************************************************************/
int
Abc_NtkMultiLimit_rec
(
Abc_Obj_t
*
pNode
,
Vec_Ptr_t
*
vCone
,
int
nFaninMax
,
int
fCanStop
,
int
fFirst
)
{
int
nNodes0
,
nNodes1
;
assert
(
!
Abc_ObjIsComplement
(
pNode
)
);
// check if the node should be added to the fanins
if
(
!
fFirst
&&
(
pNode
->
fMarkA
||
!
Abc_ObjIsNode
(
pNode
))
)
{
Vec_PtrPushUnique
(
vCone
,
pNode
);
return
0
;
}
// if we cannot stop in this branch, collect all nodes
if
(
!
fCanStop
)
{
Abc_NtkMultiLimit_rec
(
Abc_ObjFanin
(
pNode
,
0
),
vCone
,
nFaninMax
,
0
,
0
);
Abc_NtkMultiLimit_rec
(
Abc_ObjFanin
(
pNode
,
1
),
vCone
,
nFaninMax
,
0
,
0
);
return
0
;
}
// if we can stop, try the left branch first, and return if we stopped
assert
(
vCone
->
nSize
==
0
);
if
(
Abc_NtkMultiLimit_rec
(
Abc_ObjFanin
(
pNode
,
0
),
vCone
,
nFaninMax
,
1
,
0
)
)
return
1
;
// save the number of nodes in the left branch and call for the right branch
nNodes0
=
vCone
->
nSize
;
assert
(
nNodes0
<=
nFaninMax
);
Abc_NtkMultiLimit_rec
(
Abc_ObjFanin
(
pNode
,
1
),
vCone
,
nFaninMax
,
0
,
0
);
// check the number of nodes
if
(
vCone
->
nSize
<=
nFaninMax
)
return
0
;
// the number of nodes exceeds the limit
// get the number of nodes in the right branch
vCone
->
nSize
=
0
;
Abc_NtkMultiLimit_rec
(
Abc_ObjFanin
(
pNode
,
1
),
vCone
,
nFaninMax
,
0
,
0
);
// if this number exceeds the limit, solve the problem for this branch
if
(
vCone
->
nSize
>
nFaninMax
)
{
int
RetValue
;
vCone
->
nSize
=
0
;
RetValue
=
Abc_NtkMultiLimit_rec
(
Abc_ObjFanin
(
pNode
,
1
),
vCone
,
nFaninMax
,
1
,
0
);
assert
(
RetValue
==
1
);
return
1
;
}
nNodes1
=
vCone
->
nSize
;
assert
(
nNodes1
<=
nFaninMax
);
if
(
nNodes0
>=
nNodes1
)
{
// the left branch is larger - cut it
assert
(
Abc_ObjFanin
(
pNode
,
0
)
->
fMarkA
==
0
);
Abc_ObjFanin
(
pNode
,
0
)
->
fMarkA
=
1
;
}
else
{
// the right branch is larger - cut it
assert
(
Abc_ObjFanin
(
pNode
,
1
)
->
fMarkA
==
0
);
Abc_ObjFanin
(
pNode
,
1
)
->
fMarkA
=
1
;
}
return
1
;
}
/**Function*************************************************************
Synopsis [Limits the cones to be no more than the given size.]
Description [Returns 1 if the last cone was limited. Returns 0 if no changes.]
SideEffects []
SeeAlso []
***********************************************************************/
int
Abc_NtkMultiLimit
(
Abc_Obj_t
*
pNode
,
Vec_Ptr_t
*
vCone
,
int
nFaninMax
)
{
vCone
->
nSize
=
0
;
return
Abc_NtkMultiLimit_rec
(
pNode
,
vCone
,
nFaninMax
,
1
,
1
);
}
/**Function*************************************************************
Synopsis [Sets the expansion boundary for multi-input nodes.]
Description [The boundary includes the set of PIs and all nodes such that
when expanding over the node we duplicate no more than nThresh nodes.]
SideEffects []
SeeAlso []
***********************************************************************/
void
Abc_NtkMultiSetBounds
(
Abc_Ntk_t
*
pNtk
,
int
nThresh
,
int
nFaninMax
)
{
Vec_Ptr_t
*
vCone
=
Vec_PtrAlloc
(
10
);
Abc_Obj_t
*
pNode
;
int
i
,
nFanouts
,
nConeSize
;
// make sure the mark is not set
Abc_NtkForEachObj
(
pNtk
,
pNode
,
i
)
assert
(
pNode
->
fMarkA
==
0
);
// mark the nodes where expansion stops using pNode->fMarkA
Abc_NtkForEachNode
(
pNtk
,
pNode
,
i
)
{
// skip PI/PO nodes
// if ( Abc_NodeIsConst(pNode) )
// continue;
// mark the nodes with multiple fanouts
nFanouts
=
Abc_ObjFanoutNum
(
pNode
);
nConeSize
=
Abc_NodeMffcSize
(
pNode
);
if
(
(
nFanouts
-
1
)
*
nConeSize
>
nThresh
)
pNode
->
fMarkA
=
1
;
}
// mark the PO drivers
Abc_NtkForEachCo
(
pNtk
,
pNode
,
i
)
Abc_ObjFanin0
(
pNode
)
->
fMarkA
=
1
;
// make sure the fanin limit is met
Abc_NtkForEachNode
(
pNtk
,
pNode
,
i
)
{
// skip PI/PO nodes
// if ( Abc_NodeIsConst(pNode) )
// continue;
if
(
pNode
->
fMarkA
==
0
)
continue
;
// continue cutting branches until it meets the fanin limit
while
(
Abc_NtkMultiLimit
(
pNode
,
vCone
,
nFaninMax
)
);
assert
(
vCone
->
nSize
<=
nFaninMax
);
}
Vec_PtrFree
(
vCone
);
/*
// make sure the fanin limit is met
Abc_NtkForEachNode( pNtk, pNode, i )
{
// skip PI/PO nodes
// if ( Abc_NodeIsConst(pNode) )
// continue;
if ( pNode->fMarkA == 0 )
continue;
Abc_NtkMultiCone( pNode, vCone );
assert( vCone->nSize <= nFaninMax );
}
*/
}
/**Function*************************************************************
Synopsis [Sets the expansion boundary for conversion into CNF.]
Description [The boundary includes the set of PIs, the roots of MUXes,
the nodes with multiple fanouts and the nodes with complemented outputs.]
SideEffects []
SeeAlso []
***********************************************************************/
void
Abc_NtkMultiSetBoundsCnf
(
Abc_Ntk_t
*
pNtk
)
{
Abc_Obj_t
*
pNode
;
int
i
,
nMuxes
;
// make sure the mark is not set
Abc_NtkForEachObj
(
pNtk
,
pNode
,
i
)
assert
(
pNode
->
fMarkA
==
0
);
// mark the nodes where expansion stops using pNode->fMarkA
Abc_NtkForEachNode
(
pNtk
,
pNode
,
i
)
{
// skip PI/PO nodes
// if ( Abc_NodeIsConst(pNode) )
// continue;
// mark the nodes with multiple fanouts
if
(
Abc_ObjFanoutNum
(
pNode
)
>
1
)
pNode
->
fMarkA
=
1
;
// mark the nodes that are roots of MUXes
if
(
Abc_NodeIsMuxType
(
pNode
)
)
{
pNode
->
fMarkA
=
1
;
Abc_ObjFanin0
(
Abc_ObjFanin0
(
pNode
)
)
->
fMarkA
=
1
;
Abc_ObjFanin0
(
Abc_ObjFanin1
(
pNode
)
)
->
fMarkA
=
1
;
Abc_ObjFanin1
(
Abc_ObjFanin0
(
pNode
)
)
->
fMarkA
=
1
;
Abc_ObjFanin1
(
Abc_ObjFanin1
(
pNode
)
)
->
fMarkA
=
1
;
}
else
// mark the complemented edges
{
if
(
Abc_ObjFaninC0
(
pNode
)
)
Abc_ObjFanin0
(
pNode
)
->
fMarkA
=
1
;
if
(
Abc_ObjFaninC1
(
pNode
)
)
Abc_ObjFanin1
(
pNode
)
->
fMarkA
=
1
;
}
}
// mark the PO drivers
Abc_NtkForEachCo
(
pNtk
,
pNode
,
i
)
Abc_ObjFanin0
(
pNode
)
->
fMarkA
=
1
;
// count the number of MUXes
nMuxes
=
0
;
Abc_NtkForEachNode
(
pNtk
,
pNode
,
i
)
{
// skip PI/PO nodes
// if ( Abc_NodeIsConst(pNode) )
// continue;
if
(
Abc_NodeIsMuxType
(
pNode
)
&&
Abc_ObjFanin0
(
pNode
)
->
fMarkA
==
0
&&
Abc_ObjFanin1
(
pNode
)
->
fMarkA
==
0
)
nMuxes
++
;
}
// printf( "The number of MUXes detected = %d (%5.2f %% of logic).\n", nMuxes, 300.0*nMuxes/Abc_NtkNodeNum(pNtk) );
}
/**Function*************************************************************
Synopsis [Sets the expansion boundary for conversion into multi-input AND graph.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
Abc_NtkMultiSetBoundsMulti
(
Abc_Ntk_t
*
pNtk
,
int
nThresh
)
{
Abc_Obj_t
*
pNode
;
int
i
,
nFanouts
,
nConeSize
;
// make sure the mark is not set
Abc_NtkForEachObj
(
pNtk
,
pNode
,
i
)
assert
(
pNode
->
fMarkA
==
0
);
// mark the nodes where expansion stops using pNode->fMarkA
Abc_NtkForEachNode
(
pNtk
,
pNode
,
i
)
{
// skip PI/PO nodes
// if ( Abc_NodeIsConst(pNode) )
// continue;
// mark the nodes with multiple fanouts
// if ( Abc_ObjFanoutNum(pNode) > 1 )
// pNode->fMarkA = 1;
// mark the nodes with multiple fanouts
nFanouts
=
Abc_ObjFanoutNum
(
pNode
);
nConeSize
=
Abc_NodeMffcSizeStop
(
pNode
);
if
(
(
nFanouts
-
1
)
*
nConeSize
>
nThresh
)
pNode
->
fMarkA
=
1
;
// mark the children if they are pointed by the complemented edges
if
(
Abc_ObjFaninC0
(
pNode
)
)
Abc_ObjFanin0
(
pNode
)
->
fMarkA
=
1
;
if
(
Abc_ObjFaninC1
(
pNode
)
)
Abc_ObjFanin1
(
pNode
)
->
fMarkA
=
1
;
}
// mark the PO drivers
Abc_NtkForEachCo
(
pNtk
,
pNode
,
i
)
Abc_ObjFanin0
(
pNode
)
->
fMarkA
=
1
;
}
/**Function*************************************************************
Synopsis [Sets a simple boundary.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
Abc_NtkMultiSetBoundsSimple
(
Abc_Ntk_t
*
pNtk
)
{
Abc_Obj_t
*
pNode
;
int
i
;
// make sure the mark is not set
Abc_NtkForEachObj
(
pNtk
,
pNode
,
i
)
assert
(
pNode
->
fMarkA
==
0
);
// mark the nodes where expansion stops using pNode->fMarkA
Abc_NtkForEachNode
(
pNtk
,
pNode
,
i
)
pNode
->
fMarkA
=
1
;
}
/**Function*************************************************************
Synopsis [Sets a factor-cut boundary.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
Abc_NtkMultiSetBoundsFactor
(
Abc_Ntk_t
*
pNtk
)
{
Abc_Obj_t
*
pNode
;
int
i
;
// make sure the mark is not set
Abc_NtkForEachObj
(
pNtk
,
pNode
,
i
)
assert
(
pNode
->
fMarkA
==
0
);
// mark the nodes where expansion stops using pNode->fMarkA
Abc_NtkForEachNode
(
pNtk
,
pNode
,
i
)
pNode
->
fMarkA
=
(
pNode
->
vFanouts
.
nSize
>
1
&&
!
Abc_NodeIsMuxControlType
(
pNode
));
// mark the PO drivers
Abc_NtkForEachCo
(
pNtk
,
pNode
,
i
)
Abc_ObjFanin0
(
pNode
)
->
fMarkA
=
1
;
}
/**Function*************************************************************
Synopsis [Collects the fanins of a large node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
Abc_NtkMultiCone_rec
(
Abc_Obj_t
*
pNode
,
Vec_Ptr_t
*
vCone
)
{
assert
(
!
Abc_ObjIsComplement
(
pNode
)
);
if
(
pNode
->
fMarkA
||
!
Abc_ObjIsNode
(
pNode
)
)
{
Vec_PtrPushUnique
(
vCone
,
pNode
);
return
;
}
Abc_NtkMultiCone_rec
(
Abc_ObjFanin
(
pNode
,
0
),
vCone
);
Abc_NtkMultiCone_rec
(
Abc_ObjFanin
(
pNode
,
1
),
vCone
);
}
/**Function*************************************************************
Synopsis [Collects the fanins of a large node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
Abc_NtkMultiCone
(
Abc_Obj_t
*
pNode
,
Vec_Ptr_t
*
vCone
)
{
assert
(
!
Abc_ObjIsComplement
(
pNode
)
);
assert
(
Abc_ObjIsNode
(
pNode
)
);
vCone
->
nSize
=
0
;
Abc_NtkMultiCone_rec
(
Abc_ObjFanin
(
pNode
,
0
),
vCone
);
Abc_NtkMultiCone_rec
(
Abc_ObjFanin
(
pNode
,
1
),
vCone
);
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
src/base/abci/abcNtbdd.c
View file @
38254947
...
@@ -536,73 +536,6 @@ double Abc_NtkSpacePercentage( Abc_Obj_t * pNode )
...
@@ -536,73 +536,6 @@ double Abc_NtkSpacePercentage( Abc_Obj_t * pNode )
#include "reo.h"
/**Function*************************************************************
Synopsis [Reorders BDD of the local function of the node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
Abc_NodeBddReorder
(
reo_man
*
p
,
Abc_Obj_t
*
pNode
)
{
Abc_Obj_t
*
pFanin
;
DdNode
*
bFunc
;
int
*
pOrder
,
i
;
// create the temporary array for the variable order
pOrder
=
ALLOC
(
int
,
Abc_ObjFaninNum
(
pNode
)
);
for
(
i
=
0
;
i
<
Abc_ObjFaninNum
(
pNode
);
i
++
)
pOrder
[
i
]
=
-
1
;
// reorder the BDD
bFunc
=
Extra_Reorder
(
p
,
pNode
->
pNtk
->
pManFunc
,
pNode
->
pData
,
pOrder
);
Cudd_Ref
(
bFunc
);
Cudd_RecursiveDeref
(
pNode
->
pNtk
->
pManFunc
,
pNode
->
pData
);
pNode
->
pData
=
bFunc
;
// update the fanin order
Abc_ObjForEachFanin
(
pNode
,
pFanin
,
i
)
pOrder
[
i
]
=
pNode
->
vFanins
.
pArray
[
pOrder
[
i
]
];
Abc_ObjForEachFanin
(
pNode
,
pFanin
,
i
)
pNode
->
vFanins
.
pArray
[
i
]
=
pOrder
[
i
];
free
(
pOrder
);
}
/**Function*************************************************************
Synopsis [Reorders BDDs of the local functions.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
Abc_NtkBddReorder
(
Abc_Ntk_t
*
pNtk
,
int
fVerbose
)
{
reo_man
*
p
;
Abc_Obj_t
*
pNode
;
int
i
;
p
=
Extra_ReorderInit
(
Abc_NtkGetFaninMax
(
pNtk
),
100
);
Abc_NtkForEachNode
(
pNtk
,
pNode
,
i
)
{
if
(
Abc_ObjFaninNum
(
pNode
)
<
3
)
continue
;
if
(
fVerbose
)
fprintf
(
stdout
,
"%10s: "
,
Abc_ObjName
(
pNode
)
);
if
(
fVerbose
)
fprintf
(
stdout
,
"Before = %5d BDD nodes. "
,
Cudd_DagSize
(
pNode
->
pData
)
);
Abc_NodeBddReorder
(
p
,
pNode
);
if
(
fVerbose
)
fprintf
(
stdout
,
"After = %5d BDD nodes.
\n
"
,
Cudd_DagSize
(
pNode
->
pData
)
);
}
Extra_ReorderQuit
(
p
);
}
/**Function*************************************************************
/**Function*************************************************************
...
...
src/base/abci/abcRenode.c
View file @
38254947
...
@@ -6,7 +6,7 @@
...
@@ -6,7 +6,7 @@
PackageName [Network and node package.]
PackageName [Network and node package.]
Synopsis [
Procedures which transform an AIG into the network of SOP logic nodes.
]
Synopsis []
Author [Alan Mishchenko]
Author [Alan Mishchenko]
...
@@ -19,22 +19,22 @@
...
@@ -19,22 +19,22 @@
***********************************************************************/
***********************************************************************/
#include "abc.h"
#include "abc.h"
#include "reo.h"
#include "if.h"
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
static
void
Abc_NtkRenodeInt
(
Abc_Ntk_t
*
pNtk
,
Abc_Ntk_t
*
pNtkNew
);
static
int
Abc_NtkRenodeEvalBdd
(
unsigned
*
pTruth
,
int
nVars
);
static
Abc_Obj_t
*
Abc_NtkRenode_rec
(
Abc_Ntk_t
*
pNtkNew
,
Abc_Obj_t
*
pNodeOld
);
static
int
Abc_NtkRenodeEvalSop
(
unsigned
*
pTruth
,
int
nVars
);
static
DdNode
*
Abc_NtkRenodeDeriveBdd_rec
(
DdManager
*
dd
,
Abc_Obj_t
*
pNodeOld
,
Vec_Ptr_t
*
vFanins
);
static
reo_man
*
s_pReo
=
NULL
;
static
DdManager
*
s_pDd
=
NULL
;
static
void
Abc_NtkRenodeSetBounds
(
Abc_Ntk_t
*
pNtk
,
int
nThresh
,
int
nFaninMax
);
typedef
int
Kit_Graph_t
;
static
void
Abc_NtkRenodeSetBoundsCnf
(
Abc_Ntk_t
*
pNtk
);
extern
DdNode
*
Kit_TruthToBdd
(
DdManager
*
dd
,
unsigned
*
pTruth
,
int
nVars
);
static
void
Abc_NtkRenodeSetBoundsMulti
(
Abc_Ntk_t
*
pNtk
,
int
nThresh
);
extern
Kit_Graph_t
*
Kit_TruthToGraph
(
unsigned
*
pTruth
,
int
nVars
);
static
void
Abc_NtkRenodeSetBoundsSimple
(
Abc_Ntk_t
*
pNtk
);
static
void
Abc_NtkRenodeSetBoundsFactor
(
Abc_Ntk_t
*
pNtk
);
static
void
Abc_NtkRenodeCone
(
Abc_Obj_t
*
pNode
,
Vec_Ptr_t
*
vCone
);
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
/// FUNCTION DEFINITIONS ///
...
@@ -42,203 +42,70 @@ static void Abc_NtkRenodeCone( Abc_Obj_t * pNode, Vec_Ptr_t * vCone );
...
@@ -42,203 +42,70 @@ static void Abc_NtkRenodeCone( Abc_Obj_t * pNode, Vec_Ptr_t * vCone );
/**Function*************************************************************
/**Function*************************************************************
Synopsis [
Transforms the AIG into nodes
.]
Synopsis [
Performs renoding as technology mapping
.]
Description [
Threhold is the max number of nodes duplicated at a node.
]
Description []
SideEffects []
SideEffects []
SeeAlso []
SeeAlso []
***********************************************************************/
***********************************************************************/
Abc_Ntk_t
*
Abc_NtkRenode
(
Abc_Ntk_t
*
pNtk
,
int
n
Thresh
,
int
nFaninMax
,
int
fCnf
,
int
fMulti
,
int
fSimple
,
int
fFactor
)
Abc_Ntk_t
*
Abc_NtkRenode
(
Abc_Ntk_t
*
pNtk
,
int
n
FaninMax
,
int
fUseBdds
,
int
fVerbose
)
{
{
extern
Abc_Ntk_t
*
Abc_NtkIf
(
Abc_Ntk_t
*
pNtk
,
If_Par_t
*
pPars
);
If_Par_t
Pars
,
*
pPars
=
&
Pars
;
Abc_Ntk_t
*
pNtkNew
;
Abc_Ntk_t
*
pNtkNew
;
assert
(
Abc_NtkIsStrash
(
pNtk
)
);
// set defaults
assert
(
nThresh
>=
0
);
memset
(
pPars
,
0
,
sizeof
(
If_Par_t
)
);
assert
(
nFaninMax
>
1
);
// user-controlable paramters
pPars
->
Mode
=
0
;
// print a warning about choice nodes
pPars
->
nLutSize
=
nFaninMax
;
if
(
Abc_NtkGetChoiceNum
(
pNtk
)
)
pPars
->
nCutsMax
=
10
;
printf
(
"Warning: The choice nodes in the AIG are removed by renoding.
\n
"
);
pPars
->
DelayTarget
=
-
1
;
pPars
->
fPreprocess
=
1
;
// define the boundary
pPars
->
fArea
=
0
;
if
(
fCnf
)
pPars
->
fFancy
=
0
;
Abc_NtkRenodeSetBoundsCnf
(
pNtk
);
pPars
->
fExpRed
=
0
;
//
else
if
(
fMulti
)
pPars
->
fLatchPaths
=
0
;
Abc_NtkRenodeSetBoundsMulti
(
pNtk
,
nThresh
);
pPars
->
fSeq
=
0
;
else
if
(
fSimple
)
pPars
->
fVerbose
=
0
;
Abc_NtkRenodeSetBoundsSimple
(
pNtk
);
// internal parameters
else
if
(
fFactor
)
pPars
->
fTruth
=
1
;
Abc_NtkRenodeSetBoundsFactor
(
pNtk
);
pPars
->
nLatches
=
0
;
else
pPars
->
pLutLib
=
NULL
;
// Abc_FrameReadLibLut();
Abc_NtkRenodeSetBounds
(
pNtk
,
nThresh
,
nFaninMax
);
pPars
->
pTimesArr
=
NULL
;
pPars
->
pTimesArr
=
NULL
;
// perform renoding for this boundary
pPars
->
pFuncCost
=
fUseBdds
?
Abc_NtkRenodeEvalBdd
:
Abc_NtkRenodeEvalSop
;
pNtkNew
=
Abc_NtkStartFrom
(
pNtk
,
ABC_NTK_LOGIC
,
ABC_FUNC_BDD
);
Abc_NtkRenodeInt
(
pNtk
,
pNtkNew
);
// start the manager
Abc_NtkFinalize
(
pNtk
,
pNtkNew
);
if
(
fUseBdds
)
{
// make the network minimum base
assert
(
s_pReo
==
NULL
);
Abc_NtkMinimumBase
(
pNtkNew
);
s_pDd
=
Cudd_Init
(
nFaninMax
,
0
,
CUDD_UNIQUE_SLOTS
,
CUDD_CACHE_SLOTS
,
0
);
s_pReo
=
Extra_ReorderInit
(
nFaninMax
,
100
);
// fix the problem with complemented and duplicated CO edges
pPars
->
fUseBdds
=
1
;
Abc_NtkLogicMakeSimpleCos
(
pNtkNew
,
0
);
pPars
->
pReoMan
=
s_pReo
;
}
// report the number of CNF objects
if
(
fCnf
)
// perform mapping/renoding
{
pNtkNew
=
Abc_NtkIf
(
pNtk
,
pPars
);
// int nClauses = Abc_NtkGetClauseNum(pNtkNew) + 2*Abc_NtkPoNum(pNtkNew) + 2*Abc_NtkLatchNum(pNtkNew);
// printf( "CNF variables = %d. CNF clauses = %d.\n", Abc_NtkNodeNum(pNtkNew), nClauses );
// start the manager
}
if
(
fUseBdds
)
//printf( "Maximum fanin = %d.\n", Abc_NtkGetFaninMax(pNtkNew) );
{
Extra_StopManager
(
s_pDd
);
if
(
pNtk
->
pExdc
)
Extra_ReorderQuit
(
s_pReo
);
pNtkNew
->
pExdc
=
Abc_NtkDup
(
pNtk
->
pExdc
);
s_pReo
=
NULL
;
// make sure everything is okay
s_pDd
=
NULL
;
if
(
!
Abc_NtkCheck
(
pNtkNew
)
)
{
printf
(
"Abc_NtkRenode: The network check has failed.
\n
"
);
Abc_NtkDelete
(
pNtkNew
);
return
NULL
;
}
}
return
pNtkNew
;
return
pNtkNew
;
}
}
/**Function*************************************************************
/**Function*************************************************************
Synopsis [Transforms the AIG into nodes.]
Synopsis [Derives the BDD after reordering.]
Description [Threhold is the max number of nodes duplicated at a node.]
SideEffects []
SeeAlso []
***********************************************************************/
void
Abc_NtkRenodeInt
(
Abc_Ntk_t
*
pNtk
,
Abc_Ntk_t
*
pNtkNew
)
{
ProgressBar
*
pProgress
;
Abc_Obj_t
*
pNode
,
*
pConst1
,
*
pNodeNew
;
int
i
;
// set the constant node
pConst1
=
Abc_AigConst1
(
pNtk
);
if
(
Abc_ObjFanoutNum
(
pConst1
)
>
0
)
{
pNodeNew
=
Abc_NtkCreateNode
(
pNtkNew
);
pNodeNew
->
pData
=
Cudd_ReadOne
(
pNtkNew
->
pManFunc
);
Cudd_Ref
(
pNodeNew
->
pData
);
pConst1
->
pCopy
=
pNodeNew
;
}
// perform renoding for POs
pProgress
=
Extra_ProgressBarStart
(
stdout
,
Abc_NtkCoNum
(
pNtk
)
);
Abc_NtkForEachCo
(
pNtk
,
pNode
,
i
)
{
Extra_ProgressBarUpdate
(
pProgress
,
i
,
NULL
);
if
(
Abc_ObjIsCi
(
Abc_ObjFanin0
(
pNode
))
)
continue
;
Abc_NtkRenode_rec
(
pNtkNew
,
Abc_ObjFanin0
(
pNode
)
);
}
Extra_ProgressBarStop
(
pProgress
);
// clean the boundaries and data field in the old network
Abc_NtkForEachObj
(
pNtk
,
pNode
,
i
)
{
pNode
->
fMarkA
=
0
;
pNode
->
pData
=
NULL
;
}
}
/**Function*************************************************************
Synopsis [Find the best multi-input node rooted at the given node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Obj_t
*
Abc_NtkRenode_rec
(
Abc_Ntk_t
*
pNtkNew
,
Abc_Obj_t
*
pNodeOld
)
{
Vec_Ptr_t
*
vCone
;
Abc_Obj_t
*
pNodeNew
;
int
i
;
assert
(
!
Abc_ObjIsComplement
(
pNodeOld
)
);
// return if the result if known
if
(
pNodeOld
->
pCopy
)
return
pNodeOld
->
pCopy
;
assert
(
Abc_ObjIsNode
(
pNodeOld
)
);
assert
(
!
Abc_AigNodeIsConst
(
pNodeOld
)
);
assert
(
pNodeOld
->
fMarkA
);
//printf( "%d ", Abc_NodeMffcSizeSupp(pNodeOld) );
// collect the renoding cone
vCone
=
Vec_PtrAlloc
(
10
);
Abc_NtkRenodeCone
(
pNodeOld
,
vCone
);
// create a new node
pNodeNew
=
Abc_NtkCreateNode
(
pNtkNew
);
for
(
i
=
0
;
i
<
vCone
->
nSize
;
i
++
)
Abc_ObjAddFanin
(
pNodeNew
,
Abc_NtkRenode_rec
(
pNtkNew
,
vCone
->
pArray
[
i
])
);
// derive the function of this node
pNodeNew
->
pData
=
Abc_NtkRenodeDeriveBdd
(
pNtkNew
->
pManFunc
,
pNodeOld
,
vCone
);
Cudd_Ref
(
pNodeNew
->
pData
);
Vec_PtrFree
(
vCone
);
// remember the node
pNodeOld
->
pCopy
=
pNodeNew
;
return
pNodeOld
->
pCopy
;
}
/**Function*************************************************************
Synopsis [Derives the local BDD of the node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
DdNode
*
Abc_NtkRenodeDeriveBdd
(
DdManager
*
dd
,
Abc_Obj_t
*
pNodeOld
,
Vec_Ptr_t
*
vFaninsOld
)
{
Abc_Obj_t
*
pFaninOld
;
DdNode
*
bFunc
;
int
i
;
assert
(
!
Abc_AigNodeIsConst
(
pNodeOld
)
);
assert
(
Abc_ObjIsNode
(
pNodeOld
)
);
// set the elementary BDD variables for the input nodes
for
(
i
=
0
;
i
<
vFaninsOld
->
nSize
;
i
++
)
{
pFaninOld
=
vFaninsOld
->
pArray
[
i
];
pFaninOld
->
pData
=
Cudd_bddIthVar
(
dd
,
i
);
Cudd_Ref
(
pFaninOld
->
pData
);
pFaninOld
->
fMarkC
=
1
;
}
// call the recursive BDD computation
bFunc
=
Abc_NtkRenodeDeriveBdd_rec
(
dd
,
pNodeOld
,
vFaninsOld
);
Cudd_Ref
(
bFunc
);
// dereference the intermediate nodes
for
(
i
=
0
;
i
<
vFaninsOld
->
nSize
;
i
++
)
{
pFaninOld
=
vFaninsOld
->
pArray
[
i
];
Cudd_RecursiveDeref
(
dd
,
pFaninOld
->
pData
);
pFaninOld
->
fMarkC
=
0
;
}
Cudd_Deref
(
bFunc
);
return
bFunc
;
}
/**Function*************************************************************
Synopsis [Derives the local BDD of the node.]
Description []
Description []
...
@@ -247,377 +114,22 @@ DdNode * Abc_NtkRenodeDeriveBdd( DdManager * dd, Abc_Obj_t * pNodeOld, Vec_Ptr_t
...
@@ -247,377 +114,22 @@ DdNode * Abc_NtkRenodeDeriveBdd( DdManager * dd, Abc_Obj_t * pNodeOld, Vec_Ptr_t
SeeAlso []
SeeAlso []
***********************************************************************/
***********************************************************************/
DdNode
*
Abc_NtkRenodeDeriveBdd_rec
(
DdManager
*
dd
,
Abc_Obj_t
*
pNode
,
Vec_Ptr_t
*
vFanins
)
int
Abc_NtkRenodeEvalBdd
(
unsigned
*
pTruth
,
int
nVars
)
{
DdNode
*
bFunc
,
*
bFunc0
,
*
bFunc1
;
assert
(
!
Abc_ObjIsComplement
(
pNode
)
);
// if the result is available return
if
(
pNode
->
fMarkC
)
{
assert
(
pNode
->
pData
);
// network has a cycle
return
pNode
->
pData
;
}
// mark the node as visited
pNode
->
fMarkC
=
1
;
Vec_PtrPush
(
vFanins
,
pNode
);
// compute the result for both branches
bFunc0
=
Abc_NtkRenodeDeriveBdd_rec
(
dd
,
Abc_ObjFanin
(
pNode
,
0
),
vFanins
);
Cudd_Ref
(
bFunc0
);
bFunc1
=
Abc_NtkRenodeDeriveBdd_rec
(
dd
,
Abc_ObjFanin
(
pNode
,
1
),
vFanins
);
Cudd_Ref
(
bFunc1
);
bFunc0
=
Cudd_NotCond
(
bFunc0
,
Abc_ObjFaninC0
(
pNode
)
);
bFunc1
=
Cudd_NotCond
(
bFunc1
,
Abc_ObjFaninC1
(
pNode
)
);
// get the final result
bFunc
=
Cudd_bddAnd
(
dd
,
bFunc0
,
bFunc1
);
Cudd_Ref
(
bFunc
);
Cudd_RecursiveDeref
(
dd
,
bFunc0
);
Cudd_RecursiveDeref
(
dd
,
bFunc1
);
// set the result
pNode
->
pData
=
bFunc
;
assert
(
pNode
->
pData
);
return
bFunc
;
}
/**Function*************************************************************
Synopsis [Limits the cones to be no more than the given size.]
Description [Returns 1 if the last cone was limited. Returns 0 if no changes.]
SideEffects []
SeeAlso []
***********************************************************************/
int
Abc_NtkRenodeLimit_rec
(
Abc_Obj_t
*
pNode
,
Vec_Ptr_t
*
vCone
,
int
nFaninMax
,
int
fCanStop
,
int
fFirst
)
{
int
nNodes0
,
nNodes1
;
assert
(
!
Abc_ObjIsComplement
(
pNode
)
);
// check if the node should be added to the fanins
if
(
!
fFirst
&&
(
pNode
->
fMarkA
||
!
Abc_ObjIsNode
(
pNode
))
)
{
Vec_PtrPushUnique
(
vCone
,
pNode
);
return
0
;
}
// if we cannot stop in this branch, collect all nodes
if
(
!
fCanStop
)
{
Abc_NtkRenodeLimit_rec
(
Abc_ObjFanin
(
pNode
,
0
),
vCone
,
nFaninMax
,
0
,
0
);
Abc_NtkRenodeLimit_rec
(
Abc_ObjFanin
(
pNode
,
1
),
vCone
,
nFaninMax
,
0
,
0
);
return
0
;
}
// if we can stop, try the left branch first, and return if we stopped
assert
(
vCone
->
nSize
==
0
);
if
(
Abc_NtkRenodeLimit_rec
(
Abc_ObjFanin
(
pNode
,
0
),
vCone
,
nFaninMax
,
1
,
0
)
)
return
1
;
// save the number of nodes in the left branch and call for the right branch
nNodes0
=
vCone
->
nSize
;
assert
(
nNodes0
<=
nFaninMax
);
Abc_NtkRenodeLimit_rec
(
Abc_ObjFanin
(
pNode
,
1
),
vCone
,
nFaninMax
,
0
,
0
);
// check the number of nodes
if
(
vCone
->
nSize
<=
nFaninMax
)
return
0
;
// the number of nodes exceeds the limit
// get the number of nodes in the right branch
vCone
->
nSize
=
0
;
Abc_NtkRenodeLimit_rec
(
Abc_ObjFanin
(
pNode
,
1
),
vCone
,
nFaninMax
,
0
,
0
);
// if this number exceeds the limit, solve the problem for this branch
if
(
vCone
->
nSize
>
nFaninMax
)
{
int
RetValue
;
vCone
->
nSize
=
0
;
RetValue
=
Abc_NtkRenodeLimit_rec
(
Abc_ObjFanin
(
pNode
,
1
),
vCone
,
nFaninMax
,
1
,
0
);
assert
(
RetValue
==
1
);
return
1
;
}
nNodes1
=
vCone
->
nSize
;
assert
(
nNodes1
<=
nFaninMax
);
if
(
nNodes0
>=
nNodes1
)
{
// the left branch is larger - cut it
assert
(
Abc_ObjFanin
(
pNode
,
0
)
->
fMarkA
==
0
);
Abc_ObjFanin
(
pNode
,
0
)
->
fMarkA
=
1
;
}
else
{
// the right branch is larger - cut it
assert
(
Abc_ObjFanin
(
pNode
,
1
)
->
fMarkA
==
0
);
Abc_ObjFanin
(
pNode
,
1
)
->
fMarkA
=
1
;
}
return
1
;
}
/**Function*************************************************************
Synopsis [Limits the cones to be no more than the given size.]
Description [Returns 1 if the last cone was limited. Returns 0 if no changes.]
SideEffects []
SeeAlso []
***********************************************************************/
int
Abc_NtkRenodeLimit
(
Abc_Obj_t
*
pNode
,
Vec_Ptr_t
*
vCone
,
int
nFaninMax
)
{
{
vCone
->
nSize
=
0
;
DdNode
*
bFunc
,
*
bFuncNew
;
return
Abc_NtkRenodeLimit_rec
(
pNode
,
vCone
,
nFaninMax
,
1
,
1
);
int
nNodes
,
nSupport
;
}
bFunc
=
Kit_TruthToBdd
(
s_pDd
,
pTruth
,
nVars
);
Cudd_Ref
(
bFunc
);
bFuncNew
=
Extra_Reorder
(
s_pReo
,
s_pDd
,
bFunc
,
NULL
);
Cudd_Ref
(
bFuncNew
);
/**Function*************************************************************
nSupport
=
Cudd_SupportSize
(
s_pDd
,
bFuncNew
);
nNodes
=
Cudd_DagSize
(
bFuncNew
);
Synopsis [Sets the expansion boundary for multi-input nodes.]
Cudd_RecursiveDeref
(
s_pDd
,
bFuncNew
);
Cudd_RecursiveDeref
(
s_pDd
,
bFunc
);
Description [The boundary includes the set of PIs and all nodes such that
return
(
nSupport
<<
16
)
|
nNodes
;
when expanding over the node we duplicate no more than nThresh nodes.]
SideEffects []
SeeAlso []
***********************************************************************/
void
Abc_NtkRenodeSetBounds
(
Abc_Ntk_t
*
pNtk
,
int
nThresh
,
int
nFaninMax
)
{
Vec_Ptr_t
*
vCone
=
Vec_PtrAlloc
(
10
);
Abc_Obj_t
*
pNode
;
int
i
,
nFanouts
,
nConeSize
;
// make sure the mark is not set
Abc_NtkForEachObj
(
pNtk
,
pNode
,
i
)
assert
(
pNode
->
fMarkA
==
0
);
// mark the nodes where expansion stops using pNode->fMarkA
Abc_NtkForEachNode
(
pNtk
,
pNode
,
i
)
{
// skip PI/PO nodes
// if ( Abc_NodeIsConst(pNode) )
// continue;
// mark the nodes with multiple fanouts
nFanouts
=
Abc_ObjFanoutNum
(
pNode
);
nConeSize
=
Abc_NodeMffcSize
(
pNode
);
if
(
(
nFanouts
-
1
)
*
nConeSize
>
nThresh
)
pNode
->
fMarkA
=
1
;
}
// mark the PO drivers
Abc_NtkForEachCo
(
pNtk
,
pNode
,
i
)
Abc_ObjFanin0
(
pNode
)
->
fMarkA
=
1
;
// make sure the fanin limit is met
Abc_NtkForEachNode
(
pNtk
,
pNode
,
i
)
{
// skip PI/PO nodes
// if ( Abc_NodeIsConst(pNode) )
// continue;
if
(
pNode
->
fMarkA
==
0
)
continue
;
// continue cutting branches until it meets the fanin limit
while
(
Abc_NtkRenodeLimit
(
pNode
,
vCone
,
nFaninMax
)
);
assert
(
vCone
->
nSize
<=
nFaninMax
);
}
Vec_PtrFree
(
vCone
);
/*
// make sure the fanin limit is met
Abc_NtkForEachNode( pNtk, pNode, i )
{
// skip PI/PO nodes
// if ( Abc_NodeIsConst(pNode) )
// continue;
if ( pNode->fMarkA == 0 )
continue;
Abc_NtkRenodeCone( pNode, vCone );
assert( vCone->nSize <= nFaninMax );
}
*/
}
/**Function*************************************************************
Synopsis [Sets the expansion boundary for conversion into CNF.]
Description [The boundary includes the set of PIs, the roots of MUXes,
the nodes with multiple fanouts and the nodes with complemented outputs.]
SideEffects []
SeeAlso []
***********************************************************************/
void
Abc_NtkRenodeSetBoundsCnf
(
Abc_Ntk_t
*
pNtk
)
{
Abc_Obj_t
*
pNode
;
int
i
,
nMuxes
;
// make sure the mark is not set
Abc_NtkForEachObj
(
pNtk
,
pNode
,
i
)
assert
(
pNode
->
fMarkA
==
0
);
// mark the nodes where expansion stops using pNode->fMarkA
Abc_NtkForEachNode
(
pNtk
,
pNode
,
i
)
{
// skip PI/PO nodes
// if ( Abc_NodeIsConst(pNode) )
// continue;
// mark the nodes with multiple fanouts
if
(
Abc_ObjFanoutNum
(
pNode
)
>
1
)
pNode
->
fMarkA
=
1
;
// mark the nodes that are roots of MUXes
if
(
Abc_NodeIsMuxType
(
pNode
)
)
{
pNode
->
fMarkA
=
1
;
Abc_ObjFanin0
(
Abc_ObjFanin0
(
pNode
)
)
->
fMarkA
=
1
;
Abc_ObjFanin0
(
Abc_ObjFanin1
(
pNode
)
)
->
fMarkA
=
1
;
Abc_ObjFanin1
(
Abc_ObjFanin0
(
pNode
)
)
->
fMarkA
=
1
;
Abc_ObjFanin1
(
Abc_ObjFanin1
(
pNode
)
)
->
fMarkA
=
1
;
}
else
// mark the complemented edges
{
if
(
Abc_ObjFaninC0
(
pNode
)
)
Abc_ObjFanin0
(
pNode
)
->
fMarkA
=
1
;
if
(
Abc_ObjFaninC1
(
pNode
)
)
Abc_ObjFanin1
(
pNode
)
->
fMarkA
=
1
;
}
}
// mark the PO drivers
Abc_NtkForEachCo
(
pNtk
,
pNode
,
i
)
Abc_ObjFanin0
(
pNode
)
->
fMarkA
=
1
;
// count the number of MUXes
nMuxes
=
0
;
Abc_NtkForEachNode
(
pNtk
,
pNode
,
i
)
{
// skip PI/PO nodes
// if ( Abc_NodeIsConst(pNode) )
// continue;
if
(
Abc_NodeIsMuxType
(
pNode
)
&&
Abc_ObjFanin0
(
pNode
)
->
fMarkA
==
0
&&
Abc_ObjFanin1
(
pNode
)
->
fMarkA
==
0
)
nMuxes
++
;
}
// printf( "The number of MUXes detected = %d (%5.2f %% of logic).\n", nMuxes, 300.0*nMuxes/Abc_NtkNodeNum(pNtk) );
}
/**Function*************************************************************
Synopsis [Sets the expansion boundary for conversion into multi-input AND graph.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
Abc_NtkRenodeSetBoundsMulti
(
Abc_Ntk_t
*
pNtk
,
int
nThresh
)
{
Abc_Obj_t
*
pNode
;
int
i
,
nFanouts
,
nConeSize
;
// make sure the mark is not set
Abc_NtkForEachObj
(
pNtk
,
pNode
,
i
)
assert
(
pNode
->
fMarkA
==
0
);
// mark the nodes where expansion stops using pNode->fMarkA
Abc_NtkForEachNode
(
pNtk
,
pNode
,
i
)
{
// skip PI/PO nodes
// if ( Abc_NodeIsConst(pNode) )
// continue;
// mark the nodes with multiple fanouts
// if ( Abc_ObjFanoutNum(pNode) > 1 )
// pNode->fMarkA = 1;
// mark the nodes with multiple fanouts
nFanouts
=
Abc_ObjFanoutNum
(
pNode
);
nConeSize
=
Abc_NodeMffcSizeStop
(
pNode
);
if
(
(
nFanouts
-
1
)
*
nConeSize
>
nThresh
)
pNode
->
fMarkA
=
1
;
// mark the children if they are pointed by the complemented edges
if
(
Abc_ObjFaninC0
(
pNode
)
)
Abc_ObjFanin0
(
pNode
)
->
fMarkA
=
1
;
if
(
Abc_ObjFaninC1
(
pNode
)
)
Abc_ObjFanin1
(
pNode
)
->
fMarkA
=
1
;
}
// mark the PO drivers
Abc_NtkForEachCo
(
pNtk
,
pNode
,
i
)
Abc_ObjFanin0
(
pNode
)
->
fMarkA
=
1
;
}
/**Function*************************************************************
Synopsis [Sets a simple boundary.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
Abc_NtkRenodeSetBoundsSimple
(
Abc_Ntk_t
*
pNtk
)
{
Abc_Obj_t
*
pNode
;
int
i
;
// make sure the mark is not set
Abc_NtkForEachObj
(
pNtk
,
pNode
,
i
)
assert
(
pNode
->
fMarkA
==
0
);
// mark the nodes where expansion stops using pNode->fMarkA
Abc_NtkForEachNode
(
pNtk
,
pNode
,
i
)
pNode
->
fMarkA
=
1
;
}
/**Function*************************************************************
Synopsis [Sets a factor-cut boundary.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
Abc_NtkRenodeSetBoundsFactor
(
Abc_Ntk_t
*
pNtk
)
{
Abc_Obj_t
*
pNode
;
int
i
;
// make sure the mark is not set
Abc_NtkForEachObj
(
pNtk
,
pNode
,
i
)
assert
(
pNode
->
fMarkA
==
0
);
// mark the nodes where expansion stops using pNode->fMarkA
Abc_NtkForEachNode
(
pNtk
,
pNode
,
i
)
pNode
->
fMarkA
=
(
pNode
->
vFanouts
.
nSize
>
1
&&
!
Abc_NodeIsMuxControlType
(
pNode
));
// mark the PO drivers
Abc_NtkForEachCo
(
pNtk
,
pNode
,
i
)
Abc_ObjFanin0
(
pNode
)
->
fMarkA
=
1
;
}
/**Function*************************************************************
Synopsis [Collects the fanins of a large node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
Abc_NtkRenodeCone_rec
(
Abc_Obj_t
*
pNode
,
Vec_Ptr_t
*
vCone
)
{
assert
(
!
Abc_ObjIsComplement
(
pNode
)
);
if
(
pNode
->
fMarkA
||
!
Abc_ObjIsNode
(
pNode
)
)
{
Vec_PtrPushUnique
(
vCone
,
pNode
);
return
;
}
Abc_NtkRenodeCone_rec
(
Abc_ObjFanin
(
pNode
,
0
),
vCone
);
Abc_NtkRenodeCone_rec
(
Abc_ObjFanin
(
pNode
,
1
),
vCone
);
}
}
/**Function*************************************************************
/**Function*************************************************************
Synopsis [
Collects the fanins of a large node
.]
Synopsis [
Derives the BDD after reordering
.]
Description []
Description []
...
@@ -626,13 +138,15 @@ void Abc_NtkRenodeCone_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vCone )
...
@@ -626,13 +138,15 @@ void Abc_NtkRenodeCone_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vCone )
SeeAlso []
SeeAlso []
***********************************************************************/
***********************************************************************/
void
Abc_NtkRenodeCone
(
Abc_Obj_t
*
pNode
,
Vec_Ptr_t
*
vCone
)
int
Abc_NtkRenodeEvalSop
(
unsigned
*
pTruth
,
int
nVars
)
{
{
assert
(
!
Abc_ObjIsComplement
(
pNode
)
);
Kit_Graph_t
*
pGraph
;
assert
(
Abc_ObjIsNode
(
pNode
)
);
int
nNodes
,
nDepth
;
vCone
->
nSize
=
0
;
pGraph
=
Kit_TruthToGraph
(
pTruth
,
nVars
);
Abc_NtkRenodeCone_rec
(
Abc_ObjFanin
(
pNode
,
0
),
vCone
);
nNodes
=
Kit_GraphNodeNum
(
pGraph
);
Abc_NtkRenodeCone_rec
(
Abc_ObjFanin
(
pNode
,
1
),
vCone
);
nDepth
=
Kit_GraphLevelNum
(
pGraph
);
Kit_GraphFree
(
pGraph
);
return
(
nDepth
<<
16
)
|
nNodes
;
}
}
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
...
...
src/base/abci/abcReorder.c
0 → 100644
View file @
38254947
/**CFile****************************************************************
FileName [abcReorder.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Network and node package.]
Synopsis [Reordering local BDDs of the nodes.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: abcReorder.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "abc.h"
#include "reo.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Reorders BDD of the local function of the node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
Abc_NodeBddReorder
(
reo_man
*
p
,
Abc_Obj_t
*
pNode
)
{
Abc_Obj_t
*
pFanin
;
DdNode
*
bFunc
;
int
*
pOrder
,
i
;
// create the temporary array for the variable order
pOrder
=
ALLOC
(
int
,
Abc_ObjFaninNum
(
pNode
)
);
for
(
i
=
0
;
i
<
Abc_ObjFaninNum
(
pNode
);
i
++
)
pOrder
[
i
]
=
-
1
;
// reorder the BDD
bFunc
=
Extra_Reorder
(
p
,
pNode
->
pNtk
->
pManFunc
,
pNode
->
pData
,
pOrder
);
Cudd_Ref
(
bFunc
);
Cudd_RecursiveDeref
(
pNode
->
pNtk
->
pManFunc
,
pNode
->
pData
);
pNode
->
pData
=
bFunc
;
// update the fanin order
Abc_ObjForEachFanin
(
pNode
,
pFanin
,
i
)
pOrder
[
i
]
=
pNode
->
vFanins
.
pArray
[
pOrder
[
i
]
];
Abc_ObjForEachFanin
(
pNode
,
pFanin
,
i
)
pNode
->
vFanins
.
pArray
[
i
]
=
pOrder
[
i
];
free
(
pOrder
);
}
/**Function*************************************************************
Synopsis [Reorders BDDs of the local functions.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
Abc_NtkBddReorder
(
Abc_Ntk_t
*
pNtk
,
int
fVerbose
)
{
reo_man
*
p
;
Abc_Obj_t
*
pNode
;
int
i
;
p
=
Extra_ReorderInit
(
Abc_NtkGetFaninMax
(
pNtk
),
100
);
Abc_NtkForEachNode
(
pNtk
,
pNode
,
i
)
{
if
(
Abc_ObjFaninNum
(
pNode
)
<
3
)
continue
;
if
(
fVerbose
)
fprintf
(
stdout
,
"%10s: "
,
Abc_ObjName
(
pNode
)
);
if
(
fVerbose
)
fprintf
(
stdout
,
"Before = %5d BDD nodes. "
,
Cudd_DagSize
(
pNode
->
pData
)
);
Abc_NodeBddReorder
(
p
,
pNode
);
if
(
fVerbose
)
fprintf
(
stdout
,
"After = %5d BDD nodes.
\n
"
,
Cudd_DagSize
(
pNode
->
pData
)
);
}
Extra_ReorderQuit
(
p
);
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
src/base/abci/abcVerify.c
View file @
38254947
...
@@ -46,6 +46,7 @@ static void Abc_NtkVerifyReportErrorSeq( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2,
...
@@ -46,6 +46,7 @@ static void Abc_NtkVerifyReportErrorSeq( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2,
***********************************************************************/
***********************************************************************/
void
Abc_NtkCecSat
(
Abc_Ntk_t
*
pNtk1
,
Abc_Ntk_t
*
pNtk2
,
int
nConfLimit
,
int
nInsLimit
)
void
Abc_NtkCecSat
(
Abc_Ntk_t
*
pNtk1
,
Abc_Ntk_t
*
pNtk2
,
int
nConfLimit
,
int
nInsLimit
)
{
{
extern
Abc_Ntk_t
*
Abc_NtkMulti
(
Abc_Ntk_t
*
pNtk
,
int
nThresh
,
int
nFaninMax
,
int
fCnf
,
int
fMulti
,
int
fSimple
,
int
fFactor
);
Abc_Ntk_t
*
pMiter
;
Abc_Ntk_t
*
pMiter
;
Abc_Ntk_t
*
pCnf
;
Abc_Ntk_t
*
pCnf
;
int
RetValue
;
int
RetValue
;
...
@@ -76,7 +77,7 @@ void Abc_NtkCecSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nConfLimit, int nI
...
@@ -76,7 +77,7 @@ void Abc_NtkCecSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nConfLimit, int nI
}
}
// convert the miter into a CNF
// convert the miter into a CNF
pCnf
=
Abc_Ntk
Renode
(
pMiter
,
0
,
100
,
1
,
0
,
0
,
0
);
pCnf
=
Abc_Ntk
Multi
(
pMiter
,
0
,
100
,
1
,
0
,
0
,
0
);
Abc_NtkDelete
(
pMiter
);
Abc_NtkDelete
(
pMiter
);
if
(
pCnf
==
NULL
)
if
(
pCnf
==
NULL
)
{
{
...
@@ -207,6 +208,7 @@ void Abc_NtkCecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int fV
...
@@ -207,6 +208,7 @@ void Abc_NtkCecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int fV
***********************************************************************/
***********************************************************************/
void
Abc_NtkSecSat
(
Abc_Ntk_t
*
pNtk1
,
Abc_Ntk_t
*
pNtk2
,
int
nConfLimit
,
int
nInsLimit
,
int
nFrames
)
void
Abc_NtkSecSat
(
Abc_Ntk_t
*
pNtk1
,
Abc_Ntk_t
*
pNtk2
,
int
nConfLimit
,
int
nInsLimit
,
int
nFrames
)
{
{
extern
Abc_Ntk_t
*
Abc_NtkMulti
(
Abc_Ntk_t
*
pNtk
,
int
nThresh
,
int
nFaninMax
,
int
fCnf
,
int
fMulti
,
int
fSimple
,
int
fFactor
);
Abc_Ntk_t
*
pMiter
;
Abc_Ntk_t
*
pMiter
;
Abc_Ntk_t
*
pFrames
;
Abc_Ntk_t
*
pFrames
;
Abc_Ntk_t
*
pCnf
;
Abc_Ntk_t
*
pCnf
;
...
@@ -256,7 +258,7 @@ void Abc_NtkSecSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nConfLimit, int nI
...
@@ -256,7 +258,7 @@ void Abc_NtkSecSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nConfLimit, int nI
}
}
// convert the miter into a CNF
// convert the miter into a CNF
pCnf
=
Abc_Ntk
Renode
(
pFrames
,
0
,
100
,
1
,
0
,
0
,
0
);
pCnf
=
Abc_Ntk
Multi
(
pFrames
,
0
,
100
,
1
,
0
,
0
,
0
);
Abc_NtkDelete
(
pFrames
);
Abc_NtkDelete
(
pFrames
);
if
(
pCnf
==
NULL
)
if
(
pCnf
==
NULL
)
{
{
...
...
src/base/abci/module.make
View file @
38254947
...
@@ -21,6 +21,7 @@ SRC += src/base/abci/abc.c \
...
@@ -21,6 +21,7 @@ SRC += src/base/abci/abc.c \
src/base/abci/abcMap.c
\
src/base/abci/abcMap.c
\
src/base/abci/abcMini.c
\
src/base/abci/abcMini.c
\
src/base/abci/abcMiter.c
\
src/base/abci/abcMiter.c
\
src/base/abci/abcMulti.c
\
src/base/abci/abcNtbdd.c
\
src/base/abci/abcNtbdd.c
\
src/base/abci/abcOrder.c
\
src/base/abci/abcOrder.c
\
src/base/abci/abcPrint.c
\
src/base/abci/abcPrint.c
\
...
@@ -28,6 +29,7 @@ SRC += src/base/abci/abc.c \
...
@@ -28,6 +29,7 @@ SRC += src/base/abci/abc.c \
src/base/abci/abcReconv.c
\
src/base/abci/abcReconv.c
\
src/base/abci/abcRefactor.c
\
src/base/abci/abcRefactor.c
\
src/base/abci/abcRenode.c
\
src/base/abci/abcRenode.c
\
src/base/abci/abcReorder.c
\
src/base/abci/abcRestruct.c
\
src/base/abci/abcRestruct.c
\
src/base/abci/abcResub.c
\
src/base/abci/abcResub.c
\
src/base/abci/abcRewrite.c
\
src/base/abci/abcRewrite.c
\
...
...
src/map/if/if.h
View file @
38254947
...
@@ -70,21 +70,27 @@ typedef struct If_Cut_t_ If_Cut_t;
...
@@ -70,21 +70,27 @@ typedef struct If_Cut_t_ If_Cut_t;
// parameters
// parameters
struct
If_Par_t_
struct
If_Par_t_
{
{
// user-controlable paramters
int
Mode
;
// the mapping mode
int
Mode
;
// the mapping mode
int
nLutSize
;
// the LUT size
int
nLutSize
;
// the LUT size
If_Lib_t
*
pLutLib
;
// the LUT library
int
nCutsMax
;
// the max number of cuts
int
nCutsMax
;
// the max number of cuts
int
fVerbose
;
// the verbosity flag
float
DelayTarget
;
// delay target
int
fPreprocess
;
// preprossing
int
fPreprocess
;
// preprossing
int
fArea
;
// area-oriented mapping
int
fArea
;
// area-oriented mapping
int
fFancy
;
// a fancy feature
int
fFancy
;
// a fancy feature
int
fExpRed
;
// expand/reduce of the best cuts
int
fExpRed
;
// expand/reduce of the best cuts
int
fLatchPaths
;
// reset timing on latch paths
int
fLatchPaths
;
// reset timing on latch paths
int
fSeq
;
// sequential mapping
int
fSeq
;
// sequential mapping
int
nLatches
;
// the number of latches
int
fVerbose
;
// the verbosity flag
float
DelayTarget
;
// delay target
// internal parameters
int
fTruth
;
// truth table computation enabled
int
fUseBdds
;
// sets local BDDs at the nodes
int
nLatches
;
// the number of latches in seq mapping
If_Lib_t
*
pLutLib
;
// the LUT library
float
*
pTimesArr
;
// arrival times
float
*
pTimesArr
;
// arrival times
float
*
pTimesReq
;
// required times
float
*
pTimesReq
;
// required times
int
(
*
pFuncCost
)(
unsigned
*
,
int
);
// procedure the user's cost of a cut
void
*
pReoMan
;
// reordering manager
};
};
// the LUT library
// the LUT library
...
@@ -118,10 +124,13 @@ struct If_Man_t_
...
@@ -118,10 +124,13 @@ struct If_Man_t_
int
nCutsMerged
;
// the total number of cuts merged
int
nCutsMerged
;
// the total number of cuts merged
int
nCutsMax
;
// the maximum number of cuts at a node
int
nCutsMax
;
// the maximum number of cuts at a node
float
Fi
;
// the current value of the clock period (for seq mapping)
float
Fi
;
// the current value of the clock period (for seq mapping)
unsigned
*
puTemp
[
4
];
// used for the truth table computation
// memory management
// memory management
Mem_Fixed_t
*
pMem
;
// memory manager
Mem_Fixed_t
*
pMem
;
// memory manager
int
nEntrySize
;
// the size of the entry
int
nEntrySize
;
// the size of the entry
int
nEntryBase
;
// the size of the entry minus cut leaf arrays
int
nEntryBase
;
// the size of the entry minus cut leaf arrays
int
nTruthSize
;
// the size of the truth table if allocated
int
nCutSize
;
// the size of the cut
// temporary cut storage
// temporary cut storage
int
nCuts
;
// the number of cuts used
int
nCuts
;
// the number of cuts used
If_Cut_t
**
ppCuts
;
// the storage space for cuts
If_Cut_t
**
ppCuts
;
// the storage space for cuts
...
@@ -132,14 +141,14 @@ struct If_Cut_t_
...
@@ -132,14 +141,14 @@ struct If_Cut_t_
{
{
float
Delay
;
// delay of the cut
float
Delay
;
// delay of the cut
float
Area
;
// area (or area-flow) of the cut
float
Area
;
// area (or area-flow) of the cut
If_Cut_t
*
pOne
;
// parent cut
If_Cut_t
*
pTwo
;
// parent cut
unsigned
uSign
;
// cut signature
unsigned
uSign
;
// cut signature
char
fCompl0
;
// complemented attribute
unsigned
Cost
:
10
;
// the user's cost of the cut
char
fCompl1
;
// complemented attribute
unsigned
Depth
:
9
;
// the user's depth of the cut
char
Phase
;
// complemented attribute
unsigned
fCompl
:
1
;
// the complemented attribute
char
nLeaves
;
// number of leaves
unsigned
nLimit
:
6
;
// the maximum number of leaves
unsigned
nLeaves
:
6
;
// the number of leaves
int
*
pLeaves
;
// array of fanins
int
*
pLeaves
;
// array of fanins
unsigned
*
pTruth
;
// the truth table
};
};
// node extension
// node extension
...
@@ -197,8 +206,11 @@ static inline unsigned If_ObjCutSign( unsigned ObjId ) { r
...
@@ -197,8 +206,11 @@ static inline unsigned If_ObjCutSign( unsigned ObjId ) { r
static
inline
void
*
If_CutData
(
If_Cut_t
*
pCut
)
{
return
*
(
void
**
)
pCut
;
}
static
inline
void
*
If_CutData
(
If_Cut_t
*
pCut
)
{
return
*
(
void
**
)
pCut
;
}
static
inline
void
If_CutSetData
(
If_Cut_t
*
pCut
,
void
*
pData
)
{
*
(
void
**
)
pCut
=
pData
;
}
static
inline
void
If_CutSetData
(
If_Cut_t
*
pCut
,
void
*
pData
)
{
*
(
void
**
)
pCut
=
pData
;
}
static
inline
float
If_CutLutDelay
(
If_Man_t
*
p
,
If_Cut_t
*
pCut
)
{
return
p
->
pPars
->
pLutLib
?
p
->
pPars
->
pLutLib
->
pLutDelays
[
pCut
->
nLeaves
]
:
(
float
)
1
.
0
;
}
static
inline
int
If_CutTruthWords
(
int
nVarsMax
)
{
return
nVarsMax
<=
5
?
1
:
(
1
<<
(
nVarsMax
-
5
));
}
static
inline
float
If_CutLutArea
(
If_Man_t
*
p
,
If_Cut_t
*
pCut
)
{
return
p
->
pPars
->
pLutLib
?
p
->
pPars
->
pLutLib
->
pLutAreas
[
pCut
->
nLeaves
]
:
(
float
)
1
.
0
;
}
static
inline
unsigned
*
If_CutTruth
(
If_Cut_t
*
pCut
)
{
return
pCut
->
pTruth
;
}
static
inline
float
If_CutLutDelay
(
If_Man_t
*
p
,
If_Cut_t
*
pCut
)
{
return
pCut
->
Depth
?
(
float
)
pCut
->
Depth
:
(
p
->
pPars
->
pLutLib
?
p
->
pPars
->
pLutLib
->
pLutDelays
[
pCut
->
nLeaves
]
:
(
float
)
1
.
0
);
}
static
inline
float
If_CutLutArea
(
If_Man_t
*
p
,
If_Cut_t
*
pCut
)
{
return
pCut
->
Cost
?
(
float
)
pCut
->
Cost
:
(
p
->
pPars
->
pLutLib
?
p
->
pPars
->
pLutLib
->
pLutAreas
[
pCut
->
nLeaves
]
:
(
float
)
1
.
0
);
}
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// MACRO DEFINITIONS ///
/// MACRO DEFINITIONS ///
...
@@ -244,14 +256,7 @@ static inline float If_CutLutArea( If_Man_t * p, If_Cut_t * pCut ) { r
...
@@ -244,14 +256,7 @@ static inline float If_CutLutArea( If_Man_t * p, If_Cut_t * pCut ) { r
/*=== ifCore.c ==========================================================*/
/*=== ifCore.c ==========================================================*/
extern
int
If_ManPerformMapping
(
If_Man_t
*
p
);
extern
int
If_ManPerformMapping
(
If_Man_t
*
p
);
extern
int
If_ManPerformMappingRound
(
If_Man_t
*
p
,
int
nCutsUsed
,
int
Mode
,
int
fRequired
);
extern
int
If_ManPerformMappingRound
(
If_Man_t
*
p
,
int
nCutsUsed
,
int
Mode
,
int
fRequired
);
/*=== ifMan.c ==========================================================*/
/*=== ifCut.c ==========================================================*/
extern
If_Man_t
*
If_ManStart
(
If_Par_t
*
pPars
);
extern
void
If_ManStop
(
If_Man_t
*
p
);
extern
If_Obj_t
*
If_ManCreatePi
(
If_Man_t
*
p
);
extern
If_Obj_t
*
If_ManCreatePo
(
If_Man_t
*
p
,
If_Obj_t
*
pDriver
,
int
fCompl0
);
extern
If_Obj_t
*
If_ManCreateAnd
(
If_Man_t
*
p
,
If_Obj_t
*
pFan0
,
int
fCompl0
,
If_Obj_t
*
pFan1
,
int
fCompl1
);
/*=== ifMap.c ==========================================================*/
extern
void
If_ObjPerformMapping
(
If_Man_t
*
p
,
If_Obj_t
*
pObj
,
int
Mode
);
extern
float
If_CutAreaDerefed
(
If_Man_t
*
p
,
If_Cut_t
*
pCut
,
int
nLevels
);
extern
float
If_CutAreaDerefed
(
If_Man_t
*
p
,
If_Cut_t
*
pCut
,
int
nLevels
);
extern
float
If_CutAreaRefed
(
If_Man_t
*
p
,
If_Cut_t
*
pCut
,
int
nLevels
);
extern
float
If_CutAreaRefed
(
If_Man_t
*
p
,
If_Cut_t
*
pCut
,
int
nLevels
);
extern
float
If_CutDeref
(
If_Man_t
*
p
,
If_Cut_t
*
pCut
,
int
nLevels
);
extern
float
If_CutDeref
(
If_Man_t
*
p
,
If_Cut_t
*
pCut
,
int
nLevels
);
...
@@ -259,12 +264,26 @@ extern float If_CutRef( If_Man_t * p, If_Cut_t * pCut, int nLevels );
...
@@ -259,12 +264,26 @@ extern float If_CutRef( If_Man_t * p, If_Cut_t * pCut, int nLevels );
extern
void
If_CutPrint
(
If_Man_t
*
p
,
If_Cut_t
*
pCut
);
extern
void
If_CutPrint
(
If_Man_t
*
p
,
If_Cut_t
*
pCut
);
extern
float
If_CutDelay
(
If_Man_t
*
p
,
If_Cut_t
*
pCut
);
extern
float
If_CutDelay
(
If_Man_t
*
p
,
If_Cut_t
*
pCut
);
extern
float
If_CutFlow
(
If_Man_t
*
p
,
If_Cut_t
*
pCut
);
extern
float
If_CutFlow
(
If_Man_t
*
p
,
If_Cut_t
*
pCut
);
extern
int
If_CutMerge
(
If_Cut_t
*
pCut0
,
If_Cut_t
*
pCut1
,
If_Cut_t
*
pCut
,
int
nLimit
);
extern
int
If_CutFilter
(
If_Man_t
*
p
,
If_Cut_t
*
pCut
);
extern
int
If_CutMerge
(
If_Cut_t
*
pCut0
,
If_Cut_t
*
pCut1
,
If_Cut_t
*
pCut
);
extern
void
If_CutCopy
(
If_Cut_t
*
pCutDest
,
If_Cut_t
*
pCutSrc
);
extern
void
If_CutCopy
(
If_Cut_t
*
pCutDest
,
If_Cut_t
*
pCutSrc
);
extern
void
If_ManSortCuts
(
If_Man_t
*
p
,
int
Mode
);
/*=== ifMan.c ==========================================================*/
extern
If_Man_t
*
If_ManStart
(
If_Par_t
*
pPars
);
extern
void
If_ManStop
(
If_Man_t
*
p
);
extern
If_Obj_t
*
If_ManCreatePi
(
If_Man_t
*
p
);
extern
If_Obj_t
*
If_ManCreatePo
(
If_Man_t
*
p
,
If_Obj_t
*
pDriver
,
int
fCompl0
);
extern
If_Obj_t
*
If_ManCreateAnd
(
If_Man_t
*
p
,
If_Obj_t
*
pFan0
,
int
fCompl0
,
If_Obj_t
*
pFan1
,
int
fCompl1
);
/*=== ifMap.c ==========================================================*/
extern
void
If_ObjPerformMapping
(
If_Man_t
*
p
,
If_Obj_t
*
pObj
,
int
Mode
);
/*=== ifPrepro.c ==========================================================*/
extern
void
If_ManPerformMappingPreprocess
(
If_Man_t
*
p
);
/*=== ifReduce.c ==========================================================*/
/*=== ifReduce.c ==========================================================*/
extern
void
If_ManImproveMapping
(
If_Man_t
*
p
);
extern
void
If_ManImproveMapping
(
If_Man_t
*
p
);
/*=== ifSelect.c ==========================================================*/
/*=== ifSeq.c ==========================================================*/
extern
void
If_ManPerformMappingPreprocess
(
If_Man_t
*
p
);
extern
int
If_ManPerformMappingSeq
(
If_Man_t
*
p
);
/*=== ifTruth.c ==========================================================*/
extern
void
If_CutComputeTruth
(
If_Man_t
*
p
,
If_Cut_t
*
pCut
,
If_Cut_t
*
pCut0
,
If_Cut_t
*
pCut1
,
int
fCompl0
,
int
fCompl1
);
/*=== ifUtil.c ==========================================================*/
/*=== ifUtil.c ==========================================================*/
extern
float
If_ManDelayMax
(
If_Man_t
*
p
);
extern
float
If_ManDelayMax
(
If_Man_t
*
p
);
extern
void
If_ManCleanNodeCopy
(
If_Man_t
*
p
);
extern
void
If_ManCleanNodeCopy
(
If_Man_t
*
p
);
...
...
src/map/if/ifCore.c
View file @
38254947
...
@@ -59,20 +59,20 @@ int If_ManPerformMapping( If_Man_t * p )
...
@@ -59,20 +59,20 @@ int If_ManPerformMapping( If_Man_t * p )
else
else
If_ManPerformMappingRound
(
p
,
p
->
pPars
->
nCutsMax
,
0
,
1
);
If_ManPerformMappingRound
(
p
,
p
->
pPars
->
nCutsMax
,
0
,
1
);
// try to improve area by expanding and reducing the cuts
// try to improve area by expanding and reducing the cuts
if
(
p
->
pPars
->
fExpRed
)
if
(
p
->
pPars
->
fExpRed
&&
!
p
->
pPars
->
fTruth
)
If_ManImproveMapping
(
p
);
If_ManImproveMapping
(
p
);
// area flow oriented mapping
// area flow oriented mapping
for
(
i
=
0
;
i
<
nItersFlow
;
i
++
)
for
(
i
=
0
;
i
<
nItersFlow
;
i
++
)
{
{
If_ManPerformMappingRound
(
p
,
p
->
pPars
->
nCutsMax
,
1
,
1
);
If_ManPerformMappingRound
(
p
,
p
->
pPars
->
nCutsMax
,
1
,
1
);
if
(
p
->
pPars
->
fExpRed
)
if
(
p
->
pPars
->
fExpRed
&&
!
p
->
pPars
->
fTruth
)
If_ManImproveMapping
(
p
);
If_ManImproveMapping
(
p
);
}
}
// area oriented mapping
// area oriented mapping
for
(
i
=
0
;
i
<
nItersArea
;
i
++
)
for
(
i
=
0
;
i
<
nItersArea
;
i
++
)
{
{
If_ManPerformMappingRound
(
p
,
p
->
pPars
->
nCutsMax
,
2
,
1
);
If_ManPerformMappingRound
(
p
,
p
->
pPars
->
nCutsMax
,
2
,
1
);
if
(
p
->
pPars
->
fExpRed
)
if
(
p
->
pPars
->
fExpRed
&&
!
p
->
pPars
->
fTruth
)
If_ManImproveMapping
(
p
);
If_ManImproveMapping
(
p
);
}
}
if
(
p
->
pPars
->
fVerbose
)
if
(
p
->
pPars
->
fVerbose
)
...
...
src/map/if/ifCut.c
View file @
38254947
...
@@ -28,9 +28,405 @@
...
@@ -28,9 +28,405 @@
/// FUNCTION DEFINITIONS ///
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Returns 1 if pDom is contained in pCut.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static
inline
int
If_CutCheckDominance
(
If_Cut_t
*
pDom
,
If_Cut_t
*
pCut
)
{
int
i
,
k
;
for
(
i
=
0
;
i
<
(
int
)
pDom
->
nLeaves
;
i
++
)
{
for
(
k
=
0
;
k
<
(
int
)
pCut
->
nLeaves
;
k
++
)
if
(
pDom
->
pLeaves
[
i
]
==
pCut
->
pLeaves
[
k
]
)
break
;
if
(
k
==
(
int
)
pCut
->
nLeaves
)
// node i in pDom is not contained in pCut
return
0
;
}
// every node in pDom is contained in pCut
return
1
;
}
/**Function*************************************************************
Synopsis [Returns 1 if pDom is equal to pCut.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static
inline
int
If_CutCheckEquality
(
If_Cut_t
*
pDom
,
If_Cut_t
*
pCut
)
{
int
i
;
if
(
(
int
)
pDom
->
nLeaves
!=
(
int
)
pCut
->
nLeaves
)
return
0
;
for
(
i
=
0
;
i
<
(
int
)
pDom
->
nLeaves
;
i
++
)
if
(
pDom
->
pLeaves
[
i
]
!=
pCut
->
pLeaves
[
i
]
)
return
0
;
return
1
;
}
/**Function*************************************************************
Synopsis [Returns 1 if the cut is contained.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int
If_CutFilter
(
If_Man_t
*
p
,
If_Cut_t
*
pCut
)
{
If_Cut_t
*
pTemp
;
int
i
;
for
(
i
=
0
;
i
<
p
->
nCuts
;
i
++
)
{
pTemp
=
p
->
ppCuts
[
i
];
if
(
pTemp
->
nLeaves
>
pCut
->
nLeaves
)
{
// continue;
// skip the non-contained cuts
if
(
(
pTemp
->
uSign
&
pCut
->
uSign
)
!=
pCut
->
uSign
)
continue
;
// check containment seriously
if
(
If_CutCheckDominance
(
pCut
,
pTemp
)
)
{
// removed contained cut
p
->
ppCuts
[
i
]
=
p
->
ppCuts
[
p
->
nCuts
-
1
];
p
->
ppCuts
[
p
->
nCuts
-
1
]
=
pTemp
;
p
->
nCuts
--
;
i
--
;
}
}
else
{
// skip the non-contained cuts
if
(
(
pTemp
->
uSign
&
pCut
->
uSign
)
!=
pTemp
->
uSign
)
continue
;
// check containment seriously
if
(
If_CutCheckDominance
(
pTemp
,
pCut
)
)
return
1
;
}
}
return
0
;
}
/**Function*************************************************************
Synopsis [Merges two cuts.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static
inline
int
If_CutMergeOrdered
(
If_Cut_t
*
pC0
,
If_Cut_t
*
pC1
,
If_Cut_t
*
pC
)
{
int
i
,
k
,
c
;
assert
(
pC0
->
nLeaves
>=
pC1
->
nLeaves
);
// the case of the largest cut sizes
if
(
pC0
->
nLeaves
==
pC
->
nLimit
&&
pC1
->
nLeaves
==
pC
->
nLimit
)
{
for
(
i
=
0
;
i
<
(
int
)
pC0
->
nLeaves
;
i
++
)
if
(
pC0
->
pLeaves
[
i
]
!=
pC1
->
pLeaves
[
i
]
)
return
0
;
for
(
i
=
0
;
i
<
(
int
)
pC0
->
nLeaves
;
i
++
)
pC
->
pLeaves
[
i
]
=
pC0
->
pLeaves
[
i
];
pC
->
nLeaves
=
pC0
->
nLeaves
;
return
1
;
}
// the case when one of the cuts is the largest
if
(
pC0
->
nLeaves
==
pC
->
nLimit
)
{
for
(
i
=
0
;
i
<
(
int
)
pC1
->
nLeaves
;
i
++
)
{
for
(
k
=
(
int
)
pC0
->
nLeaves
-
1
;
k
>=
0
;
k
--
)
if
(
pC0
->
pLeaves
[
k
]
==
pC1
->
pLeaves
[
i
]
)
break
;
if
(
k
==
-
1
)
// did not find
return
0
;
}
for
(
i
=
0
;
i
<
(
int
)
pC0
->
nLeaves
;
i
++
)
pC
->
pLeaves
[
i
]
=
pC0
->
pLeaves
[
i
];
pC
->
nLeaves
=
pC0
->
nLeaves
;
return
1
;
}
// compare two cuts with different numbers
i
=
k
=
0
;
for
(
c
=
0
;
c
<
(
int
)
pC
->
nLimit
;
c
++
)
{
if
(
k
==
(
int
)
pC1
->
nLeaves
)
{
if
(
i
==
(
int
)
pC0
->
nLeaves
)
{
pC
->
nLeaves
=
c
;
return
1
;
}
pC
->
pLeaves
[
c
]
=
pC0
->
pLeaves
[
i
++
];
continue
;
}
if
(
i
==
(
int
)
pC0
->
nLeaves
)
{
if
(
k
==
(
int
)
pC1
->
nLeaves
)
{
pC
->
nLeaves
=
c
;
return
1
;
}
pC
->
pLeaves
[
c
]
=
pC1
->
pLeaves
[
k
++
];
continue
;
}
if
(
pC0
->
pLeaves
[
i
]
<
pC1
->
pLeaves
[
k
]
)
{
pC
->
pLeaves
[
c
]
=
pC0
->
pLeaves
[
i
++
];
continue
;
}
if
(
pC0
->
pLeaves
[
i
]
>
pC1
->
pLeaves
[
k
]
)
{
pC
->
pLeaves
[
c
]
=
pC1
->
pLeaves
[
k
++
];
continue
;
}
pC
->
pLeaves
[
c
]
=
pC0
->
pLeaves
[
i
++
];
k
++
;
}
if
(
i
<
(
int
)
pC0
->
nLeaves
||
k
<
(
int
)
pC1
->
nLeaves
)
return
0
;
pC
->
nLeaves
=
c
;
return
1
;
}
/**Function*************************************************************
Synopsis [Merges two cuts.]
Description [Special case when the cut is known to exist.]
SideEffects []
SeeAlso []
***********************************************************************/
static
inline
int
If_CutMergeOrdered2
(
If_Cut_t
*
pC0
,
If_Cut_t
*
pC1
,
If_Cut_t
*
pC
)
{
int
i
,
k
,
c
;
assert
(
pC0
->
nLeaves
>=
pC1
->
nLeaves
);
// copy the first cut
for
(
i
=
0
;
i
<
(
int
)
pC0
->
nLeaves
;
i
++
)
pC
->
pLeaves
[
i
]
=
pC0
->
pLeaves
[
i
];
pC
->
nLeaves
=
pC0
->
nLeaves
;
// the case when one of the cuts is the largest
if
(
pC0
->
nLeaves
==
pC
->
nLimit
)
return
1
;
// add nodes of the second cut
k
=
0
;
for
(
i
=
0
;
i
<
(
int
)
pC1
->
nLeaves
;
i
++
)
{
// find k-th node before which i-th node should be added
for
(
;
k
<
(
int
)
pC
->
nLeaves
;
k
++
)
if
(
pC
->
pLeaves
[
k
]
>=
pC1
->
pLeaves
[
i
]
)
break
;
// check the case when this should be the last node
if
(
k
==
(
int
)
pC
->
nLeaves
)
{
pC
->
pLeaves
[
k
++
]
=
pC1
->
pLeaves
[
i
];
pC
->
nLeaves
++
;
continue
;
}
// check the case when equal node is found
if
(
pC1
->
pLeaves
[
i
]
==
pC
->
pLeaves
[
k
]
)
continue
;
// add the node
for
(
c
=
(
int
)
pC
->
nLeaves
;
c
>
k
;
c
--
)
pC
->
pLeaves
[
c
]
=
pC
->
pLeaves
[
c
-
1
];
pC
->
pLeaves
[
k
++
]
=
pC1
->
pLeaves
[
i
];
pC
->
nLeaves
++
;
}
assert
(
pC
->
nLeaves
<=
pC
->
nLimit
);
for
(
i
=
1
;
i
<
(
int
)
pC
->
nLeaves
;
i
++
)
assert
(
pC
->
pLeaves
[
i
-
1
]
<
pC
->
pLeaves
[
i
]
);
return
1
;
}
/**Function*************************************************************
Synopsis [Prepares the object for FPGA mapping.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int
If_CutMerge
(
If_Cut_t
*
pCut0
,
If_Cut_t
*
pCut1
,
If_Cut_t
*
pCut
)
{
assert
(
pCut
->
nLimit
>
0
);
// merge the nodes
if
(
pCut0
->
nLeaves
<
pCut1
->
nLeaves
)
{
if
(
!
If_CutMergeOrdered
(
pCut1
,
pCut0
,
pCut
)
)
return
0
;
}
else
{
if
(
!
If_CutMergeOrdered
(
pCut0
,
pCut1
,
pCut
)
)
return
0
;
}
return
1
;
}
/**Function*************************************************************
Synopsis [Prepares the object for FPGA mapping.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int
If_CutCompareDelay
(
If_Cut_t
**
ppC0
,
If_Cut_t
**
ppC1
)
{
If_Cut_t
*
pC0
=
*
ppC0
;
If_Cut_t
*
pC1
=
*
ppC1
;
if
(
pC0
->
Delay
<
pC1
->
Delay
-
0
.
0001
)
return
-
1
;
if
(
pC0
->
Delay
>
pC1
->
Delay
+
0
.
0001
)
return
1
;
if
(
pC0
->
nLeaves
<
pC1
->
nLeaves
)
return
-
1
;
if
(
pC0
->
nLeaves
>
pC1
->
nLeaves
)
return
1
;
if
(
pC0
->
Area
<
pC1
->
Area
-
0
.
0001
)
return
-
1
;
if
(
pC0
->
Area
>
pC1
->
Area
+
0
.
0001
)
return
1
;
return
0
;
}
/**Function*************************************************************
Synopsis [Prepares the object for FPGA mapping.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int
If_CutCompareDelayOld
(
If_Cut_t
**
ppC0
,
If_Cut_t
**
ppC1
)
{
If_Cut_t
*
pC0
=
*
ppC0
;
If_Cut_t
*
pC1
=
*
ppC1
;
if
(
pC0
->
Delay
<
pC1
->
Delay
-
0
.
0001
)
return
-
1
;
if
(
pC0
->
Delay
>
pC1
->
Delay
+
0
.
0001
)
return
1
;
if
(
pC0
->
Area
<
pC1
->
Area
-
0
.
0001
)
return
-
1
;
if
(
pC0
->
Area
>
pC1
->
Area
+
0
.
0001
)
return
1
;
if
(
pC0
->
nLeaves
<
pC1
->
nLeaves
)
return
-
1
;
if
(
pC0
->
nLeaves
>
pC1
->
nLeaves
)
return
1
;
return
0
;
}
/**Function*************************************************************
Synopsis [Prepares the object for FPGA mapping.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int
If_CutCompareArea
(
If_Cut_t
**
ppC0
,
If_Cut_t
**
ppC1
)
{
If_Cut_t
*
pC0
=
*
ppC0
;
If_Cut_t
*
pC1
=
*
ppC1
;
if
(
pC0
->
Area
<
pC1
->
Area
-
0
.
0001
)
return
-
1
;
if
(
pC0
->
Area
>
pC1
->
Area
+
0
.
0001
)
return
1
;
if
(
pC0
->
nLeaves
<
pC1
->
nLeaves
)
return
-
1
;
if
(
pC0
->
nLeaves
>
pC1
->
nLeaves
)
return
1
;
if
(
pC0
->
Delay
<
pC1
->
Delay
-
0
.
0001
)
return
-
1
;
if
(
pC0
->
Delay
>
pC1
->
Delay
+
0
.
0001
)
return
1
;
return
0
;
}
/**Function*************************************************************
Synopsis [Sorts the cuts.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
If_ManSortCuts
(
If_Man_t
*
p
,
int
Mode
)
{
// sort the cuts
if
(
Mode
||
p
->
pPars
->
fArea
)
// area
qsort
(
p
->
ppCuts
,
p
->
nCuts
,
sizeof
(
If_Cut_t
*
),
(
int
(
*
)(
const
void
*
,
const
void
*
))
If_CutCompareArea
);
else
if
(
p
->
pPars
->
fFancy
)
qsort
(
p
->
ppCuts
,
p
->
nCuts
,
sizeof
(
If_Cut_t
*
),
(
int
(
*
)(
const
void
*
,
const
void
*
))
If_CutCompareDelayOld
);
else
qsort
(
p
->
ppCuts
,
p
->
nCuts
,
sizeof
(
If_Cut_t
*
),
(
int
(
*
)(
const
void
*
,
const
void
*
))
If_CutCompareDelay
);
}
/**Function*************************************************************
Synopsis [Computes delay.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
float
If_CutDelay
(
If_Man_t
*
p
,
If_Cut_t
*
pCut
)
{
If_Obj_t
*
pLeaf
;
float
Delay
;
int
i
;
assert
(
pCut
->
nLeaves
>
1
);
Delay
=
-
IF_FLOAT_LARGE
;
If_CutForEachLeaf
(
p
,
pCut
,
pLeaf
,
i
)
Delay
=
IF_MAX
(
Delay
,
If_ObjCutBest
(
pLeaf
)
->
Delay
);
return
Delay
+
If_CutLutDelay
(
p
,
pCut
);
}
/**Function*************************************************************
/**Function*************************************************************
Synopsis []
Synopsis [
Computes area flow.
]
Description []
Description []
...
@@ -39,6 +435,166 @@
...
@@ -39,6 +435,166 @@
SeeAlso []
SeeAlso []
***********************************************************************/
***********************************************************************/
float
If_CutFlow
(
If_Man_t
*
p
,
If_Cut_t
*
pCut
)
{
If_Obj_t
*
pLeaf
;
float
Flow
;
int
i
;
assert
(
pCut
->
nLeaves
>
1
);
Flow
=
If_CutLutArea
(
p
,
pCut
);
If_CutForEachLeaf
(
p
,
pCut
,
pLeaf
,
i
)
{
if
(
pLeaf
->
nRefs
==
0
)
Flow
+=
If_ObjCutBest
(
pLeaf
)
->
Area
;
else
{
assert
(
pLeaf
->
EstRefs
>
p
->
fEpsilon
);
Flow
+=
If_ObjCutBest
(
pLeaf
)
->
Area
/
pLeaf
->
EstRefs
;
}
}
return
Flow
;
}
/**Function*************************************************************
Synopsis [Computes area of the first level.]
Description [The cut need to be derefed.]
SideEffects []
SeeAlso []
***********************************************************************/
float
If_CutDeref
(
If_Man_t
*
p
,
If_Cut_t
*
pCut
,
int
nLevels
)
{
If_Obj_t
*
pLeaf
;
float
Area
;
int
i
;
Area
=
If_CutLutArea
(
p
,
pCut
);
If_CutForEachLeaf
(
p
,
pCut
,
pLeaf
,
i
)
{
assert
(
pLeaf
->
nRefs
>
0
);
if
(
--
pLeaf
->
nRefs
>
0
||
!
If_ObjIsAnd
(
pLeaf
)
||
nLevels
==
1
)
continue
;
Area
+=
If_CutDeref
(
p
,
If_ObjCutBest
(
pLeaf
),
nLevels
-
1
);
}
return
Area
;
}
/**Function*************************************************************
Synopsis [Computes area of the first level.]
Description [The cut need to be derefed.]
SideEffects []
SeeAlso []
***********************************************************************/
float
If_CutRef
(
If_Man_t
*
p
,
If_Cut_t
*
pCut
,
int
nLevels
)
{
If_Obj_t
*
pLeaf
;
float
Area
;
int
i
;
Area
=
If_CutLutArea
(
p
,
pCut
);
If_CutForEachLeaf
(
p
,
pCut
,
pLeaf
,
i
)
{
assert
(
pLeaf
->
nRefs
>=
0
);
if
(
pLeaf
->
nRefs
++
>
0
||
!
If_ObjIsAnd
(
pLeaf
)
||
nLevels
==
1
)
continue
;
Area
+=
If_CutRef
(
p
,
If_ObjCutBest
(
pLeaf
),
nLevels
-
1
);
}
return
Area
;
}
/**Function*************************************************************
Synopsis [Prints one cut.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
If_CutPrint
(
If_Man_t
*
p
,
If_Cut_t
*
pCut
)
{
unsigned
i
;
printf
(
"{"
);
for
(
i
=
0
;
i
<
pCut
->
nLeaves
;
i
++
)
printf
(
" %d"
,
pCut
->
pLeaves
[
i
]
);
printf
(
" }
\n
"
);
}
/**Function*************************************************************
Synopsis [Computes area of the first level.]
Description [The cut need to be derefed.]
SideEffects []
SeeAlso []
***********************************************************************/
float
If_CutAreaDerefed
(
If_Man_t
*
p
,
If_Cut_t
*
pCut
,
int
nLevels
)
{
float
aResult
,
aResult2
;
assert
(
pCut
->
nLeaves
>
1
);
aResult2
=
If_CutRef
(
p
,
pCut
,
nLevels
);
aResult
=
If_CutDeref
(
p
,
pCut
,
nLevels
);
assert
(
aResult
==
aResult2
);
return
aResult
;
}
/**Function*************************************************************
Synopsis [Computes area of the first level.]
Description [The cut need to be derefed.]
SideEffects []
SeeAlso []
***********************************************************************/
float
If_CutAreaRefed
(
If_Man_t
*
p
,
If_Cut_t
*
pCut
,
int
nLevels
)
{
float
aResult
,
aResult2
;
assert
(
pCut
->
nLeaves
>
1
);
aResult2
=
If_CutDeref
(
p
,
pCut
,
nLevels
);
aResult
=
If_CutRef
(
p
,
pCut
,
nLevels
);
assert
(
aResult
==
aResult2
);
return
aResult
;
}
/**Function*************************************************************
Synopsis [Computes area of the first level.]
Description [The cut need to be derefed.]
SideEffects []
SeeAlso []
***********************************************************************/
void
If_CutCopy
(
If_Cut_t
*
pCutDest
,
If_Cut_t
*
pCutSrc
)
{
int
*
pLeaves
;
unsigned
*
pTruth
;
pLeaves
=
pCutDest
->
pLeaves
;
pTruth
=
pCutDest
->
pTruth
;
*
pCutDest
=
*
pCutSrc
;
pCutDest
->
pLeaves
=
pLeaves
;
pCutDest
->
pTruth
=
pTruth
;
memcpy
(
pCutDest
->
pLeaves
,
pCutSrc
->
pLeaves
,
sizeof
(
int
)
*
pCutSrc
->
nLeaves
);
if
(
pCutSrc
->
pTruth
)
memcpy
(
pCutDest
->
pTruth
,
pCutSrc
->
pTruth
,
sizeof
(
unsigned
)
*
If_CutTruthWords
(
pCutSrc
->
nLimit
)
);
}
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
/// END OF FILE ///
...
...
src/map/if/ifMan.c
View file @
38254947
...
@@ -57,9 +57,20 @@ If_Man_t * If_ManStart( If_Par_t * pPars )
...
@@ -57,9 +57,20 @@ If_Man_t * If_ManStart( If_Par_t * pPars )
p
->
vMapped
=
Vec_PtrAlloc
(
100
);
p
->
vMapped
=
Vec_PtrAlloc
(
100
);
p
->
vTemp
=
Vec_PtrAlloc
(
100
);
p
->
vTemp
=
Vec_PtrAlloc
(
100
);
// prepare the memory manager
// prepare the memory manager
p
->
nEntrySize
=
sizeof
(
If_Obj_t
)
+
p
->
pPars
->
nCutsMax
*
(
sizeof
(
If_Cut_t
)
+
sizeof
(
int
)
*
p
->
pPars
->
nLutSize
);
p
->
nTruthSize
=
p
->
pPars
->
fTruth
?
If_CutTruthWords
(
p
->
pPars
->
nLutSize
)
:
0
;
p
->
nEntryBase
=
sizeof
(
If_Obj_t
)
+
p
->
pPars
->
nCutsMax
*
(
sizeof
(
If_Cut_t
));
p
->
nCutSize
=
sizeof
(
If_Cut_t
)
+
sizeof
(
int
)
*
p
->
pPars
->
nLutSize
+
sizeof
(
unsigned
)
*
p
->
nTruthSize
;
p
->
nEntrySize
=
sizeof
(
If_Obj_t
)
+
p
->
pPars
->
nCutsMax
*
p
->
nCutSize
;
p
->
nEntryBase
=
sizeof
(
If_Obj_t
)
+
p
->
pPars
->
nCutsMax
*
sizeof
(
If_Cut_t
);
p
->
pMem
=
Mem_FixedStart
(
p
->
nEntrySize
);
p
->
pMem
=
Mem_FixedStart
(
p
->
nEntrySize
);
// report expected memory usage
if
(
p
->
pPars
->
fVerbose
)
printf
(
"Memory (bytes): Truth = %3d. Cut = %3d. Entry = %4d. Total = %.2f Mb / 1K AIG nodes
\n
"
,
4
*
p
->
nTruthSize
,
p
->
nCutSize
,
p
->
nEntrySize
,
1000
.
0
*
p
->
nEntrySize
/
(
1
<<
20
)
);
// room for temporary truth tables
p
->
puTemp
[
0
]
=
p
->
pPars
->
fTruth
?
ALLOC
(
unsigned
,
4
*
p
->
nTruthSize
)
:
NULL
;
p
->
puTemp
[
1
]
=
p
->
puTemp
[
0
]
+
p
->
nTruthSize
;
p
->
puTemp
[
2
]
=
p
->
puTemp
[
1
]
+
p
->
nTruthSize
;
p
->
puTemp
[
3
]
=
p
->
puTemp
[
2
]
+
p
->
nTruthSize
;
// create the constant node
// create the constant node
p
->
pConst1
=
If_ManSetupObj
(
p
);
p
->
pConst1
=
If_ManSetupObj
(
p
);
p
->
pConst1
->
Type
=
IF_CONST1
;
p
->
pConst1
->
Type
=
IF_CONST1
;
...
@@ -100,6 +111,7 @@ void If_ManStop( If_Man_t * p )
...
@@ -100,6 +111,7 @@ void If_ManStop( If_Man_t * p )
for
(
i
=
1
;
i
<
1
+
p
->
pPars
->
nCutsMax
*
p
->
pPars
->
nCutsMax
;
i
++
)
for
(
i
=
1
;
i
<
1
+
p
->
pPars
->
nCutsMax
*
p
->
pPars
->
nCutsMax
;
i
++
)
if
(
pTemp
>
p
->
ppCuts
[
i
]
)
if
(
pTemp
>
p
->
ppCuts
[
i
]
)
pTemp
=
p
->
ppCuts
[
i
];
pTemp
=
p
->
ppCuts
[
i
];
FREE
(
p
->
puTemp
[
0
]
);
free
(
pTemp
);
free
(
pTemp
);
free
(
p
->
ppCuts
);
free
(
p
->
ppCuts
);
free
(
p
);
free
(
p
);
...
@@ -200,7 +212,12 @@ If_Obj_t * If_ManSetupObj( If_Man_t * p )
...
@@ -200,7 +212,12 @@ If_Obj_t * If_ManSetupObj( If_Man_t * p )
// organize memory
// organize memory
pArrays
=
(
int
*
)((
char
*
)
pObj
+
p
->
nEntryBase
);
pArrays
=
(
int
*
)((
char
*
)
pObj
+
p
->
nEntryBase
);
for
(
i
=
0
;
i
<
p
->
pPars
->
nCutsMax
;
i
++
)
for
(
i
=
0
;
i
<
p
->
pPars
->
nCutsMax
;
i
++
)
pObj
->
Cuts
[
i
].
pLeaves
=
pArrays
+
i
*
p
->
pPars
->
nLutSize
;
{
pCut
=
pObj
->
Cuts
+
i
;
pCut
->
nLimit
=
p
->
pPars
->
nLutSize
;
pCut
->
pLeaves
=
pArrays
+
i
*
p
->
pPars
->
nLutSize
;
pCut
->
pTruth
=
pArrays
+
p
->
pPars
->
nCutsMax
*
p
->
pPars
->
nLutSize
+
i
*
p
->
nTruthSize
;
}
// assign ID and save
// assign ID and save
pObj
->
Id
=
Vec_PtrSize
(
p
->
vObjs
);
pObj
->
Id
=
Vec_PtrSize
(
p
->
vObjs
);
Vec_PtrPush
(
p
->
vObjs
,
pObj
);
Vec_PtrPush
(
p
->
vObjs
,
pObj
);
...
@@ -230,22 +247,24 @@ If_Obj_t * If_ManSetupObj( If_Man_t * p )
...
@@ -230,22 +247,24 @@ If_Obj_t * If_ManSetupObj( If_Man_t * p )
If_Cut_t
**
If_ManSetupCuts
(
If_Man_t
*
p
)
If_Cut_t
**
If_ManSetupCuts
(
If_Man_t
*
p
)
{
{
If_Cut_t
**
pCutStore
;
If_Cut_t
**
pCutStore
;
int
*
pArrays
,
nCut
Size
,
nCut
sTotal
,
i
;
int
*
pArrays
,
nCutsTotal
,
i
;
// decide how many cuts to alloc
// decide how many cuts to alloc
nCutsTotal
=
1
+
p
->
pPars
->
nCutsMax
*
p
->
pPars
->
nCutsMax
;
nCutsTotal
=
1
+
p
->
pPars
->
nCutsMax
*
p
->
pPars
->
nCutsMax
;
// figure out the cut size
nCutSize
=
sizeof
(
If_Cut_t
)
+
sizeof
(
int
)
*
p
->
pPars
->
nLutSize
;
// allocate and clean space for cuts
// allocate and clean space for cuts
pCutStore
=
(
If_Cut_t
**
)
ALLOC
(
If_Cut_t
*
,
(
nCutsTotal
+
1
)
);
pCutStore
=
(
If_Cut_t
**
)
ALLOC
(
If_Cut_t
*
,
(
nCutsTotal
+
1
)
);
memset
(
pCutStore
,
0
,
sizeof
(
If_Cut_t
*
)
*
(
nCutsTotal
+
1
)
);
memset
(
pCutStore
,
0
,
sizeof
(
If_Cut_t
*
)
*
(
nCutsTotal
+
1
)
);
pCutStore
[
0
]
=
(
If_Cut_t
*
)
ALLOC
(
char
,
nCutSize
*
nCutsTotal
);
pCutStore
[
0
]
=
(
If_Cut_t
*
)
ALLOC
(
char
,
p
->
nCutSize
*
nCutsTotal
);
memset
(
pCutStore
[
0
],
0
,
nCutSize
*
nCutsTotal
);
memset
(
pCutStore
[
0
],
0
,
p
->
nCutSize
*
nCutsTotal
);
for
(
i
=
1
;
i
<
nCutsTotal
;
i
++
)
// assign cut paramters and space for the cut leaves
pCutStore
[
i
]
=
(
If_Cut_t
*
)((
char
*
)
pCutStore
[
0
]
+
sizeof
(
If_Cut_t
)
*
i
);
assert
(
sizeof
(
int
)
==
sizeof
(
unsigned
)
);
// assign room for cut leaves
pArrays
=
(
int
*
)((
char
*
)
pCutStore
[
0
]
+
sizeof
(
If_Cut_t
)
*
nCutsTotal
);
pArrays
=
(
int
*
)((
char
*
)
pCutStore
[
0
]
+
sizeof
(
If_Cut_t
)
*
nCutsTotal
);
for
(
i
=
0
;
i
<
nCutsTotal
;
i
++
)
for
(
i
=
0
;
i
<
nCutsTotal
;
i
++
)
{
pCutStore
[
i
]
=
(
If_Cut_t
*
)((
char
*
)
pCutStore
[
0
]
+
sizeof
(
If_Cut_t
)
*
i
);
pCutStore
[
i
]
->
nLimit
=
p
->
pPars
->
nLutSize
;
pCutStore
[
i
]
->
pLeaves
=
pArrays
+
i
*
p
->
pPars
->
nLutSize
;
pCutStore
[
i
]
->
pLeaves
=
pArrays
+
i
*
p
->
pPars
->
nLutSize
;
pCutStore
[
i
]
->
pTruth
=
pArrays
+
nCutsTotal
*
p
->
pPars
->
nLutSize
+
i
*
p
->
nTruthSize
;
}
return
pCutStore
;
return
pCutStore
;
}
}
...
...
src/map/if/ifMap.c
View file @
38254947
...
@@ -59,567 +59,6 @@ static inline int If_WordCountOnes( unsigned uWord )
...
@@ -59,567 +59,6 @@ static inline int If_WordCountOnes( unsigned uWord )
/**Function*************************************************************
/**Function*************************************************************
Synopsis [Returns 1 if pDom is contained in pCut.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static
inline
int
If_CutCheckDominance
(
If_Cut_t
*
pDom
,
If_Cut_t
*
pCut
)
{
int
i
,
k
;
for
(
i
=
0
;
i
<
(
int
)
pDom
->
nLeaves
;
i
++
)
{
for
(
k
=
0
;
k
<
(
int
)
pCut
->
nLeaves
;
k
++
)
if
(
pDom
->
pLeaves
[
i
]
==
pCut
->
pLeaves
[
k
]
)
break
;
if
(
k
==
(
int
)
pCut
->
nLeaves
)
// node i in pDom is not contained in pCut
return
0
;
}
// every node in pDom is contained in pCut
return
1
;
}
/**Function*************************************************************
Synopsis [Returns 1 if pDom is equal to pCut.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static
inline
int
If_CutCheckEquality
(
If_Cut_t
*
pDom
,
If_Cut_t
*
pCut
)
{
int
i
;
if
(
(
int
)
pDom
->
nLeaves
!=
(
int
)
pCut
->
nLeaves
)
return
0
;
for
(
i
=
0
;
i
<
(
int
)
pDom
->
nLeaves
;
i
++
)
if
(
pDom
->
pLeaves
[
i
]
!=
pCut
->
pLeaves
[
i
]
)
return
0
;
return
1
;
}
/**Function*************************************************************
Synopsis [Returns 1 if the cut is contained.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int
If_CutFilter
(
If_Man_t
*
p
,
If_Cut_t
*
pCut
,
int
Mode
)
{
If_Cut_t
*
pTemp
;
int
i
;
for
(
i
=
0
;
i
<
p
->
nCuts
;
i
++
)
{
pTemp
=
p
->
ppCuts
[
i
];
if
(
pTemp
->
nLeaves
>
pCut
->
nLeaves
)
{
// continue;
// skip the non-contained cuts
if
(
(
pTemp
->
uSign
&
pCut
->
uSign
)
!=
pCut
->
uSign
)
continue
;
// check containment seriously
if
(
If_CutCheckDominance
(
pCut
,
pTemp
)
)
{
// removed contained cut
p
->
ppCuts
[
i
]
=
p
->
ppCuts
[
p
->
nCuts
-
1
];
p
->
ppCuts
[
p
->
nCuts
-
1
]
=
pTemp
;
p
->
nCuts
--
;
i
--
;
}
}
else
{
// skip the non-contained cuts
if
(
(
pTemp
->
uSign
&
pCut
->
uSign
)
!=
pTemp
->
uSign
)
continue
;
// check containment seriously
if
(
If_CutCheckDominance
(
pTemp
,
pCut
)
)
return
1
;
}
}
return
0
;
}
/**Function*************************************************************
Synopsis [Merges two cuts.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static
inline
int
If_CutMergeOrdered
(
If_Cut_t
*
pC0
,
If_Cut_t
*
pC1
,
If_Cut_t
*
pC
,
int
nLimit
)
{
int
i
,
k
,
c
;
assert
(
pC0
->
nLeaves
>=
pC1
->
nLeaves
);
// the case of the largest cut sizes
if
(
pC0
->
nLeaves
==
nLimit
&&
pC1
->
nLeaves
==
nLimit
)
{
for
(
i
=
0
;
i
<
pC0
->
nLeaves
;
i
++
)
if
(
pC0
->
pLeaves
[
i
]
!=
pC1
->
pLeaves
[
i
]
)
return
0
;
for
(
i
=
0
;
i
<
pC0
->
nLeaves
;
i
++
)
pC
->
pLeaves
[
i
]
=
pC0
->
pLeaves
[
i
];
pC
->
nLeaves
=
pC0
->
nLeaves
;
return
1
;
}
// the case when one of the cuts is the largest
if
(
pC0
->
nLeaves
==
nLimit
)
{
for
(
i
=
0
;
i
<
pC1
->
nLeaves
;
i
++
)
{
for
(
k
=
pC0
->
nLeaves
-
1
;
k
>=
0
;
k
--
)
if
(
pC0
->
pLeaves
[
k
]
==
pC1
->
pLeaves
[
i
]
)
break
;
if
(
k
==
-
1
)
// did not find
return
0
;
}
for
(
i
=
0
;
i
<
pC0
->
nLeaves
;
i
++
)
pC
->
pLeaves
[
i
]
=
pC0
->
pLeaves
[
i
];
pC
->
nLeaves
=
pC0
->
nLeaves
;
return
1
;
}
// compare two cuts with different numbers
i
=
k
=
0
;
for
(
c
=
0
;
c
<
nLimit
;
c
++
)
{
if
(
k
==
pC1
->
nLeaves
)
{
if
(
i
==
pC0
->
nLeaves
)
{
pC
->
nLeaves
=
c
;
return
1
;
}
pC
->
pLeaves
[
c
]
=
pC0
->
pLeaves
[
i
++
];
continue
;
}
if
(
i
==
pC0
->
nLeaves
)
{
if
(
k
==
pC1
->
nLeaves
)
{
pC
->
nLeaves
=
c
;
return
1
;
}
pC
->
pLeaves
[
c
]
=
pC1
->
pLeaves
[
k
++
];
continue
;
}
if
(
pC0
->
pLeaves
[
i
]
<
pC1
->
pLeaves
[
k
]
)
{
pC
->
pLeaves
[
c
]
=
pC0
->
pLeaves
[
i
++
];
continue
;
}
if
(
pC0
->
pLeaves
[
i
]
>
pC1
->
pLeaves
[
k
]
)
{
pC
->
pLeaves
[
c
]
=
pC1
->
pLeaves
[
k
++
];
continue
;
}
pC
->
pLeaves
[
c
]
=
pC0
->
pLeaves
[
i
++
];
k
++
;
}
if
(
i
<
pC0
->
nLeaves
||
k
<
pC1
->
nLeaves
)
return
0
;
pC
->
nLeaves
=
c
;
return
1
;
}
/**Function*************************************************************
Synopsis [Merges two cuts.]
Description [Special case when the cut is known to exist.]
SideEffects []
SeeAlso []
***********************************************************************/
static
inline
int
If_CutMergeOrdered2
(
If_Cut_t
*
pC0
,
If_Cut_t
*
pC1
,
If_Cut_t
*
pC
,
int
nLimit
)
{
int
i
,
k
,
c
;
assert
(
pC0
->
nLeaves
>=
pC1
->
nLeaves
);
// copy the first cut
for
(
i
=
0
;
i
<
pC0
->
nLeaves
;
i
++
)
pC
->
pLeaves
[
i
]
=
pC0
->
pLeaves
[
i
];
pC
->
nLeaves
=
pC0
->
nLeaves
;
// the case when one of the cuts is the largest
if
(
pC0
->
nLeaves
==
nLimit
)
return
1
;
// add nodes of the second cut
k
=
0
;
for
(
i
=
0
;
i
<
pC1
->
nLeaves
;
i
++
)
{
// find k-th node before which i-th node should be added
for
(
;
k
<
pC
->
nLeaves
;
k
++
)
if
(
pC
->
pLeaves
[
k
]
>=
pC1
->
pLeaves
[
i
]
)
break
;
// check the case when this should be the last node
if
(
k
==
pC
->
nLeaves
)
{
pC
->
pLeaves
[
k
++
]
=
pC1
->
pLeaves
[
i
];
pC
->
nLeaves
++
;
continue
;
}
// check the case when equal node is found
if
(
pC1
->
pLeaves
[
i
]
==
pC
->
pLeaves
[
k
]
)
continue
;
// add the node
for
(
c
=
pC
->
nLeaves
;
c
>
k
;
c
--
)
pC
->
pLeaves
[
c
]
=
pC
->
pLeaves
[
c
-
1
];
pC
->
pLeaves
[
k
++
]
=
pC1
->
pLeaves
[
i
];
pC
->
nLeaves
++
;
}
assert
(
pC
->
nLeaves
<=
nLimit
);
for
(
i
=
1
;
i
<
pC
->
nLeaves
;
i
++
)
assert
(
pC
->
pLeaves
[
i
-
1
]
<
pC
->
pLeaves
[
i
]
);
return
1
;
}
/**Function*************************************************************
Synopsis [Prepares the object for FPGA mapping.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int
If_CutMerge
(
If_Cut_t
*
pCut0
,
If_Cut_t
*
pCut1
,
If_Cut_t
*
pCut
,
int
nLimit
)
{
// merge the nodes
if
(
pCut0
->
nLeaves
<
pCut1
->
nLeaves
)
{
if
(
!
If_CutMergeOrdered
(
pCut1
,
pCut0
,
pCut
,
nLimit
)
)
return
0
;
}
else
{
if
(
!
If_CutMergeOrdered
(
pCut0
,
pCut1
,
pCut
,
nLimit
)
)
return
0
;
}
return
1
;
}
/**Function*************************************************************
Synopsis [Prepares the object for FPGA mapping.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int
If_CutCompareDelay
(
If_Cut_t
**
ppC0
,
If_Cut_t
**
ppC1
)
{
If_Cut_t
*
pC0
=
*
ppC0
;
If_Cut_t
*
pC1
=
*
ppC1
;
if
(
pC0
->
Delay
<
pC1
->
Delay
-
0
.
0001
)
return
-
1
;
if
(
pC0
->
Delay
>
pC1
->
Delay
+
0
.
0001
)
return
1
;
if
(
pC0
->
nLeaves
<
pC1
->
nLeaves
)
return
-
1
;
if
(
pC0
->
nLeaves
>
pC1
->
nLeaves
)
return
1
;
if
(
pC0
->
Area
<
pC1
->
Area
-
0
.
0001
)
return
-
1
;
if
(
pC0
->
Area
>
pC1
->
Area
+
0
.
0001
)
return
1
;
return
0
;
}
/**Function*************************************************************
Synopsis [Prepares the object for FPGA mapping.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int
If_CutCompareDelayOld
(
If_Cut_t
**
ppC0
,
If_Cut_t
**
ppC1
)
{
If_Cut_t
*
pC0
=
*
ppC0
;
If_Cut_t
*
pC1
=
*
ppC1
;
if
(
pC0
->
Delay
<
pC1
->
Delay
-
0
.
0001
)
return
-
1
;
if
(
pC0
->
Delay
>
pC1
->
Delay
+
0
.
0001
)
return
1
;
if
(
pC0
->
Area
<
pC1
->
Area
-
0
.
0001
)
return
-
1
;
if
(
pC0
->
Area
>
pC1
->
Area
+
0
.
0001
)
return
1
;
if
(
pC0
->
nLeaves
<
pC1
->
nLeaves
)
return
-
1
;
if
(
pC0
->
nLeaves
>
pC1
->
nLeaves
)
return
1
;
return
0
;
}
/**Function*************************************************************
Synopsis [Prepares the object for FPGA mapping.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int
If_CutCompareArea
(
If_Cut_t
**
ppC0
,
If_Cut_t
**
ppC1
)
{
If_Cut_t
*
pC0
=
*
ppC0
;
If_Cut_t
*
pC1
=
*
ppC1
;
if
(
pC0
->
Area
<
pC1
->
Area
-
0
.
0001
)
return
-
1
;
if
(
pC0
->
Area
>
pC1
->
Area
+
0
.
0001
)
return
1
;
if
(
pC0
->
nLeaves
<
pC1
->
nLeaves
)
return
-
1
;
if
(
pC0
->
nLeaves
>
pC1
->
nLeaves
)
return
1
;
if
(
pC0
->
Delay
<
pC1
->
Delay
-
0
.
0001
)
return
-
1
;
if
(
pC0
->
Delay
>
pC1
->
Delay
+
0
.
0001
)
return
1
;
return
0
;
}
/**Function*************************************************************
Synopsis [Sorts the cuts.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
If_ManSortCuts
(
If_Man_t
*
p
,
int
Mode
)
{
// sort the cuts
if
(
Mode
||
p
->
pPars
->
fArea
)
// area
qsort
(
p
->
ppCuts
,
p
->
nCuts
,
sizeof
(
If_Cut_t
*
),
(
int
(
*
)(
const
void
*
,
const
void
*
))
If_CutCompareArea
);
else
if
(
p
->
pPars
->
fFancy
)
qsort
(
p
->
ppCuts
,
p
->
nCuts
,
sizeof
(
If_Cut_t
*
),
(
int
(
*
)(
const
void
*
,
const
void
*
))
If_CutCompareDelayOld
);
else
qsort
(
p
->
ppCuts
,
p
->
nCuts
,
sizeof
(
If_Cut_t
*
),
(
int
(
*
)(
const
void
*
,
const
void
*
))
If_CutCompareDelay
);
}
/**Function*************************************************************
Synopsis [Computes delay.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
float
If_CutDelay
(
If_Man_t
*
p
,
If_Cut_t
*
pCut
)
{
If_Obj_t
*
pLeaf
;
float
Delay
;
int
i
;
assert
(
pCut
->
nLeaves
>
1
);
Delay
=
-
IF_FLOAT_LARGE
;
If_CutForEachLeaf
(
p
,
pCut
,
pLeaf
,
i
)
Delay
=
IF_MAX
(
Delay
,
If_ObjCutBest
(
pLeaf
)
->
Delay
);
return
Delay
+
If_CutLutDelay
(
p
,
pCut
);
}
/**Function*************************************************************
Synopsis [Computes area flow.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
float
If_CutFlow
(
If_Man_t
*
p
,
If_Cut_t
*
pCut
)
{
If_Obj_t
*
pLeaf
;
float
Flow
;
int
i
;
assert
(
pCut
->
nLeaves
>
1
);
Flow
=
If_CutLutArea
(
p
,
pCut
);
If_CutForEachLeaf
(
p
,
pCut
,
pLeaf
,
i
)
{
if
(
pLeaf
->
nRefs
==
0
)
Flow
+=
If_ObjCutBest
(
pLeaf
)
->
Area
;
else
{
assert
(
pLeaf
->
EstRefs
>
p
->
fEpsilon
);
Flow
+=
If_ObjCutBest
(
pLeaf
)
->
Area
/
pLeaf
->
EstRefs
;
}
}
return
Flow
;
}
/**Function*************************************************************
Synopsis [Computes area of the first level.]
Description [The cut need to be derefed.]
SideEffects []
SeeAlso []
***********************************************************************/
float
If_CutDeref
(
If_Man_t
*
p
,
If_Cut_t
*
pCut
,
int
nLevels
)
{
If_Obj_t
*
pLeaf
;
float
Area
;
int
i
;
Area
=
If_CutLutArea
(
p
,
pCut
);
If_CutForEachLeaf
(
p
,
pCut
,
pLeaf
,
i
)
{
assert
(
pLeaf
->
nRefs
>
0
);
if
(
--
pLeaf
->
nRefs
>
0
||
!
If_ObjIsAnd
(
pLeaf
)
||
nLevels
==
1
)
continue
;
Area
+=
If_CutDeref
(
p
,
If_ObjCutBest
(
pLeaf
),
nLevels
-
1
);
}
return
Area
;
}
/**Function*************************************************************
Synopsis [Computes area of the first level.]
Description [The cut need to be derefed.]
SideEffects []
SeeAlso []
***********************************************************************/
float
If_CutRef
(
If_Man_t
*
p
,
If_Cut_t
*
pCut
,
int
nLevels
)
{
If_Obj_t
*
pLeaf
;
float
Area
;
int
i
;
Area
=
If_CutLutArea
(
p
,
pCut
);
If_CutForEachLeaf
(
p
,
pCut
,
pLeaf
,
i
)
{
assert
(
pLeaf
->
nRefs
>=
0
);
if
(
pLeaf
->
nRefs
++
>
0
||
!
If_ObjIsAnd
(
pLeaf
)
||
nLevels
==
1
)
continue
;
Area
+=
If_CutRef
(
p
,
If_ObjCutBest
(
pLeaf
),
nLevels
-
1
);
}
return
Area
;
}
/**Function*************************************************************
Synopsis [Prints one cut.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
If_CutPrint
(
If_Man_t
*
p
,
If_Cut_t
*
pCut
)
{
int
i
;
printf
(
"{"
);
for
(
i
=
0
;
i
<
pCut
->
nLeaves
;
i
++
)
printf
(
" %d"
,
pCut
->
pLeaves
[
i
]
);
printf
(
" }
\n
"
);
}
/**Function*************************************************************
Synopsis [Computes area of the first level.]
Description [The cut need to be derefed.]
SideEffects []
SeeAlso []
***********************************************************************/
float
If_CutAreaDerefed
(
If_Man_t
*
p
,
If_Cut_t
*
pCut
,
int
nLevels
)
{
float
aResult
,
aResult2
;
assert
(
pCut
->
nLeaves
>
1
);
aResult2
=
If_CutRef
(
p
,
pCut
,
nLevels
);
aResult
=
If_CutDeref
(
p
,
pCut
,
nLevels
);
assert
(
aResult
==
aResult2
);
return
aResult
;
}
/**Function*************************************************************
Synopsis [Computes area of the first level.]
Description [The cut need to be derefed.]
SideEffects []
SeeAlso []
***********************************************************************/
float
If_CutAreaRefed
(
If_Man_t
*
p
,
If_Cut_t
*
pCut
,
int
nLevels
)
{
float
aResult
,
aResult2
;
assert
(
pCut
->
nLeaves
>
1
);
aResult2
=
If_CutDeref
(
p
,
pCut
,
nLevels
);
aResult
=
If_CutRef
(
p
,
pCut
,
nLevels
);
assert
(
aResult
==
aResult2
);
return
aResult
;
}
/**Function*************************************************************
Synopsis [Computes area of the first level.]
Description [The cut need to be derefed.]
SideEffects []
SeeAlso []
***********************************************************************/
void
If_CutCopy
(
If_Cut_t
*
pCutDest
,
If_Cut_t
*
pCutSrc
)
{
int
*
pArray
;
pArray
=
pCutDest
->
pLeaves
;
*
pCutDest
=
*
pCutSrc
;
pCutDest
->
pLeaves
=
pArray
;
memcpy
(
pCutDest
->
pLeaves
,
pCutSrc
->
pLeaves
,
sizeof
(
int
)
*
pCutSrc
->
nLeaves
);
}
/**Function*************************************************************
Synopsis [Finds the best cut.]
Synopsis [Finds the best cut.]
Description [Mapping modes: delay (0), area flow (1), area (2).]
Description [Mapping modes: delay (0), area flow (1), area (2).]
...
@@ -632,7 +71,7 @@ void If_CutCopy( If_Cut_t * pCutDest, If_Cut_t * pCutSrc )
...
@@ -632,7 +71,7 @@ void If_CutCopy( If_Cut_t * pCutDest, If_Cut_t * pCutSrc )
void
If_ObjPerformMapping
(
If_Man_t
*
p
,
If_Obj_t
*
pObj
,
int
Mode
)
void
If_ObjPerformMapping
(
If_Man_t
*
p
,
If_Obj_t
*
pObj
,
int
Mode
)
{
{
If_Cut_t
*
pCut0
,
*
pCut1
,
*
pCut
;
If_Cut_t
*
pCut0
,
*
pCut1
,
*
pCut
;
int
i
,
k
,
iCut
;
int
i
,
k
,
iCut
,
Temp
;
// prepare
// prepare
if
(
Mode
==
0
)
if
(
Mode
==
0
)
...
@@ -670,29 +109,34 @@ void If_ObjPerformMapping( If_Man_t * p, If_Obj_t * pObj, int Mode )
...
@@ -670,29 +109,34 @@ void If_ObjPerformMapping( If_Man_t * p, If_Obj_t * pObj, int Mode )
if
(
Mode
&&
(
pCut0
->
Delay
>
pObj
->
Required
+
p
->
fEpsilon
||
pCut1
->
Delay
>
pObj
->
Required
+
p
->
fEpsilon
)
)
if
(
Mode
&&
(
pCut0
->
Delay
>
pObj
->
Required
+
p
->
fEpsilon
||
pCut1
->
Delay
>
pObj
->
Required
+
p
->
fEpsilon
)
)
continue
;
continue
;
// merge the nodes
// merge the nodes
if
(
!
If_CutMerge
(
pCut0
,
pCut1
,
pCut
,
p
->
pPars
->
nLutSize
)
)
if
(
!
If_CutMerge
(
pCut0
,
pCut1
,
pCut
)
)
continue
;
continue
;
// check if this cut is contained in any of the available cuts
// check if this cut is contained in any of the available cuts
pCut
->
uSign
=
pCut0
->
uSign
|
pCut1
->
uSign
;
pCut
->
uSign
=
pCut0
->
uSign
|
pCut1
->
uSign
;
if
(
If_CutFilter
(
p
,
pCut
,
Mode
)
)
if
(
If_CutFilter
(
p
,
pCut
)
)
continue
;
continue
;
// check if the cut satisfies the required times
// check if the cut satisfies the required times
pCut
->
Delay
=
If_CutDelay
(
p
,
pCut
);
pCut
->
Delay
=
If_CutDelay
(
p
,
pCut
);
if
(
Mode
&&
pCut
->
Delay
>
pObj
->
Required
+
p
->
fEpsilon
)
if
(
Mode
&&
pCut
->
Delay
>
pObj
->
Required
+
p
->
fEpsilon
)
continue
;
continue
;
// the cuts have been successfully merged
// the cuts have been successfully merged
pCut
->
pOne
=
pCut0
;
pCut
->
fCompl0
=
pObj
->
fCompl0
;
// compute the truth table
pCut
->
pTwo
=
pCut1
;
pCut
->
fCompl1
=
pObj
->
fCompl1
;
if
(
p
->
pPars
->
fTruth
)
// pCut->Phase = ...
If_CutComputeTruth
(
p
,
pCut
,
pCut0
,
pCut1
,
pObj
->
fCompl0
,
pObj
->
fCompl1
);
// pCut->Phase = (char)(int)If_CutAreaDerefed( p, pCut, 1 );
// compute the application-specific cost and depth
Temp
=
p
->
pPars
->
pFuncCost
?
p
->
pPars
->
pFuncCost
(
If_CutTruth
(
pCut
),
pCut
->
nLimit
)
:
0
;
pCut
->
Cost
=
(
Temp
&
0xffff
);
pCut
->
Depth
=
(
Temp
>>
16
);
// compute area of the cut (this area may depend on the application specific cost)
pCut
->
Area
=
(
Mode
==
2
)
?
If_CutAreaDerefed
(
p
,
pCut
,
100
)
:
If_CutFlow
(
p
,
pCut
);
pCut
->
Area
=
(
Mode
==
2
)
?
If_CutAreaDerefed
(
p
,
pCut
,
100
)
:
If_CutFlow
(
p
,
pCut
);
p
->
nCutsMerged
++
;
// make sure the cut is the last one (after filtering it may not be so)
// make sure the cut is the last one (after filtering it may not be so)
assert
(
pCut
==
p
->
ppCuts
[
iCut
]
);
assert
(
pCut
==
p
->
ppCuts
[
iCut
]
);
p
->
ppCuts
[
iCut
]
=
p
->
ppCuts
[
p
->
nCuts
];
p
->
ppCuts
[
iCut
]
=
p
->
ppCuts
[
p
->
nCuts
];
p
->
ppCuts
[
p
->
nCuts
]
=
pCut
;
p
->
ppCuts
[
p
->
nCuts
]
=
pCut
;
// count the cut
p
->
nCuts
++
;
p
->
nCutsMerged
++
;
// prepare room for the next cut
// prepare room for the next cut
iCut
=
++
p
->
nCuts
;
iCut
=
p
->
nCuts
;
pCut
=
p
->
ppCuts
[
iCut
];
pCut
=
p
->
ppCuts
[
iCut
];
}
}
//printf( "%d ", p->nCuts );
//printf( "%d ", p->nCuts );
...
...
src/map/if/if
Select
.c
→
src/map/if/if
Prepro
.c
View file @
38254947
/**CFile****************************************************************
/**CFile****************************************************************
FileName [if
Select
.c]
FileName [if
Prepro
.c]
SystemName [ABC: Logic synthesis and verification system.]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [FPGA mapping based on priority cuts.]
PackageName [FPGA mapping based on priority cuts.]
Synopsis [Selects
what mapping to use
.]
Synopsis [Selects
the starting mapping
.]
Author [Alan Mishchenko]
Author [Alan Mishchenko]
...
@@ -14,7 +14,7 @@
...
@@ -14,7 +14,7 @@
Date [Ver. 1.0. Started - November 21, 2006.]
Date [Ver. 1.0. Started - November 21, 2006.]
Revision [$Id: if
Select
.c,v 1.00 2006/11/21 00:00:00 alanmi Exp $]
Revision [$Id: if
Prepro
.c,v 1.00 2006/11/21 00:00:00 alanmi Exp $]
***********************************************************************/
***********************************************************************/
...
...
src/map/if/ifReduce.c
View file @
38254947
...
@@ -522,11 +522,11 @@ void If_ManImproveNodeReduce( If_Man_t * p, If_Obj_t * pObj, int nLimit )
...
@@ -522,11 +522,11 @@ void If_ManImproveNodeReduce( If_Man_t * p, If_Obj_t * pObj, int nLimit )
// merge the cuts
// merge the cuts
pCutR
=
p
->
ppCuts
[
0
];
pCutR
=
p
->
ppCuts
[
0
];
RetValue
=
If_CutMerge
(
pCut0
,
pCut1
,
pCutR
,
nLimit
);
RetValue
=
If_CutMerge
(
pCut0
,
pCut1
,
pCutR
);
// try very simple cut
// try very simple cut
if
(
!
RetValue
)
if
(
!
RetValue
)
{
{
RetValue
=
If_CutMerge
(
If_ObjCutTriv
(
pFanin0
),
If_ObjCutTriv
(
pFanin1
),
pCutR
,
nLimit
);
RetValue
=
If_CutMerge
(
If_ObjCutTriv
(
pFanin0
),
If_ObjCutTriv
(
pFanin1
),
pCutR
);
assert
(
RetValue
==
1
);
assert
(
RetValue
==
1
);
}
}
if
(
RetValue
)
if
(
RetValue
)
...
...
src/map/if/ifSeq.c
View file @
38254947
...
@@ -95,7 +95,7 @@ int If_ManPerformMappingSeq( If_Man_t * p )
...
@@ -95,7 +95,7 @@ int If_ManPerformMappingSeq( If_Man_t * p )
***********************************************************************/
***********************************************************************/
void
If_CutLift
(
If_Cut_t
*
pCut
)
void
If_CutLift
(
If_Cut_t
*
pCut
)
{
{
int
i
;
unsigned
i
;
for
(
i
=
0
;
i
<
pCut
->
nLeaves
;
i
++
)
for
(
i
=
0
;
i
<
pCut
->
nLeaves
;
i
++
)
pCut
->
pLeaves
[
i
]
=
((
pCut
->
pLeaves
[
i
]
>>
8
)
<<
8
)
|
((
pCut
->
pLeaves
[
i
]
&
255
)
+
1
);
pCut
->
pLeaves
[
i
]
=
((
pCut
->
pLeaves
[
i
]
>>
8
)
<<
8
)
|
((
pCut
->
pLeaves
[
i
]
&
255
)
+
1
);
}
}
...
...
src/map/if/ifTruth.c
0 → 100644
View file @
38254947
/**CFile****************************************************************
FileName [ifTruth.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [FPGA mapping based on priority cuts.]
Synopsis [Computation of truth tables of the cuts.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - November 21, 2006.]
Revision [$Id: ifTruth.c,v 1.00 2006/11/21 00:00:00 alanmi Exp $]
***********************************************************************/
#include "if.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Computes the stretching phase of the cut w.r.t. the merged cut.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static
inline
unsigned
Cut_TruthPhase
(
If_Cut_t
*
pCut
,
If_Cut_t
*
pCut1
)
{
unsigned
uPhase
=
0
;
int
i
,
k
;
for
(
i
=
k
=
0
;
i
<
(
int
)
pCut
->
nLeaves
;
i
++
)
{
if
(
k
==
(
int
)
pCut1
->
nLeaves
)
break
;
if
(
pCut
->
pLeaves
[
i
]
<
pCut1
->
pLeaves
[
k
]
)
continue
;
assert
(
pCut
->
pLeaves
[
i
]
==
pCut1
->
pLeaves
[
k
]
);
uPhase
|=
(
1
<<
i
);
k
++
;
}
return
uPhase
;
}
/**Function*************************************************************
Synopsis [Performs truth table computation.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
If_CutComputeTruth
(
If_Man_t
*
p
,
If_Cut_t
*
pCut
,
If_Cut_t
*
pCut0
,
If_Cut_t
*
pCut1
,
int
fCompl0
,
int
fCompl1
)
{
// permute the first table
if
(
fCompl0
)
Extra_TruthNot
(
p
->
puTemp
[
0
],
If_CutTruth
(
pCut0
),
pCut
->
nLimit
);
else
Extra_TruthCopy
(
p
->
puTemp
[
0
],
If_CutTruth
(
pCut0
),
pCut
->
nLimit
);
Extra_TruthStretch
(
p
->
puTemp
[
2
],
p
->
puTemp
[
0
],
pCut0
->
nLeaves
,
pCut
->
nLimit
,
Cut_TruthPhase
(
pCut
,
pCut0
)
);
// permute the second table
if
(
fCompl1
)
Extra_TruthNot
(
p
->
puTemp
[
1
],
If_CutTruth
(
pCut1
),
pCut
->
nLimit
);
else
Extra_TruthCopy
(
p
->
puTemp
[
1
],
If_CutTruth
(
pCut1
),
pCut
->
nLimit
);
Extra_TruthStretch
(
p
->
puTemp
[
3
],
p
->
puTemp
[
1
],
pCut1
->
nLeaves
,
pCut
->
nLimit
,
Cut_TruthPhase
(
pCut
,
pCut1
)
);
// produce the resulting table
if
(
pCut
->
fCompl
)
Extra_TruthNand
(
If_CutTruth
(
pCut
),
p
->
puTemp
[
2
],
p
->
puTemp
[
3
],
pCut
->
nLimit
);
else
Extra_TruthAnd
(
If_CutTruth
(
pCut
),
p
->
puTemp
[
2
],
p
->
puTemp
[
3
],
pCut
->
nLimit
);
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
src/map/if/module.make
View file @
38254947
...
@@ -2,7 +2,8 @@ SRC += src/map/if/ifCore.c \
...
@@ -2,7 +2,8 @@ SRC += src/map/if/ifCore.c \
src/map/if/ifCut.c
\
src/map/if/ifCut.c
\
src/map/if/ifMan.c
\
src/map/if/ifMan.c
\
src/map/if/ifMap.c
\
src/map/if/ifMap.c
\
src/map/if/ifPrepro.c
\
src/map/if/ifReduce.c
\
src/map/if/ifReduce.c
\
src/map/if/ifSelect.c
\
src/map/if/ifSeq.c
\
src/map/if/ifSeq.c
\
src/map/if/ifTruth.c
\
src/map/if/ifUtil.c
src/map/if/ifUtil.c
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