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
770bc99e
Commit
770bc99e
authored
Mar 15, 2009
by
Alan Mishchenko
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Version abc90315
parent
81b51657
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
1344 additions
and
91 deletions
+1344
-91
abclib.dsp
+8
-0
src/aig/cec/cecCore.c
+3
-0
src/aig/gia/gia.h
+4
-3
src/aig/gia/giaCSat0.c
+4
-2
src/aig/gia/giaCSat2.c
+745
-0
src/base/abci/abc.c
+6
-6
src/base/abci/abcLut.c
+1
-1
src/base/abci/abcLutmin.c
+566
-78
src/misc/extra/extra.h
+1
-1
src/misc/extra/extraBddMisc.c
+1
-0
src/opt/mfs/mfsSat.c
+5
-0
No files found.
abclib.dsp
View file @
770bc99e
...
...
@@ -3651,6 +3651,14 @@ SOURCE=.\src\aig\gia\giaCof.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\gia\giaCSat0.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\gia\giaCSat2.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\gia\giaDfs.c
# End Source File
# Begin Source File
...
...
src/aig/cec/cecCore.c
View file @
770bc99e
...
...
@@ -282,6 +282,9 @@ p->timeSim += clock() - clk;
// Gia_ManEquivTransform( p->pAig, 1 );
}
pSrm
=
Cec_ManFraSpecReduction
(
p
);
// Gia_WriteAiger( pSrm, "gia_srm.aig", 0, 0 );
if
(
pPars
->
fVeryVerbose
)
Gia_ManPrintStats
(
pSrm
);
if
(
Gia_ManCoNum
(
pSrm
)
==
0
)
...
...
src/aig/gia/gia.h
View file @
770bc99e
...
...
@@ -435,14 +435,15 @@ static inline int * Gia_ObjGateFanins( Gia_Man_t * p, int Id ) { re
/// FUNCTION DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
/*=== giaAig.c ============================================================*/
/*=== giaAig.c ============================================================
=
*/
extern
Gia_Man_t
*
Gia_ManFromAig
(
Aig_Man_t
*
p
);
extern
Gia_Man_t
*
Gia_ManFromAigSwitch
(
Aig_Man_t
*
p
);
extern
Aig_Man_t
*
Gia_ManToAig
(
Gia_Man_t
*
p
);
/*=== giaAiger.c ==========================================================*/
/*=== giaAiger.c ==========================================================
=
*/
extern
Gia_Man_t
*
Gia_ReadAiger
(
char
*
pFileName
,
int
fCheck
);
extern
void
Gia_WriteAiger
(
Gia_Man_t
*
p
,
char
*
pFileName
,
int
fWriteSymbols
,
int
fCompact
);
/*=== giaCof.c ============================================================*/
/*=== giaCsat.c ============================================================*/
/*=== giaCof.c =============================================================*/
extern
void
Gia_ManPrintFanio
(
Gia_Man_t
*
pGia
,
int
nNodes
);
extern
Gia_Man_t
*
Gia_ManDupCof
(
Gia_Man_t
*
p
,
int
iVar
);
extern
Gia_Man_t
*
Gia_ManDupCofAllInt
(
Gia_Man_t
*
p
,
Vec_Int_t
*
vSigs
,
int
fVerbose
);
...
...
src/aig/gia/giaCSat0.c
View file @
770bc99e
...
...
@@ -122,8 +122,10 @@ void Gia_SatVerifyPattern( Gia_Man_t * p, Gia_Obj_t * pRoot, Vec_Int_t * vCex, V
}
Value
=
Gia_XsimNotCond
(
Value
,
Gia_ObjFaninC0
(
pRoot
)
);
if
(
Value
!=
GIA_ONE
)
printf
(
"Gia_SatVerifyPattern(): Verification failed.
\n
"
);
assert
(
Value
==
GIA_ONE
);
printf
(
"Gia_SatVerifyPattern(): Verification FAILED.
\n
"
);
// else
// printf( "Gia_SatVerifyPattern(): Verification succeeded.\n" );
// assert( Value == GIA_ONE );
// clean the nodes
Gia_ManForEachObjVec
(
vVisit
,
p
,
pObj
,
i
)
Sat_ObjSetXValue
(
pObj
,
0
);
...
...
src/aig/gia/giaCSat2.c
0 → 100644
View file @
770bc99e
/**CFile****************************************************************
FileName [giaCSat2.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Scalable AIG package.]
Synopsis [A simple circuit-based solver.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: giaCSat2.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "gia.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
typedef
struct
Cbs_Par_t_
Cbs_Par_t
;
struct
Cbs_Par_t_
{
// conflict limits
int
nBTLimit
;
// limit on the number of conflicts
int
nJustLimit
;
// limit on the size of justification queue
// current parameters
int
nBTThis
;
// number of conflicts
int
nJustThis
;
// max size of the frontier
int
nBTTotal
;
// total number of conflicts
int
nJustTotal
;
// total size of the frontier
// decision heuristics
int
fUseHighest
;
// use node with the highest ID
int
fUseLowest
;
// use node with the highest ID
int
fUseMaxFF
;
// use node with the largest fanin fanout
// other
int
fVerbose
;
};
typedef
struct
Cbs_Que_t_
Cbs_Que_t
;
struct
Cbs_Que_t_
{
int
iHead
;
// beginning of the queue
int
iTail
;
// end of the queue
int
nSize
;
// allocated size
Gia_Obj_t
**
pData
;
// nodes stored in the queue
};
typedef
struct
Cbs_Man_t_
Cbs_Man_t
;
struct
Cbs_Man_t_
{
Cbs_Par_t
Pars
;
// parameters
Gia_Man_t
*
pAig
;
// AIG manager
Cbs_Que_t
pProp
;
// propagation queue
Cbs_Que_t
pJust
;
// justification queue
Vec_Int_t
*
vModel
;
// satisfying assignment
};
static
inline
int
Cbs_VarIsAssigned
(
Gia_Obj_t
*
pVar
)
{
return
pVar
->
fMark0
;
}
static
inline
void
Cbs_VarAssign
(
Gia_Obj_t
*
pVar
)
{
assert
(
!
pVar
->
fMark0
);
pVar
->
fMark0
=
1
;
}
static
inline
void
Cbs_VarUnassign
(
Gia_Obj_t
*
pVar
)
{
assert
(
pVar
->
fMark0
);
pVar
->
fMark0
=
0
;
pVar
->
fMark1
=
0
;
}
static
inline
int
Cbs_VarValue
(
Gia_Obj_t
*
pVar
)
{
assert
(
pVar
->
fMark0
);
return
pVar
->
fMark1
;
}
static
inline
void
Cbs_VarSetValue
(
Gia_Obj_t
*
pVar
,
int
v
)
{
assert
(
pVar
->
fMark0
);
pVar
->
fMark1
=
v
;
}
static
inline
int
Cbs_VarIsJust
(
Gia_Obj_t
*
pVar
)
{
return
Gia_ObjIsAnd
(
pVar
)
&&
!
Cbs_VarIsAssigned
(
Gia_ObjFanin0
(
pVar
))
&&
!
Cbs_VarIsAssigned
(
Gia_ObjFanin1
(
pVar
));
}
static
inline
int
Cbs_VarFanin0Value
(
Gia_Obj_t
*
pVar
)
{
return
!
Cbs_VarIsAssigned
(
Gia_ObjFanin0
(
pVar
))
?
2
:
(
Cbs_VarValue
(
Gia_ObjFanin0
(
pVar
))
^
Gia_ObjFaninC0
(
pVar
));
}
static
inline
int
Cbs_VarFanin1Value
(
Gia_Obj_t
*
pVar
)
{
return
!
Cbs_VarIsAssigned
(
Gia_ObjFanin1
(
pVar
))
?
2
:
(
Cbs_VarValue
(
Gia_ObjFanin1
(
pVar
))
^
Gia_ObjFaninC1
(
pVar
));
}
#define Cbs_QueForEachEntry( Que, pObj, i ) \
for ( i = (Que).iHead; (i < (Que).iTail) && ((pObj) = (Que).pData[i]); i++ )
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Sets default values of the parameters.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
Cbs_SetDefaultParams
(
Cbs_Par_t
*
pPars
)
{
memset
(
pPars
,
0
,
sizeof
(
Cbs_Par_t
)
);
pPars
->
nBTLimit
=
1000
;
// limit on the number of conflicts
pPars
->
nJustLimit
=
100
;
// limit on the size of justification queue
pPars
->
fUseHighest
=
1
;
// use node with the highest ID
pPars
->
fUseLowest
=
0
;
// use node with the highest ID
pPars
->
fUseMaxFF
=
0
;
// use node with the largest fanin fanout
pPars
->
fVerbose
=
1
;
// print detailed statistics
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Cbs_Man_t
*
Cbs_ManAlloc
()
{
Cbs_Man_t
*
p
;
p
=
ABC_CALLOC
(
Cbs_Man_t
,
1
);
p
->
pProp
.
nSize
=
p
->
pJust
.
nSize
=
10000
;
p
->
pProp
.
pData
=
ABC_ALLOC
(
Gia_Obj_t
*
,
p
->
pProp
.
nSize
);
p
->
pJust
.
pData
=
ABC_ALLOC
(
Gia_Obj_t
*
,
p
->
pJust
.
nSize
);
p
->
vModel
=
Vec_IntAlloc
(
1000
);
Cbs_SetDefaultParams
(
&
p
->
Pars
);
return
p
;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
Cbs_ManStop
(
Cbs_Man_t
*
p
)
{
Vec_IntFree
(
p
->
vModel
);
ABC_FREE
(
p
->
pProp
.
pData
);
ABC_FREE
(
p
->
pJust
.
pData
);
ABC_FREE
(
p
);
}
/**Function*************************************************************
Synopsis [Returns satisfying assignment.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Int_t
*
Cbs_ReadModel
(
Cbs_Man_t
*
p
)
{
return
p
->
vModel
;
}
/**Function*************************************************************
Synopsis [Returns 1 if the solver is out of limits.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static
inline
int
Cbs_ManCheckLimits
(
Cbs_Man_t
*
p
)
{
return
p
->
Pars
.
nJustThis
>
p
->
Pars
.
nJustLimit
||
p
->
Pars
.
nBTThis
>
p
->
Pars
.
nBTLimit
;
}
/**Function*************************************************************
Synopsis [Saves the satisfying assignment as an array of literals.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static
inline
void
Cbs_ManSaveModel
(
Cbs_Man_t
*
p
,
Vec_Int_t
*
vCex
)
{
Gia_Obj_t
*
pVar
;
int
i
;
Vec_IntClear
(
vCex
);
p
->
pProp
.
iHead
=
0
;
Cbs_QueForEachEntry
(
p
->
pProp
,
pVar
,
i
)
if
(
Gia_ObjIsCi
(
pVar
)
)
Vec_IntPush
(
vCex
,
Gia_Var2Lit
(
Gia_ObjId
(
p
->
pAig
,
pVar
),
!
Cbs_VarValue
(
pVar
))
);
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static
inline
int
Cbs_QueIsEmpty
(
Cbs_Que_t
*
p
)
{
return
p
->
iHead
==
p
->
iTail
;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static
inline
void
Cbs_QuePush
(
Cbs_Que_t
*
p
,
Gia_Obj_t
*
pObj
)
{
if
(
p
->
iTail
==
p
->
nSize
)
{
p
->
nSize
*=
2
;
p
->
pData
=
ABC_REALLOC
(
Gia_Obj_t
*
,
p
->
pData
,
p
->
nSize
);
}
p
->
pData
[
p
->
iTail
++
]
=
pObj
;
}
/**Function*************************************************************
Synopsis [Returns 1 if the object in the queue.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static
inline
int
Cbs_QueHasNode
(
Cbs_Que_t
*
p
,
Gia_Obj_t
*
pObj
)
{
Gia_Obj_t
*
pTemp
;
int
i
;
Cbs_QueForEachEntry
(
*
p
,
pTemp
,
i
)
if
(
pTemp
==
pObj
)
return
1
;
return
0
;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static
inline
void
Cbs_QueStore
(
Cbs_Que_t
*
p
,
int
*
piHeadOld
,
int
*
piTailOld
)
{
int
i
;
*
piHeadOld
=
p
->
iHead
;
*
piTailOld
=
p
->
iTail
;
for
(
i
=
*
piHeadOld
;
i
<
*
piTailOld
;
i
++
)
Cbs_QuePush
(
p
,
p
->
pData
[
i
]
);
p
->
iHead
=
*
piTailOld
;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static
inline
void
Cbs_QueRestore
(
Cbs_Que_t
*
p
,
int
iHeadOld
,
int
iTailOld
)
{
p
->
iHead
=
iHeadOld
;
p
->
iTail
=
iTailOld
;
}
/**Function*************************************************************
Synopsis [Max number of fanins fanouts.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static
inline
int
Cbs_VarFaninFanoutMax
(
Cbs_Man_t
*
p
,
Gia_Obj_t
*
pObj
)
{
int
Count0
,
Count1
;
assert
(
!
Gia_IsComplement
(
pObj
)
);
assert
(
Gia_ObjIsAnd
(
pObj
)
);
Count0
=
Gia_ObjRefs
(
p
->
pAig
,
Gia_ObjFanin0
(
pObj
)
);
Count1
=
Gia_ObjRefs
(
p
->
pAig
,
Gia_ObjFanin1
(
pObj
)
);
return
ABC_MAX
(
Count0
,
Count1
);
}
/**Function*************************************************************
Synopsis [Find variable with the highest ID.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static
inline
Gia_Obj_t
*
Cbs_ManDecideHighest
(
Cbs_Man_t
*
p
)
{
Gia_Obj_t
*
pObj
,
*
pObjMax
=
NULL
;
int
i
;
Cbs_QueForEachEntry
(
p
->
pJust
,
pObj
,
i
)
if
(
pObjMax
==
NULL
||
pObjMax
<
pObj
)
pObjMax
=
pObj
;
return
pObjMax
;
}
/**Function*************************************************************
Synopsis [Find variable with the lowest ID.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static
inline
Gia_Obj_t
*
Cbs_ManDecideLowest
(
Cbs_Man_t
*
p
)
{
Gia_Obj_t
*
pObj
,
*
pObjMin
=
NULL
;
int
i
;
Cbs_QueForEachEntry
(
p
->
pJust
,
pObj
,
i
)
if
(
pObjMin
==
NULL
||
pObjMin
>
pObj
)
pObjMin
=
pObj
;
return
pObjMin
;
}
/**Function*************************************************************
Synopsis [Find variable with the maximum number of fanin fanouts.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static
inline
Gia_Obj_t
*
Cbs_ManDecideMaxFF
(
Cbs_Man_t
*
p
)
{
Gia_Obj_t
*
pObj
,
*
pObjMax
=
NULL
;
int
i
,
iMaxFF
=
0
,
iCurFF
;
assert
(
p
->
pAig
->
pRefs
!=
NULL
);
Cbs_QueForEachEntry
(
p
->
pJust
,
pObj
,
i
)
{
iCurFF
=
Cbs_VarFaninFanoutMax
(
p
,
pObj
);
assert
(
iCurFF
>
0
);
if
(
iMaxFF
<
iCurFF
)
{
iMaxFF
=
iCurFF
;
pObjMax
=
pObj
;
}
}
return
pObjMax
;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static
inline
void
Cbs_ManCancelUntil
(
Cbs_Man_t
*
p
,
int
iBound
)
{
Gia_Obj_t
*
pVar
;
int
i
;
assert
(
iBound
<=
p
->
pProp
.
iTail
);
p
->
pProp
.
iHead
=
iBound
;
Cbs_QueForEachEntry
(
p
->
pProp
,
pVar
,
i
)
Cbs_VarUnassign
(
pVar
);
p
->
pProp
.
iTail
=
iBound
;
}
/**Function*************************************************************
Synopsis [Assigns the variables a value.]
Description [Returns 1 if conflict; 0 if no conflict.]
SideEffects []
SeeAlso []
***********************************************************************/
static
inline
void
Cbs_ManAssign
(
Cbs_Man_t
*
p
,
Gia_Obj_t
*
pObj
)
{
Gia_Obj_t
*
pObjR
=
Gia_Regular
(
pObj
);
assert
(
Gia_ObjIsCand
(
pObjR
)
);
assert
(
!
Cbs_VarIsAssigned
(
pObjR
)
);
Cbs_VarAssign
(
pObjR
);
Cbs_VarSetValue
(
pObjR
,
!
Gia_IsComplement
(
pObj
)
);
Cbs_QuePush
(
&
p
->
pProp
,
pObjR
);
}
/**Function*************************************************************
Synopsis [Propagates a variable.]
Description [Returns 1 if conflict; 0 if no conflict.]
SideEffects []
SeeAlso []
***********************************************************************/
static
inline
int
Cbs_ManPropagateOne
(
Cbs_Man_t
*
p
,
Gia_Obj_t
*
pVar
)
{
int
Value0
,
Value1
;
assert
(
!
Gia_IsComplement
(
pVar
)
);
assert
(
Cbs_VarIsAssigned
(
pVar
)
);
if
(
Gia_ObjIsCi
(
pVar
)
)
return
0
;
assert
(
Gia_ObjIsAnd
(
pVar
)
);
Value0
=
Cbs_VarFanin0Value
(
pVar
);
Value1
=
Cbs_VarFanin1Value
(
pVar
);
if
(
Cbs_VarValue
(
pVar
)
)
{
// value is 1
if
(
Value0
==
0
||
Value1
==
0
)
// one is 0
return
1
;
if
(
Value0
==
2
)
// first is unassigned
Cbs_ManAssign
(
p
,
Gia_ObjChild0
(
pVar
)
);
if
(
Value1
==
2
)
// first is unassigned
Cbs_ManAssign
(
p
,
Gia_ObjChild1
(
pVar
)
);
return
0
;
}
// value is 0
if
(
Value0
==
0
||
Value1
==
0
)
// one is 0
return
0
;
if
(
Value0
==
1
&&
Value1
==
1
)
// both are 1
return
1
;
if
(
Value0
==
1
||
Value1
==
1
)
// one is 1
{
if
(
Value0
==
2
)
// first is unassigned
Cbs_ManAssign
(
p
,
Gia_Not
(
Gia_ObjChild0
(
pVar
))
);
if
(
Value1
==
2
)
// first is unassigned
Cbs_ManAssign
(
p
,
Gia_Not
(
Gia_ObjChild1
(
pVar
))
);
return
0
;
}
assert
(
Cbs_VarIsJust
(
pVar
)
);
assert
(
!
Cbs_QueHasNode
(
&
p
->
pJust
,
pVar
)
);
Cbs_QuePush
(
&
p
->
pJust
,
pVar
);
return
0
;
}
/**Function*************************************************************
Synopsis [Propagates a variable.]
Description [Returns 1 if conflict; 0 if no conflict.]
SideEffects []
SeeAlso []
***********************************************************************/
static
inline
int
Cbs_ManPropagateTwo
(
Cbs_Man_t
*
p
,
Gia_Obj_t
*
pVar
)
{
int
Value0
,
Value1
;
assert
(
!
Gia_IsComplement
(
pVar
)
);
assert
(
Gia_ObjIsAnd
(
pVar
)
);
assert
(
Cbs_VarIsAssigned
(
pVar
)
);
assert
(
!
Cbs_VarValue
(
pVar
)
);
Value0
=
Cbs_VarFanin0Value
(
pVar
);
Value1
=
Cbs_VarFanin1Value
(
pVar
);
// value is 0
if
(
Value0
==
0
||
Value1
==
0
)
// one is 0
return
0
;
if
(
Value0
==
1
&&
Value1
==
1
)
// both are 1
return
1
;
assert
(
Value0
==
1
||
Value1
==
1
);
if
(
Value0
==
2
)
// first is unassigned
Cbs_ManAssign
(
p
,
Gia_Not
(
Gia_ObjChild0
(
pVar
))
);
if
(
Value1
==
2
)
// first is unassigned
Cbs_ManAssign
(
p
,
Gia_Not
(
Gia_ObjChild1
(
pVar
))
);
return
0
;
}
/**Function*************************************************************
Synopsis [Propagates all variables.]
Description [Returns 1 if conflict; 0 if no conflict.]
SideEffects []
SeeAlso []
***********************************************************************/
int
Cbs_ManPropagate
(
Cbs_Man_t
*
p
)
{
Gia_Obj_t
*
pVar
;
int
i
,
k
;
while
(
1
)
{
Cbs_QueForEachEntry
(
p
->
pProp
,
pVar
,
i
)
{
if
(
Cbs_ManPropagateOne
(
p
,
pVar
)
)
return
1
;
}
p
->
pProp
.
iHead
=
p
->
pProp
.
iTail
;
k
=
p
->
pJust
.
iHead
;
Cbs_QueForEachEntry
(
p
->
pJust
,
pVar
,
i
)
{
if
(
Cbs_VarIsJust
(
pVar
)
)
p
->
pJust
.
pData
[
k
++
]
=
pVar
;
else
if
(
Cbs_ManPropagateTwo
(
p
,
pVar
)
)
return
1
;
}
if
(
k
==
p
->
pJust
.
iTail
)
break
;
p
->
pJust
.
iTail
=
k
;
}
return
0
;
}
/**Function*************************************************************
Synopsis [Solve the problem recursively.]
Description [Returns 1 if unsat or undecided; 0 if satisfiable.]
SideEffects []
SeeAlso []
***********************************************************************/
int
Cbs_ManSolve_rec
(
Cbs_Man_t
*
p
)
{
Gia_Obj_t
*
pVar
;
int
iPropHead
,
iJustHead
,
iJustTail
;
// propagate assignments
assert
(
!
Cbs_QueIsEmpty
(
&
p
->
pProp
)
);
if
(
Cbs_ManPropagate
(
p
)
)
return
1
;
// check for satisfying assignment
assert
(
Cbs_QueIsEmpty
(
&
p
->
pProp
)
);
if
(
Cbs_QueIsEmpty
(
&
p
->
pJust
)
)
return
0
;
// quit using resource limits
p
->
Pars
.
nBTThis
++
;
p
->
Pars
.
nJustThis
=
ABC_MAX
(
p
->
Pars
.
nJustThis
,
p
->
pJust
.
iTail
-
p
->
pJust
.
iHead
);
if
(
Cbs_ManCheckLimits
(
p
)
)
return
1
;
// remember the state before branching
iPropHead
=
p
->
pProp
.
iHead
;
Cbs_QueStore
(
&
p
->
pJust
,
&
iJustHead
,
&
iJustTail
);
// find the decision variable
if
(
p
->
Pars
.
fUseHighest
)
pVar
=
Cbs_ManDecideHighest
(
p
);
else
if
(
p
->
Pars
.
fUseLowest
)
pVar
=
Cbs_ManDecideLowest
(
p
);
else
if
(
p
->
Pars
.
fUseMaxFF
)
pVar
=
Cbs_ManDecideMaxFF
(
p
);
else
assert
(
0
);
assert
(
Cbs_VarIsJust
(
pVar
)
);
// decide using fanout count!
if
(
Gia_ObjRefs
(
p
->
pAig
,
Gia_ObjFanin0
(
pVar
))
<
Gia_ObjRefs
(
p
->
pAig
,
Gia_ObjFanin1
(
pVar
))
)
{
// decide on first fanin
Cbs_ManAssign
(
p
,
Gia_Not
(
Gia_ObjChild0
(
pVar
))
);
if
(
!
Cbs_ManSolve_rec
(
p
)
)
return
0
;
if
(
Cbs_ManCheckLimits
(
p
)
)
return
1
;
Cbs_ManCancelUntil
(
p
,
iPropHead
);
Cbs_QueRestore
(
&
p
->
pJust
,
iJustHead
,
iJustTail
);
// decide on second fanin
Cbs_ManAssign
(
p
,
Gia_Not
(
Gia_ObjChild1
(
pVar
))
);
}
else
{
// decide on first fanin
Cbs_ManAssign
(
p
,
Gia_Not
(
Gia_ObjChild1
(
pVar
))
);
if
(
!
Cbs_ManSolve_rec
(
p
)
)
return
0
;
if
(
Cbs_ManCheckLimits
(
p
)
)
return
1
;
Cbs_ManCancelUntil
(
p
,
iPropHead
);
Cbs_QueRestore
(
&
p
->
pJust
,
iJustHead
,
iJustTail
);
// decide on second fanin
Cbs_ManAssign
(
p
,
Gia_Not
(
Gia_ObjChild0
(
pVar
))
);
}
if
(
!
Cbs_ManSolve_rec
(
p
)
)
return
0
;
if
(
Cbs_ManCheckLimits
(
p
)
)
return
1
;
return
1
;
}
/**Function*************************************************************
Synopsis [Looking for a satisfying assignment of the node.]
Description [Assumes that each node has flag pObj->fMark0 set to 0.
Returns 1 if unsatisfiable, 0 if satisfiable, and -1 if undecided.
The node may be complemented. ]
SideEffects []
SeeAlso []
***********************************************************************/
int
Cbs_ManSolve
(
Cbs_Man_t
*
p
,
Gia_Obj_t
*
pObj
)
{
// Gia_Obj_t * pTemp;
// int i;
int
RetValue
;
// Gia_ManForEachObj( p->pAig, pTemp, i )
// assert( pTemp->fMark0 == 0 );
assert
(
!
p
->
pProp
.
iHead
&&
!
p
->
pProp
.
iTail
);
assert
(
!
p
->
pJust
.
iHead
&&
!
p
->
pJust
.
iTail
);
p
->
Pars
.
nBTThis
=
p
->
Pars
.
nJustThis
=
0
;
Cbs_ManAssign
(
p
,
pObj
);
RetValue
=
Cbs_ManSolve_rec
(
p
);
if
(
RetValue
==
0
)
Cbs_ManSaveModel
(
p
,
p
->
vModel
);
Cbs_ManCancelUntil
(
p
,
0
);
p
->
pJust
.
iHead
=
p
->
pJust
.
iTail
=
0
;
p
->
Pars
.
nBTTotal
+=
p
->
Pars
.
nBTThis
;
p
->
Pars
.
nJustTotal
=
ABC_MAX
(
p
->
Pars
.
nJustTotal
,
p
->
Pars
.
nJustThis
);
if
(
Cbs_ManCheckLimits
(
p
)
)
return
-
1
;
return
RetValue
;
}
/**Function*************************************************************
Synopsis [Procedure to test the new SAT solver.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
Cbs_ManSolveTest
(
Gia_Man_t
*
pGia
)
{
extern
void
Gia_SatVerifyPattern
(
Gia_Man_t
*
p
,
Gia_Obj_t
*
pRoot
,
Vec_Int_t
*
vCex
,
Vec_Int_t
*
vVisit
);
int
nConfsMax
=
1000
;
int
CountUnsat
,
CountSat
,
CountUndec
;
Cbs_Man_t
*
p
;
Vec_Int_t
*
vCex
;
Vec_Int_t
*
vVisit
;
Gia_Obj_t
*
pRoot
;
int
i
,
RetValue
,
clk
=
clock
();
Gia_ManCreateRefs
(
pGia
);
// create logic network
p
=
Cbs_ManAlloc
();
p
->
pAig
=
pGia
;
// prepare AIG
Gia_ManCleanValue
(
pGia
);
Gia_ManCleanMark0
(
pGia
);
Gia_ManCleanMark1
(
pGia
);
// vCex = Vec_IntAlloc( 100 );
vVisit
=
Vec_IntAlloc
(
100
);
// solve for each output
CountUnsat
=
CountSat
=
CountUndec
=
0
;
Gia_ManForEachCo
(
pGia
,
pRoot
,
i
)
{
if
(
Gia_ObjIsConst0
(
Gia_ObjFanin0
(
pRoot
))
)
continue
;
// Gia_ManIncrementTravId( pGia );
//printf( "Output %6d : ", i );
// iLit = Gia_Var2Lit( Gia_ObjHandle(Gia_ObjFanin0(pRoot)), Gia_ObjFaninC0(pRoot) );
// RetValue = Cbs_ManSolve( p, &iLit, 1, nConfsMax, vCex );
RetValue
=
Cbs_ManSolve
(
p
,
Gia_ObjChild0
(
pRoot
)
);
if
(
RetValue
==
1
)
CountUnsat
++
;
else
if
(
RetValue
==
-
1
)
CountUndec
++
;
else
{
int
iLit
,
k
;
vCex
=
Cbs_ReadModel
(
p
);
// printf( "complemented = %d. ", Gia_ObjFaninC0(pRoot) );
//printf( "conflicts = %6d max-frontier = %6d \n", p->Pars.nBTThis, p->Pars.nJustThis );
// Vec_IntForEachEntry( vCex, iLit, k )
// printf( "%s%d ", Gia_LitIsCompl(iLit)? "!": "", Gia_ObjCioId(Gia_ManObj(pGia,Gia_Lit2Var(iLit))) );
// printf( "\n" );
Gia_SatVerifyPattern
(
pGia
,
pRoot
,
vCex
,
vVisit
);
assert
(
RetValue
==
0
);
CountSat
++
;
}
// Gia_ManCheckMark0( p );
// Gia_ManCheckMark1( p );
}
Cbs_ManStop
(
p
);
// Vec_IntFree( vCex );
Vec_IntFree
(
vVisit
);
printf
(
"Unsat = %d. Sat = %d. Undec = %d. "
,
CountUnsat
,
CountSat
,
CountUndec
);
ABC_PRT
(
"Time"
,
clock
()
-
clk
);
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
src/base/abci/abc.c
View file @
770bc99e
...
...
@@ -3729,8 +3729,8 @@ int Abc_CommandLutmin( Abc_Frame_t * pAbc, int argc, char ** argv )
pErr
=
Abc_FrameReadErr
(
pAbc
);
// set defaults
nLutSize
=
6
;
fVerbose
=
1
;
nLutSize
=
4
;
fVerbose
=
0
;
Extra_UtilGetoptReset
();
while
(
(
c
=
Extra_UtilGetopt
(
argc
,
argv
,
"Kvh"
)
)
!=
EOF
)
{
...
...
@@ -3744,8 +3744,6 @@ int Abc_CommandLutmin( Abc_Frame_t * pAbc, int argc, char ** argv )
}
nLutSize
=
atoi
(
argv
[
globalUtilOptind
]);
globalUtilOptind
++
;
if
(
nLutSize
>
1
)
goto
usage
;
break
;
case
'v'
:
fVerbose
^=
1
;
...
...
@@ -23956,6 +23954,7 @@ int Abc_CommandAbc9Test( Abc_Frame_t * pAbc, int argc, char ** argv )
Gia_Man_t
*
pTemp
=
NULL
;
int
c
,
fVerbose
=
0
;
extern
void
Gia_SatSolveTest
(
Gia_Man_t
*
p
);
extern
void
Cbs_ManSolveTest
(
Gia_Man_t
*
pGia
);
Extra_UtilGetoptReset
();
while
(
(
c
=
Extra_UtilGetopt
(
argc
,
argv
,
"vh"
)
)
!=
EOF
)
...
...
@@ -23983,8 +23982,9 @@ int Abc_CommandAbc9Test( Abc_Frame_t * pAbc, int argc, char ** argv )
// Gia_SatSolveTest( pAbc->pAig );
// For_ManExperiment( pAbc->pAig, 20, 1, 1 );
// Gia_ManUnrollSpecial( pAbc->pAig, 5, 100, 1 );
pAbc
->
pAig
=
Gia_ManDupSelf
(
pTemp
=
pAbc
->
pAig
);
Gia_ManStop
(
pTemp
);
// pAbc->pAig = Gia_ManDupSelf( pTemp = pAbc->pAig );
// Gia_ManStop( pTemp );
// Cbs_ManSolveTest( pAbc->pAig );
return
0
;
usage:
...
...
src/base/abci/abcLut.c
View file @
770bc99e
...
...
@@ -19,7 +19,7 @@
***********************************************************************/
#include "abc.h"
#include "cut.h"
#include "cut.h"
#define LARGE_LEVEL 1000000
...
...
src/base/abci/abcLutmin.c
View file @
770bc99e
...
...
@@ -20,6 +20,12 @@
#include "abc.h"
/*
Implememented here is the algorithm for minimal-LUT decomposition
described in the paper: T. Sasao et al. "On the number of LUTs
to implement logic functions", To appear in Proc. IWLS'09.
*/
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
...
...
@@ -30,6 +36,254 @@
/**Function*************************************************************
Synopsis [Implements 2:1 MUX using one 3-LUT.]
Description [The fanins are (c, d0, d1).]
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Obj_t
*
Abc_NtkBddMux21
(
Abc_Ntk_t
*
pNtkNew
,
Abc_Obj_t
*
pFanins
[]
)
{
DdManager
*
dd
=
pNtkNew
->
pManFunc
;
Abc_Obj_t
*
pNode
;
DdNode
*
bSpin
,
*
bCof0
,
*
bCof1
;
pNode
=
Abc_NtkCreateNode
(
pNtkNew
);
Abc_ObjAddFanin
(
pNode
,
pFanins
[
0
]
);
Abc_ObjAddFanin
(
pNode
,
pFanins
[
1
]
);
Abc_ObjAddFanin
(
pNode
,
pFanins
[
2
]
);
bSpin
=
Cudd_bddIthVar
(
dd
,
0
);
bCof0
=
Cudd_bddIthVar
(
dd
,
1
);
bCof1
=
Cudd_bddIthVar
(
dd
,
2
);
pNode
->
pData
=
Cudd_bddIte
(
dd
,
bSpin
,
bCof1
,
bCof0
);
Cudd_Ref
(
pNode
->
pData
);
return
pNode
;
}
/**Function*************************************************************
Synopsis [Implements 4:1 MUX using one 6-LUT.]
Description [The fanins are (c0, c1, d00, d01, d10, d11).]
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Obj_t
*
Abc_NtkBddMux411
(
Abc_Ntk_t
*
pNtkNew
,
Abc_Obj_t
*
pFanins
[]
)
{
DdManager
*
dd
=
pNtkNew
->
pManFunc
;
Abc_Obj_t
*
pNode
;
DdNode
*
bSpin
,
*
bCof0
,
*
bCof1
;
pNode
=
Abc_NtkCreateNode
(
pNtkNew
);
Abc_ObjAddFanin
(
pNode
,
pFanins
[
0
]
);
Abc_ObjAddFanin
(
pNode
,
pFanins
[
1
]
);
Abc_ObjAddFanin
(
pNode
,
pFanins
[
2
]
);
Abc_ObjAddFanin
(
pNode
,
pFanins
[
3
]
);
Abc_ObjAddFanin
(
pNode
,
pFanins
[
4
]
);
Abc_ObjAddFanin
(
pNode
,
pFanins
[
5
]
);
bSpin
=
Cudd_bddIthVar
(
dd
,
1
);
bCof0
=
Cudd_bddIte
(
dd
,
bSpin
,
Cudd_bddIthVar
(
dd
,
3
),
Cudd_bddIthVar
(
dd
,
2
)
);
Cudd_Ref
(
bCof0
);
bCof1
=
Cudd_bddIte
(
dd
,
bSpin
,
Cudd_bddIthVar
(
dd
,
5
),
Cudd_bddIthVar
(
dd
,
4
)
);
Cudd_Ref
(
bCof1
);
bSpin
=
Cudd_bddIthVar
(
dd
,
0
);
pNode
->
pData
=
Cudd_bddIte
(
dd
,
bSpin
,
bCof1
,
bCof0
);
Cudd_Ref
(
pNode
->
pData
);
Cudd_RecursiveDeref
(
dd
,
bCof0
);
Cudd_RecursiveDeref
(
dd
,
bCof1
);
return
pNode
;
}
/**Function*************************************************************
Synopsis [Implementes 4:1 MUX using two 4-LUTs.]
Description [The fanins are (c0, c1, d00, d01, d10, d11).]
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Obj_t
*
Abc_NtkBddMux412
(
Abc_Ntk_t
*
pNtkNew
,
Abc_Obj_t
*
pFanins
[]
)
{
DdManager
*
dd
=
pNtkNew
->
pManFunc
;
Abc_Obj_t
*
pNodeBot
,
*
pNodeTop
;
DdNode
*
bSpin
,
*
bCof0
,
*
bCof1
;
// bottom node
pNodeBot
=
Abc_NtkCreateNode
(
pNtkNew
);
Abc_ObjAddFanin
(
pNodeBot
,
pFanins
[
0
]
);
Abc_ObjAddFanin
(
pNodeBot
,
pFanins
[
1
]
);
Abc_ObjAddFanin
(
pNodeBot
,
pFanins
[
2
]
);
Abc_ObjAddFanin
(
pNodeBot
,
pFanins
[
3
]
);
bSpin
=
Cudd_bddIthVar
(
dd
,
0
);
bCof0
=
Cudd_bddIte
(
dd
,
Cudd_bddIthVar
(
dd
,
1
),
Cudd_bddIthVar
(
dd
,
3
),
Cudd_bddIthVar
(
dd
,
2
)
);
Cudd_Ref
(
bCof0
);
bCof1
=
Cudd_bddIthVar
(
dd
,
1
);
pNodeBot
->
pData
=
Cudd_bddIte
(
dd
,
bSpin
,
bCof1
,
bCof0
);
Cudd_Ref
(
pNodeBot
->
pData
);
Cudd_RecursiveDeref
(
dd
,
bCof0
);
// top node
pNodeTop
=
Abc_NtkCreateNode
(
pNtkNew
);
Abc_ObjAddFanin
(
pNodeTop
,
pFanins
[
0
]
);
Abc_ObjAddFanin
(
pNodeTop
,
pNodeBot
);
Abc_ObjAddFanin
(
pNodeTop
,
pFanins
[
4
]
);
Abc_ObjAddFanin
(
pNodeTop
,
pFanins
[
5
]
);
bSpin
=
Cudd_bddIthVar
(
dd
,
0
);
bCof0
=
Cudd_bddIthVar
(
dd
,
1
);
bCof1
=
Cudd_bddIte
(
dd
,
Cudd_bddIthVar
(
dd
,
1
),
Cudd_bddIthVar
(
dd
,
3
),
Cudd_bddIthVar
(
dd
,
2
)
);
Cudd_Ref
(
bCof1
);
pNodeTop
->
pData
=
Cudd_bddIte
(
dd
,
bSpin
,
bCof1
,
bCof0
);
Cudd_Ref
(
pNodeTop
->
pData
);
Cudd_RecursiveDeref
(
dd
,
bCof1
);
return
pNodeTop
;
}
/**Function*************************************************************
Synopsis [Implementes 4:1 MUX using two 4-LUTs.]
Description [The fanins are (c0, c1, d00, d01, d10, d11).]
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Obj_t
*
Abc_NtkBddMux412a
(
Abc_Ntk_t
*
pNtkNew
,
Abc_Obj_t
*
pFanins
[]
)
{
DdManager
*
dd
=
pNtkNew
->
pManFunc
;
Abc_Obj_t
*
pNodeBot
,
*
pNodeTop
;
DdNode
*
bSpin
,
*
bCof0
,
*
bCof1
;
// bottom node
pNodeBot
=
Abc_NtkCreateNode
(
pNtkNew
);
Abc_ObjAddFanin
(
pNodeBot
,
pFanins
[
1
]
);
Abc_ObjAddFanin
(
pNodeBot
,
pFanins
[
2
]
);
Abc_ObjAddFanin
(
pNodeBot
,
pFanins
[
3
]
);
bSpin
=
Cudd_bddIthVar
(
dd
,
0
);
bCof0
=
Cudd_bddIthVar
(
dd
,
1
);
bCof1
=
Cudd_bddIthVar
(
dd
,
2
);
pNodeBot
->
pData
=
Cudd_bddIte
(
dd
,
bSpin
,
bCof1
,
bCof0
);
Cudd_Ref
(
pNodeBot
->
pData
);
// top node
pNodeTop
=
Abc_NtkCreateNode
(
pNtkNew
);
Abc_ObjAddFanin
(
pNodeTop
,
pFanins
[
0
]
);
Abc_ObjAddFanin
(
pNodeTop
,
pFanins
[
1
]
);
Abc_ObjAddFanin
(
pNodeTop
,
pNodeBot
);
Abc_ObjAddFanin
(
pNodeTop
,
pFanins
[
4
]
);
Abc_ObjAddFanin
(
pNodeTop
,
pFanins
[
5
]
);
bSpin
=
Cudd_bddIthVar
(
dd
,
0
);
bCof0
=
Cudd_bddIthVar
(
dd
,
2
);
bCof1
=
Cudd_bddIte
(
dd
,
Cudd_bddIthVar
(
dd
,
1
),
Cudd_bddIthVar
(
dd
,
4
),
Cudd_bddIthVar
(
dd
,
3
)
);
Cudd_Ref
(
bCof1
);
pNodeTop
->
pData
=
Cudd_bddIte
(
dd
,
bSpin
,
bCof1
,
bCof0
);
Cudd_Ref
(
pNodeTop
->
pData
);
Cudd_RecursiveDeref
(
dd
,
bCof1
);
return
pNodeTop
;
}
/**Function*************************************************************
Synopsis [Implements 4:1 MUX using three 2:1 MUXes.]
Description [The fanins are (c0, c1, d00, d01, d10, d11).]
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Obj_t
*
Abc_NtkBddMux413
(
Abc_Ntk_t
*
pNtkNew
,
Abc_Obj_t
*
pFanins
[]
)
{
Abc_Obj_t
*
pNodesBot
[
3
],
*
pNodesTop
[
3
];
// left bottom
pNodesBot
[
0
]
=
pFanins
[
1
];
pNodesBot
[
1
]
=
pFanins
[
2
];
pNodesBot
[
2
]
=
pFanins
[
3
];
pNodesTop
[
1
]
=
Abc_NtkBddMux21
(
pNtkNew
,
pNodesBot
);
// right bottom
pNodesBot
[
0
]
=
pFanins
[
1
];
pNodesBot
[
1
]
=
pFanins
[
4
];
pNodesBot
[
2
]
=
pFanins
[
5
];
pNodesTop
[
2
]
=
Abc_NtkBddMux21
(
pNtkNew
,
pNodesBot
);
// top node
pNodesTop
[
0
]
=
pFanins
[
0
];
return
Abc_NtkBddMux21
(
pNtkNew
,
pNodesTop
);
}
/**Function*************************************************************
Synopsis [Finds unique cofactors of the function on the given level.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
DdNode
*
Abc_NtkBddCofactors_rec
(
DdManager
*
dd
,
DdNode
*
bNode
,
int
iCof
,
int
iLevel
,
int
nLevels
)
{
DdNode
*
bNode0
,
*
bNode1
;
if
(
Cudd_IsConstant
(
bNode
)
||
iLevel
==
nLevels
)
return
bNode
;
if
(
Cudd_ReadPerm
(
dd
,
Cudd_NodeReadIndex
(
bNode
)
)
>
iLevel
)
{
bNode0
=
bNode
;
bNode1
=
bNode
;
}
else
if
(
Cudd_IsComplement
(
bNode
)
)
{
bNode0
=
Cudd_Not
(
cuddE
(
Cudd_Regular
(
bNode
)));
bNode1
=
Cudd_Not
(
cuddT
(
Cudd_Regular
(
bNode
)));
}
else
{
bNode0
=
cuddE
(
bNode
);
bNode1
=
cuddT
(
bNode
);
}
if
(
(
iCof
>>
(
nLevels
-
1
-
iLevel
))
&
1
)
return
Abc_NtkBddCofactors_rec
(
dd
,
bNode1
,
iCof
,
iLevel
+
1
,
nLevels
);
return
Abc_NtkBddCofactors_rec
(
dd
,
bNode0
,
iCof
,
iLevel
+
1
,
nLevels
);
}
/**Function*************************************************************
Synopsis [Finds unique cofactors of the function on the given level.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Ptr_t
*
Abc_NtkBddCofactors
(
DdManager
*
dd
,
DdNode
*
bNode
,
int
Level
)
{
Vec_Ptr_t
*
vCofs
;
int
i
,
nCofs
=
(
1
<<
Level
);
assert
(
Level
>
0
&&
Level
<
10
);
vCofs
=
Vec_PtrAlloc
(
8
);
for
(
i
=
0
;
i
<
nCofs
;
i
++
)
Vec_PtrPush
(
vCofs
,
Abc_NtkBddCofactors_rec
(
dd
,
bNode
,
i
,
0
,
Level
)
);
return
vCofs
;
}
/**Function*************************************************************
Synopsis [Comparison procedure for two integers.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static
int
Vec_PtrSortCompare
(
void
**
pp1
,
void
**
pp2
)
{
if
(
*
pp1
<
*
pp2
)
return
-
1
;
if
(
*
pp1
>
*
pp2
)
return
1
;
return
0
;
}
/**Function*************************************************************
Synopsis [Converts the node to MUXes.]
Description []
...
...
@@ -39,27 +293,43 @@
SeeAlso []
***********************************************************************/
Abc_Obj_t
*
Abc_NtkCreate
NodeLut
(
Abc_Ntk_t
*
pNtkNew
,
DdManager
*
dd
,
DdNode
*
bFunc
,
Abc_Obj_t
*
pNode
,
int
nLutSize
)
Abc_Obj_t
*
Abc_NtkCreate
CofLut
(
Abc_Ntk_t
*
pNtkNew
,
DdManager
*
dd
,
DdNode
*
bCof
,
Abc_Obj_t
*
pNode
,
int
Level
)
{
int
fVerbose
=
0
;
DdNode
*
bFuncNew
;
Abc_Obj_t
*
pNodeNew
;
int
i
,
nStart
=
ABC_MIN
(
0
,
Abc_ObjFaninNum
(
pNode
)
-
nLutSize
);
int
i
;
assert
(
Abc_ObjFaninNum
(
pNode
)
>
Level
);
// create a new node
pNodeNew
=
Abc_NtkCreateNode
(
pNtkNew
);
// add the fanins in the order, in which they appear in the reordered manager
for
(
i
=
nStart
;
i
<
Abc_ObjFaninNum
(
pNode
);
i
++
)
for
(
i
=
Level
;
i
<
Abc_ObjFaninNum
(
pNode
);
i
++
)
Abc_ObjAddFanin
(
pNodeNew
,
Abc_ObjFanin
(
pNode
,
i
)
->
pCopy
);
if
(
fVerbose
)
{
Extra_bddPrint
(
dd
,
bCof
);
printf
(
"
\n
"
);
printf
(
"
\n
"
);
}
// transfer the function
bFuncNew
=
Extra_bddMove
(
dd
,
bFunc
,
nStart
);
Cudd_Ref
(
bFuncNew
);
assert
(
Cudd_SupportSize
(
dd
,
bFuncNew
)
<=
nLutSize
);
bFuncNew
=
Extra_bddMove
(
dd
,
bCof
,
-
Level
);
Cudd_Ref
(
bFuncNew
);
if
(
fVerbose
)
{
Extra_bddPrint
(
dd
,
bFuncNew
);
printf
(
"
\n
"
);
printf
(
"
\n
"
);
}
pNodeNew
->
pData
=
Extra_TransferLevelByLevel
(
dd
,
pNtkNew
->
pManFunc
,
bFuncNew
);
Cudd_Ref
(
pNodeNew
->
pData
);
//Extra_bddPrint( pNtkNew->pManFunc, pNodeNew->pData );
//printf( "\n" );
//printf( "\n" );
Cudd_RecursiveDeref
(
dd
,
bFuncNew
);
return
pNodeNew
;
}
/**Function*************************************************************
Synopsis [
Converts the node to MUXes
.]
Synopsis [
Performs one step of Ashenhurst-Curtis decomposition
.]
Description []
...
...
@@ -68,36 +338,164 @@ Abc_Obj_t * Abc_NtkCreateNodeLut( Abc_Ntk_t * pNtkNew, DdManager * dd, DdNode *
SeeAlso []
***********************************************************************/
Abc_Obj_t
*
Abc_NodeBddToMuxesLut_rec
(
DdManager
*
dd
,
DdNode
*
bFunc
,
Abc_Ntk_t
*
pNtkNew
,
st_table
*
tBdd2Node
,
Abc_Obj_t
*
pNode
,
int
nLutSize
)
{
Abc_Obj_t
*
pNodeNew
,
*
pNodeNew0
,
*
pNodeNew1
,
*
pNodeNewC
;
assert
(
!
Cudd_IsComplement
(
bFunc
)
);
if
(
bFunc
==
b1
)
return
Abc_NtkCreateNodeConst1
(
pNtkNew
);
if
(
st_lookup
(
tBdd2Node
,
(
char
*
)
bFunc
,
(
char
**
)
&
pNodeNew
)
)
return
pNodeNew
;
if
(
dd
->
perm
[
bFunc
->
index
]
>=
Abc_ObjFaninNum
(
pNode
)
-
nLutSize
)
{
pNodeNew
=
Abc_NtkCreateNodeLut
(
pNtkNew
,
dd
,
bFunc
,
pNode
,
nLutSize
);
st_insert
(
tBdd2Node
,
(
char
*
)
bFunc
,
(
char
*
)
pNodeNew
);
return
pNodeNew
;
}
// solve for the children nodes
pNodeNew0
=
Abc_NodeBddToMuxesLut_rec
(
dd
,
Cudd_Regular
(
cuddE
(
bFunc
)),
pNtkNew
,
tBdd2Node
,
pNode
,
nLutSize
);
if
(
Cudd_IsComplement
(
cuddE
(
bFunc
))
)
pNodeNew0
=
Abc_NtkCreateNodeInv
(
pNtkNew
,
pNodeNew0
);
pNodeNew1
=
Abc_NodeBddToMuxesLut_rec
(
dd
,
cuddT
(
bFunc
),
pNtkNew
,
tBdd2Node
,
pNode
,
nLutSize
);
if
(
!
st_lookup
(
tBdd2Node
,
(
char
*
)
Cudd_bddIthVar
(
dd
,
bFunc
->
index
),
(
char
**
)
&
pNodeNewC
)
)
assert
(
0
);
// create the MUX node
pNodeNew
=
Abc_NtkCreateNodeMux
(
pNtkNew
,
pNodeNewC
,
pNodeNew1
,
pNodeNew0
);
st_insert
(
tBdd2Node
,
(
char
*
)
bFunc
,
(
char
*
)
pNodeNew
);
Abc_Obj_t
*
Abc_NtkBddCurtis
(
Abc_Ntk_t
*
pNtkNew
,
Abc_Obj_t
*
pNode
,
Vec_Ptr_t
*
vCofs
,
Vec_Ptr_t
*
vUniq
)
{
DdManager
*
ddOld
=
pNode
->
pNtk
->
pManFunc
;
DdManager
*
ddNew
=
pNtkNew
->
pManFunc
;
DdNode
*
bCof
,
*
bUniq
,
*
bMint
,
*
bTemp
,
*
bFunc
,
*
bBits
[
10
],
**
pbCodeVars
;
Abc_Obj_t
*
pNodeNew
=
NULL
,
*
pNodeBS
[
10
];
int
nLutSize
=
Extra_Base2Log
(
Vec_PtrSize
(
vCofs
)
);
int
nBits
=
Extra_Base2Log
(
Vec_PtrSize
(
vUniq
)
);
int
b
,
c
,
u
,
i
;
assert
(
nBits
+
2
<=
nLutSize
);
assert
(
nLutSize
<
Abc_ObjFaninNum
(
pNode
)
);
// start BDDs for the decompoosed blocks
for
(
b
=
0
;
b
<
nBits
;
b
++
)
bBits
[
b
]
=
Cudd_ReadLogicZero
(
ddNew
),
Cudd_Ref
(
bBits
[
b
]
);
// add each bound set minterm to one of the blccks
Vec_PtrForEachEntry
(
vCofs
,
bCof
,
c
)
{
Vec_PtrForEachEntry
(
vUniq
,
bUniq
,
u
)
if
(
bUniq
==
bCof
)
break
;
assert
(
u
<
Vec_PtrSize
(
vUniq
)
);
for
(
b
=
0
;
b
<
nBits
;
b
++
)
{
if
(
((
u
>>
b
)
&
1
)
==
0
)
continue
;
bMint
=
Extra_bddBitsToCube
(
ddNew
,
c
,
nLutSize
,
ddNew
->
vars
,
1
);
Cudd_Ref
(
bMint
);
bBits
[
b
]
=
Cudd_bddOr
(
ddNew
,
bTemp
=
bBits
[
b
],
bMint
);
Cudd_Ref
(
bBits
[
b
]
);
Cudd_RecursiveDeref
(
ddNew
,
bTemp
);
Cudd_RecursiveDeref
(
ddNew
,
bMint
);
}
}
// create bound set nodes
for
(
b
=
0
;
b
<
nBits
;
b
++
)
{
pNodeBS
[
b
]
=
Abc_NtkCreateNode
(
pNtkNew
);
for
(
i
=
0
;
i
<
nLutSize
;
i
++
)
Abc_ObjAddFanin
(
pNodeBS
[
b
],
Abc_ObjFanin
(
pNode
,
i
)
->
pCopy
);
pNodeBS
[
b
]
->
pData
=
bBits
[
b
];
// takes ref
}
// create composition node
pNodeNew
=
Abc_NtkCreateNode
(
pNtkNew
);
// add free set variables first
for
(
i
=
nLutSize
;
i
<
Abc_ObjFaninNum
(
pNode
);
i
++
)
Abc_ObjAddFanin
(
pNodeNew
,
Abc_ObjFanin
(
pNode
,
i
)
->
pCopy
);
// add code bit variables next
for
(
b
=
0
;
b
<
nBits
;
b
++
)
Abc_ObjAddFanin
(
pNodeNew
,
pNodeBS
[
b
]
);
// derive function of the composition node
bFunc
=
Cudd_ReadLogicZero
(
ddNew
);
Cudd_Ref
(
bFunc
);
pbCodeVars
=
ddNew
->
vars
+
Abc_ObjFaninNum
(
pNode
)
-
nLutSize
;
Vec_PtrForEachEntry
(
vUniq
,
bUniq
,
u
)
{
bUniq
=
Extra_bddMove
(
ddOld
,
bUniq
,
-
nLutSize
);
Cudd_Ref
(
bUniq
);
bUniq
=
Extra_TransferLevelByLevel
(
ddOld
,
ddNew
,
bTemp
=
bUniq
);
Cudd_Ref
(
bUniq
);
Cudd_RecursiveDeref
(
ddOld
,
bTemp
);
bMint
=
Extra_bddBitsToCube
(
ddNew
,
u
,
nBits
,
pbCodeVars
,
0
);
Cudd_Ref
(
bMint
);
bMint
=
Cudd_bddAnd
(
ddNew
,
bTemp
=
bMint
,
bUniq
);
Cudd_Ref
(
bMint
);
Cudd_RecursiveDeref
(
ddNew
,
bTemp
);
Cudd_RecursiveDeref
(
ddNew
,
bUniq
);
bFunc
=
Cudd_bddOr
(
ddNew
,
bTemp
=
bFunc
,
bMint
);
Cudd_Ref
(
bFunc
);
Cudd_RecursiveDeref
(
ddNew
,
bTemp
);
Cudd_RecursiveDeref
(
ddNew
,
bMint
);
}
pNodeNew
->
pData
=
bFunc
;
// takes ref
return
pNodeNew
;
}
/**Function*************************************************************
Synopsis [Converts the node to MUXes.]
Synopsis [Tries to decompose using cofactoring into two LUTs.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Obj_t
*
Abc_NtkBddFindCofactor
(
Abc_Ntk_t
*
pNtkNew
,
Abc_Obj_t
*
pNode
,
int
nLutSize
)
{
Abc_Obj_t
*
pNodeBot
,
*
pNodeTop
;
DdManager
*
ddOld
=
pNode
->
pNtk
->
pManFunc
;
DdManager
*
ddNew
=
pNtkNew
->
pManFunc
;
DdNode
*
bCof0
,
*
bCof1
,
*
bSupp
,
*
bTemp
,
*
bVar
;
DdNode
*
bCof0n
,
*
bCof1n
;
int
i
,
iCof
,
iFreeVar
,
fCof1Smaller
=
-
1
;
assert
(
Abc_ObjFaninNum
(
pNode
)
==
nLutSize
+
1
);
for
(
iCof
=
0
;
iCof
<
Abc_ObjFaninNum
(
pNode
);
iCof
++
)
{
bVar
=
Cudd_bddIthVar
(
ddOld
,
iCof
);
bCof0
=
Cudd_Cofactor
(
ddOld
,
pNode
->
pData
,
Cudd_Not
(
bVar
)
);
Cudd_Ref
(
bCof0
);
bCof1
=
Cudd_Cofactor
(
ddOld
,
pNode
->
pData
,
bVar
);
Cudd_Ref
(
bCof1
);
if
(
Cudd_SupportSize
(
ddOld
,
bCof0
)
<=
nLutSize
-
2
)
{
fCof1Smaller
=
0
;
break
;
}
if
(
Cudd_SupportSize
(
ddOld
,
bCof1
)
<=
nLutSize
-
2
)
{
fCof1Smaller
=
1
;
break
;
}
Cudd_RecursiveDeref
(
ddOld
,
bCof0
);
Cudd_RecursiveDeref
(
ddOld
,
bCof1
);
}
if
(
iCof
==
Abc_ObjFaninNum
(
pNode
)
)
return
NULL
;
// find unused variable
bSupp
=
Cudd_Support
(
ddOld
,
fCof1Smaller
?
bCof1
:
bCof0
);
Cudd_Ref
(
bSupp
);
iFreeVar
=
-
1
;
for
(
i
=
0
;
i
<
Abc_ObjFaninNum
(
pNode
);
i
++
)
{
assert
(
i
==
Cudd_ReadPerm
(
ddOld
,
i
)
);
if
(
i
==
iCof
)
continue
;
for
(
bTemp
=
bSupp
;
!
Cudd_IsConstant
(
bTemp
);
bTemp
=
cuddT
(
bTemp
)
)
if
(
i
==
(
int
)
Cudd_NodeReadIndex
(
bTemp
)
)
break
;
if
(
Cudd_IsConstant
(
bTemp
)
)
{
iFreeVar
=
i
;
break
;
}
}
assert
(
iFreeVar
!=
iCof
&&
iFreeVar
<
Abc_ObjFaninNum
(
pNode
)
);
Cudd_RecursiveDeref
(
ddOld
,
bSupp
);
// transfer the cofactors
bCof0n
=
Extra_TransferLevelByLevel
(
ddOld
,
ddNew
,
bCof0
);
Cudd_Ref
(
bCof0n
);
bCof1n
=
Extra_TransferLevelByLevel
(
ddOld
,
ddNew
,
bCof1
);
Cudd_Ref
(
bCof1n
);
Cudd_RecursiveDeref
(
ddOld
,
bCof0
);
Cudd_RecursiveDeref
(
ddOld
,
bCof1
);
// create bottom node
pNodeBot
=
Abc_NtkCreateNode
(
pNtkNew
);
for
(
i
=
0
;
i
<
Abc_ObjFaninNum
(
pNode
);
i
++
)
Abc_ObjAddFanin
(
pNodeBot
,
Abc_ObjFanin
(
pNode
,
i
)
->
pCopy
);
pNodeBot
->
pData
=
fCof1Smaller
?
bCof0n
:
bCof1n
;
// create top node
pNodeTop
=
Abc_NtkCreateNode
(
pNtkNew
);
for
(
i
=
0
;
i
<
Abc_ObjFaninNum
(
pNode
);
i
++
)
if
(
i
==
iFreeVar
)
Abc_ObjAddFanin
(
pNodeTop
,
pNodeBot
);
else
Abc_ObjAddFanin
(
pNodeTop
,
Abc_ObjFanin
(
pNode
,
i
)
->
pCopy
);
// derive the new function
pNodeTop
->
pData
=
Cudd_bddIte
(
ddNew
,
Cudd_bddIthVar
(
ddNew
,
iCof
),
fCof1Smaller
?
bCof1n
:
Cudd_bddIthVar
(
ddNew
,
iFreeVar
),
fCof1Smaller
?
Cudd_bddIthVar
(
ddNew
,
iFreeVar
)
:
bCof0n
);
Cudd_Ref
(
pNodeTop
->
pData
);
Cudd_RecursiveDeref
(
ddNew
,
fCof1Smaller
?
bCof1n
:
bCof0n
);
return
pNodeTop
;
}
/**Function*************************************************************
Synopsis [Decompose the function once.]
Description []
...
...
@@ -106,23 +504,64 @@ Abc_Obj_t * Abc_NodeBddToMuxesLut_rec( DdManager * dd, DdNode * bFunc, Abc_Ntk_t
SeeAlso []
***********************************************************************/
Abc_Obj_t
*
Abc_N
odeBddToMuxesLut
(
Abc_Ntk_t
*
pNtkNew
,
Abc_Obj_t
*
pNodeOld
,
int
nLutSiz
e
)
Abc_Obj_t
*
Abc_N
tkBddDecompose
(
Abc_Ntk_t
*
pNtkNew
,
Abc_Obj_t
*
pNode
,
int
nLutSize
,
int
fVerbos
e
)
{
DdManager
*
dd
=
pNodeOld
->
pNtk
->
pManFunc
;
DdNode
*
bFunc
=
pNodeOld
->
pData
;
Abc_Obj_t
*
pFaninOld
,
*
pNodeNew
;
st_table
*
tBdd2Node
;
Vec_Ptr_t
*
vCofs
,
*
vUniq
;
DdManager
*
dd
=
pNode
->
pNtk
->
pManFunc
;
DdNode
*
bCof
;
Abc_Obj_t
*
pNodeNew
=
NULL
;
Abc_Obj_t
*
pCofs
[
20
];
int
i
;
// create the table mapping BDD nodes into the ABC nodes
tBdd2Node
=
st_init_table
(
st_ptrcmp
,
st_ptrhash
);
// add the constant and the elementary vars
Abc_ObjForEachFanin
(
pNodeOld
,
pFaninOld
,
i
)
st_insert
(
tBdd2Node
,
(
char
*
)
Cudd_bddIthVar
(
dd
,
i
),
(
char
*
)
pFaninOld
->
pCopy
);
// create the new nodes recursively
pNodeNew
=
Abc_NodeBddToMuxesLut_rec
(
dd
,
Cudd_Regular
(
bFunc
),
pNtkNew
,
tBdd2Node
,
pNodeOld
,
nLutSize
);
st_free_table
(
tBdd2Node
);
if
(
Cudd_IsComplement
(
bFunc
)
)
pNodeNew
=
Abc_NtkCreateNodeInv
(
pNtkNew
,
pNodeNew
);
assert
(
Abc_ObjFaninNum
(
pNode
)
>
nLutSize
);
// try to decompose with two LUTs (the best case for Supp = LutSize + 1)
if
(
Abc_ObjFaninNum
(
pNode
)
==
nLutSize
+
1
)
{
pNodeNew
=
Abc_NtkBddFindCofactor
(
pNtkNew
,
pNode
,
nLutSize
);
if
(
pNodeNew
!=
NULL
)
{
if
(
fVerbose
)
printf
(
"Decomposing %d-input node %d using MUX.
\n
"
,
Abc_ObjFaninNum
(
pNode
),
Abc_ObjId
(
pNode
)
);
return
pNodeNew
;
}
}
// cofactor w.r.t. the bound set variables
vCofs
=
Abc_NtkBddCofactors
(
dd
,
pNode
->
pData
,
nLutSize
);
vUniq
=
Vec_PtrDup
(
vCofs
);
Vec_PtrUniqify
(
vUniq
,
(
int
(
*
)())
Vec_PtrSortCompare
);
// only perform decomposition with it is support reduring with two less vars
if
(
Vec_PtrSize
(
vUniq
)
>
(
1
<<
(
nLutSize
-
2
))
)
{
Vec_PtrFree
(
vCofs
);
vCofs
=
Abc_NtkBddCofactors
(
dd
,
pNode
->
pData
,
2
);
if
(
fVerbose
)
printf
(
"Decomposing %d-input node %d using cofactoring with %d cofactors.
\n
"
,
Abc_ObjFaninNum
(
pNode
),
Abc_ObjId
(
pNode
),
Vec_PtrSize
(
vCofs
)
);
// implement the cofactors
pCofs
[
0
]
=
Abc_ObjFanin
(
pNode
,
0
)
->
pCopy
;
pCofs
[
1
]
=
Abc_ObjFanin
(
pNode
,
1
)
->
pCopy
;
Vec_PtrForEachEntry
(
vCofs
,
bCof
,
i
)
pCofs
[
2
+
i
]
=
Abc_NtkCreateCofLut
(
pNtkNew
,
dd
,
bCof
,
pNode
,
2
);
if
(
nLutSize
==
4
)
pNodeNew
=
Abc_NtkBddMux412
(
pNtkNew
,
pCofs
);
else
if
(
nLutSize
==
5
)
pNodeNew
=
Abc_NtkBddMux412a
(
pNtkNew
,
pCofs
);
else
if
(
nLutSize
==
6
)
pNodeNew
=
Abc_NtkBddMux411
(
pNtkNew
,
pCofs
);
else
assert
(
0
);
}
// alternative decompose using MUX-decomposition
else
{
if
(
fVerbose
)
printf
(
"Decomposing %d-input node %d using Curtis with %d unique columns.
\n
"
,
Abc_ObjFaninNum
(
pNode
),
Abc_ObjId
(
pNode
),
Vec_PtrSize
(
vUniq
)
);
pNodeNew
=
Abc_NtkBddCurtis
(
pNtkNew
,
pNode
,
vCofs
,
vUniq
);
}
Vec_PtrFree
(
vCofs
);
Vec_PtrFree
(
vUniq
);
return
pNodeNew
;
}
...
...
@@ -137,20 +576,24 @@ Abc_Obj_t * Abc_NodeBddToMuxesLut( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNodeOld, in
SeeAlso []
***********************************************************************/
void
Abc_NtkLutminConstruct
(
Abc_Ntk_t
*
pNtkClp
,
Abc_Ntk_t
*
pNtkDec
,
int
nLutSize
)
void
Abc_NtkLutminConstruct
(
Abc_Ntk_t
*
pNtkClp
,
Abc_Ntk_t
*
pNtkDec
,
int
nLutSize
,
int
fVerbose
)
{
Abc_Obj_t
*
pObj
,
*
pDriver
;
int
i
;
Abc_NtkForEachCo
(
pNtkClp
,
pObj
,
i
)
Vec_Ptr_t
*
vNodes
;
Abc_Obj_t
*
pNode
,
*
pFanin
;
int
i
,
k
;
vNodes
=
Abc_NtkDfs
(
pNtkClp
,
0
);
Vec_PtrForEachEntry
(
vNodes
,
pNode
,
i
)
{
pDriver
=
Abc_ObjFanin0
(
pObj
);
if
(
!
Abc_ObjIsNode
(
pDriver
)
)
continue
;
if
(
Abc_ObjFaninNum
(
pDriver
)
==
0
)
pDriver
->
pCopy
=
Abc_NtkDupObj
(
pNtkDec
,
pDriver
,
0
);
if
(
Abc_ObjFaninNum
(
pNode
)
<=
nLutSize
)
{
pNode
->
pCopy
=
Abc_NtkDupObj
(
pNtkDec
,
pNode
,
0
);
Abc_ObjForEachFanin
(
pNode
,
pFanin
,
k
)
Abc_ObjAddFanin
(
pNode
->
pCopy
,
pFanin
->
pCopy
);
}
else
p
Driver
->
pCopy
=
Abc_NodeBddToMuxesLut
(
pNtkDec
,
pDriver
,
nLutSiz
e
);
p
Node
->
pCopy
=
Abc_NtkBddDecompose
(
pNtkDec
,
pNode
,
nLutSize
,
fVerbos
e
);
}
Vec_PtrFree
(
vNodes
);
}
/**Function*************************************************************
...
...
@@ -164,42 +607,87 @@ void Abc_NtkLutminConstruct( Abc_Ntk_t * pNtkClp, Abc_Ntk_t * pNtkDec, int nLutS
SeeAlso []
***********************************************************************/
Abc_Ntk_t
*
Abc_NtkLutmin
(
Abc_Ntk_t
*
pNtk
,
int
nLutSize
,
int
fVerbose
)
Abc_Ntk_t
*
Abc_NtkLutmin
Int
(
Abc_Ntk_t
*
pNtk
,
int
nLutSize
,
int
fVerbose
)
{
extern
void
Abc_NtkBddReorder
(
Abc_Ntk_t
*
pNtk
,
int
fVerbose
);
Abc_Ntk_t
*
pNtkDec
,
*
pNtkClp
,
*
pTemp
;
// collapse the network and reorder BDDs
if
(
Abc_NtkIsStrash
(
pNtk
)
)
pTemp
=
Abc_NtkDup
(
pNtk
);
else
pTemp
=
Abc_NtkStrash
(
pNtk
,
0
,
1
,
0
);
pNtkClp
=
Abc_NtkCollapse
(
pTemp
,
10000
,
0
,
1
,
0
);
Abc_NtkDelete
(
pTemp
);
if
(
pNtkClp
==
NULL
)
return
NULL
;
if
(
!
Abc_NtkIsBddLogic
(
pNtkClp
)
)
Abc_NtkToBdd
(
pNtkClp
);
Abc_NtkBddReorder
(
pNtkClp
,
fVerbose
);
Abc_Ntk_t
*
pNtkDec
;
// minimize BDDs
// Abc_NtkBddReorder( pNtk, fVerbose );
Abc_NtkBddReorder
(
pNtk
,
0
);
// decompose one output at a time
pNtkDec
=
Abc_NtkStartFrom
(
pNtk
Clp
,
ABC_NTK_LOGIC
,
ABC_FUNC_BDD
);
pNtkDec
=
Abc_NtkStartFrom
(
pNtk
,
ABC_NTK_LOGIC
,
ABC_FUNC_BDD
);
// make sure the new manager has enough inputs
Cudd_bddIthVar
(
pNtkDec
->
pManFunc
,
nLutSize
);
Cudd_bddIthVar
(
pNtkDec
->
pManFunc
,
Abc_NtkGetFaninMax
(
pNtk
)
);
// put the results into the new network (save new CO drivers in old CO drivers)
Abc_NtkLutminConstruct
(
pNtk
Clp
,
pNtkDec
,
nLutSiz
e
);
Abc_NtkLutminConstruct
(
pNtk
,
pNtkDec
,
nLutSize
,
fVerbos
e
);
// finalize the new network
Abc_NtkFinalize
(
pNtkClp
,
pNtkDec
);
Abc_NtkDelete
(
pNtkClp
);
Abc_NtkFinalize
(
pNtk
,
pNtkDec
);
// make the network minimum base
Abc_NtkMinimumBase
(
pNtkDec
);
return
pNtkDec
;
}
/**Function*************************************************************
Synopsis [Performs minimum-LUT decomposition of the network.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t
*
Abc_NtkLutmin
(
Abc_Ntk_t
*
pNtkInit
,
int
nLutSize
,
int
fVerbose
)
{
extern
bool
Abc_NtkFraigSweep
(
Abc_Ntk_t
*
pNtk
,
int
fUseInv
,
int
fExdc
,
int
fVerbose
,
int
fVeryVerbose
);
Abc_Ntk_t
*
pNtkNew
,
*
pTemp
;
int
i
;
if
(
nLutSize
<
4
)
{
printf
(
"The LUT count (%d) should be at least 4.
\n
"
,
nLutSize
);
return
NULL
;
}
if
(
nLutSize
>
6
)
{
printf
(
"The LUT count (%d) should not exceed 6.
\n
"
,
nLutSize
);
return
NULL
;
}
// create internal representation
if
(
Abc_NtkIsStrash
(
pNtkInit
)
)
pNtkNew
=
Abc_NtkDup
(
pNtkInit
);
else
pNtkNew
=
Abc_NtkStrash
(
pNtkInit
,
0
,
1
,
0
);
// collapse the network
pNtkNew
=
Abc_NtkCollapse
(
pTemp
=
pNtkNew
,
10000
,
0
,
1
,
0
);
Abc_NtkDelete
(
pTemp
);
if
(
pNtkNew
==
NULL
)
return
NULL
;
// convert it to BDD
if
(
!
Abc_NtkIsBddLogic
(
pNtkNew
)
)
Abc_NtkToBdd
(
pNtkNew
);
// iterate decomposition
for
(
i
=
0
;
Abc_NtkGetFaninMax
(
pNtkNew
)
>
nLutSize
;
i
++
)
{
if
(
fVerbose
)
printf
(
"*** Iteration %d:
\n
"
,
i
+
1
);
if
(
fVerbose
)
printf
(
"Decomposing network with %d nodes and %d max fanin count for K = %d.
\n
"
,
Abc_NtkNodeNum
(
pNtkNew
),
Abc_NtkGetFaninMax
(
pNtkNew
),
nLutSize
);
pNtkNew
=
Abc_NtkLutminInt
(
pTemp
=
pNtkNew
,
nLutSize
,
fVerbose
);
Abc_NtkDelete
(
pTemp
);
}
// fix the problem with complemented and duplicated CO edges
Abc_NtkLogicMakeSimpleCos
(
pNtkDec
,
0
);
Abc_NtkLogicMakeSimpleCos
(
pNtkNew
,
0
);
// merge functionally equivalent nodes
Abc_NtkFraigSweep
(
pNtkNew
,
1
,
0
,
0
,
0
);
// make sure everything is okay
if
(
!
Abc_NtkCheck
(
pNtk
Dec
)
)
if
(
!
Abc_NtkCheck
(
pNtk
New
)
)
{
printf
(
"Abc_NtkLutmin: The network check has failed.
\n
"
);
return
0
;
}
return
pNtk
Dec
;
return
pNtk
New
;
}
////////////////////////////////////////////////////////////////////////
...
...
src/misc/extra/extra.h
View file @
770bc99e
...
...
@@ -169,7 +169,7 @@ extern DdNode * Extra_bddImageRead2( Extra_ImageTree2_t * pTree );
extern
DdNode
*
Extra_TransferPermute
(
DdManager
*
ddSource
,
DdManager
*
ddDestination
,
DdNode
*
f
,
int
*
Permute
);
extern
DdNode
*
Extra_TransferLevelByLevel
(
DdManager
*
ddSource
,
DdManager
*
ddDestination
,
DdNode
*
f
);
extern
DdNode
*
Extra_bddRemapUp
(
DdManager
*
dd
,
DdNode
*
bF
);
extern
DdNode
*
Extra_bddMove
(
DdManager
*
dd
,
DdNode
*
bF
,
int
fShiftUp
);
extern
DdNode
*
Extra_bddMove
(
DdManager
*
dd
,
DdNode
*
bF
,
int
nVars
);
extern
DdNode
*
extraBddMove
(
DdManager
*
dd
,
DdNode
*
bF
,
DdNode
*
bFlag
);
extern
void
Extra_StopManager
(
DdManager
*
dd
);
extern
void
Extra_bddPrint
(
DdManager
*
dd
,
DdNode
*
F
);
...
...
src/misc/extra/extraBddMisc.c
View file @
770bc99e
...
...
@@ -221,6 +221,7 @@ void Extra_StopManager( DdManager * dd )
// check for remaining references in the package
RetValue
=
Cudd_CheckZeroRef
(
dd
);
if
(
RetValue
>
10
)
// if ( RetValue )
printf
(
"
\n
The number of referenced nodes = %d
\n\n
"
,
RetValue
);
// Cudd_PrintInfo( dd, stdout );
Cudd_Quit
(
dd
);
...
...
src/opt/mfs/mfsSat.c
View file @
770bc99e
...
...
@@ -43,11 +43,16 @@ int Abc_NtkMfsSolveSat_iter( Mfs_Man_t * p )
{
int
Lits
[
MFS_FANIN_MAX
];
int
RetValue
,
nBTLimit
,
iVar
,
b
,
Mint
;
// int nConfs = p->pSat->stats.conflicts;
if
(
p
->
nTotConfLim
&&
p
->
nTotConfLim
<=
p
->
pSat
->
stats
.
conflicts
)
return
-
1
;
nBTLimit
=
p
->
nTotConfLim
?
p
->
nTotConfLim
-
p
->
pSat
->
stats
.
conflicts
:
0
;
RetValue
=
sat_solver_solve
(
p
->
pSat
,
NULL
,
NULL
,
(
ABC_INT64_T
)
nBTLimit
,
(
ABC_INT64_T
)
0
,
(
ABC_INT64_T
)
0
,
(
ABC_INT64_T
)
0
);
assert
(
RetValue
==
l_Undef
||
RetValue
==
l_True
||
RetValue
==
l_False
);
//printf( "%c", RetValue==l_Undef ? '?' : (RetValue==l_False ? '-' : '+') );
//printf( "%d ", p->pSat->stats.conflicts-nConfs );
//if ( RetValue==l_False )
//printf( "\n" );
if
(
RetValue
==
l_Undef
)
return
-
1
;
if
(
RetValue
==
l_False
)
...
...
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