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
6f17c44e
Commit
6f17c44e
authored
Mar 23, 2014
by
Alan Mishchenko
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Integrating barrier buffers into the mapper.
parent
f6eb5262
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
945 additions
and
1265 deletions
+945
-1265
src/base/abc/abc.h
+1
-0
src/base/abc/abcBarBuf.c
+64
-0
src/base/abc/abcDfs.c
+44
-0
src/base/abci/abcMap.c
+126
-138
src/map/mapper/mapper.h
+5
-3
src/map/mapper/mapperCore.c
+12
-14
src/map/mapper/mapperCreate.c
+32
-82
src/map/mapper/mapperCut.c
+67
-62
src/map/mapper/mapperInt.h
+9
-31
src/map/mapper/mapperMatch.c
+264
-244
src/map/mapper/mapperRefs.c
+102
-145
src/map/mapper/mapperSwitch.c
+6
-5
src/map/mapper/mapperTime.c
+172
-261
src/map/mapper/mapperTruth.c
+2
-2
src/map/mapper/mapperUtils.c
+18
-278
src/map/mapper/mapperVec.c
+21
-0
No files found.
src/base/abc/abc.h
View file @
6f17c44e
...
...
@@ -610,6 +610,7 @@ extern ABC_DLL int Abc_NtkIsDfsOrdered( Abc_Ntk_t * pNtk );
extern
ABC_DLL
Vec_Ptr_t
*
Abc_NtkSupport
(
Abc_Ntk_t
*
pNtk
);
extern
ABC_DLL
Vec_Ptr_t
*
Abc_NtkNodeSupport
(
Abc_Ntk_t
*
pNtk
,
Abc_Obj_t
**
ppNodes
,
int
nNodes
);
extern
ABC_DLL
Vec_Ptr_t
*
Abc_AigDfs
(
Abc_Ntk_t
*
pNtk
,
int
fCollectAll
,
int
fCollectCos
);
extern
ABC_DLL
Vec_Ptr_t
*
Abc_AigDfsMap
(
Abc_Ntk_t
*
pNtk
);
extern
ABC_DLL
Vec_Vec_t
*
Abc_DfsLevelized
(
Abc_Obj_t
*
pNode
,
int
fTfi
);
extern
ABC_DLL
Vec_Vec_t
*
Abc_NtkLevelize
(
Abc_Ntk_t
*
pNtk
);
extern
ABC_DLL
int
Abc_NtkLevel
(
Abc_Ntk_t
*
pNtk
);
...
...
src/base/abc/abcBarBuf.c
View file @
6f17c44e
...
...
@@ -311,6 +311,70 @@ Abc_Ntk_t * Abc_NtkFromBarBufs( Abc_Ntk_t * pNtkBase, Abc_Ntk_t * pNtk )
return
pNtkNew
;
}
/**Function*************************************************************
Synopsis [Collect nodes in the barbuf-friendly order.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
Abc_NtkToBarBufsCollect_rec
(
Abc_Obj_t
*
pObj
,
Vec_Ptr_t
*
vNodes
)
{
Abc_Obj_t
*
pFanin
;
int
i
;
if
(
Abc_NodeIsTravIdCurrent
(
pObj
)
)
return
;
Abc_NodeSetTravIdCurrent
(
pObj
);
assert
(
Abc_ObjIsNode
(
pObj
)
);
Abc_ObjForEachFanin
(
pObj
,
pFanin
,
i
)
Abc_NtkToBarBufsCollect_rec
(
pFanin
,
vNodes
);
Vec_PtrPush
(
vNodes
,
pObj
);
}
Vec_Ptr_t
*
Abc_NtkToBarBufsCollect
(
Abc_Ntk_t
*
pNtk
)
{
Vec_Ptr_t
*
vNodes
;
Abc_Obj_t
*
pObj
;
int
i
;
assert
(
Abc_NtkIsLogic
(
pNtk
)
);
assert
(
pNtk
->
nBarBufs
>
0
);
assert
(
pNtk
->
nBarBufs
==
Abc_NtkLatchNum
(
pNtk
)
);
vNodes
=
Vec_PtrAlloc
(
Abc_NtkObjNum
(
pNtk
)
);
Abc_NtkIncrementTravId
(
pNtk
);
Abc_NtkForEachCi
(
pNtk
,
pObj
,
i
)
{
if
(
i
>=
Abc_NtkCiNum
(
pNtk
)
-
pNtk
->
nBarBufs
)
break
;
Vec_PtrPush
(
vNodes
,
pObj
);
Abc_NodeSetTravIdCurrent
(
pObj
);
}
Abc_NtkForEachCo
(
pNtk
,
pObj
,
i
)
{
if
(
i
<
Abc_NtkCoNum
(
pNtk
)
-
pNtk
->
nBarBufs
)
continue
;
Abc_NtkToBarBufsCollect_rec
(
Abc_ObjFanin0
(
pObj
),
vNodes
);
Vec_PtrPush
(
vNodes
,
pObj
);
Vec_PtrPush
(
vNodes
,
Abc_ObjFanout0
(
pObj
)
);
Vec_PtrPush
(
vNodes
,
Abc_ObjFanout0
(
Abc_ObjFanout0
(
pObj
))
);
Abc_NodeSetTravIdCurrent
(
pObj
);
Abc_NodeSetTravIdCurrent
(
Abc_ObjFanout0
(
pObj
)
);
Abc_NodeSetTravIdCurrent
(
Abc_ObjFanout0
(
Abc_ObjFanout0
(
pObj
))
);
}
Abc_NtkForEachCo
(
pNtk
,
pObj
,
i
)
{
if
(
i
>=
Abc_NtkCoNum
(
pNtk
)
-
pNtk
->
nBarBufs
)
break
;
Abc_NtkToBarBufsCollect_rec
(
Abc_ObjFanin0
(
pObj
),
vNodes
);
Vec_PtrPush
(
vNodes
,
pObj
);
Abc_NodeSetTravIdCurrent
(
pObj
);
}
assert
(
Vec_PtrSize
(
vNodes
)
==
Abc_NtkObjNum
(
pNtk
)
);
return
vNodes
;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
...
...
src/base/abc/abcDfs.c
View file @
6f17c44e
...
...
@@ -946,6 +946,50 @@ Vec_Ptr_t * Abc_AigDfs( Abc_Ntk_t * pNtk, int fCollectAll, int fCollectCos )
return
vNodes
;
}
/**Function*************************************************************
Synopsis [Returns the DFS ordered array of logic nodes.]
Description [Collects only the internal nodes, leaving out CIs/COs.
However it marks both CIs and COs with the current TravId.]
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Ptr_t
*
Abc_AigDfsMap
(
Abc_Ntk_t
*
pNtk
)
{
Vec_Ptr_t
*
vNodes
;
Abc_Obj_t
*
pNode
;
int
i
;
assert
(
Abc_NtkIsStrash
(
pNtk
)
);
// set the traversal ID
Abc_NtkIncrementTravId
(
pNtk
);
// start the array of nodes
vNodes
=
Vec_PtrAlloc
(
100
);
// collect cones of barbufs
Abc_NtkForEachCo
(
pNtk
,
pNode
,
i
)
{
if
(
i
<
Abc_NtkCoNum
(
pNtk
)
-
pNtk
->
nBarBufs
)
continue
;
Abc_AigDfs_rec
(
Abc_ObjFanin0
(
pNode
),
vNodes
);
Abc_NodeSetTravIdCurrent
(
pNode
);
// collect latch as a placeholder
assert
(
Abc_ObjIsLatch
(
Abc_ObjFanout0
(
pNode
))
);
Vec_PtrPush
(
vNodes
,
Abc_ObjFanout0
(
pNode
)
);
}
// collect nodes of real POs
Abc_NtkForEachCo
(
pNtk
,
pNode
,
i
)
{
if
(
i
>=
Abc_NtkCoNum
(
pNtk
)
-
pNtk
->
nBarBufs
)
break
;
Abc_AigDfs_rec
(
Abc_ObjFanin0
(
pNode
),
vNodes
);
assert
(
Abc_ObjIsPo
(
pNode
)
);
Abc_NodeSetTravIdCurrent
(
pNode
);
}
return
vNodes
;
}
/**Function*************************************************************
...
...
src/base/abci/abcMap.c
View file @
6f17c44e
...
...
@@ -34,7 +34,6 @@ static Map_Man_t * Abc_NtkToMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRec
static
Abc_Ntk_t
*
Abc_NtkFromMap
(
Map_Man_t
*
pMan
,
Abc_Ntk_t
*
pNtk
);
static
Abc_Obj_t
*
Abc_NodeFromMap_rec
(
Abc_Ntk_t
*
pNtkNew
,
Map_Node_t
*
pNodeMap
,
int
fPhase
);
static
Abc_Obj_t
*
Abc_NodeFromMapPhase_rec
(
Abc_Ntk_t
*
pNtkNew
,
Map_Node_t
*
pNodeMap
,
int
fPhase
);
static
Abc_Obj_t
*
Abc_NodeFromMapSuper_rec
(
Abc_Ntk_t
*
pNtkNew
,
Map_Node_t
*
pNodeMap
,
Map_Super_t
*
pSuper
,
Abc_Obj_t
*
pNodePis
[],
int
nNodePis
);
static
Abc_Ntk_t
*
Abc_NtkFromMapSuperChoice
(
Map_Man_t
*
pMan
,
Abc_Ntk_t
*
pNtk
);
static
void
Abc_NodeSuperChoice
(
Abc_Ntk_t
*
pNtkNew
,
Abc_Obj_t
*
pNode
);
...
...
@@ -219,7 +218,6 @@ Map_Time_t * Abc_NtkMapCopyCoRequired( Abc_Ntk_t * pNtk, Abc_Time_t * ppTimes )
Map_Man_t
*
Abc_NtkToMap
(
Abc_Ntk_t
*
pNtk
,
double
DelayTarget
,
int
fRecovery
,
float
*
pSwitching
,
int
fVerbose
)
{
Map_Man_t
*
pMan
;
ProgressBar
*
pProgress
;
Map_Node_t
*
pNodeMap
;
Vec_Ptr_t
*
vNodes
;
Abc_Obj_t
*
pNode
,
*
pFanin
,
*
pPrev
;
...
...
@@ -228,7 +226,7 @@ Map_Man_t * Abc_NtkToMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, f
assert
(
Abc_NtkIsStrash
(
pNtk
)
);
// start the mapping manager and set its parameters
pMan
=
Map_ManCreate
(
Abc_NtkPiNum
(
pNtk
)
+
Abc_NtkLatchNum
(
pNtk
)
,
Abc_NtkPoNum
(
pNtk
)
+
Abc_NtkLatchNum
(
pNtk
)
,
fVerbose
);
pMan
=
Map_ManCreate
(
Abc_NtkPiNum
(
pNtk
)
+
Abc_NtkLatchNum
(
pNtk
)
-
pNtk
->
nBarBufs
,
Abc_NtkPoNum
(
pNtk
)
+
Abc_NtkLatchNum
(
pNtk
)
-
pNtk
->
nBarBufs
,
fVerbose
);
if
(
pMan
==
NULL
)
return
NULL
;
Map_ManSetAreaRecovery
(
pMan
,
fRecovery
);
...
...
@@ -242,6 +240,8 @@ Map_Man_t * Abc_NtkToMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, f
Abc_AigConst1
(
pNtk
)
->
pCopy
=
(
Abc_Obj_t
*
)
Map_ManReadConst1
(
pMan
);
Abc_NtkForEachCi
(
pNtk
,
pNode
,
i
)
{
if
(
i
==
Abc_NtkCiNum
(
pNtk
)
-
pNtk
->
nBarBufs
)
break
;
pNodeMap
=
Map_ManReadInputs
(
pMan
)[
i
];
pNode
->
pCopy
=
(
Abc_Obj_t
*
)
pNodeMap
;
if
(
pSwitching
)
...
...
@@ -249,11 +249,17 @@ Map_Man_t * Abc_NtkToMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, f
}
// load the AIG into the mapper
vNodes
=
Abc_AigDfs
(
pNtk
,
0
,
0
);
pProgress
=
Extra_ProgressBarStart
(
stdout
,
vNodes
->
nSize
);
vNodes
=
Abc_AigDfsMap
(
pNtk
);
Vec_PtrForEachEntry
(
Abc_Obj_t
*
,
vNodes
,
pNode
,
i
)
{
Extra_ProgressBarUpdate
(
pProgress
,
i
,
NULL
);
if
(
Abc_ObjIsLatch
(
pNode
)
)
{
pFanin
=
Abc_ObjFanin0
(
pNode
);
pNodeMap
=
Map_NodeBuf
(
pMan
,
Map_NotCond
(
Abc_ObjFanin0
(
pFanin
)
->
pCopy
,
(
int
)
Abc_ObjFaninC0
(
pFanin
)
)
);
Abc_ObjFanout0
(
pNode
)
->
pCopy
=
(
Abc_Obj_t
*
)
pNodeMap
;
continue
;
}
assert
(
Abc_ObjIsNode
(
pNode
)
);
// add the node to the mapper
pNodeMap
=
Map_NodeAnd
(
pMan
,
Map_NotCond
(
Abc_ObjFanin0
(
pNode
)
->
pCopy
,
(
int
)
Abc_ObjFaninC0
(
pNode
)
),
...
...
@@ -271,12 +277,16 @@ Map_Man_t * Abc_NtkToMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, f
Map_NodeSetRepr
(
(
Map_Node_t
*
)
pFanin
->
pCopy
,
(
Map_Node_t
*
)
pNode
->
pCopy
);
}
}
Extra_ProgressBarStop
(
pProgres
s
);
assert
(
Map_ManReadBufNum
(
pMan
)
==
pNtk
->
nBarBuf
s
);
Vec_PtrFree
(
vNodes
);
// set the primary outputs in the required phase
Abc_NtkForEachCo
(
pNtk
,
pNode
,
i
)
{
if
(
i
==
Abc_NtkCoNum
(
pNtk
)
-
pNtk
->
nBarBufs
)
break
;
Map_ManReadOutputs
(
pMan
)[
i
]
=
Map_NotCond
(
(
Map_Node_t
*
)
Abc_ObjFanin0
(
pNode
)
->
pCopy
,
(
int
)
Abc_ObjFaninC0
(
pNode
)
);
}
return
pMan
;
}
...
...
@@ -291,95 +301,50 @@ Map_Man_t * Abc_NtkToMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, f
SeeAlso []
***********************************************************************/
Abc_
Ntk_t
*
Abc_NtkFromMap
(
Map_Man_t
*
pMan
,
Abc_Ntk_t
*
pNtk
)
Abc_
Obj_t
*
Abc_NodeFromMapSuper_rec
(
Abc_Ntk_t
*
pNtkNew
,
Map_Node_t
*
pNodeMap
,
Map_Super_t
*
pSuper
,
Abc_Obj_t
*
pNodePis
[],
int
nNodePis
)
{
ProgressBar
*
pProgress
;
Abc_Ntk_t
*
pNtkNew
;
Map_Node_t
*
pNodeMap
;
Abc_Obj_t
*
pNode
,
*
pNodeNew
;
int
i
,
nDupGates
;
// create the new network
pNtkNew
=
Abc_NtkStartFrom
(
pNtk
,
ABC_NTK_LOGIC
,
ABC_FUNC_MAP
);
// make the mapper point to the new network
Map_ManCleanData
(
pMan
);
Abc_NtkForEachCi
(
pNtk
,
pNode
,
i
)
Map_NodeSetData
(
Map_ManReadInputs
(
pMan
)[
i
],
1
,
(
char
*
)
pNode
->
pCopy
);
// assign the mapping of the required phase to the POs
pProgress
=
Extra_ProgressBarStart
(
stdout
,
Abc_NtkCoNum
(
pNtk
)
);
Abc_NtkForEachCo
(
pNtk
,
pNode
,
i
)
Mio_Library_t
*
pLib
=
(
Mio_Library_t
*
)
Abc_FrameReadLibGen
();
Mio_Gate_t
*
pRoot
;
Map_Super_t
**
ppFanins
;
Abc_Obj_t
*
pNodeNew
,
*
pNodeFanin
;
int
nFanins
,
Number
,
i
;
// get the parameters of the supergate
pRoot
=
Map_SuperReadRoot
(
pSuper
);
if
(
pRoot
==
NULL
)
{
Extra_ProgressBarUpdate
(
pProgress
,
i
,
NULL
);
pNodeMap
=
Map_ManReadOutputs
(
pMan
)[
i
];
pNodeNew
=
Abc_NodeFromMap_rec
(
pNtkNew
,
Map_Regular
(
pNodeMap
),
!
Map_IsComplement
(
pNodeMap
)
);
assert
(
!
Abc_ObjIsComplement
(
pNodeNew
)
);
Abc_ObjAddFanin
(
pNode
->
pCopy
,
pNodeNew
);
Number
=
Map_SuperReadNum
(
pSuper
);
if
(
Number
<
nNodePis
)
{
return
pNodePis
[
Number
];
}
else
{
// assert( 0 );
/* It might happen that a super gate with 5 inputs is constructed that
* actually depends only on the first four variables; i.e the fifth is a
* don't care -- in that case we connect constant node for the fifth
* (since the cut only has 4 variables). An interesting question is what
* if the first variable (and not the fifth one is the redundant one;
* can that happen?) */
return
Abc_NtkCreateNodeConst0
(
pNtkNew
);
}
}
Extra_ProgressBarStop
(
pProgress
);
// decouple the PO driver nodes to reduce the number of levels
nDupGates
=
Abc_NtkLogicMakeSimpleCos
(
pNtkNew
,
1
);
// if ( nDupGates && Map_ManReadVerbose(pMan) )
// printf( "Duplicated %d gates to decouple the CO drivers.\n", nDupGates );
return
pNtkNew
;
}
/**Function*************************************************************
Synopsis [Constructs the nodes corrresponding to one node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Obj_t
*
Abc_NodeFromMap_rec
(
Abc_Ntk_t
*
pNtkNew
,
Map_Node_t
*
pNodeMap
,
int
fPhase
)
{
Abc_Obj_t
*
pNodeNew
,
*
pNodeInv
;
pRoot
=
Mio_LibraryReadGateByName
(
pLib
,
Mio_GateReadName
(
pRoot
),
NULL
);
// check the case of constant node
if
(
Map_NodeIsConst
(
pNodeMap
)
)
// get information about the fanins of the supergate
nFanins
=
Map_SuperReadFaninNum
(
pSuper
);
ppFanins
=
Map_SuperReadFanins
(
pSuper
);
// create a new node with these fanins
pNodeNew
=
Abc_NtkCreateNode
(
pNtkNew
);
for
(
i
=
0
;
i
<
nFanins
;
i
++
)
{
pNodeNew
=
fPhase
?
Abc_NtkCreateNodeConst1
(
pNtkNew
)
:
Abc_NtkCreateNodeConst0
(
pNtkNew
);
if
(
pNodeNew
->
pData
==
NULL
)
printf
(
"Error creating mapped network: Library does not have a constant %d gate.
\n
"
,
fPhase
);
return
pNodeNew
;
pNodeFanin
=
Abc_NodeFromMapSuper_rec
(
pNtkNew
,
pNodeMap
,
ppFanins
[
i
],
pNodePis
,
nNodePis
);
Abc_ObjAddFanin
(
pNodeNew
,
pNodeFanin
);
}
// check if the phase is already implemented
pNodeNew
=
(
Abc_Obj_t
*
)
Map_NodeReadData
(
pNodeMap
,
fPhase
);
if
(
pNodeNew
)
return
pNodeNew
;
// implement the node if the best cut is assigned
if
(
Map_NodeReadCutBest
(
pNodeMap
,
fPhase
)
!=
NULL
)
return
Abc_NodeFromMapPhase_rec
(
pNtkNew
,
pNodeMap
,
fPhase
);
// if the cut is not assigned, implement the node
assert
(
Map_NodeReadCutBest
(
pNodeMap
,
!
fPhase
)
!=
NULL
||
Map_NodeIsConst
(
pNodeMap
)
);
pNodeNew
=
Abc_NodeFromMapPhase_rec
(
pNtkNew
,
pNodeMap
,
!
fPhase
);
// add the inverter
pNodeInv
=
Abc_NtkCreateNode
(
pNtkNew
);
Abc_ObjAddFanin
(
pNodeInv
,
pNodeNew
);
pNodeInv
->
pData
=
Mio_LibraryReadInv
(
Map_ManReadGenLib
(
Map_NodeReadMan
(
pNodeMap
)));
// set the inverter
Map_NodeSetData
(
pNodeMap
,
fPhase
,
(
char
*
)
pNodeInv
);
return
pNodeInv
;
pNodeNew
->
pData
=
pRoot
;
return
pNodeNew
;
}
/**Function*************************************************************
Synopsis [Constructs the nodes corrresponding to one node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Obj_t
*
Abc_NodeFromMapPhase_rec
(
Abc_Ntk_t
*
pNtkNew
,
Map_Node_t
*
pNodeMap
,
int
fPhase
)
{
Abc_Obj_t
*
pNodePIs
[
10
];
...
...
@@ -417,67 +382,90 @@ Abc_Obj_t * Abc_NodeFromMapPhase_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap
Map_NodeSetData
(
pNodeMap
,
fPhase
,
(
char
*
)
pNodeNew
);
return
pNodeNew
;
}
Abc_Obj_t
*
Abc_NodeFromMap_rec
(
Abc_Ntk_t
*
pNtkNew
,
Map_Node_t
*
pNodeMap
,
int
fPhase
)
{
Abc_Obj_t
*
pNodeNew
,
*
pNodeInv
;
/**Function*************************************************************
// check the case of constant node
if
(
Map_NodeIsConst
(
pNodeMap
)
)
{
pNodeNew
=
fPhase
?
Abc_NtkCreateNodeConst1
(
pNtkNew
)
:
Abc_NtkCreateNodeConst0
(
pNtkNew
);
if
(
pNodeNew
->
pData
==
NULL
)
printf
(
"Error creating mapped network: Library does not have a constant %d gate.
\n
"
,
fPhase
);
return
pNodeNew
;
}
Synopsis [Constructs the nodes corrresponding to one supergate.]
// check if the phase is already implemented
pNodeNew
=
(
Abc_Obj_t
*
)
Map_NodeReadData
(
pNodeMap
,
fPhase
);
if
(
pNodeNew
)
return
pNodeNew
;
Description []
SideEffects []
// implement the node if the best cut is assigned
if
(
Map_NodeReadCutBest
(
pNodeMap
,
fPhase
)
!=
NULL
)
return
Abc_NodeFromMapPhase_rec
(
pNtkNew
,
pNodeMap
,
fPhase
);
SeeAlso []
// if the cut is not assigned, implement the node
assert
(
Map_NodeReadCutBest
(
pNodeMap
,
!
fPhase
)
!=
NULL
||
Map_NodeIsConst
(
pNodeMap
)
);
pNodeNew
=
Abc_NodeFromMapPhase_rec
(
pNtkNew
,
pNodeMap
,
!
fPhase
);
***********************************************************************/
Abc_Obj_t
*
Abc_NodeFromMapSuper_rec
(
Abc_Ntk_t
*
pNtkNew
,
Map_Node_t
*
pNodeMap
,
Map_Super_t
*
pSuper
,
Abc_Obj_t
*
pNodePis
[],
int
nNodePis
)
{
Mio_Library_t
*
pLib
=
(
Mio_Library_t
*
)
Abc_FrameReadLibGen
();
Mio_Gate_t
*
pRoot
;
Map_Super_t
**
ppFanins
;
Abc_Obj_t
*
pNodeNew
,
*
pNodeFanin
;
int
nFanins
,
Number
,
i
;
// add the inverter
pNodeInv
=
Abc_NtkCreateNode
(
pNtkNew
);
Abc_ObjAddFanin
(
pNodeInv
,
pNodeNew
);
pNodeInv
->
pData
=
Mio_LibraryReadInv
(
Map_ManReadGenLib
(
Map_NodeReadMan
(
pNodeMap
)));
// get the parameters of the supergate
pRoot
=
Map_SuperReadRoot
(
pSuper
);
if
(
pRoot
==
NULL
)
// set the inverter
Map_NodeSetData
(
pNodeMap
,
fPhase
,
(
char
*
)
pNodeInv
);
return
pNodeInv
;
}
Abc_Ntk_t
*
Abc_NtkFromMap
(
Map_Man_t
*
pMan
,
Abc_Ntk_t
*
pNtk
)
{
Abc_Ntk_t
*
pNtkNew
;
Map_Node_t
*
pNodeMap
;
Abc_Obj_t
*
pNode
,
*
pNodeNew
;
int
i
,
nDupGates
;
assert
(
Map_ManReadBufNum
(
pMan
)
==
pNtk
->
nBarBufs
);
// create the new network
pNtkNew
=
Abc_NtkStartFrom
(
pNtk
,
ABC_NTK_LOGIC
,
ABC_FUNC_MAP
);
// make the mapper point to the new network
Map_ManCleanData
(
pMan
);
Abc_NtkForEachCi
(
pNtk
,
pNode
,
i
)
{
Number
=
Map_SuperReadNum
(
pSuper
);
if
(
Number
<
nNodePis
)
{
return
pNodePis
[
Number
];
}
else
{
// assert( 0 );
/* It might happen that a super gate with 5 inputs is constructed that
* actually depends only on the first four variables; i.e the fifth is a
* don't care -- in that case we connect constant node for the fifth
* (since the cut only has 4 variables). An interesting question is what
* if the first variable (and not the fifth one is the redundant one;
* can that happen?) */
return
Abc_NtkCreateNodeConst0
(
pNtkNew
);
}
if
(
i
>=
Abc_NtkCiNum
(
pNtk
)
-
pNtk
->
nBarBufs
)
break
;
Map_NodeSetData
(
Map_ManReadInputs
(
pMan
)[
i
],
1
,
(
char
*
)
pNode
->
pCopy
);
}
pRoot
=
Mio_LibraryReadGateByName
(
pLib
,
Mio_GateReadName
(
pRoot
),
NULL
);
// get information about the fanins of the supergate
nFanins
=
Map_SuperReadFaninNum
(
pSuper
);
ppFanins
=
Map_SuperReadFanins
(
pSuper
);
// create a new node with these fanins
pNodeNew
=
Abc_NtkCreateNode
(
pNtkNew
);
for
(
i
=
0
;
i
<
nFanins
;
i
++
)
Abc_NtkForEachCi
(
pNtk
,
pNode
,
i
)
{
pNodeFanin
=
Abc_NodeFromMapSuper_rec
(
pNtkNew
,
pNodeMap
,
ppFanins
[
i
],
pNodePis
,
nNodePis
);
Abc_ObjAddFanin
(
pNodeNew
,
pNodeFanin
);
if
(
i
<
Abc_NtkCiNum
(
pNtk
)
-
pNtk
->
nBarBufs
)
continue
;
Map_NodeSetData
(
Map_ManReadBufs
(
pMan
)[
i
-
(
Abc_NtkCiNum
(
pNtk
)
-
pNtk
->
nBarBufs
)],
1
,
(
char
*
)
pNode
->
pCopy
);
}
pNodeNew
->
pData
=
pRoot
;
return
pNodeNew
;
// assign the mapping of the required phase to the POs
Abc_NtkForEachCo
(
pNtk
,
pNode
,
i
)
{
if
(
i
<
Abc_NtkCoNum
(
pNtk
)
-
pNtk
->
nBarBufs
)
continue
;
pNodeMap
=
Map_ManReadBufDriver
(
pMan
,
i
-
(
Abc_NtkCoNum
(
pNtk
)
-
pNtk
->
nBarBufs
)
);
pNodeNew
=
Abc_NodeFromMap_rec
(
pNtkNew
,
Map_Regular
(
pNodeMap
),
!
Map_IsComplement
(
pNodeMap
)
);
assert
(
!
Abc_ObjIsComplement
(
pNodeNew
)
);
Abc_ObjAddFanin
(
pNode
->
pCopy
,
pNodeNew
);
}
Abc_NtkForEachCo
(
pNtk
,
pNode
,
i
)
{
if
(
i
>=
Abc_NtkCoNum
(
pNtk
)
-
pNtk
->
nBarBufs
)
break
;
pNodeMap
=
Map_ManReadOutputs
(
pMan
)[
i
];
pNodeNew
=
Abc_NodeFromMap_rec
(
pNtkNew
,
Map_Regular
(
pNodeMap
),
!
Map_IsComplement
(
pNodeMap
)
);
assert
(
!
Abc_ObjIsComplement
(
pNodeNew
)
);
Abc_ObjAddFanin
(
pNode
->
pCopy
,
pNodeNew
);
}
// decouple the PO driver nodes to reduce the number of levels
nDupGates
=
Abc_NtkLogicMakeSimpleCos
(
pNtkNew
,
1
);
// if ( nDupGates && Map_ManReadVerbose(pMan) )
// printf( "Duplicated %d gates to decouple the CO drivers.\n", nDupGates );
return
pNtkNew
;
}
/**Function*************************************************************
Synopsis [Interface with the mapping package.]
...
...
src/map/mapper/mapper.h
View file @
6f17c44e
...
...
@@ -82,8 +82,11 @@ extern void Map_ManPrintTimeStats( Map_Man_t * p );
extern
void
Map_ManPrintStatsToFile
(
char
*
pName
,
float
Area
,
float
Delay
,
abctime
Time
);
extern
int
Map_ManReadInputNum
(
Map_Man_t
*
p
);
extern
int
Map_ManReadOutputNum
(
Map_Man_t
*
p
);
extern
int
Map_ManReadBufNum
(
Map_Man_t
*
p
);
extern
Map_Node_t
**
Map_ManReadInputs
(
Map_Man_t
*
p
);
extern
Map_Node_t
**
Map_ManReadOutputs
(
Map_Man_t
*
p
);
extern
Map_Node_t
**
Map_ManReadBufs
(
Map_Man_t
*
p
);
extern
Map_Node_t
*
Map_ManReadBufDriver
(
Map_Man_t
*
p
,
int
i
);
extern
Map_Node_t
*
Map_ManReadConst1
(
Map_Man_t
*
p
);
extern
Map_Time_t
*
Map_ManReadInputArrivals
(
Map_Man_t
*
p
);
extern
Mio_Library_t
*
Map_ManReadGenLib
(
Map_Man_t
*
p
);
...
...
@@ -121,6 +124,7 @@ extern void Map_NodeSetSwitching( Map_Node_t * p, float Switching );
extern
int
Map_NodeIsConst
(
Map_Node_t
*
p
);
extern
int
Map_NodeIsVar
(
Map_Node_t
*
p
);
extern
int
Map_NodeIsBuf
(
Map_Node_t
*
p
);
extern
int
Map_NodeIsAnd
(
Map_Node_t
*
p
);
extern
int
Map_NodeComparePhase
(
Map_Node_t
*
p1
,
Map_Node_t
*
p2
);
...
...
@@ -150,9 +154,7 @@ extern Map_Time_t Map_SuperLibReadDelayInv( Map_SuperLib_t * p );
extern
int
Map_SuperLibReadVarsMax
(
Map_SuperLib_t
*
p
);
extern
Map_Node_t
*
Map_NodeAnd
(
Map_Man_t
*
p
,
Map_Node_t
*
p1
,
Map_Node_t
*
p2
);
extern
Map_Node_t
*
Map_NodeOr
(
Map_Man_t
*
p
,
Map_Node_t
*
p1
,
Map_Node_t
*
p2
);
extern
Map_Node_t
*
Map_NodeExor
(
Map_Man_t
*
p
,
Map_Node_t
*
p1
,
Map_Node_t
*
p2
);
extern
Map_Node_t
*
Map_NodeMux
(
Map_Man_t
*
p
,
Map_Node_t
*
pNode
,
Map_Node_t
*
pNodeT
,
Map_Node_t
*
pNodeE
);
extern
Map_Node_t
*
Map_NodeBuf
(
Map_Man_t
*
p
,
Map_Node_t
*
p1
);
extern
void
Map_NodeSetChoice
(
Map_Man_t
*
pMan
,
Map_Node_t
*
pNodeOld
,
Map_Node_t
*
pNodeNew
);
/*=== resmCanon.c =============================================================*/
...
...
src/map/mapper/mapperCore.c
View file @
6f17c44e
...
...
@@ -57,8 +57,6 @@ int Map_Mapping( Map_Man_t * p )
//////////////////////////////////////////////////////////////////////
// perform pre-mapping computations
// collect the nodes reachable from POs in the DFS order (including the choices)
p
->
vAnds
=
Map_MappingDfs
(
p
,
1
);
if
(
p
->
fVerbose
)
Map_MappingReportChoices
(
p
);
Map_MappingSetChoiceLevels
(
p
);
// should always be called before mapping!
...
...
@@ -84,12 +82,12 @@ int Map_Mapping( Map_Man_t * p )
p
->
timeMatch
=
Abc_Clock
()
-
clk
;
// compute the references and collect the nodes used in the mapping
Map_MappingSetRefs
(
p
);
p
->
AreaBase
=
Map_MappingGetArea
(
p
,
p
->
vMapping
);
p
->
AreaBase
=
Map_MappingGetArea
(
p
);
if
(
p
->
fVerbose
)
{
printf
(
"Delay : %s = %8.2f Flow = %11.1f Area = %11.1f %4.1f %% "
,
fShowSwitching
?
"Switch"
:
"Delay"
,
fShowSwitching
?
Map_MappingGetSwitching
(
p
,
p
->
vMapping
)
:
p
->
fRequiredGlo
,
fShowSwitching
?
Map_MappingGetSwitching
(
p
)
:
p
->
fRequiredGlo
,
Map_MappingGetAreaFlow
(
p
),
p
->
AreaBase
,
0
.
0
);
ABC_PRT
(
"Time"
,
p
->
timeMatch
);
}
...
...
@@ -114,12 +112,12 @@ ABC_PRT( "Time", p->timeMatch );
Map_MappingMatches
(
p
);
// compute the references and collect the nodes used in the mapping
Map_MappingSetRefs
(
p
);
p
->
AreaFinal
=
Map_MappingGetArea
(
p
,
p
->
vMapping
);
p
->
AreaFinal
=
Map_MappingGetArea
(
p
);
if
(
p
->
fVerbose
)
{
printf
(
"AreaFlow : %s = %8.2f Flow = %11.1f Area = %11.1f %4.1f %% "
,
fShowSwitching
?
"Switch"
:
"Delay"
,
fShowSwitching
?
Map_MappingGetSwitching
(
p
,
p
->
vMapping
)
:
p
->
fRequiredGlo
,
fShowSwitching
?
Map_MappingGetSwitching
(
p
)
:
p
->
fRequiredGlo
,
Map_MappingGetAreaFlow
(
p
),
p
->
AreaFinal
,
100
.
0
*
(
p
->
AreaBase
-
p
->
AreaFinal
)
/
p
->
AreaBase
);
ABC_PRT
(
"Time"
,
Abc_Clock
()
-
clk
);
...
...
@@ -140,12 +138,12 @@ ABC_PRT( "Time", Abc_Clock() - clk );
Map_MappingMatches
(
p
);
// compute the references and collect the nodes used in the mapping
Map_MappingSetRefs
(
p
);
p
->
AreaFinal
=
Map_MappingGetArea
(
p
,
p
->
vMapping
);
p
->
AreaFinal
=
Map_MappingGetArea
(
p
);
if
(
p
->
fVerbose
)
{
printf
(
"Area : %s = %8.2f Flow = %11.1f Area = %11.1f %4.1f %% "
,
fShowSwitching
?
"Switch"
:
"Delay"
,
fShowSwitching
?
Map_MappingGetSwitching
(
p
,
p
->
vMapping
)
:
p
->
fRequiredGlo
,
fShowSwitching
?
Map_MappingGetSwitching
(
p
)
:
p
->
fRequiredGlo
,
0
.
0
,
p
->
AreaFinal
,
100
.
0
*
(
p
->
AreaBase
-
p
->
AreaFinal
)
/
p
->
AreaBase
);
ABC_PRT
(
"Time"
,
Abc_Clock
()
-
clk
);
...
...
@@ -166,12 +164,12 @@ ABC_PRT( "Time", Abc_Clock() - clk );
Map_MappingMatches
(
p
);
// compute the references and collect the nodes used in the mapping
Map_MappingSetRefs
(
p
);
p
->
AreaFinal
=
Map_MappingGetArea
(
p
,
p
->
vMapping
);
p
->
AreaFinal
=
Map_MappingGetArea
(
p
);
if
(
p
->
fVerbose
)
{
printf
(
"Area : %s = %8.2f Flow = %11.1f Area = %11.1f %4.1f %% "
,
fShowSwitching
?
"Switch"
:
"Delay"
,
fShowSwitching
?
Map_MappingGetSwitching
(
p
,
p
->
vMapping
)
:
p
->
fRequiredGlo
,
fShowSwitching
?
Map_MappingGetSwitching
(
p
)
:
p
->
fRequiredGlo
,
0
.
0
,
p
->
AreaFinal
,
100
.
0
*
(
p
->
AreaBase
-
p
->
AreaFinal
)
/
p
->
AreaBase
);
ABC_PRT
(
"Time"
,
Abc_Clock
()
-
clk
);
...
...
@@ -192,12 +190,12 @@ ABC_PRT( "Time", Abc_Clock() - clk );
Map_MappingMatches
(
p
);
// compute the references and collect the nodes used in the mapping
Map_MappingSetRefs
(
p
);
p
->
AreaFinal
=
Map_MappingGetArea
(
p
,
p
->
vMapping
);
p
->
AreaFinal
=
Map_MappingGetArea
(
p
);
if
(
p
->
fVerbose
)
{
printf
(
"Switching: %s = %8.2f Flow = %11.1f Area = %11.1f %4.1f %% "
,
fShowSwitching
?
"Switch"
:
"Delay"
,
fShowSwitching
?
Map_MappingGetSwitching
(
p
,
p
->
vMapping
)
:
p
->
fRequiredGlo
,
fShowSwitching
?
Map_MappingGetSwitching
(
p
)
:
p
->
fRequiredGlo
,
0
.
0
,
p
->
AreaFinal
,
100
.
0
*
(
p
->
AreaBase
-
p
->
AreaFinal
)
/
p
->
AreaBase
);
ABC_PRT
(
"Time"
,
Abc_Clock
()
-
clk
);
...
...
@@ -210,12 +208,12 @@ ABC_PRT( "Time", Abc_Clock() - clk );
Map_MappingMatches
(
p
);
// compute the references and collect the nodes used in the mapping
Map_MappingSetRefs
(
p
);
p
->
AreaFinal
=
Map_MappingGetArea
(
p
,
p
->
vMapping
);
p
->
AreaFinal
=
Map_MappingGetArea
(
p
);
if
(
p
->
fVerbose
)
{
printf
(
"Switching: %s = %8.2f Flow = %11.1f Area = %11.1f %4.1f %% "
,
fShowSwitching
?
"Switch"
:
"Delay"
,
fShowSwitching
?
Map_MappingGetSwitching
(
p
,
p
->
vMapping
)
:
p
->
fRequiredGlo
,
fShowSwitching
?
Map_MappingGetSwitching
(
p
)
:
p
->
fRequiredGlo
,
0
.
0
,
p
->
AreaFinal
,
100
.
0
*
(
p
->
AreaBase
-
p
->
AreaFinal
)
/
p
->
AreaBase
);
ABC_PRT
(
"Time"
,
Abc_Clock
()
-
clk
);
...
...
src/map/mapper/mapperCreate.c
View file @
6f17c44e
...
...
@@ -27,7 +27,6 @@ ABC_NAMESPACE_IMPL_START
static
void
Map_TableCreate
(
Map_Man_t
*
p
);
static
void
Map_TableResize
(
Map_Man_t
*
p
);
static
Map_Node_t
*
Map_TableLookup
(
Map_Man_t
*
p
,
Map_Node_t
*
p1
,
Map_Node_t
*
p2
);
// hash key for the structural hash table
static
inline
unsigned
Map_HashKey2
(
Map_Node_t
*
p0
,
Map_Node_t
*
p1
,
int
TableSize
)
{
return
(
unsigned
)(((
ABC_PTRUINT_T
)(
p0
)
+
(
ABC_PTRUINT_T
)(
p1
)
*
12582917
)
%
TableSize
);
}
...
...
@@ -49,8 +48,11 @@ static inline unsigned Map_HashKey2( Map_Node_t * p0, Map_Node_t * p1, int Table
***********************************************************************/
int
Map_ManReadInputNum
(
Map_Man_t
*
p
)
{
return
p
->
nInputs
;
}
int
Map_ManReadOutputNum
(
Map_Man_t
*
p
)
{
return
p
->
nOutputs
;
}
int
Map_ManReadBufNum
(
Map_Man_t
*
p
)
{
return
Map_NodeVecReadSize
(
p
->
vMapBufs
);
}
Map_Node_t
**
Map_ManReadInputs
(
Map_Man_t
*
p
)
{
return
p
->
pInputs
;
}
Map_Node_t
**
Map_ManReadOutputs
(
Map_Man_t
*
p
)
{
return
p
->
pOutputs
;
}
Map_Node_t
**
Map_ManReadBufs
(
Map_Man_t
*
p
)
{
return
Map_NodeVecReadArray
(
p
->
vMapBufs
);
}
Map_Node_t
*
Map_ManReadBufDriver
(
Map_Man_t
*
p
,
int
i
)
{
return
Map_ManReadBufs
(
p
)[
i
]
->
p1
;
}
Map_Node_t
*
Map_ManReadConst1
(
Map_Man_t
*
p
)
{
return
p
->
pConst1
;
}
Map_Time_t
*
Map_ManReadInputArrivals
(
Map_Man_t
*
p
)
{
return
p
->
pInputArrivals
;
}
Map_Time_t
*
Map_ManReadOutputRequireds
(
Map_Man_t
*
p
)
{
return
p
->
pOutputRequireds
;
}
...
...
@@ -109,7 +111,8 @@ void Map_NodeSetSwitching( Map_Node_t * p, float Switching ) { p-
***********************************************************************/
int
Map_NodeIsConst
(
Map_Node_t
*
p
)
{
return
(
Map_Regular
(
p
))
->
Num
==
-
1
;
}
int
Map_NodeIsVar
(
Map_Node_t
*
p
)
{
return
(
Map_Regular
(
p
))
->
p1
==
NULL
&&
(
Map_Regular
(
p
))
->
Num
>=
0
;
}
int
Map_NodeIsAnd
(
Map_Node_t
*
p
)
{
return
(
Map_Regular
(
p
))
->
p1
!=
NULL
;
}
int
Map_NodeIsBuf
(
Map_Node_t
*
p
)
{
return
(
Map_Regular
(
p
))
->
p1
!=
NULL
&&
(
Map_Regular
(
p
))
->
p2
==
NULL
;
}
int
Map_NodeIsAnd
(
Map_Node_t
*
p
)
{
return
(
Map_Regular
(
p
))
->
p1
!=
NULL
&&
(
Map_Regular
(
p
))
->
p2
!=
NULL
;
}
int
Map_NodeComparePhase
(
Map_Node_t
*
p1
,
Map_Node_t
*
p2
)
{
assert
(
!
Map_IsComplement
(
p1
)
);
assert
(
!
Map_IsComplement
(
p2
)
);
return
p1
->
fInv
^
p2
->
fInv
;
}
/**Function*************************************************************
...
...
@@ -214,9 +217,8 @@ Map_Man_t * Map_ManCreate( int nInputs, int nOutputs, int fVerbose )
p
->
nNodes
=
-
1
;
// create the constant node
p
->
pConst1
=
Map_NodeCreate
(
p
,
NULL
,
NULL
);
p
->
vNodesAll
=
Map_NodeVecAlloc
(
100
);
p
->
vNodesTemp
=
Map_NodeVecAlloc
(
100
);
p
->
vMapping
=
Map_NodeVecAlloc
(
100
);
p
->
vMapObjs
=
Map_NodeVecAlloc
(
100
);
p
->
vMapBufs
=
Map_NodeVecAlloc
(
100
);
p
->
vVisited
=
Map_NodeVecAlloc
(
100
);
// create the PI nodes
...
...
@@ -246,19 +248,12 @@ Map_Man_t * Map_ManCreate( int nInputs, int nOutputs, int fVerbose )
void
Map_ManFree
(
Map_Man_t
*
p
)
{
// int i;
// for ( i = 0; i < p->v
NodesAll
->nSize; i++ )
// Map_NodeVecFree( p->v
NodesAll
->pArray[i]->vFanouts );
// for ( i = 0; i < p->v
MapObjs
->nSize; i++ )
// Map_NodeVecFree( p->v
MapObjs
->pArray[i]->vFanouts );
// Map_NodeVecFree( p->pConst1->vFanouts );
if
(
p
->
vAnds
)
Map_NodeVecFree
(
p
->
vAnds
);
if
(
p
->
vNodesAll
)
Map_NodeVecFree
(
p
->
vNodesAll
);
if
(
p
->
vNodesTemp
)
Map_NodeVecFree
(
p
->
vNodesTemp
);
if
(
p
->
vMapping
)
Map_NodeVecFree
(
p
->
vMapping
);
if
(
p
->
vVisited
)
Map_NodeVecFree
(
p
->
vVisited
);
Map_NodeVecFree
(
p
->
vMapObjs
);
Map_NodeVecFree
(
p
->
vMapBufs
);
Map_NodeVecFree
(
p
->
vVisited
);
if
(
p
->
uCanons
)
ABC_FREE
(
p
->
uCanons
);
if
(
p
->
uPhases
)
ABC_FREE
(
p
->
uPhases
);
if
(
p
->
pCounters
)
ABC_FREE
(
p
->
pCounters
);
...
...
@@ -291,10 +286,10 @@ void Map_ManCreateNodeDelays( Map_Man_t * p, int LogFan )
Map_Node_t
*
pNode
;
int
k
;
assert
(
p
->
pNodeDelays
==
NULL
);
p
->
pNodeDelays
=
ABC_CALLOC
(
float
,
p
->
v
NodesAll
->
nSize
);
for
(
k
=
0
;
k
<
p
->
v
NodesAll
->
nSize
;
k
++
)
p
->
pNodeDelays
=
ABC_CALLOC
(
float
,
p
->
v
MapObjs
->
nSize
);
for
(
k
=
0
;
k
<
p
->
v
MapObjs
->
nSize
;
k
++
)
{
pNode
=
p
->
v
NodesAll
->
pArray
[
k
];
pNode
=
p
->
v
MapObjs
->
pArray
[
k
];
if
(
pNode
->
nRefs
==
0
)
continue
;
p
->
pNodeDelays
[
k
]
=
0
.
014426
*
LogFan
*
p
->
pSuperLib
->
tDelayInv
.
Worst
*
log
(
(
double
)
pNode
->
nRefs
);
// 1.4426 = 1/ln(2)
...
...
@@ -383,7 +378,7 @@ Map_Node_t * Map_NodeCreate( Map_Man_t * p, Map_Node_t * p1, Map_Node_t * p2 )
// pNode->vFanouts = Map_NodeVecAlloc( 5 );
// store this node in the internal array
if
(
pNode
->
Num
>=
0
)
Map_NodeVecPush
(
p
->
v
NodesAll
,
pNode
);
Map_NodeVecPush
(
p
->
v
MapObjs
,
pNode
);
else
pNode
->
fInv
=
1
;
// set the level of this node
...
...
@@ -392,10 +387,20 @@ Map_Node_t * Map_NodeCreate( Map_Man_t * p, Map_Node_t * p1, Map_Node_t * p2 )
#ifdef MAP_ALLOCATE_FANOUT
// create the fanout info
Map_NodeAddFaninFanout
(
Map_Regular
(
p1
),
pNode
);
if
(
p2
)
Map_NodeAddFaninFanout
(
Map_Regular
(
p2
),
pNode
);
#endif
pNode
->
Level
=
1
+
MAP_MAX
(
Map_Regular
(
pNode
->
p1
)
->
Level
,
Map_Regular
(
pNode
->
p2
)
->
Level
);
pNode
->
fInv
=
Map_NodeIsSimComplement
(
p1
)
&
Map_NodeIsSimComplement
(
p2
);
if
(
p2
)
{
pNode
->
Level
=
1
+
MAP_MAX
(
Map_Regular
(
pNode
->
p1
)
->
Level
,
Map_Regular
(
pNode
->
p2
)
->
Level
);
pNode
->
fInv
=
Map_NodeIsSimComplement
(
p1
)
&
Map_NodeIsSimComplement
(
p2
);
}
else
{
pNode
->
Level
=
Map_Regular
(
pNode
->
p1
)
->
Level
;
pNode
->
fInv
=
Map_NodeIsSimComplement
(
p1
);
}
}
// reference the inputs (will be used to compute the number of fanouts)
if
(
p1
)
Map_NodeRef
(
p1
);
...
...
@@ -439,7 +444,7 @@ void Map_TableCreate( Map_Man_t * pMan )
SeeAlso []
***********************************************************************/
Map_Node_t
*
Map_
TableLookup
(
Map_Man_t
*
pMan
,
Map_Node_t
*
p1
,
Map_Node_t
*
p2
)
Map_Node_t
*
Map_
NodeAnd
(
Map_Man_t
*
pMan
,
Map_Node_t
*
p1
,
Map_Node_t
*
p2
)
{
Map_Node_t
*
pEnt
;
unsigned
Key
;
...
...
@@ -544,70 +549,15 @@ clk = Abc_Clock();
SeeAlso []
***********************************************************************/
Map_Node_t
*
Map_NodeAnd
(
Map_Man_t
*
p
,
Map_Node_t
*
p1
,
Map_Node_t
*
p2
)
{
Map_Node_t
*
pNode
;
pNode
=
Map_TableLookup
(
p
,
p1
,
p2
);
return
pNode
;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Map_Node_t
*
Map_NodeOr
(
Map_Man_t
*
p
,
Map_Node_t
*
p1
,
Map_Node_t
*
p2
)
Map_Node_t
*
Map_NodeBuf
(
Map_Man_t
*
p
,
Map_Node_t
*
p1
)
{
Map_Node_t
*
pNode
;
pNode
=
Map_Not
(
Map_TableLookup
(
p
,
Map_Not
(
p1
),
Map_Not
(
p2
)
)
);
Map_Node_t
*
pNode
=
Map_NodeCreate
(
p
,
p1
,
NULL
)
;
Map_NodeVecPush
(
p
->
vMapBufs
,
pNode
);
return
pNode
;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Map_Node_t
*
Map_NodeExor
(
Map_Man_t
*
p
,
Map_Node_t
*
p1
,
Map_Node_t
*
p2
)
{
return
Map_NodeMux
(
p
,
p1
,
Map_Not
(
p2
),
p2
);
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Map_Node_t
*
Map_NodeMux
(
Map_Man_t
*
p
,
Map_Node_t
*
pC
,
Map_Node_t
*
pT
,
Map_Node_t
*
pE
)
{
Map_Node_t
*
pAnd1
,
*
pAnd2
,
*
pRes
;
pAnd1
=
Map_TableLookup
(
p
,
pC
,
pT
);
pAnd2
=
Map_TableLookup
(
p
,
Map_Not
(
pC
),
pE
);
pRes
=
Map_NodeOr
(
p
,
pAnd1
,
pAnd2
);
return
pRes
;
}
/**Function*************************************************************
Synopsis [Sets the node to be equivalent to the given one.]
Description [This procedure is a work-around for the equivalence check.
...
...
src/map/mapper/mapperCut.c
View file @
6f17c44e
...
...
@@ -88,6 +88,51 @@ static unsigned Map_CutComputeTruth( Map_Man_t * p, Map_Cut_t * pCut, Ma
/**Function*************************************************************
Synopsis [Counts all the cuts.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int
Map_MappingCountAllCuts
(
Map_Man_t
*
pMan
)
{
Map_Node_t
*
pNode
;
Map_Cut_t
*
pCut
;
int
i
,
nCuts
;
// int nCuts55 = 0, nCuts5x = 0, nCuts4x = 0, nCuts3x = 0;
// int pCounts[7] = {0};
nCuts
=
0
;
for
(
i
=
0
;
i
<
pMan
->
nBins
;
i
++
)
for
(
pNode
=
pMan
->
pBins
[
i
];
pNode
;
pNode
=
pNode
->
pNext
)
for
(
pCut
=
pNode
->
pCuts
;
pCut
;
pCut
=
pCut
->
pNext
)
if
(
pCut
->
nLeaves
>
1
)
// skip the elementary cuts
{
nCuts
++
;
/*
if ( Map_CutRegular(pCut->pOne)->nLeaves == 5 && Map_CutRegular(pCut->pTwo)->nLeaves == 5 )
nCuts55++;
if ( Map_CutRegular(pCut->pOne)->nLeaves == 5 || Map_CutRegular(pCut->pTwo)->nLeaves == 5 )
nCuts5x++;
else if ( Map_CutRegular(pCut->pOne)->nLeaves == 4 || Map_CutRegular(pCut->pTwo)->nLeaves == 4 )
nCuts4x++;
else if ( Map_CutRegular(pCut->pOne)->nLeaves == 3 || Map_CutRegular(pCut->pTwo)->nLeaves == 3 )
nCuts3x++;
*/
// pCounts[ Map_CutRegular(pCut->pOne)->nLeaves ]++;
// pCounts[ Map_CutRegular(pCut->pTwo)->nLeaves ]++;
}
// printf( "Total cuts = %6d. 55 = %6d. 5x = %6d. 4x = %6d. 3x = %6d.\n", nCuts, nCuts55, nCuts5x, nCuts4x, nCuts3x );
// printf( "Total cuts = %6d. 6= %6d. 5= %6d. 4= %6d. 3= %6d. 2= %6d. 1= %6d.\n",
// nCuts, pCounts[6], pCounts[5], pCounts[4], pCounts[3], pCounts[2], pCounts[1] );
return
nCuts
;
}
/**Function*************************************************************
Synopsis [Computes the cuts for each node in the object graph.]
Description [The cuts are computed in one sweep over the mapping graph.
...
...
@@ -110,39 +155,44 @@ static unsigned Map_CutComputeTruth( Map_Man_t * p, Map_Cut_t * pCut, Ma
SeeAlso []
***********************************************************************/
void
Map_MappingCutsInput
(
Map_Man_t
*
p
,
Map_Node_t
*
pNode
)
{
Map_Cut_t
*
pCut
;
assert
(
Map_NodeIsVar
(
pNode
)
||
Map_NodeIsBuf
(
pNode
)
);
pCut
=
Map_CutAlloc
(
p
);
pCut
->
nLeaves
=
1
;
pCut
->
ppLeaves
[
0
]
=
pNode
;
pNode
->
pCuts
=
pCut
;
pNode
->
pCutBest
[
0
]
=
NULL
;
// negative polarity is not mapped
pNode
->
pCutBest
[
1
]
=
pCut
;
// positive polarity is a trivial cut
pCut
->
uTruth
=
0xAAAAAAAA
;
// the first variable "1010"
pCut
->
M
[
0
].
AreaFlow
=
0
.
0
;
pCut
->
M
[
1
].
AreaFlow
=
0
.
0
;
}
void
Map_MappingCuts
(
Map_Man_t
*
p
)
{
ProgressBar
*
pProgress
;
Map_CutTable_t
*
pTable
;
Map_Node_t
*
pNode
;
Map_Cut_t
*
pCut
;
int
nCuts
,
nNodes
,
i
;
abctime
clk
=
Abc_Clock
();
// set the elementary cuts for the PI variables
assert
(
p
->
nVarsMax
>
1
&&
p
->
nVarsMax
<
7
);
for
(
i
=
0
;
i
<
p
->
nInputs
;
i
++
)
{
pCut
=
Map_CutAlloc
(
p
);
pCut
->
nLeaves
=
1
;
pCut
->
ppLeaves
[
0
]
=
p
->
pInputs
[
i
];
p
->
pInputs
[
i
]
->
pCuts
=
pCut
;
p
->
pInputs
[
i
]
->
pCutBest
[
0
]
=
NULL
;
// negative polarity is not mapped
p
->
pInputs
[
i
]
->
pCutBest
[
1
]
=
pCut
;
// positive polarity is a trivial cut
pCut
->
uTruth
=
0xAAAAAAAA
;
// the first variable "10101010"
pCut
->
M
[
0
].
AreaFlow
=
0
.
0
;
pCut
->
M
[
1
].
AreaFlow
=
0
.
0
;
}
Map_MappingCutsInput
(
p
,
p
->
pInputs
[
i
]
);
// compute the cuts for the internal nodes
nNodes
=
p
->
v
And
s
->
nSize
;
nNodes
=
p
->
v
MapObj
s
->
nSize
;
pProgress
=
Extra_ProgressBarStart
(
stdout
,
nNodes
);
pTable
=
Map_CutTableStart
(
p
);
for
(
i
=
0
;
i
<
nNodes
;
i
++
)
{
pNode
=
p
->
vAnds
->
pArray
[
i
];
if
(
!
Map_NodeIsAnd
(
pNode
)
)
continue
;
Map_CutCompute
(
p
,
pTable
,
pNode
);
pNode
=
p
->
vMapObjs
->
pArray
[
i
];
if
(
Map_NodeIsBuf
(
pNode
)
)
Map_MappingCutsInput
(
p
,
pNode
);
else
if
(
Map_NodeIsAnd
(
pNode
)
)
Map_CutCompute
(
p
,
pTable
,
pNode
);
else
continue
;
Extra_ProgressBarUpdate
(
pProgress
,
i
,
"Cuts ..."
);
}
Extra_ProgressBarStop
(
pProgress
);
...
...
@@ -679,51 +729,6 @@ int Map_CutBelongsToList( Map_Cut_t * pList, Map_Node_t * ppNodes[], int nNodes
return
0
;
}
/**Function*************************************************************
Synopsis [Counts all the cuts.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int
Map_MappingCountAllCuts
(
Map_Man_t
*
pMan
)
{
Map_Node_t
*
pNode
;
Map_Cut_t
*
pCut
;
int
i
,
nCuts
;
// int nCuts55 = 0, nCuts5x = 0, nCuts4x = 0, nCuts3x = 0;
// int pCounts[7] = {0};
nCuts
=
0
;
for
(
i
=
0
;
i
<
pMan
->
nBins
;
i
++
)
for
(
pNode
=
pMan
->
pBins
[
i
];
pNode
;
pNode
=
pNode
->
pNext
)
for
(
pCut
=
pNode
->
pCuts
;
pCut
;
pCut
=
pCut
->
pNext
)
if
(
pCut
->
nLeaves
>
1
)
// skip the elementary cuts
{
nCuts
++
;
/*
if ( Map_CutRegular(pCut->pOne)->nLeaves == 5 && Map_CutRegular(pCut->pTwo)->nLeaves == 5 )
nCuts55++;
if ( Map_CutRegular(pCut->pOne)->nLeaves == 5 || Map_CutRegular(pCut->pTwo)->nLeaves == 5 )
nCuts5x++;
else if ( Map_CutRegular(pCut->pOne)->nLeaves == 4 || Map_CutRegular(pCut->pTwo)->nLeaves == 4 )
nCuts4x++;
else if ( Map_CutRegular(pCut->pOne)->nLeaves == 3 || Map_CutRegular(pCut->pTwo)->nLeaves == 3 )
nCuts3x++;
*/
// pCounts[ Map_CutRegular(pCut->pOne)->nLeaves ]++;
// pCounts[ Map_CutRegular(pCut->pTwo)->nLeaves ]++;
}
// printf( "Total cuts = %6d. 55 = %6d. 5x = %6d. 4x = %6d. 3x = %6d.\n", nCuts, nCuts55, nCuts5x, nCuts4x, nCuts3x );
// printf( "Total cuts = %6d. 6= %6d. 5= %6d. 4= %6d. 3= %6d. 2= %6d. 1= %6d.\n",
// nCuts, pCounts[6], pCounts[5], pCounts[4], pCounts[3], pCounts[2], pCounts[1] );
return
nCuts
;
}
/**Function*************************************************************
...
...
src/map/mapper/mapperInt.h
View file @
6f17c44e
...
...
@@ -98,10 +98,8 @@ struct Map_ManStruct_t_
int
nOutputs
;
// the number of outputs
int
nNodes
;
// the total number of nodes
Map_Node_t
*
pConst1
;
// the constant 1 node
Map_NodeVec_t
*
vAnds
;
// the array of nodes in the DFS order
Map_NodeVec_t
*
vNodesAll
;
// the array of all nodes
Map_NodeVec_t
*
vNodesTemp
;
// the array of all nodes
Map_NodeVec_t
*
vMapping
;
// the array of internal nodes used in the mapping
Map_NodeVec_t
*
vMapObjs
;
// the array of all nodes
Map_NodeVec_t
*
vMapBufs
;
// the array of all nodes
float
*
pNodeDelays
;
// the array of node delays
// info about the original circuit
...
...
@@ -358,10 +356,6 @@ struct Map_HashEntryStruct_t_
/*=== mapperCanon.c =============================================================*/
/*=== mapperCut.c ===============================================================*/
extern
void
Map_MappingCuts
(
Map_Man_t
*
p
);
extern
int
Map_MappingCountAllCuts
(
Map_Man_t
*
p
);
/*=== mapperCutDcs.c ===============================================================*/
extern
void
Map_ComputeDcs
(
Map_Man_t
*
p
);
extern
unsigned
Map_ComputeIsop_rec
(
Map_Man_t
*
p
,
unsigned
uF
,
unsigned
uFD
,
int
iVar
,
int
nVars
,
int
fDir
);
/*=== mapperCutUtils.c ===============================================================*/
extern
Map_Cut_t
*
Map_CutAlloc
(
Map_Man_t
*
p
);
extern
void
Map_CutFree
(
Map_Man_t
*
p
,
Map_Cut_t
*
pCut
);
...
...
@@ -383,17 +377,7 @@ extern Map_SuperLib_t * Map_SuperLibCreate( Mio_Library_t * pGenlib, Vec_Str_t
extern
void
Map_SuperLibFree
(
Map_SuperLib_t
*
p
);
/*=== mapperMatch.c ===============================================================*/
extern
int
Map_MappingMatches
(
Map_Man_t
*
p
);
extern
float
Map_MappingCombinePhases
(
Map_Man_t
*
p
);
extern
void
Map_MatchClean
(
Map_Match_t
*
pMatch
);
extern
int
Map_MatchCompare
(
Map_Man_t
*
pMan
,
Map_Match_t
*
pM1
,
Map_Match_t
*
pM2
,
int
fDoingArea
);
/*=== mapperPower.c =============================================================*/
extern
float
Map_SwitchCutGetDerefed
(
Map_Node_t
*
pNode
,
Map_Cut_t
*
pCut
,
int
fPhase
);
extern
float
Map_SwitchCutRef
(
Map_Node_t
*
pNode
,
Map_Cut_t
*
pCut
,
int
fPhase
);
extern
float
Map_SwitchCutDeref
(
Map_Node_t
*
pNode
,
Map_Cut_t
*
pCut
,
int
fPhase
);
extern
float
Map_MappingGetSwitching
(
Map_Man_t
*
pMan
,
Map_NodeVec_t
*
vMapping
);
/*=== mapperRefs.c =============================================================*/
extern
int
Map_NodeReadRefPhaseAct
(
Map_Node_t
*
pNode
,
int
fPhase
);
extern
float
Map_NodeReadRefPhaseEst
(
Map_Node_t
*
pNode
,
int
fPhase
);
extern
void
Map_MappingEstimateRefsInit
(
Map_Man_t
*
p
);
extern
void
Map_MappingEstimateRefs
(
Map_Man_t
*
p
);
extern
float
Map_CutGetAreaFlow
(
Map_Cut_t
*
pCut
,
int
fPhase
);
...
...
@@ -402,9 +386,12 @@ extern float Map_CutGetAreaDerefed( Map_Cut_t * pCut, int fPhase );
extern
float
Map_CutRef
(
Map_Cut_t
*
pCut
,
int
fPhase
);
extern
float
Map_CutDeref
(
Map_Cut_t
*
pCut
,
int
fPhase
);
extern
void
Map_MappingSetRefs
(
Map_Man_t
*
pMan
);
extern
float
Map_MappingGetArea
(
Map_Man_t
*
pMan
,
Map_NodeVec_t
*
vMapping
);
/*=== mapperShow.c =============================================================*/
extern
void
Map_MappingShow
(
Map_Man_t
*
pMan
,
char
*
pFileName
);
extern
float
Map_MappingGetArea
(
Map_Man_t
*
pMan
);
/*=== mapperSwitch.c =============================================================*/
extern
float
Map_SwitchCutGetDerefed
(
Map_Node_t
*
pNode
,
Map_Cut_t
*
pCut
,
int
fPhase
);
extern
float
Map_SwitchCutRef
(
Map_Node_t
*
pNode
,
Map_Cut_t
*
pCut
,
int
fPhase
);
extern
float
Map_SwitchCutDeref
(
Map_Node_t
*
pNode
,
Map_Cut_t
*
pCut
,
int
fPhase
);
extern
float
Map_MappingGetSwitching
(
Map_Man_t
*
pMan
);
/*=== mapperTree.c ===============================================================*/
extern
int
Map_LibraryDeriveGateInfo
(
Map_SuperLib_t
*
pLib
,
st__table
*
tExcludeGate
);
extern
int
Map_LibraryReadFileTreeStr
(
Map_SuperLib_t
*
pLib
,
Mio_Library_t
*
pGenlib
,
Vec_Str_t
*
vStr
,
char
*
pFileName
);
...
...
@@ -423,13 +410,8 @@ extern void Map_SuperTableSortSupergates( Map_HashTable_t * p, int
extern
void
Map_SuperTableSortSupergatesByDelay
(
Map_HashTable_t
*
p
,
int
nSupersMax
);
/*=== mapperTime.c =============================================================*/
extern
float
Map_TimeCutComputeArrival
(
Map_Node_t
*
pNode
,
Map_Cut_t
*
pCut
,
int
fPhase
,
float
tWorstCaseLimit
);
extern
void
Map_TimeCutComputeArrival_rec
(
Map_Cut_t
*
pCut
,
int
fPhase
);
extern
float
Map_TimeComputeArrivalMax
(
Map_Man_t
*
p
);
extern
void
Map_TimeComputeRequiredGlobal
(
Map_Man_t
*
p
);
extern
void
Map_TimeComputeRequired
(
Map_Man_t
*
p
,
float
fRequired
);
extern
float
Map_TimeNodeFanoutDelay
(
Map_Node_t
*
pNode
,
int
fPhase
);
extern
float
Map_TimeCutFanoutDelay
(
Map_Node_t
*
pNode
,
Map_Cut_t
*
pCut
,
int
fPhase
);
extern
float
Map_TimeMatchWithInverter
(
Map_Man_t
*
p
,
Map_Match_t
*
pMatch
);
/*=== mapperTruth.c ===============================================================*/
extern
void
Map_MappingTruths
(
Map_Man_t
*
pMan
);
extern
int
Map_TruthsCutDontCare
(
Map_Man_t
*
pMan
,
Map_Cut_t
*
pCut
,
unsigned
*
uTruthDc
);
...
...
@@ -437,11 +419,6 @@ extern int Map_TruthCountOnes( unsigned * uTruth, int nLeaves );
extern
int
Map_TruthDetectTwoFirst
(
unsigned
*
uTruth
,
int
nLeaves
);
/*=== mapperUtils.c ===============================================================*/
extern
Map_NodeVec_t
*
Map_MappingDfs
(
Map_Man_t
*
pMan
,
int
fCollectEquiv
);
extern
Map_NodeVec_t
*
Map_MappingDfsNodes
(
Map_Man_t
*
pMan
,
Map_Node_t
**
ppNodes
,
int
nNodes
,
int
fEquiv
);
extern
void
Map_MappingDfsMarked1_rec
(
Map_Node_t
*
pNode
,
Map_NodeVec_t
*
vNodes
,
int
fFirst
);
extern
void
Map_MappingDfsMarked2_rec
(
Map_Node_t
*
pNode
,
Map_NodeVec_t
*
vNodes
,
Map_NodeVec_t
*
vBoundary
,
int
fFirst
);
extern
int
Map_MappingCountLevels
(
Map_Man_t
*
pMan
);
extern
void
Map_MappingUnmark
(
Map_Man_t
*
pMan
);
extern
void
Map_MappingMark_rec
(
Map_Node_t
*
pNode
);
...
...
@@ -464,6 +441,7 @@ extern void Map_MappingReportChoices( Map_Man_t * pMan );
/*=== mapperVec.c =============================================================*/
extern
Map_NodeVec_t
*
Map_NodeVecAlloc
(
int
nCap
);
extern
void
Map_NodeVecFree
(
Map_NodeVec_t
*
p
);
extern
Map_NodeVec_t
*
Map_NodeVecDup
(
Map_NodeVec_t
*
p
);
extern
Map_Node_t
**
Map_NodeVecReadArray
(
Map_NodeVec_t
*
p
);
extern
int
Map_NodeVecReadSize
(
Map_NodeVec_t
*
p
);
extern
void
Map_NodeVecGrow
(
Map_NodeVec_t
*
p
,
int
nCapMin
);
...
...
src/map/mapper/mapperMatch.c
View file @
6f17c44e
...
...
@@ -36,217 +36,93 @@ ABC_NAMESPACE_IMPL_START
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static
int
Map_MatchNodePhase
(
Map_Man_t
*
p
,
Map_Node_t
*
pNode
,
int
fPhase
);
static
int
Map_MatchNodeCut
(
Map_Man_t
*
p
,
Map_Node_t
*
pNode
,
Map_Cut_t
*
pCut
,
int
fPhase
,
float
fWorstLimit
);
static
void
Map_MappingSetPiArrivalTimes
(
Map_Man_t
*
p
);
static
void
Map_NodeTryDroppingOnePhase
(
Map_Man_t
*
p
,
Map_Node_t
*
pNode
);
static
void
Map_NodeTransferArrivalTimes
(
Map_Man_t
*
p
,
Map_Node_t
*
pNode
);
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [C
omputes the best matches of the nodes
.]
Synopsis [C
leans the match
.]
Description [Uses parameter p->fMappingMode to decide how to assign
the matches for both polarities of the node. While the matches are
being assigned, one of them may turn out to be better than the other
(in terms of delay, for example). In this case, the worse match can
be permanently dropped, and the corresponding pointer set to NULL.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int
Map_MappingMatches
(
Map_Man_t
*
p
)
void
Map_MatchClean
(
Map_Match_t
*
pMatch
)
{
ProgressBar
*
pProgress
;
Map_Node_t
*
pNode
;
int
i
;
assert
(
p
->
fMappingMode
>=
0
&&
p
->
fMappingMode
<=
4
);
// use the externally given PI arrival times
if
(
p
->
fMappingMode
==
0
)
Map_MappingSetPiArrivalTimes
(
p
);
// estimate the fanouts
if
(
p
->
fMappingMode
==
0
)
Map_MappingEstimateRefsInit
(
p
);
else
if
(
p
->
fMappingMode
==
1
)
Map_MappingEstimateRefs
(
p
);
// the PI cuts are matched in the cut computation package
// in the loop below we match the internal nodes
pProgress
=
Extra_ProgressBarStart
(
stdout
,
p
->
vAnds
->
nSize
);
for
(
i
=
0
;
i
<
p
->
vAnds
->
nSize
;
i
++
)
{
// skip primary inputs and secondary nodes if mapping with choices
pNode
=
p
->
vAnds
->
pArray
[
i
];
if
(
!
Map_NodeIsAnd
(
pNode
)
||
pNode
->
pRepr
)
continue
;
// make sure that at least one non-trival cut is present
if
(
pNode
->
pCuts
->
pNext
==
NULL
)
{
Extra_ProgressBarStop
(
pProgress
);
printf
(
"
\n
Error: A node in the mapping graph does not have feasible cuts.
\n
"
);
return
0
;
}
// match negative phase
if
(
!
Map_MatchNodePhase
(
p
,
pNode
,
0
)
)
{
Extra_ProgressBarStop
(
pProgress
);
return
0
;
}
// match positive phase
if
(
!
Map_MatchNodePhase
(
p
,
pNode
,
1
)
)
{
Extra_ProgressBarStop
(
pProgress
);
return
0
;
}
// make sure that at least one phase is mapped
if
(
pNode
->
pCutBest
[
0
]
==
NULL
&&
pNode
->
pCutBest
[
1
]
==
NULL
)
{
printf
(
"
\n
Error: Could not match both phases of AIG node %d.
\n
"
,
pNode
->
Num
);
printf
(
"Please make sure that the supergate library has equivalents of AND2 or NAND2.
\n
"
);
printf
(
"If such supergates exist in the library, report a bug.
\n
"
);
Extra_ProgressBarStop
(
pProgress
);
return
0
;
}
// if both phases are assigned, check if one of them can be dropped
Map_NodeTryDroppingOnePhase
(
p
,
pNode
);
// set the arrival times of the node using the best cuts
Map_NodeTransferArrivalTimes
(
p
,
pNode
);
// update the progress bar
Extra_ProgressBarUpdate
(
pProgress
,
i
,
"Matches ..."
);
}
Extra_ProgressBarStop
(
pProgress
);
return
1
;
memset
(
pMatch
,
0
,
sizeof
(
Map_Match_t
)
);
pMatch
->
AreaFlow
=
MAP_FLOAT_LARGE
;
// unassigned
pMatch
->
tArrive
.
Rise
=
MAP_FLOAT_LARGE
;
// unassigned
pMatch
->
tArrive
.
Fall
=
MAP_FLOAT_LARGE
;
// unassigned
pMatch
->
tArrive
.
Worst
=
MAP_FLOAT_LARGE
;
// unassigned
}
/**Function*************************************************************
Synopsis [
Find the matching of one polarity of the node
.]
Synopsis [
Compares two matches
.]
Description []
Description [
Returns 1 if the second match is better. Otherwise returns 0.
]
SideEffects []
SeeAlso []
***********************************************************************/
int
Map_Match
NodePhase
(
Map_Man_t
*
p
,
Map_Node_t
*
pNode
,
int
fPhase
)
int
Map_Match
Compare
(
Map_Man_t
*
pMan
,
Map_Match_t
*
pM1
,
Map_Match_t
*
pM2
,
int
fDoingArea
)
{
Map_Match_t
MatchBest
,
*
pMatch
;
Map_Cut_t
*
pCut
,
*
pCutBest
;
float
Area1
=
0
.
0
;
// Suppress "might be used uninitialized
float
Area2
,
fWorstLimit
;
// skip the cuts that have been unassigned during area recovery
pCutBest
=
pNode
->
pCutBest
[
fPhase
];
if
(
p
->
fMappingMode
!=
0
&&
pCutBest
==
NULL
)
return
1
;
// recompute the arrival times of the current best match
// because the arrival times of the fanins may have changed
// as a result of remapping fanins in the topological order
if
(
p
->
fMappingMode
!=
0
)
{
Map_TimeCutComputeArrival
(
pNode
,
pCutBest
,
fPhase
,
MAP_FLOAT_LARGE
);
// make sure that the required times are met
assert
(
pCutBest
->
M
[
fPhase
].
tArrive
.
Rise
<
pNode
->
tRequired
[
fPhase
].
Rise
+
p
->
fEpsilon
);
assert
(
pCutBest
->
M
[
fPhase
].
tArrive
.
Fall
<
pNode
->
tRequired
[
fPhase
].
Fall
+
p
->
fEpsilon
);
}
// recompute the exact area of the current best match
// because the exact area of the fanins may have changed
// as a result of remapping fanins in the topological order
if
(
p
->
fMappingMode
==
2
||
p
->
fMappingMode
==
3
)
{
pMatch
=
pCutBest
->
M
+
fPhase
;
if
(
pNode
->
nRefAct
[
fPhase
]
>
0
||
(
pNode
->
pCutBest
[
!
fPhase
]
==
NULL
&&
pNode
->
nRefAct
[
!
fPhase
]
>
0
)
)
pMatch
->
AreaFlow
=
Area1
=
Map_CutDeref
(
pCutBest
,
fPhase
);
else
pMatch
->
AreaFlow
=
Area1
=
Map_CutGetAreaDerefed
(
pCutBest
,
fPhase
);
}
else
if
(
p
->
fMappingMode
==
4
)
if
(
!
fDoingArea
)
{
pMatch
=
pCutBest
->
M
+
fPhase
;
if
(
pNode
->
nRefAct
[
fPhase
]
>
0
||
(
pNode
->
pCutBest
[
!
fPhase
]
==
NULL
&&
pNode
->
nRefAct
[
!
fPhase
]
>
0
)
)
pMatch
->
AreaFlow
=
Area1
=
Map_SwitchCutDeref
(
pNode
,
pCutBest
,
fPhase
);
else
pMatch
->
AreaFlow
=
Area1
=
Map_SwitchCutGetDerefed
(
pNode
,
pCutBest
,
fPhase
);
// compare the arrival times
if
(
pM1
->
tArrive
.
Worst
<
pM2
->
tArrive
.
Worst
-
pMan
->
fEpsilon
)
return
0
;
if
(
pM1
->
tArrive
.
Worst
>
pM2
->
tArrive
.
Worst
+
pMan
->
fEpsilon
)
return
1
;
// compare the areas or area flows
if
(
pM1
->
AreaFlow
<
pM2
->
AreaFlow
-
pMan
->
fEpsilon
)
return
0
;
if
(
pM1
->
AreaFlow
>
pM2
->
AreaFlow
+
pMan
->
fEpsilon
)
return
1
;
// compare the fanout limits
if
(
pM1
->
pSuperBest
->
nFanLimit
>
pM2
->
pSuperBest
->
nFanLimit
)
return
0
;
if
(
pM1
->
pSuperBest
->
nFanLimit
<
pM2
->
pSuperBest
->
nFanLimit
)
return
1
;
// compare the number of leaves
if
(
pM1
->
pSuperBest
->
nFanins
<
pM2
->
pSuperBest
->
nFanins
)
return
0
;
if
(
pM1
->
pSuperBest
->
nFanins
>
pM2
->
pSuperBest
->
nFanins
)
return
1
;
// otherwise prefer the old cut
return
0
;
}
// save the old mapping
if
(
pCutBest
)
MatchBest
=
pCutBest
->
M
[
fPhase
];
else
Map_MatchClean
(
&
MatchBest
);
// select the new best cut
fWorstLimit
=
pNode
->
tRequired
[
fPhase
].
Worst
;
for
(
pCut
=
pNode
->
pCuts
->
pNext
;
pCut
;
pCut
=
pCut
->
pNext
)
{
// limit gate sizes based on fanout count
if
(
(
pNode
->
nRefs
>
3
&&
pCut
->
nLeaves
>
2
)
||
(
pNode
->
nRefs
>
1
&&
pCut
->
nLeaves
>
3
)
)
continue
;
pMatch
=
pCut
->
M
+
fPhase
;
if
(
pMatch
->
pSupers
==
NULL
)
continue
;
// find the matches for the cut
Map_MatchNodeCut
(
p
,
pNode
,
pCut
,
fPhase
,
fWorstLimit
);
if
(
pMatch
->
pSuperBest
==
NULL
||
pMatch
->
tArrive
.
Worst
>
fWorstLimit
+
p
->
fEpsilon
)
continue
;
// if the cut can be matched compare the matchings
if
(
Map_MatchCompare
(
p
,
&
MatchBest
,
pMatch
,
p
->
fMappingMode
)
)
{
pCutBest
=
pCut
;
MatchBest
=
*
pMatch
;
// if we are mapping for delay, the worst-case limit should be tightened
if
(
p
->
fMappingMode
==
0
)
fWorstLimit
=
MatchBest
.
tArrive
.
Worst
;
}
}
if
(
pCutBest
==
NULL
)
return
1
;
// set the new mapping
pNode
->
pCutBest
[
fPhase
]
=
pCutBest
;
pCutBest
->
M
[
fPhase
]
=
MatchBest
;
// reference the new cut if it used
if
(
p
->
fMappingMode
>=
2
&&
(
pNode
->
nRefAct
[
fPhase
]
>
0
||
(
pNode
->
pCutBest
[
!
fPhase
]
==
NULL
&&
pNode
->
nRefAct
[
!
fPhase
]
>
0
))
)
{
if
(
p
->
fMappingMode
==
2
||
p
->
fMappingMode
==
3
)
Area2
=
Map_CutRef
(
pNode
->
pCutBest
[
fPhase
],
fPhase
);
else
if
(
p
->
fMappingMode
==
4
)
Area2
=
Map_SwitchCutRef
(
pNode
,
pNode
->
pCutBest
[
fPhase
],
fPhase
);
else
assert
(
0
);
// assert( Area2 < Area1 + p->fEpsilon );
// compare the areas or area flows
if
(
pM1
->
AreaFlow
<
pM2
->
AreaFlow
-
pMan
->
fEpsilon
)
return
0
;
if
(
pM1
->
AreaFlow
>
pM2
->
AreaFlow
+
pMan
->
fEpsilon
)
return
1
;
// compare the arrival times
if
(
pM1
->
tArrive
.
Worst
<
pM2
->
tArrive
.
Worst
-
pMan
->
fEpsilon
)
return
0
;
if
(
pM1
->
tArrive
.
Worst
>
pM2
->
tArrive
.
Worst
+
pMan
->
fEpsilon
)
return
1
;
// compare the fanout limits
if
(
pM1
->
pSuperBest
->
nFanLimit
>
pM2
->
pSuperBest
->
nFanLimit
)
return
0
;
if
(
pM1
->
pSuperBest
->
nFanLimit
<
pM2
->
pSuperBest
->
nFanLimit
)
return
1
;
// compare the number of leaves
if
(
pM1
->
pSuperBest
->
nFanins
<
pM2
->
pSuperBest
->
nFanins
)
return
0
;
if
(
pM1
->
pSuperBest
->
nFanins
>
pM2
->
pSuperBest
->
nFanins
)
return
1
;
// otherwise prefer the old cut
return
0
;
}
// make sure that the requited times are met
assert
(
MatchBest
.
tArrive
.
Rise
<
pNode
->
tRequired
[
fPhase
].
Rise
+
p
->
fEpsilon
);
assert
(
MatchBest
.
tArrive
.
Fall
<
pNode
->
tRequired
[
fPhase
].
Fall
+
p
->
fEpsilon
);
return
1
;
}
/**Function*************************************************************
...
...
@@ -347,7 +223,7 @@ int Map_MatchNodeCut( Map_Man_t * p, Map_Node_t * pNode, Map_Cut_t * pCut, int f
/**Function*************************************************************
Synopsis [
Cleans the match
.]
Synopsis [
Find the matching of one polarity of the node
.]
Description []
...
...
@@ -356,78 +232,109 @@ int Map_MatchNodeCut( Map_Man_t * p, Map_Node_t * pNode, Map_Cut_t * pCut, int f
SeeAlso []
***********************************************************************/
void
Map_MatchClean
(
Map_Match_t
*
pMatch
)
int
Map_MatchNodePhase
(
Map_Man_t
*
p
,
Map_Node_t
*
pNode
,
int
fPhase
)
{
memset
(
pMatch
,
0
,
sizeof
(
Map_Match_t
)
);
pMatch
->
AreaFlow
=
MAP_FLOAT_LARGE
;
// unassigned
pMatch
->
tArrive
.
Rise
=
MAP_FLOAT_LARGE
;
// unassigned
pMatch
->
tArrive
.
Fall
=
MAP_FLOAT_LARGE
;
// unassigned
pMatch
->
tArrive
.
Worst
=
MAP_FLOAT_LARGE
;
// unassigned
}
/**Function*************************************************************
Synopsis [Compares two matches.]
Map_Match_t
MatchBest
,
*
pMatch
;
Map_Cut_t
*
pCut
,
*
pCutBest
;
float
Area1
=
0
.
0
;
// Suppress "might be used uninitialized
float
Area2
,
fWorstLimit
;
Description [Returns 1 if the second match is better. Otherwise returns 0.]
SideEffects []
// skip the cuts that have been unassigned during area recovery
pCutBest
=
pNode
->
pCutBest
[
fPhase
];
if
(
p
->
fMappingMode
!=
0
&&
pCutBest
==
NULL
)
return
1
;
SeeAlso []
// recompute the arrival times of the current best match
// because the arrival times of the fanins may have changed
// as a result of remapping fanins in the topological order
if
(
p
->
fMappingMode
!=
0
)
{
Map_TimeCutComputeArrival
(
pNode
,
pCutBest
,
fPhase
,
MAP_FLOAT_LARGE
);
// make sure that the required times are met
assert
(
pCutBest
->
M
[
fPhase
].
tArrive
.
Rise
<
pNode
->
tRequired
[
fPhase
].
Rise
+
p
->
fEpsilon
);
assert
(
pCutBest
->
M
[
fPhase
].
tArrive
.
Fall
<
pNode
->
tRequired
[
fPhase
].
Fall
+
p
->
fEpsilon
);
}
***********************************************************************/
int
Map_MatchCompare
(
Map_Man_t
*
pMan
,
Map_Match_t
*
pM1
,
Map_Match_t
*
pM2
,
int
fDoingArea
)
{
if
(
!
fDoingArea
)
// recompute the exact area of the current best match
// because the exact area of the fanins may have changed
// as a result of remapping fanins in the topological order
if
(
p
->
fMappingMode
==
2
||
p
->
fMappingMode
==
3
)
{
// compare the arrival times
if
(
pM1
->
tArrive
.
Worst
<
pM2
->
tArrive
.
Worst
-
pMan
->
fEpsilon
)
return
0
;
if
(
pM1
->
tArrive
.
Worst
>
pM2
->
tArrive
.
Worst
+
pMan
->
fEpsilon
)
return
1
;
// compare the areas or area flows
if
(
pM1
->
AreaFlow
<
pM2
->
AreaFlow
-
pMan
->
fEpsilon
)
return
0
;
if
(
pM1
->
AreaFlow
>
pM2
->
AreaFlow
+
pMan
->
fEpsilon
)
return
1
;
// compare the fanout limits
if
(
pM1
->
pSuperBest
->
nFanLimit
>
pM2
->
pSuperBest
->
nFanLimit
)
return
0
;
if
(
pM1
->
pSuperBest
->
nFanLimit
<
pM2
->
pSuperBest
->
nFanLimit
)
return
1
;
// compare the number of leaves
if
(
pM1
->
pSuperBest
->
nFanins
<
pM2
->
pSuperBest
->
nFanins
)
return
0
;
if
(
pM1
->
pSuperBest
->
nFanins
>
pM2
->
pSuperBest
->
nFanins
)
return
1
;
// otherwise prefer the old cut
return
0
;
pMatch
=
pCutBest
->
M
+
fPhase
;
if
(
pNode
->
nRefAct
[
fPhase
]
>
0
||
(
pNode
->
pCutBest
[
!
fPhase
]
==
NULL
&&
pNode
->
nRefAct
[
!
fPhase
]
>
0
)
)
pMatch
->
AreaFlow
=
Area1
=
Map_CutDeref
(
pCutBest
,
fPhase
);
else
pMatch
->
AreaFlow
=
Area1
=
Map_CutGetAreaDerefed
(
pCutBest
,
fPhase
);
}
else
if
(
p
->
fMappingMode
==
4
)
{
pMatch
=
pCutBest
->
M
+
fPhase
;
if
(
pNode
->
nRefAct
[
fPhase
]
>
0
||
(
pNode
->
pCutBest
[
!
fPhase
]
==
NULL
&&
pNode
->
nRefAct
[
!
fPhase
]
>
0
)
)
pMatch
->
AreaFlow
=
Area1
=
Map_SwitchCutDeref
(
pNode
,
pCutBest
,
fPhase
);
else
pMatch
->
AreaFlow
=
Area1
=
Map_SwitchCutGetDerefed
(
pNode
,
pCutBest
,
fPhase
);
}
// save the old mapping
if
(
pCutBest
)
MatchBest
=
pCutBest
->
M
[
fPhase
];
else
Map_MatchClean
(
&
MatchBest
);
// select the new best cut
fWorstLimit
=
pNode
->
tRequired
[
fPhase
].
Worst
;
for
(
pCut
=
pNode
->
pCuts
->
pNext
;
pCut
;
pCut
=
pCut
->
pNext
)
{
// compare the areas or area flows
if
(
pM1
->
AreaFlow
<
pM2
->
AreaFlow
-
pMan
->
fEpsilon
)
return
0
;
if
(
pM1
->
AreaFlow
>
pM2
->
AreaFlow
+
pMan
->
fEpsilon
)
return
1
;
// compare the arrival times
if
(
pM1
->
tArrive
.
Worst
<
pM2
->
tArrive
.
Worst
-
pMan
->
fEpsilon
)
return
0
;
if
(
pM1
->
tArrive
.
Worst
>
pM2
->
tArrive
.
Worst
+
pMan
->
fEpsilon
)
return
1
;
// compare the fanout limits
if
(
pM1
->
pSuperBest
->
nFanLimit
>
pM2
->
pSuperBest
->
nFanLimit
)
return
0
;
if
(
pM1
->
pSuperBest
->
nFanLimit
<
pM2
->
pSuperBest
->
nFanLimit
)
return
1
;
// compare the number of leaves
if
(
pM1
->
pSuperBest
->
nFanins
<
pM2
->
pSuperBest
->
nFanins
)
return
0
;
if
(
pM1
->
pSuperBest
->
nFanins
>
pM2
->
pSuperBest
->
nFanins
)
return
1
;
// otherwise prefer the old cut
return
0
;
// limit gate sizes based on fanout count
if
(
(
pNode
->
nRefs
>
3
&&
pCut
->
nLeaves
>
2
)
||
(
pNode
->
nRefs
>
1
&&
pCut
->
nLeaves
>
3
)
)
continue
;
pMatch
=
pCut
->
M
+
fPhase
;
if
(
pMatch
->
pSupers
==
NULL
)
continue
;
// find the matches for the cut
Map_MatchNodeCut
(
p
,
pNode
,
pCut
,
fPhase
,
fWorstLimit
);
if
(
pMatch
->
pSuperBest
==
NULL
||
pMatch
->
tArrive
.
Worst
>
fWorstLimit
+
p
->
fEpsilon
)
continue
;
// if the cut can be matched compare the matchings
if
(
Map_MatchCompare
(
p
,
&
MatchBest
,
pMatch
,
p
->
fMappingMode
)
)
{
pCutBest
=
pCut
;
MatchBest
=
*
pMatch
;
// if we are mapping for delay, the worst-case limit should be tightened
if
(
p
->
fMappingMode
==
0
)
fWorstLimit
=
MatchBest
.
tArrive
.
Worst
;
}
}
if
(
pCutBest
==
NULL
)
return
1
;
// set the new mapping
pNode
->
pCutBest
[
fPhase
]
=
pCutBest
;
pCutBest
->
M
[
fPhase
]
=
MatchBest
;
// reference the new cut if it used
if
(
p
->
fMappingMode
>=
2
&&
(
pNode
->
nRefAct
[
fPhase
]
>
0
||
(
pNode
->
pCutBest
[
!
fPhase
]
==
NULL
&&
pNode
->
nRefAct
[
!
fPhase
]
>
0
))
)
{
if
(
p
->
fMappingMode
==
2
||
p
->
fMappingMode
==
3
)
Area2
=
Map_CutRef
(
pNode
->
pCutBest
[
fPhase
],
fPhase
);
else
if
(
p
->
fMappingMode
==
4
)
Area2
=
Map_SwitchCutRef
(
pNode
,
pNode
->
pCutBest
[
fPhase
],
fPhase
);
else
assert
(
0
);
// assert( Area2 < Area1 + p->fEpsilon );
}
// make sure that the requited times are met
assert
(
MatchBest
.
tArrive
.
Rise
<
pNode
->
tRequired
[
fPhase
].
Rise
+
p
->
fEpsilon
);
assert
(
MatchBest
.
tArrive
.
Fall
<
pNode
->
tRequired
[
fPhase
].
Fall
+
p
->
fEpsilon
);
return
1
;
}
/**Function*************************************************************
...
...
@@ -460,6 +367,25 @@ void Map_MappingSetPiArrivalTimes( Map_Man_t * p )
}
}
/**function*************************************************************
synopsis [Computes the exact area associated with the cut.]
description []
sideeffects []
seealso []
***********************************************************************/
float
Map_TimeMatchWithInverter
(
Map_Man_t
*
p
,
Map_Match_t
*
pMatch
)
{
Map_Time_t
tArrInv
;
tArrInv
.
Fall
=
pMatch
->
tArrive
.
Rise
+
p
->
pSuperLib
->
tDelayInv
.
Fall
;
tArrInv
.
Rise
=
pMatch
->
tArrive
.
Fall
+
p
->
pSuperLib
->
tDelayInv
.
Rise
;
tArrInv
.
Worst
=
MAP_MAX
(
tArrInv
.
Rise
,
tArrInv
.
Fall
);
return
tArrInv
.
Worst
;
}
/**Function*************************************************************
...
...
@@ -609,6 +535,100 @@ void Map_NodeTransferArrivalTimes( Map_Man_t * p, Map_Node_t * pNode )
assert
(
pNode
->
tArrival
[
1
].
Fall
<
pNode
->
tRequired
[
1
].
Fall
+
p
->
fEpsilon
);
}
/**Function*************************************************************
Synopsis [Computes the best matches of the nodes.]
Description [Uses parameter p->fMappingMode to decide how to assign
the matches for both polarities of the node. While the matches are
being assigned, one of them may turn out to be better than the other
(in terms of delay, for example). In this case, the worse match can
be permanently dropped, and the corresponding pointer set to NULL.]
SideEffects []
SeeAlso []
***********************************************************************/
int
Map_MappingMatches
(
Map_Man_t
*
p
)
{
ProgressBar
*
pProgress
;
Map_Node_t
*
pNode
;
int
i
;
assert
(
p
->
fMappingMode
>=
0
&&
p
->
fMappingMode
<=
4
);
// use the externally given PI arrival times
if
(
p
->
fMappingMode
==
0
)
Map_MappingSetPiArrivalTimes
(
p
);
// estimate the fanouts
if
(
p
->
fMappingMode
==
0
)
Map_MappingEstimateRefsInit
(
p
);
else
if
(
p
->
fMappingMode
==
1
)
Map_MappingEstimateRefs
(
p
);
// the PI cuts are matched in the cut computation package
// in the loop below we match the internal nodes
pProgress
=
Extra_ProgressBarStart
(
stdout
,
p
->
vMapObjs
->
nSize
);
for
(
i
=
0
;
i
<
p
->
vMapObjs
->
nSize
;
i
++
)
{
pNode
=
p
->
vMapObjs
->
pArray
[
i
];
if
(
Map_NodeIsBuf
(
pNode
)
)
{
assert
(
pNode
->
p2
==
NULL
);
pNode
->
tArrival
[
0
]
=
Map_Regular
(
pNode
->
p1
)
->
tArrival
[
Map_IsComplement
(
pNode
->
p1
)];
pNode
->
tArrival
[
1
]
=
Map_Regular
(
pNode
->
p1
)
->
tArrival
[
!
Map_IsComplement
(
pNode
->
p1
)];
continue
;
}
// skip primary inputs and secondary nodes if mapping with choices
if
(
!
Map_NodeIsAnd
(
pNode
)
||
pNode
->
pRepr
)
continue
;
// make sure that at least one non-trival cut is present
if
(
pNode
->
pCuts
->
pNext
==
NULL
)
{
Extra_ProgressBarStop
(
pProgress
);
printf
(
"
\n
Error: A node in the mapping graph does not have feasible cuts.
\n
"
);
return
0
;
}
// match negative phase
if
(
!
Map_MatchNodePhase
(
p
,
pNode
,
0
)
)
{
Extra_ProgressBarStop
(
pProgress
);
return
0
;
}
// match positive phase
if
(
!
Map_MatchNodePhase
(
p
,
pNode
,
1
)
)
{
Extra_ProgressBarStop
(
pProgress
);
return
0
;
}
// make sure that at least one phase is mapped
if
(
pNode
->
pCutBest
[
0
]
==
NULL
&&
pNode
->
pCutBest
[
1
]
==
NULL
)
{
printf
(
"
\n
Error: Could not match both phases of AIG node %d.
\n
"
,
pNode
->
Num
);
printf
(
"Please make sure that the supergate library has equivalents of AND2 or NAND2.
\n
"
);
printf
(
"If such supergates exist in the library, report a bug.
\n
"
);
Extra_ProgressBarStop
(
pProgress
);
return
0
;
}
// if both phases are assigned, check if one of them can be dropped
Map_NodeTryDroppingOnePhase
(
p
,
pNode
);
// set the arrival times of the node using the best cuts
Map_NodeTransferArrivalTimes
(
p
,
pNode
);
// update the progress bar
Extra_ProgressBarUpdate
(
pProgress
,
i
,
"Matches ..."
);
}
Extra_ProgressBarStop
(
pProgress
);
return
1
;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
...
...
src/map/mapper/mapperRefs.c
View file @
6f17c44e
...
...
@@ -25,11 +25,6 @@ ABC_NAMESPACE_IMPL_START
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static
int
Map_NodeIncRefPhaseAct
(
Map_Node_t
*
pNode
,
int
fPhase
);
static
int
Map_NodeDecRefPhaseAct
(
Map_Node_t
*
pNode
,
int
fPhase
);
static
float
Map_CutRefDeref
(
Map_Cut_t
*
pCut
,
int
fPhase
,
int
fReference
);
static
void
Map_MappingSetRefs_rec
(
Map_Man_t
*
pMan
,
Map_Node_t
*
pNode
,
Map_Node_t
**
ppStore
);
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
...
...
@@ -132,9 +127,9 @@ void Map_MappingEstimateRefsInit( Map_Man_t * p )
{
Map_Node_t
*
pNode
;
int
i
;
for
(
i
=
0
;
i
<
p
->
v
And
s
->
nSize
;
i
++
)
for
(
i
=
0
;
i
<
p
->
v
MapObj
s
->
nSize
;
i
++
)
{
pNode
=
p
->
v
And
s
->
pArray
[
i
];
pNode
=
p
->
v
MapObj
s
->
pArray
[
i
];
// pNode->nRefEst[0] = pNode->nRefEst[1] = ((float)pNode->nRefs)*(float)2.0;
pNode
->
nRefEst
[
0
]
=
pNode
->
nRefEst
[
1
]
=
pNode
->
nRefEst
[
2
]
=
((
float
)
pNode
->
nRefs
);
}
...
...
@@ -157,9 +152,9 @@ void Map_MappingEstimateRefs( Map_Man_t * p )
{
Map_Node_t
*
pNode
;
int
i
;
for
(
i
=
0
;
i
<
p
->
v
And
s
->
nSize
;
i
++
)
for
(
i
=
0
;
i
<
p
->
v
MapObj
s
->
nSize
;
i
++
)
{
pNode
=
p
->
v
And
s
->
pArray
[
i
];
pNode
=
p
->
v
MapObj
s
->
pArray
[
i
];
// pNode->nRefEst[0] = (float)((2.0 * pNode->nRefEst[0] + 1.0 * pNode->nRefAct[0]) / 3.0);
// pNode->nRefEst[1] = (float)((2.0 * pNode->nRefEst[1] + 1.0 * pNode->nRefAct[1]) / 3.0);
// pNode->nRefEst[2] = (float)((2.0 * pNode->nRefEst[2] + 1.0 * pNode->nRefAct[2]) / 3.0);
...
...
@@ -169,10 +164,6 @@ void Map_MappingEstimateRefs( Map_Man_t * p )
}
}
/**function*************************************************************
synopsis [Computes the area flow of the cut.]
...
...
@@ -223,79 +214,6 @@ float Map_CutGetAreaFlow( Map_Cut_t * pCut, int fPhase )
}
/**function*************************************************************
synopsis [Computes the exact area associated with the cut.]
description [Assumes that the cut is referenced.]
sideeffects []
seealso []
***********************************************************************/
float
Map_CutGetAreaRefed
(
Map_Cut_t
*
pCut
,
int
fPhase
)
{
float
aResult
,
aResult2
;
aResult2
=
Map_CutRefDeref
(
pCut
,
fPhase
,
0
);
// dereference
aResult
=
Map_CutRefDeref
(
pCut
,
fPhase
,
1
);
// reference
// assert( aResult == aResult2 );
return
aResult
;
}
/**function*************************************************************
synopsis [Computes the exact area associated with the cut.]
description []
sideeffects []
seealso []
***********************************************************************/
float
Map_CutGetAreaDerefed
(
Map_Cut_t
*
pCut
,
int
fPhase
)
{
float
aResult
,
aResult2
;
aResult2
=
Map_CutRefDeref
(
pCut
,
fPhase
,
1
);
// reference
aResult
=
Map_CutRefDeref
(
pCut
,
fPhase
,
0
);
// dereference
// assert( aResult == aResult2 );
return
aResult
;
}
/**function*************************************************************
synopsis [References the cut.]
description []
sideeffects []
seealso []
***********************************************************************/
float
Map_CutRef
(
Map_Cut_t
*
pCut
,
int
fPhase
)
{
return
Map_CutRefDeref
(
pCut
,
fPhase
,
1
);
// reference
}
/**function*************************************************************
synopsis [Dereferences the cut.]
description []
sideeffects []
seealso []
***********************************************************************/
float
Map_CutDeref
(
Map_Cut_t
*
pCut
,
int
fPhase
)
{
return
Map_CutRefDeref
(
pCut
,
fPhase
,
0
);
// dereference
}
/**function*************************************************************
synopsis [References or dereferences the cut.]
...
...
@@ -396,98 +314,115 @@ float Map_CutRefDeref( Map_Cut_t * pCut, int fPhase, int fReference )
return
aArea
;
}
/**function*************************************************************
synopsis [Computes the exact area associated with the cut.]
description [Assumes that the cut is referenced.]
sideeffects []
/**Function*************************************************************
seealso []
Synopsis [Computes actual reference counters.]
***********************************************************************/
float
Map_CutGetAreaRefed
(
Map_Cut_t
*
pCut
,
int
fPhase
)
{
float
aResult
,
aResult2
;
aResult2
=
Map_CutRefDeref
(
pCut
,
fPhase
,
0
);
// dereference
aResult
=
Map_CutRefDeref
(
pCut
,
fPhase
,
1
);
// reference
// assert( aResult == aResult2 );
return
aResult
;
}
Description [Collects the nodes used in the mapping in array pMan->vMapping.
Nodes are collected in reverse topological order to facilitate the
computation of required times.]
/**function*************************************************************
synopsis [Computes the exact area associated with the cut.]
description []
SideE
ffects []
sidee
ffects []
SeeA
lso []
seea
lso []
***********************************************************************/
void
Map_MappingSetRefs
(
Map_Man_t
*
pMan
)
float
Map_CutGetAreaDerefed
(
Map_Cut_t
*
pCut
,
int
fPhase
)
{
Map_Node_t
*
pNode
,
**
ppStore
;
int
i
,
fPhase
,
LevelMax
;
float
aResult
,
aResult2
;
aResult2
=
Map_CutRefDeref
(
pCut
,
fPhase
,
1
);
// reference
aResult
=
Map_CutRefDeref
(
pCut
,
fPhase
,
0
);
// dereference
// assert( aResult == aResult2 );
return
aResult
;
}
// clean all references
for
(
i
=
0
;
i
<
pMan
->
vNodesAll
->
nSize
;
i
++
)
{
pNode
=
pMan
->
vNodesAll
->
pArray
[
i
];
pNode
->
nRefAct
[
0
]
=
0
;
pNode
->
nRefAct
[
1
]
=
0
;
pNode
->
nRefAct
[
2
]
=
0
;
}
/**function*************************************************************
// find the largest level of a node
LevelMax
=
0
;
for
(
i
=
0
;
i
<
pMan
->
nOutputs
;
i
++
)
if
(
LevelMax
<
(
int
)
Map_Regular
(
pMan
->
pOutputs
[
i
])
->
Level
)
LevelMax
=
Map_Regular
(
pMan
->
pOutputs
[
i
])
->
Level
;
synopsis [References the cut.]
// allocate place to store the nodes
ppStore
=
ABC_ALLOC
(
Map_Node_t
*
,
LevelMax
+
1
);
memset
(
ppStore
,
0
,
sizeof
(
Map_Node_t
*
)
*
(
LevelMax
+
1
)
);
description []
sideeffects []
// visit nodes reachable from POs in the DFS order through the best cuts
for
(
i
=
0
;
i
<
pMan
->
nOutputs
;
i
++
)
{
pNode
=
pMan
->
pOutputs
[
i
];
fPhase
=
!
Map_IsComplement
(
pNode
);
if
(
!
Map_NodeIsConst
(
pNode
)
)
Map_MappingSetRefs_rec
(
pMan
,
pNode
,
ppStore
);
}
seealso []
// reconnect the nodes in reverse topological order
pMan
->
vMapping
->
nSize
=
0
;
for
(
i
=
LevelMax
;
i
>=
0
;
i
--
)
for
(
pNode
=
ppStore
[
i
];
pNode
;
pNode
=
(
Map_Node_t
*
)
pNode
->
pData0
)
Map_NodeVecPush
(
pMan
->
vMapping
,
pNode
);
ABC_FREE
(
ppStore
);
***********************************************************************/
float
Map_CutRef
(
Map_Cut_t
*
pCut
,
int
fPhase
)
{
return
Map_CutRefDeref
(
pCut
,
fPhase
,
1
);
// reference
}
/**function*************************************************************
synopsis [Dereferences the cut.]
description []
sideeffects []
seealso []
***********************************************************************/
float
Map_CutDeref
(
Map_Cut_t
*
pCut
,
int
fPhase
)
{
return
Map_CutRefDeref
(
pCut
,
fPhase
,
0
);
// dereference
}
/**Function*************************************************************
Synopsis [
Recursively computes the DFS ordering of the node
s.]
Synopsis [
Computes actual reference counter
s.]
Description []
Description [Collects the nodes used in the mapping in array pMan->vMapping.
Nodes are collected in reverse topological order to facilitate the
computation of required times.]
SideEffects []
SeeAlso []
***********************************************************************/
void
Map_MappingSetRefs_rec
(
Map_Man_t
*
pMan
,
Map_Node_t
*
pNode
,
Map_Node_t
**
ppStore
)
void
Map_MappingSetRefs_rec
(
Map_Man_t
*
pMan
,
Map_Node_t
*
pNode
)
{
Map_Cut_t
*
pCut
;
Map_Node_t
*
pNodeR
;
unsigned
uPhase
;
int
i
,
fPhase
,
fInvPin
;
// get the regular node and its phase
pNodeR
=
Map_Regular
(
pNode
);
fPhase
=
!
Map_IsComplement
(
pNode
);
// add the node to the list of all visited nodes
if
(
pNodeR
->
nRefAct
[
2
]
++
==
0
)
// Map_NodeVecPush( pMan->vMapping, pNodeR );
pNodeR
->
pData0
=
(
char
*
)
ppStore
[
pNodeR
->
Level
],
ppStore
[
pNodeR
->
Level
]
=
pNodeR
;
pNodeR
->
nRefAct
[
2
]
++
;
// quit if the node was already visited in this phase
if
(
pNodeR
->
nRefAct
[
fPhase
]
++
)
return
;
// quit if this is a PI node
if
(
Map_NodeIsVar
(
pNodeR
)
)
return
;
// propagate through buffer
if
(
Map_NodeIsBuf
(
pNodeR
)
)
{
Map_MappingSetRefs_rec
(
pMan
,
Map_NotCond
(
pNodeR
->
p1
,
Map_IsComplement
(
pNode
))
);
return
;
}
assert
(
Map_NodeIsAnd
(
pNode
)
);
// get the cut implementing this or opposite polarity
pCut
=
pNodeR
->
pCutBest
[
fPhase
];
if
(
pCut
==
NULL
)
...
...
@@ -495,13 +430,32 @@ void Map_MappingSetRefs_rec( Map_Man_t * pMan, Map_Node_t * pNode, Map_Node_t **
fPhase
=
!
fPhase
;
pCut
=
pNodeR
->
pCutBest
[
fPhase
];
}
// visit the transitive fanin
uPhase
=
pCut
->
M
[
fPhase
].
uPhaseBest
;
for
(
i
=
0
;
i
<
pCut
->
nLeaves
;
i
++
)
{
fInvPin
=
((
uPhase
&
(
1
<<
i
))
>
0
);
Map_MappingSetRefs_rec
(
pMan
,
Map_NotCond
(
pCut
->
ppLeaves
[
i
],
fInvPin
),
ppStore
);
Map_MappingSetRefs_rec
(
pMan
,
Map_NotCond
(
pCut
->
ppLeaves
[
i
],
fInvPin
)
);
}
}
void
Map_MappingSetRefs
(
Map_Man_t
*
pMan
)
{
Map_Node_t
*
pNode
;
int
i
;
// clean all references
for
(
i
=
0
;
i
<
pMan
->
vMapObjs
->
nSize
;
i
++
)
{
pNode
=
pMan
->
vMapObjs
->
pArray
[
i
];
pNode
->
nRefAct
[
0
]
=
0
;
pNode
->
nRefAct
[
1
]
=
0
;
pNode
->
nRefAct
[
2
]
=
0
;
}
// visit nodes reachable from POs in the DFS order through the best cuts
for
(
i
=
0
;
i
<
pMan
->
nOutputs
;
i
++
)
{
pNode
=
pMan
->
pOutputs
[
i
];
if
(
!
Map_NodeIsConst
(
pNode
)
)
Map_MappingSetRefs_rec
(
pMan
,
pNode
);
}
}
...
...
@@ -517,15 +471,18 @@ void Map_MappingSetRefs_rec( Map_Man_t * pMan, Map_Node_t * pNode, Map_Node_t **
SeeAlso []
***********************************************************************/
float
Map_MappingGetArea
(
Map_Man_t
*
pMan
,
Map_NodeVec_t
*
vMapping
)
float
Map_MappingGetArea
(
Map_Man_t
*
pMan
)
{
Map_Node_t
*
pNode
;
float
Area
;
float
Area
=
0
.
0
;
int
i
;
Area
=
0
.
0
;
for
(
i
=
0
;
i
<
vMapping
->
nSize
;
i
++
)
for
(
i
=
0
;
i
<
pMan
->
vMapObjs
->
nSize
;
i
++
)
{
pNode
=
vMapping
->
pArray
[
i
];
pNode
=
pMan
->
vMapObjs
->
pArray
[
i
];
if
(
pNode
->
nRefAct
[
2
]
==
0
)
continue
;
if
(
Map_NodeIsBuf
(
pNode
)
)
continue
;
// at least one phase has the best cut assigned
assert
(
pNode
->
pCutBest
[
0
]
!=
NULL
||
pNode
->
pCutBest
[
1
]
!=
NULL
);
// at least one phase is used in the mapping
...
...
src/map/mapper/mapperSwitch.c
View file @
6f17c44e
...
...
@@ -184,15 +184,16 @@ float Map_SwitchCutRefDeref( Map_Node_t * pNode, Map_Cut_t * pCut, int fPhase, i
SeeAlso []
***********************************************************************/
float
Map_MappingGetSwitching
(
Map_Man_t
*
pMan
,
Map_NodeVec_t
*
vMapping
)
float
Map_MappingGetSwitching
(
Map_Man_t
*
pMan
)
{
Map_Node_t
*
pNode
;
float
Switch
;
float
Switch
=
0
.
0
;
int
i
;
Switch
=
0
.
0
;
for
(
i
=
0
;
i
<
vMapping
->
nSize
;
i
++
)
for
(
i
=
0
;
i
<
pMan
->
vMapObjs
->
nSize
;
i
++
)
{
pNode
=
vMapping
->
pArray
[
i
];
pNode
=
pMan
->
vMapObjs
->
pArray
[
i
];
if
(
pNode
->
nRefAct
[
2
]
==
0
)
continue
;
// at least one phase has the best cut assigned
assert
(
pNode
->
pCutBest
[
0
]
!=
NULL
||
pNode
->
pCutBest
[
1
]
!=
NULL
);
// at least one phase is used in the mapping
...
...
src/map/mapper/mapperTime.c
View file @
6f17c44e
...
...
@@ -20,63 +20,40 @@
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static
void
Map_TimePropagateRequired
(
Map_Man_t
*
p
,
Map_NodeVec_t
*
vNodes
);
static
void
Map_TimePropagateRequiredPhase
(
Map_Man_t
*
p
,
Map_Node_t
*
pNode
,
int
fPhase
);
static
float
Map_MatchComputeReqTimes
(
Map_Cut_t
*
pCut
,
int
fPhase
,
Map_Time_t
*
ptArrRes
);
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**function*************************************************************
synopsis [Computes the exact area associated with the cut.]
description []
sideeffects []
seealso []
***********************************************************************/
float
Map_TimeMatchWithInverter
(
Map_Man_t
*
p
,
Map_Match_t
*
pMatch
)
{
Map_Time_t
tArrInv
;
tArrInv
.
Fall
=
pMatch
->
tArrive
.
Rise
+
p
->
pSuperLib
->
tDelayInv
.
Fall
;
tArrInv
.
Rise
=
pMatch
->
tArrive
.
Fall
+
p
->
pSuperLib
->
tDelayInv
.
Rise
;
tArrInv
.
Worst
=
MAP_MAX
(
tArrInv
.
Rise
,
tArrInv
.
Fall
);
return
tArrInv
.
Worst
;
}
/**Function*************************************************************
Synopsis [Computes the
arrival times of the cut recursively
.]
Synopsis [Computes the
maximum arrival times
.]
Description [When computing the arrival time for the previously unused
cuts, their arrival time may be incorrect because their fanins have
incorrect arrival time. This procedure is called to fix this problem.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
Map_TimeCutComputeArrival_rec
(
Map_Cut_t
*
pCut
,
int
fPhase
)
float
Map_TimeComputeArrivalMax
(
Map_Man_t
*
p
)
{
int
i
,
fPhaseLeaf
;
for
(
i
=
0
;
i
<
pCut
->
nLeaves
;
i
++
)
float
tReqMax
,
tReq
;
int
i
,
fPhase
;
// get the critical PO arrival time
tReqMax
=
-
MAP_FLOAT_LARGE
;
for
(
i
=
0
;
i
<
p
->
nOutputs
;
i
++
)
{
fPhaseLeaf
=
Map_CutGetLeafPhase
(
pCut
,
fPhase
,
i
);
if
(
pCut
->
ppLeaves
[
i
]
->
nRefAct
[
fPhaseLeaf
]
>
0
)
if
(
Map_NodeIsConst
(
p
->
pOutputs
[
i
])
)
continue
;
Map_TimeCutComputeArrival_rec
(
pCut
->
ppLeaves
[
i
]
->
pCutBest
[
fPhaseLeaf
],
fPhaseLeaf
);
fPhase
=
!
Map_IsComplement
(
p
->
pOutputs
[
i
]);
tReq
=
Map_Regular
(
p
->
pOutputs
[
i
])
->
tArrival
[
fPhase
].
Worst
;
tReqMax
=
MAP_MAX
(
tReqMax
,
tReq
);
}
Map_TimeCutComputeArrival
(
NULL
,
pCut
,
fPhase
,
MAP_FLOAT_LARGE
)
;
return
tReqMax
;
}
/**Function*************************************************************
...
...
@@ -160,217 +137,7 @@ float Map_TimeCutComputeArrival( Map_Node_t * pNode, Map_Cut_t * pCut, int fPhas
/**Function*************************************************************
Synopsis [Computes the maximum arrival times.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
float
Map_TimeComputeArrivalMax
(
Map_Man_t
*
p
)
{
float
tReqMax
,
tReq
;
int
i
,
fPhase
;
// get the critical PO arrival time
tReqMax
=
-
MAP_FLOAT_LARGE
;
for
(
i
=
0
;
i
<
p
->
nOutputs
;
i
++
)
{
if
(
Map_NodeIsConst
(
p
->
pOutputs
[
i
])
)
continue
;
fPhase
=
!
Map_IsComplement
(
p
->
pOutputs
[
i
]);
tReq
=
Map_Regular
(
p
->
pOutputs
[
i
])
->
tArrival
[
fPhase
].
Worst
;
tReqMax
=
MAP_MAX
(
tReqMax
,
tReq
);
}
return
tReqMax
;
}
/**Function*************************************************************
Synopsis [Computes the required times of all nodes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
Map_TimeComputeRequiredGlobal
(
Map_Man_t
*
p
)
{
p
->
fRequiredGlo
=
Map_TimeComputeArrivalMax
(
p
);
// update the required times according to the target
if
(
p
->
DelayTarget
!=
-
1
)
{
if
(
p
->
fRequiredGlo
>
p
->
DelayTarget
+
p
->
fEpsilon
)
{
if
(
p
->
fMappingMode
==
1
)
printf
(
"Cannot meet the target required times (%4.2f). Continue anyway.
\n
"
,
p
->
DelayTarget
);
}
else
if
(
p
->
fRequiredGlo
<
p
->
DelayTarget
-
p
->
fEpsilon
)
{
if
(
p
->
fMappingMode
==
1
&&
p
->
fVerbose
)
printf
(
"Relaxing the required times from (%4.2f) to the target (%4.2f).
\n
"
,
p
->
fRequiredGlo
,
p
->
DelayTarget
);
p
->
fRequiredGlo
=
p
->
DelayTarget
;
}
}
Map_TimeComputeRequired
(
p
,
p
->
fRequiredGlo
);
}
/**Function*************************************************************
Synopsis [Computes the required times of all nodes.]
Description [This procedure assumes that the nodes used in the mapping
are collected in p->vMapping.]
SideEffects []
SeeAlso []
***********************************************************************/
void
Map_TimeComputeRequired
(
Map_Man_t
*
p
,
float
fRequired
)
{
Map_Time_t
*
ptTime
,
*
ptTimeA
;
int
fPhase
,
i
;
// clean the required times
for
(
i
=
0
;
i
<
p
->
vAnds
->
nSize
;
i
++
)
{
p
->
vAnds
->
pArray
[
i
]
->
tRequired
[
0
].
Rise
=
MAP_FLOAT_LARGE
;
p
->
vAnds
->
pArray
[
i
]
->
tRequired
[
0
].
Fall
=
MAP_FLOAT_LARGE
;
p
->
vAnds
->
pArray
[
i
]
->
tRequired
[
0
].
Worst
=
MAP_FLOAT_LARGE
;
p
->
vAnds
->
pArray
[
i
]
->
tRequired
[
1
].
Rise
=
MAP_FLOAT_LARGE
;
p
->
vAnds
->
pArray
[
i
]
->
tRequired
[
1
].
Fall
=
MAP_FLOAT_LARGE
;
p
->
vAnds
->
pArray
[
i
]
->
tRequired
[
1
].
Worst
=
MAP_FLOAT_LARGE
;
}
// set the required times for the POs
for
(
i
=
0
;
i
<
p
->
nOutputs
;
i
++
)
{
fPhase
=
!
Map_IsComplement
(
p
->
pOutputs
[
i
]);
ptTime
=
Map_Regular
(
p
->
pOutputs
[
i
])
->
tRequired
+
fPhase
;
ptTimeA
=
Map_Regular
(
p
->
pOutputs
[
i
])
->
tArrival
+
fPhase
;
// if external required time can be achieved, use it
if
(
p
->
pOutputRequireds
&&
p
->
pOutputRequireds
[
i
].
Worst
>
0
&&
ptTimeA
->
Worst
<=
p
->
pOutputRequireds
[
i
].
Worst
)
//&& p->pOutputRequireds[i].Worst <= fRequired )
ptTime
->
Rise
=
ptTime
->
Fall
=
ptTime
->
Worst
=
p
->
pOutputRequireds
[
i
].
Worst
;
// if external required cannot be achieved, set the earliest possible arrival time
else
if
(
p
->
pOutputRequireds
&&
p
->
pOutputRequireds
[
i
].
Worst
>
0
&&
ptTimeA
->
Worst
>
p
->
pOutputRequireds
[
i
].
Worst
)
ptTime
->
Rise
=
ptTime
->
Fall
=
ptTime
->
Worst
=
ptTimeA
->
Worst
;
// otherwise, set the global required time
else
ptTime
->
Rise
=
ptTime
->
Fall
=
ptTime
->
Worst
=
fRequired
;
}
// sorts the nodes in the decreasing order of levels
// this puts the nodes in reverse topological order
// Map_MappingSortByLevel( p, p->vMapping );
// the array is already sorted by construction in Map_MappingSetRefs()
Map_TimePropagateRequired
(
p
,
p
->
vMapping
);
}
/**Function*************************************************************
Synopsis [Computes the required times of the given nodes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
Map_TimePropagateRequired
(
Map_Man_t
*
p
,
Map_NodeVec_t
*
vNodes
)
{
Map_Node_t
*
pNode
;
Map_Time_t
tReqOutTest
,
*
ptReqOutTest
=
&
tReqOutTest
;
Map_Time_t
*
ptReqIn
,
*
ptReqOut
;
int
fPhase
,
k
;
// go through the nodes in the reverse topological order
for
(
k
=
0
;
k
<
vNodes
->
nSize
;
k
++
)
{
pNode
=
vNodes
->
pArray
[
k
];
// this computation works for regular nodes only
assert
(
!
Map_IsComplement
(
pNode
)
);
// at least one phase should be mapped
assert
(
pNode
->
pCutBest
[
0
]
!=
NULL
||
pNode
->
pCutBest
[
1
]
!=
NULL
);
// the node should be used in the currently assigned mapping
assert
(
pNode
->
nRefAct
[
0
]
>
0
||
pNode
->
nRefAct
[
1
]
>
0
);
// if one of the cuts is not given, project the required times from the other cut
if
(
pNode
->
pCutBest
[
0
]
==
NULL
||
pNode
->
pCutBest
[
1
]
==
NULL
)
{
// assert( 0 );
// get the missing phase
fPhase
=
(
pNode
->
pCutBest
[
1
]
==
NULL
);
// check if the missing phase is needed in the mapping
if
(
pNode
->
nRefAct
[
fPhase
]
>
0
)
{
// get the pointers to the required times of the missing phase
ptReqOut
=
pNode
->
tRequired
+
fPhase
;
// assert( ptReqOut->Fall < MAP_FLOAT_LARGE );
// get the pointers to the required times of the present phase
ptReqIn
=
pNode
->
tRequired
+
!
fPhase
;
// propagate the required times from the missing phase to the present phase
// tArrInv.Fall = pMatch->tArrive.Rise + p->pSuperLib->tDelayInv.Fall;
// tArrInv.Rise = pMatch->tArrive.Fall + p->pSuperLib->tDelayInv.Rise;
ptReqIn
->
Fall
=
MAP_MIN
(
ptReqIn
->
Fall
,
ptReqOut
->
Rise
-
p
->
pSuperLib
->
tDelayInv
.
Rise
);
ptReqIn
->
Rise
=
MAP_MIN
(
ptReqIn
->
Rise
,
ptReqOut
->
Fall
-
p
->
pSuperLib
->
tDelayInv
.
Fall
);
}
}
// finalize the worst case computation
pNode
->
tRequired
[
0
].
Worst
=
MAP_MIN
(
pNode
->
tRequired
[
0
].
Fall
,
pNode
->
tRequired
[
0
].
Rise
);
pNode
->
tRequired
[
1
].
Worst
=
MAP_MIN
(
pNode
->
tRequired
[
1
].
Fall
,
pNode
->
tRequired
[
1
].
Rise
);
// skip the PIs
if
(
!
Map_NodeIsAnd
(
pNode
)
)
continue
;
// propagate required times of different phases of the node
// the ordering of phases does not matter since they are mapped independently
if
(
pNode
->
pCutBest
[
0
]
&&
pNode
->
tRequired
[
0
].
Worst
<
MAP_FLOAT_LARGE
)
Map_TimePropagateRequiredPhase
(
p
,
pNode
,
0
);
if
(
pNode
->
pCutBest
[
1
]
&&
pNode
->
tRequired
[
1
].
Worst
<
MAP_FLOAT_LARGE
)
Map_TimePropagateRequiredPhase
(
p
,
pNode
,
1
);
}
// in the end, we verify the required times
// for this, we compute the arrival times of the outputs of each phase
// of the supergates using the fanins' required times as the fanins' arrival times
// the resulting arrival time of the supergate should be less than the actual required time
for
(
k
=
0
;
k
<
vNodes
->
nSize
;
k
++
)
{
pNode
=
vNodes
->
pArray
[
k
];
if
(
!
Map_NodeIsAnd
(
pNode
)
)
continue
;
// verify that the required times are propagated correctly
// if ( pNode->pCutBest[0] && (pNode->nRefAct[0] > 0 || pNode->pCutBest[1] == NULL) )
if
(
pNode
->
pCutBest
[
0
]
&&
pNode
->
tRequired
[
0
].
Worst
<
MAP_FLOAT_LARGE
/
2
)
{
Map_MatchComputeReqTimes
(
pNode
->
pCutBest
[
0
],
0
,
ptReqOutTest
);
// assert( ptReqOutTest->Rise < pNode->tRequired[0].Rise + p->fEpsilon );
// assert( ptReqOutTest->Fall < pNode->tRequired[0].Fall + p->fEpsilon );
}
// if ( pNode->pCutBest[1] && (pNode->nRefAct[1] > 0 || pNode->pCutBest[0] == NULL) )
if
(
pNode
->
pCutBest
[
1
]
&&
pNode
->
tRequired
[
1
].
Worst
<
MAP_FLOAT_LARGE
/
2
)
{
Map_MatchComputeReqTimes
(
pNode
->
pCutBest
[
1
],
1
,
ptReqOutTest
);
// assert( ptReqOutTest->Rise < pNode->tRequired[1].Rise + p->fEpsilon );
// assert( ptReqOutTest->Fall < pNode->tRequired[1].Fall + p->fEpsilon );
}
}
}
/**Function*************************************************************
Synopsis [Computes the required times of the given nodes.]
Synopsis []
Description []
...
...
@@ -446,20 +213,6 @@ void Map_TimePropagateRequiredPhase( Map_Man_t * p, Map_Node_t * pNode, int fPha
assert
(
pNode
->
tArrival
[
fPhase
].
Rise
<
ptReqOut
->
Rise
+
p
->
fEpsilon
);
assert
(
pNode
->
tArrival
[
fPhase
].
Fall
<
ptReqOut
->
Fall
+
p
->
fEpsilon
);
}
/**Function*************************************************************
Synopsis [Computes the arrival times of the cut.]
Description [Computes the arrival times of the cut if it is implemented using
the given supergate with the given phase. Uses the constraint-type specification
of rise/fall arrival times.]
SideEffects []
SeeAlso []
***********************************************************************/
float
Map_MatchComputeReqTimes
(
Map_Cut_t
*
pCut
,
int
fPhase
,
Map_Time_t
*
ptArrRes
)
{
Map_Time_t
*
ptArrIn
;
...
...
@@ -518,6 +271,164 @@ float Map_MatchComputeReqTimes( Map_Cut_t * pCut, int fPhase, Map_Time_t * ptArr
}
/**Function*************************************************************
Synopsis [Computes the required times of all nodes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
Map_TimePropagateRequired
(
Map_Man_t
*
p
)
{
Map_Node_t
*
pNode
;
Map_Time_t
tReqOutTest
,
*
ptReqOutTest
=
&
tReqOutTest
;
Map_Time_t
*
ptReqIn
,
*
ptReqOut
;
int
fPhase
,
k
;
// go through the nodes in the reverse topological order
for
(
k
=
p
->
vMapObjs
->
nSize
-
1
;
k
>=
0
;
k
--
)
{
pNode
=
p
->
vMapObjs
->
pArray
[
k
];
if
(
pNode
->
nRefAct
[
2
]
==
0
)
continue
;
// propagate required times through the buffer
if
(
Map_NodeIsBuf
(
pNode
)
)
{
assert
(
pNode
->
p2
==
NULL
);
Map_Regular
(
pNode
->
p1
)
->
tRequired
[
Map_IsComplement
(
pNode
->
p1
)]
=
pNode
->
tRequired
[
0
];
Map_Regular
(
pNode
->
p1
)
->
tRequired
[
!
Map_IsComplement
(
pNode
->
p1
)]
=
pNode
->
tRequired
[
1
];
continue
;
}
// this computation works for regular nodes only
assert
(
!
Map_IsComplement
(
pNode
)
);
// at least one phase should be mapped
assert
(
pNode
->
pCutBest
[
0
]
!=
NULL
||
pNode
->
pCutBest
[
1
]
!=
NULL
);
// the node should be used in the currently assigned mapping
assert
(
pNode
->
nRefAct
[
0
]
>
0
||
pNode
->
nRefAct
[
1
]
>
0
);
// if one of the cuts is not given, project the required times from the other cut
if
(
pNode
->
pCutBest
[
0
]
==
NULL
||
pNode
->
pCutBest
[
1
]
==
NULL
)
{
// assert( 0 );
// get the missing phase
fPhase
=
(
pNode
->
pCutBest
[
1
]
==
NULL
);
// check if the missing phase is needed in the mapping
if
(
pNode
->
nRefAct
[
fPhase
]
>
0
)
{
// get the pointers to the required times of the missing phase
ptReqOut
=
pNode
->
tRequired
+
fPhase
;
// assert( ptReqOut->Fall < MAP_FLOAT_LARGE );
// get the pointers to the required times of the present phase
ptReqIn
=
pNode
->
tRequired
+
!
fPhase
;
// propagate the required times from the missing phase to the present phase
// tArrInv.Fall = pMatch->tArrive.Rise + p->pSuperLib->tDelayInv.Fall;
// tArrInv.Rise = pMatch->tArrive.Fall + p->pSuperLib->tDelayInv.Rise;
ptReqIn
->
Fall
=
MAP_MIN
(
ptReqIn
->
Fall
,
ptReqOut
->
Rise
-
p
->
pSuperLib
->
tDelayInv
.
Rise
);
ptReqIn
->
Rise
=
MAP_MIN
(
ptReqIn
->
Rise
,
ptReqOut
->
Fall
-
p
->
pSuperLib
->
tDelayInv
.
Fall
);
}
}
// finalize the worst case computation
pNode
->
tRequired
[
0
].
Worst
=
MAP_MIN
(
pNode
->
tRequired
[
0
].
Fall
,
pNode
->
tRequired
[
0
].
Rise
);
pNode
->
tRequired
[
1
].
Worst
=
MAP_MIN
(
pNode
->
tRequired
[
1
].
Fall
,
pNode
->
tRequired
[
1
].
Rise
);
// skip the PIs
if
(
!
Map_NodeIsAnd
(
pNode
)
)
continue
;
// propagate required times of different phases of the node
// the ordering of phases does not matter since they are mapped independently
if
(
pNode
->
pCutBest
[
0
]
&&
pNode
->
tRequired
[
0
].
Worst
<
MAP_FLOAT_LARGE
)
Map_TimePropagateRequiredPhase
(
p
,
pNode
,
0
);
if
(
pNode
->
pCutBest
[
1
]
&&
pNode
->
tRequired
[
1
].
Worst
<
MAP_FLOAT_LARGE
)
Map_TimePropagateRequiredPhase
(
p
,
pNode
,
1
);
}
// in the end, we verify the required times
// for this, we compute the arrival times of the outputs of each phase
// of the supergates using the fanins' required times as the fanins' arrival times
// the resulting arrival time of the supergate should be less than the actual required time
for
(
k
=
p
->
vMapObjs
->
nSize
-
1
;
k
>=
0
;
k
--
)
{
pNode
=
p
->
vMapObjs
->
pArray
[
k
];
if
(
pNode
->
nRefAct
[
2
]
==
0
)
continue
;
if
(
!
Map_NodeIsAnd
(
pNode
)
)
continue
;
// verify that the required times are propagated correctly
// if ( pNode->pCutBest[0] && (pNode->nRefAct[0] > 0 || pNode->pCutBest[1] == NULL) )
if
(
pNode
->
pCutBest
[
0
]
&&
pNode
->
tRequired
[
0
].
Worst
<
MAP_FLOAT_LARGE
/
2
)
{
Map_MatchComputeReqTimes
(
pNode
->
pCutBest
[
0
],
0
,
ptReqOutTest
);
// assert( ptReqOutTest->Rise < pNode->tRequired[0].Rise + p->fEpsilon );
// assert( ptReqOutTest->Fall < pNode->tRequired[0].Fall + p->fEpsilon );
}
// if ( pNode->pCutBest[1] && (pNode->nRefAct[1] > 0 || pNode->pCutBest[0] == NULL) )
if
(
pNode
->
pCutBest
[
1
]
&&
pNode
->
tRequired
[
1
].
Worst
<
MAP_FLOAT_LARGE
/
2
)
{
Map_MatchComputeReqTimes
(
pNode
->
pCutBest
[
1
],
1
,
ptReqOutTest
);
// assert( ptReqOutTest->Rise < pNode->tRequired[1].Rise + p->fEpsilon );
// assert( ptReqOutTest->Fall < pNode->tRequired[1].Fall + p->fEpsilon );
}
}
}
void
Map_TimeComputeRequiredGlobal
(
Map_Man_t
*
p
)
{
Map_Time_t
*
ptTime
,
*
ptTimeA
;
int
fPhase
,
i
;
// update the required times according to the target
p
->
fRequiredGlo
=
Map_TimeComputeArrivalMax
(
p
);
if
(
p
->
DelayTarget
!=
-
1
)
{
if
(
p
->
fRequiredGlo
>
p
->
DelayTarget
+
p
->
fEpsilon
)
{
if
(
p
->
fMappingMode
==
1
)
printf
(
"Cannot meet the target required times (%4.2f). Continue anyway.
\n
"
,
p
->
DelayTarget
);
}
else
if
(
p
->
fRequiredGlo
<
p
->
DelayTarget
-
p
->
fEpsilon
)
{
if
(
p
->
fMappingMode
==
1
&&
p
->
fVerbose
)
printf
(
"Relaxing the required times from (%4.2f) to the target (%4.2f).
\n
"
,
p
->
fRequiredGlo
,
p
->
DelayTarget
);
p
->
fRequiredGlo
=
p
->
DelayTarget
;
}
}
// clean the required times
for
(
i
=
0
;
i
<
p
->
vMapObjs
->
nSize
;
i
++
)
{
p
->
vMapObjs
->
pArray
[
i
]
->
tRequired
[
0
].
Rise
=
MAP_FLOAT_LARGE
;
p
->
vMapObjs
->
pArray
[
i
]
->
tRequired
[
0
].
Fall
=
MAP_FLOAT_LARGE
;
p
->
vMapObjs
->
pArray
[
i
]
->
tRequired
[
0
].
Worst
=
MAP_FLOAT_LARGE
;
p
->
vMapObjs
->
pArray
[
i
]
->
tRequired
[
1
].
Rise
=
MAP_FLOAT_LARGE
;
p
->
vMapObjs
->
pArray
[
i
]
->
tRequired
[
1
].
Fall
=
MAP_FLOAT_LARGE
;
p
->
vMapObjs
->
pArray
[
i
]
->
tRequired
[
1
].
Worst
=
MAP_FLOAT_LARGE
;
}
// set the required times for the POs
for
(
i
=
0
;
i
<
p
->
nOutputs
;
i
++
)
{
fPhase
=
!
Map_IsComplement
(
p
->
pOutputs
[
i
]);
ptTime
=
Map_Regular
(
p
->
pOutputs
[
i
])
->
tRequired
+
fPhase
;
ptTimeA
=
Map_Regular
(
p
->
pOutputs
[
i
])
->
tArrival
+
fPhase
;
// if external required time can be achieved, use it
if
(
p
->
pOutputRequireds
&&
p
->
pOutputRequireds
[
i
].
Worst
>
0
&&
ptTimeA
->
Worst
<=
p
->
pOutputRequireds
[
i
].
Worst
)
//&& p->pOutputRequireds[i].Worst <= p->fRequiredGlo )
ptTime
->
Rise
=
ptTime
->
Fall
=
ptTime
->
Worst
=
p
->
pOutputRequireds
[
i
].
Worst
;
// if external required cannot be achieved, set the earliest possible arrival time
else
if
(
p
->
pOutputRequireds
&&
p
->
pOutputRequireds
[
i
].
Worst
>
0
&&
ptTimeA
->
Worst
>
p
->
pOutputRequireds
[
i
].
Worst
)
ptTime
->
Rise
=
ptTime
->
Fall
=
ptTime
->
Worst
=
ptTimeA
->
Worst
;
// otherwise, set the global required time
else
ptTime
->
Rise
=
ptTime
->
Fall
=
ptTime
->
Worst
=
p
->
fRequiredGlo
;
}
// visit nodes in the reverse topological order
Map_TimePropagateRequired
(
p
);
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
...
...
src/map/mapper/mapperTruth.c
View file @
6f17c44e
...
...
@@ -51,11 +51,11 @@ void Map_MappingTruths( Map_Man_t * pMan )
Map_Cut_t
*
pCut
;
int
nNodes
,
i
;
// compute the cuts for the POs
nNodes
=
pMan
->
v
And
s
->
nSize
;
nNodes
=
pMan
->
v
MapObj
s
->
nSize
;
pProgress
=
Extra_ProgressBarStart
(
stdout
,
nNodes
);
for
(
i
=
0
;
i
<
nNodes
;
i
++
)
{
pNode
=
pMan
->
v
And
s
->
pArray
[
i
];
pNode
=
pMan
->
v
MapObj
s
->
pArray
[
i
];
if
(
!
Map_NodeIsAnd
(
pNode
)
)
continue
;
assert
(
pNode
->
pCuts
);
...
...
src/map/mapper/mapperUtils.c
View file @
6f17c44e
...
...
@@ -27,7 +27,6 @@ ABC_NAMESPACE_IMPL_START
#define MAP_CO_LIST_SIZE 5
static
void
Map_MappingDfs_rec
(
Map_Node_t
*
pNode
,
Map_NodeVec_t
*
vNodes
,
int
fCollectEquiv
);
static
int
Map_MappingCountLevels_rec
(
Map_Node_t
*
pNode
);
static
float
Map_MappingSetRefsAndArea_rec
(
Map_Man_t
*
pMan
,
Map_Node_t
*
pNode
);
static
float
Map_MappingSetRefsAndSwitch_rec
(
Map_Man_t
*
pMan
,
Map_Node_t
*
pNode
);
...
...
@@ -37,41 +36,12 @@ static float Map_MappingArea_rec( Map_Man_t * pMan, Map_Node_t * pNode, Map_Node
static
int
Map_MappingCompareOutputDelay
(
Map_Node_t
**
ppNode1
,
Map_Node_t
**
ppNode2
);
static
void
Map_MappingFindLatest
(
Map_Man_t
*
p
,
int
*
pNodes
,
int
nNodesMax
);
static
unsigned
Map_MappingExpandTruth_rec
(
unsigned
uTruth
,
int
nVars
);
static
void
Map_MappingGetChoiceLevels
(
Map_Man_t
*
pMan
,
Map_Node_t
*
p1
,
Map_Node_t
*
p2
,
int
*
pMin
,
int
*
pMax
);
static
float
Map_MappingGetChoiceVolumes
(
Map_Man_t
*
pMan
,
Map_Node_t
*
p1
,
Map_Node_t
*
p2
);
static
int
Map_MappingCountUsedNodes
(
Map_Man_t
*
pMan
,
int
fChoices
);
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Computes the DFS ordering of the nodes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Map_NodeVec_t
*
Map_MappingDfs
(
Map_Man_t
*
pMan
,
int
fCollectEquiv
)
{
Map_NodeVec_t
*
vNodes
;
int
i
;
// perform the traversal
vNodes
=
Map_NodeVecAlloc
(
100
);
for
(
i
=
0
;
i
<
pMan
->
nOutputs
;
i
++
)
Map_MappingDfs_rec
(
Map_Regular
(
pMan
->
pOutputs
[
i
]),
vNodes
,
fCollectEquiv
);
for
(
i
=
0
;
i
<
vNodes
->
nSize
;
i
++
)
vNodes
->
pArray
[
i
]
->
fMark0
=
0
;
// for ( i = 0; i < pMan->nOutputs; i++ )
// Map_MappingUnmark_rec( Map_Regular(pMan->pOutputs[i]) );
return
vNodes
;
}
/**Function*************************************************************
Synopsis [Computes the DFS ordering of the nodes.]
...
...
@@ -83,30 +53,6 @@ Map_NodeVec_t * Map_MappingDfs( Map_Man_t * pMan, int fCollectEquiv )
SeeAlso []
***********************************************************************/
Map_NodeVec_t
*
Map_MappingDfsNodes
(
Map_Man_t
*
pMan
,
Map_Node_t
**
ppCuts
,
int
nNodes
,
int
fEquiv
)
{
Map_NodeVec_t
*
vNodes
;
int
i
;
// perform the traversal
vNodes
=
Map_NodeVecAlloc
(
200
);
for
(
i
=
0
;
i
<
nNodes
;
i
++
)
Map_MappingDfs_rec
(
ppCuts
[
i
],
vNodes
,
fEquiv
);
for
(
i
=
0
;
i
<
vNodes
->
nSize
;
i
++
)
vNodes
->
pArray
[
i
]
->
fMark0
=
0
;
return
vNodes
;
}
/**Function*************************************************************
Synopsis [Recursively computes the DFS ordering of the nodes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
Map_MappingDfs_rec
(
Map_Node_t
*
pNode
,
Map_NodeVec_t
*
vNodes
,
int
fCollectEquiv
)
{
assert
(
!
Map_IsComplement
(
pNode
)
);
...
...
@@ -128,144 +74,21 @@ void Map_MappingDfs_rec( Map_Node_t * pNode, Map_NodeVec_t * vNodes, int fCollec
// add the node to the list
Map_NodeVecPush
(
vNodes
,
pNode
);
}
/**Function*************************************************************
Synopsis [Recursively computes the DFS ordering of the nodes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
Map_MappingDfsMarked1_rec
(
Map_Node_t
*
pNode
,
Map_NodeVec_t
*
vNodes
,
int
fFirst
)
{
assert
(
!
Map_IsComplement
(
pNode
)
);
if
(
pNode
->
fMark0
)
return
;
// visit the transitive fanin
if
(
Map_NodeIsAnd
(
pNode
)
)
{
Map_MappingDfsMarked1_rec
(
Map_Regular
(
pNode
->
p1
),
vNodes
,
0
);
Map_MappingDfsMarked1_rec
(
Map_Regular
(
pNode
->
p2
),
vNodes
,
0
);
}
// visit the equivalent nodes
if
(
!
fFirst
&&
pNode
->
pNextE
)
Map_MappingDfsMarked1_rec
(
pNode
->
pNextE
,
vNodes
,
0
);
// make sure the node is not visited through the equivalent nodes
assert
(
pNode
->
fMark0
==
0
);
// mark the node as visited
pNode
->
fMark0
=
1
;
// add the node to the list
Map_NodeVecPush
(
vNodes
,
pNode
);
}
/**Function*************************************************************
Synopsis [Recursively computes the DFS ordering of the nodes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
Map_MappingDfsMarked2_rec
(
Map_Node_t
*
pNode
,
Map_NodeVec_t
*
vNodes
,
Map_NodeVec_t
*
vBoundary
,
int
fFirst
)
{
assert
(
!
Map_IsComplement
(
pNode
)
);
if
(
pNode
->
fMark1
)
return
;
if
(
pNode
->
fMark0
||
Map_NodeIsVar
(
pNode
)
)
{
pNode
->
fMark1
=
1
;
Map_NodeVecPush
(
vBoundary
,
pNode
);
return
;
}
// visit the transitive fanin
if
(
Map_NodeIsAnd
(
pNode
)
)
{
Map_MappingDfsMarked2_rec
(
Map_Regular
(
pNode
->
p1
),
vNodes
,
vBoundary
,
0
);
Map_MappingDfsMarked2_rec
(
Map_Regular
(
pNode
->
p2
),
vNodes
,
vBoundary
,
0
);
}
// visit the equivalent nodes
if
(
!
fFirst
&&
pNode
->
pNextE
)
Map_MappingDfsMarked2_rec
(
pNode
->
pNextE
,
vNodes
,
vBoundary
,
0
);
// make sure the node is not visited through the equivalent nodes
assert
(
pNode
->
fMark1
==
0
);
// mark the node as visited
pNode
->
fMark1
=
1
;
// add the node to the list
Map_NodeVecPush
(
vNodes
,
pNode
);
}
/**Function*************************************************************
Synopsis [Recursively computes the DFS ordering of the nodes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
Map_MappingDfsMarked3_rec
(
Map_Node_t
*
pNode
,
Map_NodeVec_t
*
vNodes
)
{
assert
(
!
Map_IsComplement
(
pNode
)
);
if
(
pNode
->
fMark0
)
return
;
// visit the transitive fanin
if
(
Map_NodeIsAnd
(
pNode
)
)
{
Map_MappingDfsMarked3_rec
(
Map_Regular
(
pNode
->
p1
),
vNodes
);
Map_MappingDfsMarked3_rec
(
Map_Regular
(
pNode
->
p2
),
vNodes
);
}
// make sure the node is not visited through the equivalent nodes
assert
(
pNode
->
fMark0
==
0
);
// mark the node as visited
pNode
->
fMark0
=
1
;
// add the node to the list
Map_NodeVecPush
(
vNodes
,
pNode
);
}
/**Function*************************************************************
Synopsis [Recursively computes the DFS ordering of the nodes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
Map_MappingDfsMarked4_rec
(
Map_Node_t
*
pNode
,
Map_NodeVec_t
*
vNodes
)
Map_NodeVec_t
*
Map_MappingDfs
(
Map_Man_t
*
pMan
,
int
fCollectEquiv
)
{
assert
(
!
Map_IsComplement
(
pNode
)
);
if
(
pNode
->
fMark1
)
return
;
// visit the transitive fanin
if
(
Map_NodeIsAnd
(
pNode
)
)
{
Map_MappingDfsMarked4_rec
(
Map_Regular
(
pNode
->
p1
),
vNodes
);
Map_MappingDfsMarked4_rec
(
Map_Regular
(
pNode
->
p2
),
vNodes
);
}
// make sure the node is not visited through the equivalent nodes
assert
(
pNode
->
fMark1
==
0
);
// mark the node as visited
pNode
->
fMark1
=
1
;
// add the node to the list
Map_NodeVecPush
(
vNodes
,
pNode
);
Map_NodeVec_t
*
vNodes
;
int
i
;
// perform the traversal
vNodes
=
Map_NodeVecAlloc
(
100
);
for
(
i
=
0
;
i
<
pMan
->
nOutputs
;
i
++
)
Map_MappingDfs_rec
(
Map_Regular
(
pMan
->
pOutputs
[
i
]),
vNodes
,
fCollectEquiv
);
for
(
i
=
0
;
i
<
vNodes
->
nSize
;
i
++
)
vNodes
->
pArray
[
i
]
->
fMark0
=
0
;
// for ( i = 0; i < pMan->nOutputs; i++ )
// Map_MappingUnmark_rec( Map_Regular(pMan->pOutputs[i]) );
return
vNodes
;
}
/**Function*************************************************************
Synopsis [Computes the number of logic levels not counting PIs/POs.]
...
...
@@ -829,8 +652,8 @@ int Map_MappingCountDoubles( Map_Man_t * pMan, Map_NodeVec_t * vNodes )
void
Map_ManCleanData
(
Map_Man_t
*
p
)
{
int
i
;
for
(
i
=
0
;
i
<
p
->
v
NodesAll
->
nSize
;
i
++
)
p
->
v
NodesAll
->
pArray
[
i
]
->
pData0
=
p
->
vNodesAll
->
pArray
[
i
]
->
pData1
=
0
;
for
(
i
=
0
;
i
<
p
->
v
MapObjs
->
nSize
;
i
++
)
p
->
v
MapObjs
->
pArray
[
i
]
->
pData0
=
p
->
vMapObjs
->
pArray
[
i
]
->
pData1
=
0
;
}
/**Function*************************************************************
...
...
@@ -892,10 +715,10 @@ float Map_MappingComputeDelayWithFanouts( Map_Man_t * p )
Map_Node_t
*
pNode
;
float
Result
;
int
i
;
for
(
i
=
0
;
i
<
p
->
v
And
s
->
nSize
;
i
++
)
for
(
i
=
0
;
i
<
p
->
v
MapObj
s
->
nSize
;
i
++
)
{
// skip primary inputs
pNode
=
p
->
v
And
s
->
pArray
[
i
];
pNode
=
p
->
v
MapObj
s
->
pArray
[
i
];
if
(
!
Map_NodeIsAnd
(
pNode
)
)
continue
;
// skip a secondary node
...
...
@@ -1031,9 +854,9 @@ void Map_MappingReportChoices( Map_Man_t * pMan )
// report statistics about choices
nChoiceNodes
=
nChoices
=
0
;
for
(
i
=
0
;
i
<
pMan
->
v
And
s
->
nSize
;
i
++
)
for
(
i
=
0
;
i
<
pMan
->
v
MapObj
s
->
nSize
;
i
++
)
{
pNode
=
pMan
->
v
And
s
->
pArray
[
i
];
pNode
=
pMan
->
v
MapObj
s
->
pArray
[
i
];
if
(
pNode
->
pRepr
==
NULL
&&
pNode
->
pNextE
!=
NULL
)
{
// this is a choice node = the primary node that has equivalent nodes
nChoiceNodes
++
;
...
...
@@ -1056,89 +879,6 @@ void Map_MappingReportChoices( Map_Man_t * pMan )
SeeAlso []
***********************************************************************/
void
Map_MappingGetChoiceLevels
(
Map_Man_t
*
pMan
,
Map_Node_t
*
p1
,
Map_Node_t
*
p2
,
int
*
pMin
,
int
*
pMax
)
{
Map_NodeVec_t
*
vNodes
;
Map_NodeVec_t
*
vBoundary
;
Map_Node_t
*
pNode
;
int
i
,
Min
,
Max
;
vNodes
=
Map_NodeVecAlloc
(
100
);
vBoundary
=
Map_NodeVecAlloc
(
100
);
Map_MappingDfsMarked1_rec
(
p1
,
vNodes
,
1
);
Map_MappingDfsMarked2_rec
(
p2
,
vNodes
,
vBoundary
,
1
);
// clean the marks
Min
=
100000
;
Max
=
-
100000
;
for
(
i
=
0
;
i
<
vBoundary
->
nSize
;
i
++
)
{
pNode
=
vBoundary
->
pArray
[
i
];
if
(
Min
>
(
int
)
pNode
->
Level
)
Min
=
pNode
->
Level
;
if
(
Max
<
(
int
)
pNode
->
Level
)
Max
=
pNode
->
Level
;
}
Map_NodeVecFree
(
vBoundary
);
for
(
i
=
0
;
i
<
vNodes
->
nSize
;
i
++
)
{
pNode
=
vNodes
->
pArray
[
i
];
pNode
->
fMark0
=
pNode
->
fMark1
=
0
;
}
Map_NodeVecFree
(
vNodes
);
*
pMin
=
Min
;
*
pMax
=
Max
;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
float
Map_MappingGetChoiceVolumes
(
Map_Man_t
*
pMan
,
Map_Node_t
*
p1
,
Map_Node_t
*
p2
)
{
Map_NodeVec_t
*
vNodes
;
Map_Node_t
*
pNode
;
int
i
,
nVolumeTotal
,
nVolumeUnique
;
vNodes
=
Map_NodeVecAlloc
(
100
);
Map_MappingDfsMarked3_rec
(
p1
,
vNodes
);
Map_MappingDfsMarked4_rec
(
p2
,
vNodes
);
// clean the marks
nVolumeTotal
=
nVolumeUnique
=
0
;
for
(
i
=
0
;
i
<
vNodes
->
nSize
;
i
++
)
{
pNode
=
vNodes
->
pArray
[
i
];
if
(
!
Map_NodeIsAnd
(
pNode
)
)
continue
;
nVolumeTotal
++
;
if
(
pNode
->
fMark0
^
pNode
->
fMark1
)
nVolumeUnique
++
;
pNode
->
fMark0
=
pNode
->
fMark1
=
0
;
}
Map_NodeVecFree
(
vNodes
);
// return ((float)nVolumeUnique)/nVolumeTotal;
return
(
float
)
nVolumeUnique
;
}
/**Function*************************************************************
Synopsis [Computes the maximum and minimum levels of the choice nodes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int
Map_MappingCountUsedNodes
(
Map_Man_t
*
pMan
,
int
fChoices
)
{
Map_NodeVec_t
*
vNodes
;
...
...
src/map/mapper/mapperVec.c
View file @
6f17c44e
...
...
@@ -67,6 +67,8 @@ Map_NodeVec_t * Map_NodeVecAlloc( int nCap )
***********************************************************************/
void
Map_NodeVecFree
(
Map_NodeVec_t
*
p
)
{
if
(
p
==
NULL
)
return
;
ABC_FREE
(
p
->
pArray
);
ABC_FREE
(
p
);
}
...
...
@@ -82,6 +84,25 @@ void Map_NodeVecFree( Map_NodeVec_t * p )
SeeAlso []
***********************************************************************/
Map_NodeVec_t
*
Map_NodeVecDup
(
Map_NodeVec_t
*
p
)
{
Map_NodeVec_t
*
pNew
=
Map_NodeVecAlloc
(
p
->
nSize
);
memcpy
(
pNew
->
pArray
,
p
->
pArray
,
sizeof
(
int
)
*
p
->
nSize
);
pNew
->
nSize
=
p
->
nSize
;
return
pNew
;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Map_Node_t
**
Map_NodeVecReadArray
(
Map_NodeVec_t
*
p
)
{
return
p
->
pArray
;
...
...
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