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
Hide whitespace changes
Inline
Side-by-side
Showing
24 changed files
with
2225 additions
and
1877 deletions
+2225
-1877
abc.dsp
+14
-2
abc.rc
+0
-1
src/aig/ivy/ivyFactor.c
+489
-539
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
+38
-75
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
+15
-571
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
# End Source File
# Begin Source File
SOURCE=.\src\base\abci\abcMulti.c
# End Source File
# Begin Source File
SOURCE=.\src\base\abci\abcMv.c
# End Source File
# Begin Source File
...
...
@@ -294,6 +298,10 @@ SOURCE=.\src\base\abci\abcRenode.c
# End Source File
# Begin Source File
SOURCE=.\src\base\abci\abcReorder.c
# End Source File
# Begin Source File
SOURCE=.\src\base\abci\abcRestruct.c
# End Source File
# Begin Source File
...
...
@@ -1826,11 +1834,11 @@ SOURCE=.\src\map\if\ifMap.c
# End Source File
# Begin Source File
SOURCE=.\src\map\if\if
Reduce
.c
SOURCE=.\src\map\if\if
Prepro
.c
# End Source File
# Begin Source File
SOURCE=.\src\map\if\if
Select
.c
SOURCE=.\src\map\if\if
Reduce
.c
# End Source File
# Begin Source File
...
...
@@ -1838,6 +1846,10 @@ SOURCE=.\src\map\if\ifSeq.c
# End Source File
# Begin Source File
SOURCE=.\src\map\if\ifTruth.c
# End Source File
# Begin Source File
SOURCE=.\src\map\if\ifUtil.c
# End Source File
# End Group
...
...
abc.rc
View file @
38254947
...
...
@@ -30,7 +30,6 @@ alias fs fraig_sweep
alias fsto fraig_store
alias fres fraig_restore
alias ft fraig_trust
alias mu renode -m
alias pex print_exdc -d
alias pf print_factor
alias pfan print_fanio
...
...
src/aig/ivy/ivyFactor.c
View file @
38254947
...
...
@@ -25,16 +25,398 @@
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
extern
Dec_Edge_t
Dec_Factor32_rec
(
Dec_Graph_t
*
pFForm
,
Vec_Int_t
*
vCover
,
int
nVars
);
extern
Dec_Edge_t
Dec_Factor32LF_rec
(
Dec_Graph_t
*
pFForm
,
Vec_Int_t
*
vCover
,
int
nVars
,
Vec_Int_t
*
vSimple
);
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
);
// ISOP computation fails if intermediate memory usage exceed this limit
#define IVY_FACTOR_MEM_LIMIT 16*4096
// 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
;
}
static
inline
unsigned
Ivy_CubeSharp
(
unsigned
uCube
,
unsigned
uPart
)
{
return
uCube
&
~
uPart
;
}
static
inline
unsigned
Ivy_CubeMask
(
int
nVar
)
{
return
(
~
(
unsigned
)
0
)
>>
(
32
-
nVar
);
}
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
);
}
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
;
}
// iterators
#define Ivy_SopForEachCube( cSop, uCube, i ) \
for ( i = 0; (i < Ivy_SopCubeNum(cSop)) && ((uCube) = Ivy_SopCube(cSop, i)); i++ )
#define Ivy_CubeForEachLiteral( uCube, Lit, nLits, i ) \
for ( i = 0; (i < (nLits)) && ((Lit) = Ivy_CubeHasLit(uCube, i)); i++ )
/**Function*************************************************************
Synopsis [Divides cover by one cube.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
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
)
{
unsigned
uCube
,
uDiv
;
int
i
;
// get the only cube
assert
(
Ivy_SopCubeNum
(
cDiv
)
==
1
);
uDiv
=
Ivy_SopCube
(
cDiv
,
0
);
// allocate covers
vQuo
->
nCubes
=
0
;
vQuo
->
uCubes
=
Vec_IntFetch
(
vStore
,
Ivy_SopCubeNum
(
cSop
)
);
vRem
->
nCubes
=
0
;
vRem
->
uCubes
=
Vec_IntFetch
(
vStore
,
Ivy_SopCubeNum
(
cSop
)
);
// sort the cubes
Ivy_SopForEachCube
(
cSop
,
uCube
,
i
)
{
if
(
Ivy_CubeContains
(
uCube
,
uDiv
)
)
Ivy_SopAddCube
(
vQuo
,
Ivy_CubeSharp
(
uCube
,
uDiv
)
);
else
Ivy_SopAddCube
(
vRem
,
uCube
);
}
}
/**Function*************************************************************
Synopsis [Divides cover by one cube.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
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
)
{
unsigned
uCube
,
uCube2
,
uDiv
,
uDiv2
,
uQuo
;
int
i
,
i2
,
k
,
k2
;
assert
(
Ivy_SopCubeNum
(
cSop
)
>=
Ivy_SopCubeNum
(
cDiv
)
);
if
(
Ivy_SopCubeNum
(
cDiv
)
==
1
)
{
Ivy_SopDivideByCube
(
cSop
,
cDiv
,
vQuo
,
vRem
);
return
;
}
// 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
)
{
// skip taken cubes
if
(
Ivy_CubeIsMarked
(
uCube
)
)
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
Ivy_SopSetCube
(
cSop
,
Ivy_CubeMark
(
uCube2
),
i2
);
}
// if we did not find some cube, continue
// (later we will add marked cubes to the remainder)
if
(
k2
!=
Ivy_SopCubeNum
(
cDiv
)
)
continue
;
// we found all cubes - add the quotient cube
Ivy_SopAddCube
(
vQuo
,
uQuo
);
}
// allocate remainder
vRem
->
nCubes
=
0
;
vRem
->
uCubes
=
Vec_IntFetch
(
vStore
,
Ivy_SopCubeNum
(
cSop
)
-
Ivy_SopCubeNum
(
vQuo
)
*
Ivy_SopCubeNum
(
cDiv
)
);
// finally add the remaining cubes to the remainder
// and clean the marked cubes in the cover
Ivy_SopForEachCube
(
cSop
,
uCube
,
i
)
{
if
(
!
Ivy_CubeIsMarked
(
uCube
)
)
continue
;
Ivy_SopSetCube
(
cSop
,
Ivy_CubeUnmark
(
uCube
),
i
);
Ivy_SopAddCube
(
vRem
,
Ivy_CubeUnmark
(
uCube
)
);
}
}
/**Function*************************************************************
Synopsis [Derives the quotient of division by literal.]
Description [Reduces the cover to be the equal to the result of
division of the given cover by the literal.]
SideEffects []
extern
Vec_Int_t
*
Mvc_CoverCommonCubeCover
(
Vec_Int_t
*
vCover
);
SeeAlso []
***********************************************************************/
void
Ivy_SopDivideByLiteralQuo
(
Ivy_Sop_t
*
cSop
,
int
iLit
)
{
unsigned
uCube
;
int
i
,
k
=
0
;
Ivy_SopForEachCube
(
cSop
,
uCube
,
i
)
{
if
(
Ivy_CubeHasLit
(
uCube
,
iLit
)
)
Ivy_SopSetCube
(
cSop
,
Ivy_CubeRemLit
(
uCube
,
iLit
),
k
++
);
}
Ivy_SopShrink
(
cSop
,
k
);
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
Ivy_SopCommonCubeCover
(
Ivy_Sop_t
*
cSop
,
Ivy_Sop_t
*
vCommon
,
Vec_Int_t
*
vStore
)
{
unsigned
uTemp
,
uCube
;
int
i
;
uCube
=
~
(
unsigned
)
0
;
Ivy_SopForEachCube
(
cSop
,
uTemp
,
i
)
uCube
&=
uTemp
;
vCommon
->
nCubes
=
0
;
vCommon
->
uCubes
=
Vec_IntFetch
(
vStore
,
1
);
Ivy_SopPush
(
vCommon
,
uCube
);
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
Ivy_SopCreateInverse
(
Ivy_Sop_t
*
cSop
,
Vec_Int_t
*
vInput
,
int
nVars
,
Vec_Int_t
*
vStore
)
{
unsigned
uCube
,
uMask
;
int
i
;
// start the cover
cSop
->
nCubes
=
0
;
cSop
->
uCubes
=
Vec_IntFetch
(
vStore
,
Vec_IntSize
(
vInput
)
);
// add the cubes
uMask
=
Ivy_CubeMask
(
nVars
);
Vec_IntForEachEntry
(
vInput
,
uCube
,
i
)
Vec_IntPush
(
cSop
,
Ivy_CubeSharp
(
uMask
,
uCube
)
);
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
Ivy_SopDup
(
Ivy_Sop_t
*
cSop
,
Ivy_Sop_t
*
vCopy
,
Vec_Int_t
*
vStore
)
{
unsigned
uCube
;
int
i
;
// start the cover
vCopy
->
nCubes
=
0
;
vCopy
->
uCubes
=
Vec_IntFetch
(
vStore
,
Vec_IntSize
(
cSop
)
);
// add the cubes
Ivy_SopForEachCube
(
cSop
,
uTemp
,
i
)
Ivy_SopPush
(
vCopy
,
uTemp
);
}
/**Function*************************************************************
Synopsis [Find the least often occurring literal.]
Description [Find the least often occurring literal among those
that occur more than once.]
SideEffects []
SeeAlso []
***********************************************************************/
int
Ivy_SopWorstLiteral
(
Ivy_Sop_t
*
cSop
,
int
nLits
)
{
unsigned
uCube
;
int
nWord
,
nBit
;
int
i
,
k
,
iMin
,
nLitsMin
,
nLitsCur
;
int
fUseFirst
=
1
;
// go through each literal
iMin
=
-
1
;
nLitsMin
=
1000000
;
for
(
i
=
0
;
i
<
nLits
;
i
++
)
{
// go through all the cubes
nLitsCur
=
0
;
Ivy_SopForEachCube
(
cSop
,
uCube
,
k
)
if
(
Ivy_CubeHasLit
(
uCube
,
i
)
)
nLitsCur
++
;
// skip the literal that does not occur or occurs once
if
(
nLitsCur
<
2
)
continue
;
// check if this is the best literal
if
(
fUseFirst
)
{
if
(
nLitsMin
>
nLitsCur
)
{
nLitsMin
=
nLitsCur
;
iMin
=
i
;
}
}
else
{
if
(
nLitsMin
>=
nLitsCur
)
{
nLitsMin
=
nLitsCur
;
iMin
=
i
;
}
}
}
if
(
nLitsMin
<
1000000
)
return
iMin
;
return
-
1
;
}
/**Function*************************************************************
Synopsis [Computes a level-zero kernel.]
Description [Modifies the cover to contain one level-zero kernel.]
SideEffects []
SeeAlso []
***********************************************************************/
void
Ivy_SopMakeCubeFree
(
Ivy_Sop_t
*
cSop
)
{
unsigned
uMask
;
int
i
;
assert
(
Ivy_SopCubeNum
(
cSop
)
>
0
);
// find the common cube
uMask
=
~
(
unsigned
)
0
;
Ivy_SopForEachCube
(
cSop
,
uCube
,
i
)
uMask
&=
uCube
;
if
(
uMask
==
0
)
return
;
// remove the common cube
Ivy_SopForEachCube
(
cSop
,
uCube
,
i
)
Ivy_SopSetCube
(
cSop
,
Ivy_CubeSharp
(
uCube
,
uMask
),
i
);
}
/**Function*************************************************************
Synopsis [Computes a level-zero kernel.]
Description [Modifies the cover to contain one level-zero kernel.]
SideEffects []
SeeAlso []
***********************************************************************/
void
Ivy_SopDivisorZeroKernel_rec
(
Ivy_Sop_t
*
cSop
,
int
nLits
)
{
int
iLit
;
// find any literal that occurs at least two times
iLit
=
Ivy_SopWorstLiteral
(
cSop
,
nLits
);
if
(
iLit
==
-
1
)
return
;
// derive the cube-free quotient
Ivy_SopDivideByLiteralQuo
(
cSop
,
iLit
);
// the same cover
Ivy_SopMakeCubeFree
(
cSop
);
// the same cover
// call recursively
Ivy_SopDivisorZeroKernel_rec
(
cSop
);
// the same cover
}
/**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
)
////////////////////////////////////////////////////////////////////////
...
...
@@ -52,29 +434,38 @@ extern Vec_Int_t * Mvc_CoverCommonCubeCover( Vec_Int_t * vCover );
SeeAlso []
***********************************************************************/
Dec_Graph_t
*
Dec_Factor32
(
Vec_Int_t
*
vCover
,
int
nVars
)
Dec_Graph_t
*
Dec_Factor32
(
Vec_Int_t
*
cSop
,
int
nVars
,
Vec_Int_t
*
vStore
)
{
Ivy_Sop_t
cSop
,
cRes
;
Ivy_Sop_t
*
pcSop
=
&
cSop
,
*
pcRes
=
&
cRes
;
Dec_Graph_t
*
pFForm
;
Dec_Edge_t
eRoot
;
assert
(
nVars
<
16
);
// check for trivial functions
if
(
Vec_IntSize
(
vCover
)
==
0
)
if
(
Vec_IntSize
(
cSop
)
==
0
)
return
Dec_GraphCreateConst0
();
if
(
Vec_IntSize
(
vCover
)
==
1
&&
/* tautology */
)
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
Mvc_CoverInverse
(
vCover
);
// CST
Ivy_SopCreateInverse
(
cSop
,
pcSop
,
nVars
,
vStore
);
// CST
// start the factored form
pFForm
=
Dec_GraphCreate
(
Abc_SopGetVarNum
(
pSop
)
);
pFForm
=
Dec_GraphCreate
(
nVars
);
// factor the cover
eRoot
=
Dec_Factor32_rec
(
pFForm
,
vCover
,
nVars
);
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 ) )
// printf( "Verification has failed.\n" );
// Mvc_CoverInverse( vCover ); // undo CST
if
(
!
Dec_Factor32Verify
(
pSop
,
pFForm
,
nVars
)
)
printf
(
"Verification has failed.
\n
"
);
return
pFForm
;
}
...
...
@@ -89,47 +480,47 @@ Dec_Graph_t * Dec_Factor32( Vec_Int_t * vCover, int nVars )
SeeAlso []
***********************************************************************/
Dec_Edge_t
Dec_Factor32_rec
(
Dec_Graph_t
*
pFForm
,
Vec_Int_t
*
vCover
,
int
nVar
s
)
Dec_Edge_t
Dec_Factor32_rec
(
Dec_Graph_t
*
pFForm
,
Vec_Int_t
*
cSop
,
int
nLit
s
)
{
Vec_Int_t
*
v
Div
,
*
vQuo
,
*
vRem
,
*
vCom
;
Vec_Int_t
*
c
Div
,
*
vQuo
,
*
vRem
,
*
vCom
;
Dec_Edge_t
eNodeDiv
,
eNodeQuo
,
eNodeRem
;
Dec_Edge_t
eNodeAnd
,
eNode
;
// make sure the cover contains some cubes
assert
(
Vec_IntSize
(
vCover
)
);
assert
(
Vec_IntSize
(
cSop
)
);
// get the divisor
vDiv
=
Dec_Factor32Divisor
(
vCover
,
nVar
s
);
if
(
v
Div
==
NULL
)
return
Dec_Factor32Trivial
(
pFForm
,
vCover
,
nVar
s
);
cDiv
=
Ivy_SopDivisor
(
cSop
,
nLit
s
);
if
(
c
Div
==
NULL
)
return
Dec_Factor32Trivial
(
pFForm
,
cSop
,
nLit
s
);
// divide the cover by the divisor
Mvc_CoverDivideInternal
(
vCover
,
nVars
,
v
Div
,
&
vQuo
,
&
vRem
);
Ivy_SopDivideInternal
(
cSop
,
nLits
,
c
Div
,
&
vQuo
,
&
vRem
);
assert
(
Vec_IntSize
(
vQuo
)
);
Vec_IntFree
(
v
Div
);
Vec_IntFree
(
c
Div
);
Vec_IntFree
(
vRem
);
// check the trivial case
if
(
Vec_IntSize
(
vQuo
)
==
1
)
{
eNode
=
Dec_Factor32LF_rec
(
pFForm
,
vCover
,
nVar
s
,
vQuo
);
eNode
=
Dec_Factor32LF_rec
(
pFForm
,
cSop
,
nLit
s
,
vQuo
);
Vec_IntFree
(
vQuo
);
return
eNode
;
}
// make the quotient cube free
Mvc_Cover
MakeCubeFree
(
vQuo
);
Ivy_Sop
MakeCubeFree
(
vQuo
);
// divide the cover by the quotient
Mvc_CoverDivideInternal
(
vCover
,
nVars
,
vQuo
,
&
v
Div
,
&
vRem
);
Ivy_SopDivideInternal
(
cSop
,
nLits
,
vQuo
,
&
c
Div
,
&
vRem
);
// check the trivial case
if
(
Mvc_CoverIsCubeFree
(
v
Div
)
)
if
(
Ivy_SopIsCubeFree
(
c
Div
)
)
{
eNodeDiv
=
Dec_Factor32_rec
(
pFForm
,
v
Div
);
eNodeDiv
=
Dec_Factor32_rec
(
pFForm
,
c
Div
);
eNodeQuo
=
Dec_Factor32_rec
(
pFForm
,
vQuo
);
Vec_IntFree
(
v
Div
);
Vec_IntFree
(
c
Div
);
Vec_IntFree
(
vQuo
);
eNodeAnd
=
Dec_GraphAddNodeAnd
(
pFForm
,
eNodeDiv
,
eNodeQuo
);
if
(
Vec_IntSize
(
vRem
)
==
0
)
...
...
@@ -146,13 +537,13 @@ Dec_Edge_t Dec_Factor32_rec( Dec_Graph_t * pFForm, Vec_Int_t * vCover, int nVars
}
// get the common cube
vCom
=
Mvc_CoverCommonCubeCover
(
v
Div
);
Vec_IntFree
(
v
Div
);
vCom
=
Ivy_SopCommonCubeCover
(
c
Div
);
Vec_IntFree
(
c
Div
);
Vec_IntFree
(
vQuo
);
Vec_IntFree
(
vRem
);
// solve the simple problem
eNode
=
Dec_Factor32LF_rec
(
pFForm
,
vCover
,
nVar
s
,
vCom
);
eNode
=
Dec_Factor32LF_rec
(
pFForm
,
cSop
,
nLit
s
,
vCom
);
Vec_IntFree
(
vCom
);
return
eNode
;
}
...
...
@@ -169,21 +560,21 @@ Dec_Edge_t Dec_Factor32_rec( Dec_Graph_t * pFForm, Vec_Int_t * vCover, int nVars
SeeAlso []
***********************************************************************/
Dec_Edge_t
Dec_Factor32LF_rec
(
Dec_Graph_t
*
pFForm
,
Vec_Int_t
*
vCover
,
int
nVar
s
,
Vec_Int_t
*
vSimple
)
Dec_Edge_t
Dec_Factor32LF_rec
(
Dec_Graph_t
*
pFForm
,
Vec_Int_t
*
cSop
,
int
nLit
s
,
Vec_Int_t
*
vSimple
)
{
Dec_Man_t
*
pManDec
=
Abc_FrameReadManDec
();
Vec_Int_t
*
vEdgeLits
=
pManDec
->
vLits
;
Vec_Int_t
*
v
Div
,
*
vQuo
,
*
vRem
;
Vec_Int_t
*
c
Div
,
*
vQuo
,
*
vRem
;
Dec_Edge_t
eNodeDiv
,
eNodeQuo
,
eNodeRem
;
Dec_Edge_t
eNodeAnd
;
// get the most often occurring literal
vDiv
=
Mvc_CoverBestLiteralCover
(
vCover
,
nVar
s
,
vSimple
);
cDiv
=
Ivy_SopBestLiteralCover
(
cSop
,
nLit
s
,
vSimple
);
// divide the cover by the literal
Mvc_CoverDivideByLiteral
(
vCover
,
nVars
,
v
Div
,
&
vQuo
,
&
vRem
);
Ivy_SopDivideByLiteral
(
cSop
,
nLits
,
c
Div
,
&
vQuo
,
&
vRem
);
// get the node pointer for the literal
eNodeDiv
=
Dec_Factor32TrivialCube
(
pFForm
,
vDiv
,
Mvc_CoverReadCubeHead
(
v
Div
),
vEdgeLits
);
Vec_IntFree
(
v
Div
);
eNodeDiv
=
Dec_Factor32TrivialCube
(
pFForm
,
cDiv
,
Ivy_SopReadCubeHead
(
c
Div
),
vEdgeLits
);
Vec_IntFree
(
c
Div
);
// factor the quotient and remainder
eNodeQuo
=
Dec_Factor32_rec
(
pFForm
,
vQuo
);
Vec_IntFree
(
vQuo
);
...
...
@@ -214,20 +605,20 @@ Dec_Edge_t Dec_Factor32LF_rec( Dec_Graph_t * pFForm, Vec_Int_t * vCover, int nVa
SeeAlso []
***********************************************************************/
Dec_Edge_t
Dec_Factor32Trivial
(
Dec_Graph_t
*
pFForm
,
Vec_Int_t
*
vCover
,
int
nVar
s
)
Dec_Edge_t
Dec_Factor32Trivial
(
Dec_Graph_t
*
pFForm
,
Vec_Int_t
*
cSop
,
int
nLit
s
)
{
Dec_Man_t
*
pManDec
=
Abc_FrameReadManDec
();
Vec_Int_t
*
vEdgeCubes
=
pManDec
->
vCubes
;
Vec_Int_t
*
vEdgeLits
=
pManDec
->
vLits
;
Mvc_Manager_t
*
pMem
=
pManDec
->
pMvcMem
;
Dec_Edge_t
eNode
;
Mvc_Cube_t
*
p
Cube
;
unsigned
u
Cube
;
int
i
;
// create the factored form for each cube
Vec_IntClear
(
vEdgeCubes
);
Mvc_CoverForEachCube
(
vCover
,
p
Cube
)
Ivy_SopForEachCube
(
cSop
,
u
Cube
)
{
eNode
=
Dec_Factor32TrivialCube
(
pFForm
,
vCover
,
nVars
,
p
Cube
,
vEdgeLits
);
eNode
=
Dec_Factor32TrivialCube
(
pFForm
,
cSop
,
nLits
,
u
Cube
,
vEdgeLits
);
Vec_IntPush
(
vEdgeCubes
,
Dec_EdgeToInt_
(
eNode
)
);
}
// balance the factored forms
...
...
@@ -245,13 +636,13 @@ Dec_Edge_t Dec_Factor32Trivial( Dec_Graph_t * pFForm, Vec_Int_t * vCover, int nV
SeeAlso []
***********************************************************************/
Dec_Edge_t
Dec_Factor32TrivialCube
(
Dec_Graph_t
*
pFForm
,
Vec_Int_t
*
vCover
,
Mvc_Cube_t
*
pCube
,
int
nVar
s
,
Vec_Int_t
*
vEdgeLits
)
Dec_Edge_t
Dec_Factor32TrivialCube
(
Dec_Graph_t
*
pFForm
,
Vec_Int_t
*
cSop
,
unsigned
uCube
,
int
nLit
s
,
Vec_Int_t
*
vEdgeLits
)
{
Dec_Edge_t
eNode
;
int
iBit
,
Value
;
// create the factored form for each literal
Vec_IntClear
(
vEdgeLits
);
Mvc_CubeForEach
Bit
(
vCover
,
p
Cube
,
iBit
,
Value
)
Mvc_CubeForEach
Lit
(
cSop
,
u
Cube
,
iBit
,
Value
)
if
(
Value
)
{
eNode
=
Dec_EdgeCreate
(
iBit
/
2
,
iBit
%
2
);
// CST
...
...
@@ -296,126 +687,15 @@ Dec_Edge_t Dec_Factor32TrivialTree_rec( Dec_Graph_t * pFForm, Dec_Edge_t * peNod
return
Dec_GraphAddNodeAnd
(
pFForm
,
eNode1
,
eNode2
);
}
/**Function*************************************************************
Synopsis [Returns the quick divisor of the cover.]
Description [Returns NULL, if there is not divisor other than
trivial.]
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Int_t
*
Dec_Factor32Divisor
(
Vec_Int_t
*
vCover
,
int
nVars
)
{
Vec_Int_t
*
pKernel
;
if
(
Vec_IntSize
(
vCover
)
<=
1
)
return
NULL
;
// allocate the literal array and count literals
if
(
Mvc_CoverAnyLiteral
(
vCover
,
NULL
)
==
-
1
)
return
NULL
;
// duplicate the cover
pKernel
=
Mvc_CoverDup
(
vCover
);
// perform the kerneling
Dec_Factor32DivisorZeroKernel
(
pKernel
);
assert
(
Vec_IntSize
(
pKernel
)
);
return
pKernel
;
}
/**Function*************************************************************
Synopsis [Computes a level-zero kernel.]
Description [Modifies the cover to contain one level-zero kernel.]
SideEffects []
SeeAlso []
***********************************************************************/
void
Dec_Factor32DivisorZeroKernel
(
Vec_Int_t
*
vCover
,
int
nVars
)
{
int
iLit
;
// find any literal that occurs at least two times
// iLit = Mvc_CoverAnyLiteral( vCover, NULL );
iLit
=
Dec_Factor32WorstLiteral
(
vCover
,
NULL
);
// iLit = Mvc_CoverBestLiteral( vCover, NULL );
if
(
iLit
==
-
1
)
return
;
// derive the cube-free quotient
Mvc_CoverDivideByLiteralQuo
(
vCover
,
iLit
);
// the same cover
Mvc_CoverMakeCubeFree
(
vCover
);
// the same cover
// call recursively
Dec_Factor32DivisorZeroKernel
(
vCover
);
// the same cover
}
/**Function*************************************************************
Synopsis [Find the most often occurring literal.]
Description [Find the most often occurring literal among those
that occur more than once.]
SideEffects []
SeeAlso []
***********************************************************************/
int
Dec_Factor32WorstLiteral
(
Vec_Int_t
*
vCover
,
int
nVars
)
{
Mvc_Cube_t
*
pCube
;
int
nWord
,
nBit
;
int
i
,
iMin
,
nLitsMin
,
nLitsCur
;
int
fUseFirst
=
1
;
// go through each literal
iMin
=
-
1
;
nLitsMin
=
1000000
;
for
(
i
=
0
;
i
<
vCover
->
nBits
;
i
++
)
{
// get the word and bit of this literal
nWord
=
Mvc_CubeWhichWord
(
i
);
nBit
=
Mvc_CubeWhichBit
(
i
);
// go through all the cubes
nLitsCur
=
0
;
Mvc_CoverForEachCube
(
vCover
,
pCube
)
if
(
pCube
->
pData
[
nWord
]
&
(
1
<<
nBit
)
)
nLitsCur
++
;
// skip the literal that does not occur or occurs once
if
(
nLitsCur
<
2
)
continue
;
// check if this is the best literal
if
(
fUseFirst
)
{
if
(
nLitsMin
>
nLitsCur
)
{
nLitsMin
=
nLitsCur
;
iMin
=
i
;
}
}
else
{
if
(
nLitsMin
>=
nLitsCur
)
{
nLitsMin
=
nLitsCur
;
iMin
=
i
;
}
}
}
if
(
nLitsMin
<
1000000
)
return
iMin
;
return
-
1
;
}
// verification using temporary BDD package
#include "cuddInt.h"
/**Function*************************************************************
Synopsis []
Synopsis [
Verifies that the factoring is correct.
]
Description []
...
...
@@ -424,326 +704,43 @@ int Dec_Factor32WorstLiteral( Vec_Int_t * vCover, int nVars )
SeeAlso []
***********************************************************************/
Vec_Int_t
*
Mvc_CoverCommonCubeCover
(
Vec_Int_t
*
vCover
)
DdNode
*
Ivy_SopCoverToBdd
(
DdManager
*
dd
,
Vec_Int_t
*
cSop
,
int
nVars
)
{
Vec_Int_t
*
vRes
;
unsigned
uTemp
,
uCube
;
int
i
;
uCube
=
~
(
unsigned
)
0
;
Vec_IntForEachEntry
(
vCover
,
uTemp
,
i
)
uCube
&=
uTemp
;
vRes
=
Vec_IntAlloc
(
1
);
Vec_IntPush
(
vRes
,
uCube
);
return
vRes
;
}
/**Function*************************************************************
Synopsis [Returns 1 if the support of cover2 is contained in the support of cover1.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int
Mvc_CoverCheckSuppContainment
(
Vec_Int_t
*
vCover1
,
Vec_Int_t
*
vCover2
)
{
unsigned
uTemp
,
uSupp1
,
uSupp2
;
int
i
;
// set the supports
uSupp1
=
0
;
Vec_IntForEachEntry
(
vCover1
,
uTemp
,
i
)
uSupp1
|=
uTemp
;
uSupp2
=
0
;
Vec_IntForEachEntry
(
vCover2
,
uTemp
,
i
)
uSupp2
|=
uTemp
;
// return containment
return
uSupp1
&
!
uSupp2
;
// Mvc_CubeBitNotImpl( Result, vCover2->pMask, vCover1->pMask );
// return !Result;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
Mvc_CoverDivide
(
Vec_Int_t
*
vCover
,
Vec_Int_t
*
vDiv
,
Vec_Int_t
**
pvQuo
,
Vec_Int_t
**
pvRem
)
{
// check the number of cubes
if
(
Vec_IntSize
(
vCover
)
<
Vec_IntSize
(
vDiv
)
)
{
*
pvQuo
=
NULL
;
*
pvRem
=
NULL
;
return
;
}
// make sure that support of vCover contains that of vDiv
if
(
!
Mvc_CoverCheckSuppContainment
(
vCover
,
vDiv
)
)
DdNode
*
bSum
,
*
bCube
,
*
bTemp
,
*
bVar
;
unsigned
uCube
;
int
Value
,
v
;
assert
(
nVars
<
16
);
// start the cover
bSum
=
Cudd_ReadLogicZero
(
dd
);
Cudd_Ref
(
bSum
);
// check the logic function of the node
Vec_IntForEachEntry
(
cSop
,
uCube
,
i
)
{
*
pvQuo
=
NULL
;
*
pvRem
=
NULL
;
return
;
}
// perform the general division
Mvc_CoverDivideInternal
(
vCover
,
vDiv
,
pvQuo
,
pvRem
);
}
/**Function*************************************************************
Synopsis [Merge the cubes inside the groups.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
Mvc_CoverDivideInternal
(
Vec_Int_t
*
vCover
,
Vec_Int_t
*
vDiv
,
Vec_Int_t
**
pvQuo
,
Vec_Int_t
**
pvRem
)
{
Vec_Int_t
*
vQuo
,
*
vRem
;
Mvc_Cube_t
*
pCubeC
,
*
pCubeD
,
*
pCubeCopy
;
Mvc_Cube_t
*
pCube1
,
*
pCube2
;
int
*
pGroups
,
nGroups
;
// the cube groups
int
nCubesC
,
nCubesD
,
nMerges
,
iCubeC
,
iCubeD
,
iMerge
;
int
fSkipG
,
GroupSize
,
g
,
c
,
RetValue
;
int
nCubes
;
// get cover sizes
nCubesD
=
Vec_IntSize
(
vDiv
);
nCubesC
=
Vec_IntSize
(
vCover
);
// check trivial cases
if
(
nCubesD
==
1
)
{
if
(
Mvc_CoverIsOneLiteral
(
vDiv
)
)
Mvc_CoverDivideByLiteral
(
vCover
,
vDiv
,
pvQuo
,
pvRem
);
else
Mvc_CoverDivideByCube
(
vCover
,
vDiv
,
pvQuo
,
pvRem
);
return
;
}
// create the divisor and the remainder
vQuo
=
Mvc_CoverAlloc
(
vCover
->
pMem
,
vCover
->
nBits
);
vRem
=
Mvc_CoverAlloc
(
vCover
->
pMem
,
vCover
->
nBits
);
// 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
// whether it can produce a quotient cube
nCubes
=
0
;
for
(
g
=
0
;
g
<
nGroups
;
g
++
)
{
// 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
]
);
Mvc_CoverAddCubeTail
(
vRem
,
pCubeCopy
);
nCubes
++
;
}
continue
;
}
// mark the cubes as those that should be added to the remainder
for
(
c
=
pGroups
[
g
];
c
<
pGroups
[
g
+
1
];
c
++
)
Mvc_CubeSetSize
(
vCover
->
pCubes
[
c
],
1
);
// go through the cubes in the group and at the same time
// go through the cubes in the divisor
iCubeD
=
0
;
iCubeC
=
0
;
pCubeD
=
vDiv
->
pCubes
[
iCubeD
++
];
pCubeC
=
vCover
->
pCubes
[
pGroups
[
g
]
+
iCubeC
++
];
fSkipG
=
0
;
nMerges
=
0
;
while
(
1
)
bCube
=
Cudd_ReadOne
(
dd
);
Cudd_Ref
(
bCube
);
for
(
v
=
0
;
v
<
nVars
;
v
++
)
{
// compare the topmost cubes in F and in D
RetValue
=
Mvc_CubeCompareIntUnderMask
(
pCubeC
,
pCubeD
,
vDiv
->
pMask
);
// cube are ordered in increasing order of their int value
if
(
RetValue
==
-
1
)
// pCubeC is above pCubeD
{
// cube in C should be added to the remainder
// check that there is enough cubes in the group
if
(
GroupSize
-
iCubeC
<
nCubesD
-
nMerges
)
{
fSkipG
=
1
;
break
;
}
// get the next cube in the cover
pCubeC
=
vCover
->
pCubes
[
pGroups
[
g
]
+
iCubeC
++
];
Value
=
((
uCube
>>
2
*
v
)
&
3
);
if
(
Value
==
1
)
bVar
=
Cudd_Not
(
Cudd_bddIthVar
(
dd
,
v
)
);
else
if
(
Value
==
2
)
bVar
=
Cudd_bddIthVar
(
dd
,
v
);
else
continue
;
}
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
assert
(
iCubeD
<
nCubesD
);
pCubeD
=
vDiv
->
pCubes
[
iCubeD
++
];
// advance the cube of the group
assert
(
pGroups
[
g
]
+
iCubeC
<
nCubesC
);
pCubeC
=
vCover
->
pCubes
[
pGroups
[
g
]
+
iCubeC
++
];
}
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
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
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
MEM_FREE
(
vCover
->
pMem
,
int
,
nCubesC
+
1
,
pGroups
);
// return the results
*
pvRem
=
vRem
;
*
pvQuo
=
vQuo
;
// Mvc_CoverVerifyDivision( vCover, vDiv, vQuo, vRem );
}
/**Function*************************************************************
Synopsis [Divides the cover by a cube.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
Mvc_CoverDivideByCube
(
Vec_Int_t
*
vCover
,
Vec_Int_t
*
vDiv
,
Vec_Int_t
**
pvQuo
,
Vec_Int_t
**
pvRem
)
{
Vec_Int_t
*
vQuo
,
*
vRem
;
Mvc_Cube_t
*
pCubeC
,
*
pCubeD
,
*
pCubeCopy
;
int
ComvResult
;
// get the only cube of D
assert
(
Vec_IntSize
(
vDiv
)
==
1
);
// start the quotient and the remainder
vQuo
=
Mvc_CoverAlloc
(
vCover
->
pMem
,
vCover
->
nBits
);
vRem
=
Mvc_CoverAlloc
(
vCover
->
pMem
,
vCover
->
nBits
);
// get the first and only cube of the divisor
pCubeD
=
Mvc_CoverReadCubeHead
(
vDiv
);
// iterate through the cubes in the cover
Mvc_CoverForEachCube
(
vCover
,
pCubeC
)
{
// check the containment of literals from pCubeD in pCube
Mvc_Cube2BitNotImpl
(
ComvResult
,
pCubeD
,
pCubeC
);
if
(
!
ComvResult
)
{
// this cube belongs to the quotient
// alloc the cube
pCubeCopy
=
Mvc_CubeAlloc
(
vQuo
);
// clean the support of D
Mvc_CubeBitSharp
(
pCubeCopy
,
pCubeC
,
pCubeD
);
// add the cube to the quotient
Mvc_CoverAddCubeTail
(
vQuo
,
pCubeCopy
);
}
else
{
// copy the cube
pCubeCopy
=
Mvc_CubeDup
(
vRem
,
pCubeC
);
// add the cube to the remainder
Mvc_CoverAddCubeTail
(
vRem
,
pCubeCopy
);
bCube
=
Cudd_bddAnd
(
dd
,
bTemp
=
bCube
,
bVar
);
Cudd_Ref
(
bCube
);
Cudd_RecursiveDeref
(
dd
,
bTemp
);
}
bSum
=
Cudd_bddOr
(
dd
,
bTemp
=
bSum
,
bCube
);
Cudd_Ref
(
bSum
);
Cudd_RecursiveDeref
(
dd
,
bTemp
);
Cudd_RecursiveDeref
(
dd
,
bCube
);
}
//
return the results
*
pvRem
=
vRem
;
*
pvQuo
=
vQuo
;
//
complement the result if necessary
Cudd_Deref
(
bSum
)
;
return
bSum
;
}
/**Function*************************************************************
Synopsis [
Divides the cover by a literal
.]
Synopsis [
Verifies that the factoring is correct
.]
Description []
...
...
@@ -752,80 +749,33 @@ void Mvc_CoverDivideByCube( Vec_Int_t * vCover, Vec_Int_t * vDiv, Vec_Int_t ** p
SeeAlso []
***********************************************************************/
void
Mvc_CoverDivideByLiteral
(
Vec_Int_t
*
vCover
,
Vec_Int_t
*
vDiv
,
Vec_Int_t
**
pvQuo
,
Vec_Int_t
**
pvRem
)
int
Dec_Factor32Verify
(
Vec_Int_t
*
cSop
,
Dec_Graph_t
*
pFForm
,
int
nVars
)
{
Vec_Int_t
*
vQuo
,
*
vRem
;
Mvc_Cube_t
*
pCubeC
,
*
pCubeCopy
;
int
iLit
;
// get the only cube of D
assert
(
Vec_IntSize
(
vDiv
)
==
1
);
// start the quotient and the remainder
vQuo
=
Mvc_CoverAlloc
(
vCover
->
pMem
,
vCover
->
nBits
);
vRem
=
Mvc_CoverAlloc
(
vCover
->
pMem
,
vCover
->
nBits
);
// get the first and only literal in the divisor cube
iLit
=
Mvc_CoverFirstCubeFirstLit
(
vDiv
);
// iterate through the cubes in the cover
Mvc_CoverForEachCube
(
vCover
,
pCubeC
)
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
)
{
// 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
{
// add the cube ot the remainder
Mvc_CoverAddCubeTail
(
vRem
,
pCubeCopy
);
}
int
s
;
Extra_bddPrint
(
dd
,
bFunc1
);
printf
(
"
\n
"
);
Extra_bddPrint
(
dd
,
bFunc2
);
printf
(
"
\n
"
);
s
=
0
;
}
// return the results
*
pvRem
=
vRem
;
*
pvQuo
=
vQuo
;
Cudd_RecursiveDeref
(
dd
,
bFunc1
);
Cudd_RecursiveDeref
(
dd
,
bFunc2
)
;
return
RetValue
;
}
/**Function*************************************************************
Synopsis [Derives the quotient of division by literal.]
Description [Reduces the cover to be the equal to the result of
division of the given cover by the literal.]
SideEffects []
SeeAlso []
***********************************************************************/
void
Mvc_CoverDivideByLiteralQuo
(
Vec_Int_t
*
vCover
,
int
iLit
)
{
Mvc_Cube_t
*
pCube
,
*
pCube2
,
*
pPrev
;
// delete those cubes that do not have this literal
// remove this literal from other cubes
pPrev
=
NULL
;
Mvc_CoverForEachCubeSafe
(
vCover
,
pCube
,
pCube2
)
{
if
(
Mvc_CubeBitValue
(
pCube
,
iLit
)
==
0
)
{
// delete the cube from the cover
Mvc_CoverDeleteCube
(
vCover
,
pPrev
,
pCube
);
Mvc_CubeFree
(
vCover
,
pCube
);
// don't update the previous cube
}
else
{
// delete this literal from the cube
Mvc_CubeBitRemove
(
pCube
,
iLit
);
// update the previous cube
pPrev
=
pCube
;
}
}
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
...
...
src/aig/ivy/ivyIsop.c
View file @
38254947
...
...
@@ -19,7 +19,6 @@
***********************************************************************/
#include "ivy.h"
#include "mem.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
...
...
src/base/abc/abc.h
View file @
38254947
...
...
@@ -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
int
Abc_NodeDeref_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 ==========================================================*/
extern
int
Abc_NtkRefactor
(
Abc_Ntk_t
*
pNtk
,
int
nNodeSizeMax
,
int
nConeSizeMax
,
bool
fUpdateLevel
,
bool
fUseZeros
,
bool
fUseDcs
,
bool
fVerbose
);
/*=== 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
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_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_CommandCleanup
(
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 )
Cmd_CommandAdd
(
pAbc
,
"Synthesis"
,
"collapse"
,
Abc_CommandCollapse
,
1
);
Cmd_CommandAdd
(
pAbc
,
"Synthesis"
,
"strash"
,
Abc_CommandStrash
,
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"
,
"cleanup"
,
Abc_CommandCleanup
,
1
);
Cmd_CommandAdd
(
pAbc
,
"Synthesis"
,
"sweep"
,
Abc_CommandSweep
,
1
);
...
...
@@ -1911,7 +1913,7 @@ usage:
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
;
Abc_Ntk_t
*
pNtk
,
*
pNtkRes
;
...
...
@@ -1920,6 +1922,7 @@ int Abc_CommandRenode( Abc_Frame_t * pAbc, int argc, char ** argv )
int
fMulti
;
int
fSimple
;
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
);
pOut
=
Abc_FrameReadOut
(
pAbc
);
...
...
@@ -1990,7 +1993,7 @@ int Abc_CommandRenode( Abc_Frame_t * pAbc, int argc, char ** argv )
}
// 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
)
{
fprintf
(
pErr
,
"Renoding has failed.
\n
"
);
...
...
@@ -2001,7 +2004,7 @@ int Abc_CommandRenode( Abc_Frame_t * pAbc, int argc, char ** argv )
return
0
;
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
-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
);
...
...
@@ -2027,6 +2030,95 @@ usage:
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
)
{
FILE
*
pOut
,
*
pErr
;
...
...
@@ -7391,19 +7483,26 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv )
// set defaults
memset
(
pPars
,
0
,
sizeof
(
If_Par_t
)
);
// user-controlable paramters
pPars
->
Mode
=
0
;
pPars
->
nLutSize
=
4
;
// pPars->pLutLib = Abc_FrameReadLibLut();
pPars
->
nCutsMax
=
20
;
pPars
->
DelayTarget
=
-
1
;
pPars
->
fPreprocess
=
1
;
pPars
->
fArea
=
0
;
pPars
->
fFancy
=
0
;
pPars
->
fLatchPaths
=
0
;
pPars
->
fExpRed
=
1
;
pPars
->
fLatchPaths
=
0
;
pPars
->
fSeq
=
0
;
pPars
->
nLatches
=
0
;
pPars
->
DelayTarget
=
-
1
;
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
();
while
(
(
c
=
Extra_UtilGetopt
(
argc
,
argv
,
"MKCDpaflrsvh"
)
)
!=
EOF
)
{
...
...
src/base/abci/abcIf.c
View file @
38254947
...
...
@@ -28,8 +28,7 @@
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_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_NodeIfToHop2
(
Hop_Man_t
*
pHopMan
,
If_Man_t
*
pIfMan
,
If_Obj_t
*
pIfObj
);
static
Hop_Obj_t
*
Abc_NodeIfToHop
(
Hop_Man_t
*
pHopMan
,
If_Man_t
*
pIfMan
,
If_Obj_t
*
pIfObj
);
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
...
...
@@ -75,7 +74,7 @@ Abc_Ntk_t * Abc_NtkIf( Abc_Ntk_t * pNtk, If_Par_t * pPars )
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
);
if
(
pNtkNew
==
NULL
)
return
NULL
;
...
...
@@ -163,7 +162,10 @@ Abc_Ntk_t * Abc_NtkFromIf( If_Man_t * pIfMan, Abc_Ntk_t * pNtk )
Abc_Obj_t
*
pNode
,
*
pNodeNew
;
int
i
,
nDupGates
;
// create the new network
pNtkNew
=
Abc_NtkStartFrom
(
pNtk
,
ABC_NTK_LOGIC
,
ABC_FUNC_AIG
);
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
);
// prepare the mapping manager
If_ManCleanNodeCopy
(
pIfMan
);
If_ManCleanCutData
(
pIfMan
);
...
...
@@ -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
)
Abc_ObjAddFanin
(
pNodeNew
,
Abc_NodeFromIf_rec
(
pNtkNew
,
pIfMan
,
pIfLeaf
)
);
// 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 []
SideEffects []
SeeAlso []
if
(
pIfMan
->
pPars
->
fTruth
)
{
if
(
pIfMan
->
pPars
->
fUseBdds
)
{
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
***********************************************************************/
Hop_Obj_t
*
Abc_NodeIfToHop
(
Hop_Man_t
*
pHopMan
,
If_Man_t
*
pIfMan
,
If_Cut_t
*
pCut
)
{
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
;
pNodeNew
->
pData
=
Abc_NodeIfToHop
(
pNtkNew
->
pManFunc
,
pIfMan
,
pIfObj
);
If_ObjSetCopy
(
pIfObj
,
pNodeNew
);
return
pNodeNew
;
}
/**Function*************************************************************
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 *
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
;
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
if
(
If_CutData
(
pCut
)
)
return
If_CutData
(
pCut
);
// compute the functions of the children
gFunc0
=
Abc_NodeIfToHop
2
_rec
(
pHopMan
,
pIfMan
,
pIfObj
->
pFanin0
,
vVisited
);
gFunc1
=
Abc_NodeIfToHop
2
_rec
(
pHopMan
,
pIfMan
,
pIfObj
->
pFanin1
,
vVisited
);
gFunc0
=
Abc_NodeIfToHop_rec
(
pHopMan
,
pIfMan
,
pIfObj
->
pFanin0
,
vVisited
);
gFunc1
=
Abc_NodeIfToHop_rec
(
pHopMan
,
pIfMan
,
pIfObj
->
pFanin1
,
vVisited
);
// get the function of the cut
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
);
If_CutSetData
(
pCut
,
gFunc
);
// 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
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
;
Hop_Obj_t
*
gFunc
;
...
...
@@ -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
)
);
// recursively compute the function while collecting visited cuts
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) );
// clean the cuts
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 )
***********************************************************************/
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
;
Abc_Ntk_t
*
pNtkNew
,
*
pNtkNew2
;
Abc_Obj_t
*
pNode
;
...
...
@@ -484,7 +485,7 @@ Abc_Ntk_t * Abc_NtkFromMapSuperChoice( Map_Man_t * pMan, Abc_Ntk_t * pNtk )
// duplicate the network
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
)
)
{
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 )
#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*************************************************************
...
...
src/base/abci/abcRenode.c
View file @
38254947
...
...
@@ -6,7 +6,7 @@
PackageName [Network and node package.]
Synopsis [
Procedures which transform an AIG into the network of SOP logic nodes.
]
Synopsis []
Author [Alan Mishchenko]
...
...
@@ -19,22 +19,22 @@
***********************************************************************/
#include "abc.h"
#include "reo.h"
#include "if.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static
void
Abc_NtkRenodeInt
(
Abc_Ntk_t
*
pNtk
,
Abc_Ntk_t
*
pNtkNew
);
static
Abc_Obj_t
*
Abc_NtkRenode_rec
(
Abc_Ntk_t
*
pNtkNew
,
Abc_Obj_t
*
pNodeOld
);
static
int
Abc_NtkRenodeEvalBdd
(
unsigned
*
pTruth
,
int
nVars
);
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
);
static
void
Abc_NtkRenodeSetBoundsCnf
(
Abc_Ntk_t
*
pNtk
);
static
void
Abc_NtkRenodeSetBoundsMulti
(
Abc_Ntk_t
*
pNtk
,
int
nThresh
);
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
);
typedef
int
Kit_Graph_t
;
extern
DdNode
*
Kit_TruthToBdd
(
DdManager
*
dd
,
unsigned
*
pTruth
,
int
nVars
);
extern
Kit_Graph_t
*
Kit_TruthToGraph
(
unsigned
*
pTruth
,
int
nVars
);
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
...
...
@@ -42,165 +42,70 @@ static void Abc_NtkRenodeCone( Abc_Obj_t * pNode, Vec_Ptr_t * vCone );
/**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 []
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
;
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_NtkRenodeSetBoundsCnf
(
pNtk
);
else
if
(
fMulti
)
Abc_NtkRenodeSetBoundsMulti
(
pNtk
,
nThresh
);
else
if
(
fSimple
)
Abc_NtkRenodeSetBoundsSimple
(
pNtk
);
else
if
(
fFactor
)
Abc_NtkRenodeSetBoundsFactor
(
pNtk
);
else
Abc_NtkRenodeSetBounds
(
pNtk
,
nThresh
,
nFaninMax
);
// perform renoding for this boundary
pNtkNew
=
Abc_NtkStartFrom
(
pNtk
,
ABC_NTK_LOGIC
,
ABC_FUNC_BDD
);
Abc_NtkRenodeInt
(
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_NtkRenode: The network check has failed.
\n
"
);
Abc_NtkDelete
(
pNtkNew
);
return
NULL
;
// set defaults
memset
(
pPars
,
0
,
sizeof
(
If_Par_t
)
);
// user-controlable paramters
pPars
->
Mode
=
0
;
pPars
->
nLutSize
=
nFaninMax
;
pPars
->
nCutsMax
=
10
;
pPars
->
DelayTarget
=
-
1
;
pPars
->
fPreprocess
=
1
;
pPars
->
fArea
=
0
;
pPars
->
fFancy
=
0
;
pPars
->
fExpRed
=
0
;
//
pPars
->
fLatchPaths
=
0
;
pPars
->
fSeq
=
0
;
pPars
->
fVerbose
=
0
;
// internal parameters
pPars
->
fTruth
=
1
;
pPars
->
nLatches
=
0
;
pPars
->
pLutLib
=
NULL
;
// Abc_FrameReadLibLut();
pPars
->
pTimesArr
=
NULL
;
pPars
->
pTimesArr
=
NULL
;
pPars
->
pFuncCost
=
fUseBdds
?
Abc_NtkRenodeEvalBdd
:
Abc_NtkRenodeEvalSop
;
// start the manager
if
(
fUseBdds
)
{
assert
(
s_pReo
==
NULL
);
s_pDd
=
Cudd_Init
(
nFaninMax
,
0
,
CUDD_UNIQUE_SLOTS
,
CUDD_CACHE_SLOTS
,
0
);
s_pReo
=
Extra_ReorderInit
(
nFaninMax
,
100
);
pPars
->
fUseBdds
=
1
;
pPars
->
pReoMan
=
s_pReo
;
}
// perform mapping/renoding
pNtkNew
=
Abc_NtkIf
(
pNtk
,
pPars
);
// start the manager
if
(
fUseBdds
)
{
Extra_StopManager
(
s_pDd
);
Extra_ReorderQuit
(
s_pReo
);
s_pReo
=
NULL
;
s_pDd
=
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_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.]
Synopsis [Derives the BDD after reordering.]
Description []
...
...
@@ -209,415 +114,22 @@ Abc_Obj_t * Abc_NtkRenode_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNodeOld )
SeeAlso []
***********************************************************************/
DdNode
*
Abc_NtkRenodeDeriveBdd
(
DdManager
*
dd
,
Abc_Obj_t
*
pNodeOld
,
Vec_Ptr_t
*
vFaninsOld
)
int
Abc_NtkRenodeEvalBdd
(
unsigned
*
pTruth
,
int
nVars
)
{
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 []
SideEffects []
SeeAlso []
***********************************************************************/
DdNode
*
Abc_NtkRenodeDeriveBdd_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_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
;
return
Abc_NtkRenodeLimit_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_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
);
DdNode
*
bFunc
,
*
bFuncNew
;
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
);
nSupport
=
Cudd_SupportSize
(
s_pDd
,
bFuncNew
);
nNodes
=
Cudd_DagSize
(
bFuncNew
);
Cudd_RecursiveDeref
(
s_pDd
,
bFuncNew
);
Cudd_RecursiveDeref
(
s_pDd
,
bFunc
);
return
(
nSupport
<<
16
)
|
nNodes
;
}
/**Function*************************************************************
Synopsis [
Collects the fanins of a large node
.]
Synopsis [
Derives the BDD after reordering
.]
Description []
...
...
@@ -626,13 +138,15 @@ void Abc_NtkRenodeCone_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vCone )
SeeAlso []
***********************************************************************/
void
Abc_NtkRenodeCone
(
Abc_Obj_t
*
pNode
,
Vec_Ptr_t
*
vCone
)
int
Abc_NtkRenodeEvalSop
(
unsigned
*
pTruth
,
int
nVars
)
{
assert
(
!
Abc_ObjIsComplement
(
pNode
)
);
assert
(
Abc_ObjIsNode
(
pNode
)
);
vCone
->
nSize
=
0
;
Abc_NtkRenodeCone_rec
(
Abc_ObjFanin
(
pNode
,
0
),
vCone
);
Abc_NtkRenodeCone_rec
(
Abc_ObjFanin
(
pNode
,
1
),
vCone
);
Kit_Graph_t
*
pGraph
;
int
nNodes
,
nDepth
;
pGraph
=
Kit_TruthToGraph
(
pTruth
,
nVars
);
nNodes
=
Kit_GraphNodeNum
(
pGraph
);
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,
***********************************************************************/
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
*
pCnf
;
int
RetValue
;
...
...
@@ -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
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
);
if
(
pCnf
==
NULL
)
{
...
...
@@ -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
)
{
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
*
pFrames
;
Abc_Ntk_t
*
pCnf
;
...
...
@@ -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
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
);
if
(
pCnf
==
NULL
)
{
...
...
src/base/abci/module.make
View file @
38254947
...
...
@@ -21,6 +21,7 @@ SRC += src/base/abci/abc.c \
src/base/abci/abcMap.c
\
src/base/abci/abcMini.c
\
src/base/abci/abcMiter.c
\
src/base/abci/abcMulti.c
\
src/base/abci/abcNtbdd.c
\
src/base/abci/abcOrder.c
\
src/base/abci/abcPrint.c
\
...
...
@@ -28,6 +29,7 @@ SRC += src/base/abci/abc.c \
src/base/abci/abcReconv.c
\
src/base/abci/abcRefactor.c
\
src/base/abci/abcRenode.c
\
src/base/abci/abcReorder.c
\
src/base/abci/abcRestruct.c
\
src/base/abci/abcResub.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;
// parameters
struct
If_Par_t_
{
// user-controlable paramters
int
Mode
;
// the mapping mode
int
nLutSize
;
// the LUT size
If_Lib_t
*
pLutLib
;
// the LUT library
int
nCutsMax
;
// the max number of cuts
int
fVerbose
;
// the verbosity flag
float
DelayTarget
;
// delay target
int
fPreprocess
;
// preprossing
int
fArea
;
// area-oriented mapping
int
fFancy
;
// a fancy feature
int
fExpRed
;
// expand/reduce of the best cuts
int
fLatchPaths
;
// reset timing on latch paths
int
fSeq
;
// sequential mapping
int
nLatches
;
// the number of latches
float
DelayTarget
;
// delay target
int
fVerbose
;
// the verbosity flag
// 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
*
pTimesReq
;
// required times
int
(
*
pFuncCost
)(
unsigned
*
,
int
);
// procedure the user's cost of a cut
void
*
pReoMan
;
// reordering manager
};
// the LUT library
...
...
@@ -118,10 +124,13 @@ struct If_Man_t_
int
nCutsMerged
;
// the total number of cuts merged
int
nCutsMax
;
// the maximum number of cuts at a node
float
Fi
;
// the current value of the clock period (for seq mapping)
unsigned
*
puTemp
[
4
];
// used for the truth table computation
// memory management
Mem_Fixed_t
*
pMem
;
// memory manager
int
nEntrySize
;
// the size of the entry
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
int
nCuts
;
// the number of cuts used
If_Cut_t
**
ppCuts
;
// the storage space for cuts
...
...
@@ -132,14 +141,14 @@ struct If_Cut_t_
{
float
Delay
;
// delay 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
char
fCompl0
;
// complemented attribute
char
fCompl1
;
// complemented attribute
char
Phase
;
// complemented attribute
char
nLeaves
;
// number of leaves
unsigned
Cost
:
10
;
// the user's cost of the cut
unsigned
Depth
:
9
;
// the user's depth of the cut
unsigned
fCompl
:
1
;
// the complemented attribute
unsigned
nLimit
:
6
;
// the maximum number of leaves
unsigned
nLeaves
:
6
;
// the number of leaves
int
*
pLeaves
;
// array of fanins
unsigned
*
pTruth
;
// the truth table
};
// node extension
...
...
@@ -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_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
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
int
If_CutTruthWords
(
int
nVarsMax
)
{
return
nVarsMax
<=
5
?
1
:
(
1
<<
(
nVarsMax
-
5
));
}
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 ///
...
...
@@ -244,14 +256,7 @@ static inline float If_CutLutArea( If_Man_t * p, If_Cut_t * pCut ) { r
/*=== ifCore.c ==========================================================*/
extern
int
If_ManPerformMapping
(
If_Man_t
*
p
);
extern
int
If_ManPerformMappingRound
(
If_Man_t
*
p
,
int
nCutsUsed
,
int
Mode
,
int
fRequired
);
/*=== 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
);
/*=== ifCut.c ==========================================================*/
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_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 );
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_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_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 ==========================================================*/
extern
void
If_ManImproveMapping
(
If_Man_t
*
p
);
/*=== ifSelect.c ==========================================================*/
extern
void
If_ManPerformMappingPreprocess
(
If_Man_t
*
p
);
/*=== ifSeq.c ==========================================================*/
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 ==========================================================*/
extern
float
If_ManDelayMax
(
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 )
else
If_ManPerformMappingRound
(
p
,
p
->
pPars
->
nCutsMax
,
0
,
1
);
// try to improve area by expanding and reducing the cuts
if
(
p
->
pPars
->
fExpRed
)
if
(
p
->
pPars
->
fExpRed
&&
!
p
->
pPars
->
fTruth
)
If_ManImproveMapping
(
p
);
// area flow oriented mapping
for
(
i
=
0
;
i
<
nItersFlow
;
i
++
)
{
If_ManPerformMappingRound
(
p
,
p
->
pPars
->
nCutsMax
,
1
,
1
);
if
(
p
->
pPars
->
fExpRed
)
if
(
p
->
pPars
->
fExpRed
&&
!
p
->
pPars
->
fTruth
)
If_ManImproveMapping
(
p
);
}
// area oriented mapping
for
(
i
=
0
;
i
<
nItersArea
;
i
++
)
{
If_ManPerformMappingRound
(
p
,
p
->
pPars
->
nCutsMax
,
2
,
1
);
if
(
p
->
pPars
->
fExpRed
)
if
(
p
->
pPars
->
fExpRed
&&
!
p
->
pPars
->
fTruth
)
If_ManImproveMapping
(
p
);
}
if
(
p
->
pPars
->
fVerbose
)
...
...
src/map/if/ifCut.c
View file @
38254947
...
...
@@ -28,9 +28,405 @@
/// 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*************************************************************
Synopsis []
Synopsis [
Computes area flow.
]
Description []
...
...
@@ -39,6 +435,166 @@
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 ///
...
...
src/map/if/ifMan.c
View file @
38254947
...
...
@@ -57,9 +57,20 @@ If_Man_t * If_ManStart( If_Par_t * pPars )
p
->
vMapped
=
Vec_PtrAlloc
(
100
);
p
->
vTemp
=
Vec_PtrAlloc
(
100
);
// prepare the memory manager
p
->
nEntrySize
=
sizeof
(
If_Obj_t
)
+
p
->
pPars
->
nCutsMax
*
(
sizeof
(
If_Cut_t
)
+
sizeof
(
int
)
*
p
->
pPars
->
nLutSize
);
p
->
nEntryBase
=
sizeof
(
If_Obj_t
)
+
p
->
pPars
->
nCutsMax
*
(
sizeof
(
If_Cut_t
));
p
->
nTruthSize
=
p
->
pPars
->
fTruth
?
If_CutTruthWords
(
p
->
pPars
->
nLutSize
)
:
0
;
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
);
// 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
p
->
pConst1
=
If_ManSetupObj
(
p
);
p
->
pConst1
->
Type
=
IF_CONST1
;
...
...
@@ -100,6 +111,7 @@ void If_ManStop( If_Man_t * p )
for
(
i
=
1
;
i
<
1
+
p
->
pPars
->
nCutsMax
*
p
->
pPars
->
nCutsMax
;
i
++
)
if
(
pTemp
>
p
->
ppCuts
[
i
]
)
pTemp
=
p
->
ppCuts
[
i
];
FREE
(
p
->
puTemp
[
0
]
);
free
(
pTemp
);
free
(
p
->
ppCuts
);
free
(
p
);
...
...
@@ -200,7 +212,12 @@ If_Obj_t * If_ManSetupObj( If_Man_t * p )
// organize memory
pArrays
=
(
int
*
)((
char
*
)
pObj
+
p
->
nEntryBase
);
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
pObj
->
Id
=
Vec_PtrSize
(
p
->
vObjs
);
Vec_PtrPush
(
p
->
vObjs
,
pObj
);
...
...
@@ -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
**
pCutStore
;
int
*
pArrays
,
nCut
Size
,
nCut
sTotal
,
i
;
int
*
pArrays
,
nCutsTotal
,
i
;
// decide how many cuts to alloc
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
pCutStore
=
(
If_Cut_t
**
)
ALLOC
(
If_Cut_t
*
,
(
nCutsTotal
+
1
)
);
memset
(
pCutStore
,
0
,
sizeof
(
If_Cut_t
*
)
*
(
nCutsTotal
+
1
)
);
pCutStore
[
0
]
=
(
If_Cut_t
*
)
ALLOC
(
char
,
nCutSize
*
nCutsTotal
);
memset
(
pCutStore
[
0
],
0
,
nCutSize
*
nCutsTotal
);
for
(
i
=
1
;
i
<
nCutsTotal
;
i
++
)
pCutStore
[
i
]
=
(
If_Cut_t
*
)((
char
*
)
pCutStore
[
0
]
+
sizeof
(
If_Cut_t
)
*
i
);
// assign room for cut leaves
pCutStore
[
0
]
=
(
If_Cut_t
*
)
ALLOC
(
char
,
p
->
nCutSize
*
nCutsTotal
);
memset
(
pCutStore
[
0
],
0
,
p
->
nCutSize
*
nCutsTotal
);
// assign cut paramters and space for the cut leaves
assert
(
sizeof
(
int
)
==
sizeof
(
unsigned
)
);
pArrays
=
(
int
*
)((
char
*
)
pCutStore
[
0
]
+
sizeof
(
If_Cut_t
)
*
nCutsTotal
);
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
]
->
pTruth
=
pArrays
+
nCutsTotal
*
p
->
pPars
->
nLutSize
+
i
*
p
->
nTruthSize
;
}
return
pCutStore
;
}
...
...
src/map/if/ifMap.c
View file @
38254947
...
...
@@ -59,567 +59,6 @@ static inline int If_WordCountOnes( unsigned uWord )
/**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.]
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 )
void
If_ObjPerformMapping
(
If_Man_t
*
p
,
If_Obj_t
*
pObj
,
int
Mode
)
{
If_Cut_t
*
pCut0
,
*
pCut1
,
*
pCut
;
int
i
,
k
,
iCut
;
int
i
,
k
,
iCut
,
Temp
;
// prepare
if
(
Mode
==
0
)
...
...
@@ -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
)
)
continue
;
// merge the nodes
if
(
!
If_CutMerge
(
pCut0
,
pCut1
,
pCut
,
p
->
pPars
->
nLutSize
)
)
if
(
!
If_CutMerge
(
pCut0
,
pCut1
,
pCut
)
)
continue
;
// check if this cut is contained in any of the available cuts
pCut
->
uSign
=
pCut0
->
uSign
|
pCut1
->
uSign
;
if
(
If_CutFilter
(
p
,
pCut
,
Mode
)
)
if
(
If_CutFilter
(
p
,
pCut
)
)
continue
;
// check if the cut satisfies the required times
pCut
->
Delay
=
If_CutDelay
(
p
,
pCut
);
if
(
Mode
&&
pCut
->
Delay
>
pObj
->
Required
+
p
->
fEpsilon
)
continue
;
// the cuts have been successfully merged
pCut
->
pOne
=
pCut0
;
pCut
->
fCompl0
=
pObj
->
fCompl0
;
pCut
->
pTwo
=
pCut1
;
pCut
->
fCompl1
=
pObj
->
fCompl1
;
// pCut->Phase = ...
// pCut->Phase = (char)(int)If_CutAreaDerefed( p, pCut, 1 );
pCut
->
Area
=
(
Mode
==
2
)
?
If_CutAreaDerefed
(
p
,
pCut
,
100
)
:
If_CutFlow
(
p
,
pCut
);
p
->
nCutsMerged
++
;
// compute the truth table
if
(
p
->
pPars
->
fTruth
)
If_CutComputeTruth
(
p
,
pCut
,
pCut0
,
pCut1
,
pObj
->
fCompl0
,
pObj
->
fCompl1
);
// 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
);
// make sure the cut is the last one (after filtering it may not be so)
assert
(
pCut
==
p
->
ppCuts
[
iCut
]
);
p
->
ppCuts
[
iCut
]
=
p
->
ppCuts
[
p
->
nCuts
];
p
->
ppCuts
[
p
->
nCuts
]
=
pCut
;
// count the cut
p
->
nCuts
++
;
p
->
nCutsMerged
++
;
// prepare room for the next cut
iCut
=
++
p
->
nCuts
;
iCut
=
p
->
nCuts
;
pCut
=
p
->
ppCuts
[
iCut
];
}
//printf( "%d ", p->nCuts );
...
...
src/map/if/if
Select
.c
→
src/map/if/if
Prepro
.c
View file @
38254947
/**CFile****************************************************************
FileName [if
Select
.c]
FileName [if
Prepro
.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [FPGA mapping based on priority cuts.]
Synopsis [Selects
what mapping to use
.]
Synopsis [Selects
the starting mapping
.]
Author [Alan Mishchenko]
...
...
@@ -14,7 +14,7 @@
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 )
// merge the cuts
pCutR
=
p
->
ppCuts
[
0
];
RetValue
=
If_CutMerge
(
pCut0
,
pCut1
,
pCutR
,
nLimit
);
RetValue
=
If_CutMerge
(
pCut0
,
pCut1
,
pCutR
);
// try very simple cut
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
);
}
if
(
RetValue
)
...
...
src/map/if/ifSeq.c
View file @
38254947
...
...
@@ -95,7 +95,7 @@ int If_ManPerformMappingSeq( If_Man_t * p )
***********************************************************************/
void
If_CutLift
(
If_Cut_t
*
pCut
)
{
int
i
;
unsigned
i
;
for
(
i
=
0
;
i
<
pCut
->
nLeaves
;
i
++
)
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 \
src/map/if/ifCut.c
\
src/map/if/ifMan.c
\
src/map/if/ifMap.c
\
src/map/if/ifPrepro.c
\
src/map/if/ifReduce.c
\
src/map/if/ifSelect.c
\
src/map/if/ifSeq.c
\
src/map/if/ifTruth.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