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
655dc4e7
Commit
655dc4e7
authored
Aug 07, 2013
by
Alan Mishchenko
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Improvements to buffering and sizing.
parent
8576e4b4
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
159 additions
and
172 deletions
+159
-172
src/map/scl/sclSize.h
+30
-14
src/map/scl/sclUpsize.c
+129
-158
No files found.
src/map/scl/sclSize.h
View file @
655dc4e7
...
...
@@ -53,13 +53,13 @@ struct SC_Man_
Vec_Int_t
*
vUpdates2
;
// sizing updates in this round
// timing information
SC_Pair
*
pLoads
;
// loads for each gate
SC_Pair
*
pLoads2
;
// loads for each gate
SC_Pair
*
pLoads3
;
// loads for each gate
SC_Pair
*
pDepts
;
// departures for each gate
SC_Pair
*
pTimes
;
// arrivals for each gate
SC_Pair
*
pSlews
;
// slews for each gate
SC_Pair
*
pTimes2
;
// arrivals for each gate
SC_Pair
*
pSlews2
;
// slews for each gate
Vec_Flt_t
*
vLoads2
;
// backup storage for loads
Vec_Flt_t
*
vLoads3
;
// backup storage for loads
float
*
pSlack
;
// slacks for each gatt
float
*
pInDrive
;
// maximum input drive strength
Vec_Int_t
*
vBestFans
;
// best fanouts
...
...
@@ -103,8 +103,6 @@ static inline SC_Cell * Abc_SclObjCell( SC_Man * p, Abc_Obj_t * pObj )
static
inline
void
Abc_SclObjSetCell
(
SC_Man
*
p
,
Abc_Obj_t
*
pObj
,
SC_Cell
*
pCell
)
{
Vec_IntWriteEntry
(
p
->
vGates
,
Abc_ObjId
(
pObj
),
pCell
->
Id
);
}
static
inline
SC_Pair
*
Abc_SclObjLoad
(
SC_Man
*
p
,
Abc_Obj_t
*
pObj
)
{
return
p
->
pLoads
+
Abc_ObjId
(
pObj
);
}
static
inline
SC_Pair
*
Abc_SclObjLoad2
(
SC_Man
*
p
,
Abc_Obj_t
*
pObj
)
{
return
p
->
pLoads2
+
Abc_ObjId
(
pObj
);
}
static
inline
SC_Pair
*
Abc_SclObjLoad3
(
SC_Man
*
p
,
Abc_Obj_t
*
pObj
)
{
return
p
->
pLoads3
+
Abc_ObjId
(
pObj
);
}
static
inline
SC_Pair
*
Abc_SclObjDept
(
SC_Man
*
p
,
Abc_Obj_t
*
pObj
)
{
return
p
->
pDepts
+
Abc_ObjId
(
pObj
);
}
static
inline
SC_Pair
*
Abc_SclObjTime
(
SC_Man
*
p
,
Abc_Obj_t
*
pObj
)
{
return
p
->
pTimes
+
Abc_ObjId
(
pObj
);
}
static
inline
SC_Pair
*
Abc_SclObjSlew
(
SC_Man
*
p
,
Abc_Obj_t
*
pObj
)
{
return
p
->
pSlews
+
Abc_ObjId
(
pObj
);
}
...
...
@@ -153,8 +151,6 @@ static inline SC_Man * Abc_SclManAlloc( SC_Lib * pLib, Abc_Ntk_t * pNtk )
p
->
pNtk
=
pNtk
;
p
->
nObjs
=
Abc_NtkObjNumMax
(
pNtk
);
p
->
pLoads
=
ABC_CALLOC
(
SC_Pair
,
p
->
nObjs
);
p
->
pLoads2
=
ABC_CALLOC
(
SC_Pair
,
p
->
nObjs
);
p
->
pLoads3
=
ABC_CALLOC
(
SC_Pair
,
p
->
nObjs
);
p
->
pDepts
=
ABC_CALLOC
(
SC_Pair
,
p
->
nObjs
);
p
->
pTimes
=
ABC_CALLOC
(
SC_Pair
,
p
->
nObjs
);
p
->
pSlews
=
ABC_CALLOC
(
SC_Pair
,
p
->
nObjs
);
...
...
@@ -169,6 +165,8 @@ static inline SC_Man * Abc_SclManAlloc( SC_Lib * pLib, Abc_Ntk_t * pNtk )
Vec_QuePush
(
p
->
vQue
,
i
);
p
->
vUpdates
=
Vec_IntAlloc
(
1000
);
p
->
vUpdates2
=
Vec_IntAlloc
(
1000
);
p
->
vLoads2
=
Vec_FltAlloc
(
1000
);
p
->
vLoads3
=
Vec_FltAlloc
(
1000
);
// intermediate data
p
->
vNode2Gain
=
Vec_FltStart
(
p
->
nObjs
);
p
->
vNode2Gate
=
Vec_IntStart
(
p
->
nObjs
);
...
...
@@ -184,6 +182,8 @@ static inline void Abc_SclManFree( SC_Man * p )
Vec_FltFreeP
(
&
p
->
vNode2Gain
);
Vec_IntFreeP
(
&
p
->
vNode2Gate
);
// intermediate data
Vec_FltFreeP
(
&
p
->
vLoads2
);
Vec_FltFreeP
(
&
p
->
vLoads3
);
Vec_IntFreeP
(
&
p
->
vUpdates
);
Vec_IntFreeP
(
&
p
->
vUpdates2
);
Vec_IntFreeP
(
&
p
->
vGatesBest
);
...
...
@@ -194,8 +194,6 @@ static inline void Abc_SclManFree( SC_Man * p )
Vec_IntFreeP
(
&
p
->
vGates
);
Vec_IntFreeP
(
&
p
->
vBestFans
);
ABC_FREE
(
p
->
pLoads
);
ABC_FREE
(
p
->
pLoads2
);
ABC_FREE
(
p
->
pLoads3
);
ABC_FREE
(
p
->
pDepts
);
ABC_FREE
(
p
->
pTimes
);
ABC_FREE
(
p
->
pSlews
);
...
...
@@ -288,32 +286,50 @@ static inline void Abc_SclLoadStore( SC_Man * p, Abc_Obj_t * pObj )
{
Abc_Obj_t
*
pFanin
;
int
i
;
Vec_FltClear
(
p
->
vLoads2
);
Abc_ObjForEachFanin
(
pObj
,
pFanin
,
i
)
*
Abc_SclObjLoad2
(
p
,
pFanin
)
=
*
Abc_SclObjLoad
(
p
,
pFanin
);
{
Vec_FltPush
(
p
->
vLoads2
,
Abc_SclObjLoad
(
p
,
pFanin
)
->
rise
);
Vec_FltPush
(
p
->
vLoads2
,
Abc_SclObjLoad
(
p
,
pFanin
)
->
fall
);
}
}
static
inline
void
Abc_SclLoadRestore
(
SC_Man
*
p
,
Abc_Obj_t
*
pObj
)
{
Abc_Obj_t
*
pFanin
;
int
i
;
assert
(
Vec_FltSize
(
p
->
vLoads2
)
==
2
*
Abc_ObjFaninNum
(
pObj
)
);
Abc_ObjForEachFanin
(
pObj
,
pFanin
,
i
)
*
Abc_SclObjLoad
(
p
,
pFanin
)
=
*
Abc_SclObjLoad2
(
p
,
pFanin
);
{
Abc_SclObjLoad
(
p
,
pFanin
)
->
rise
=
Vec_FltEntry
(
p
->
vLoads2
,
2
*
i
);
Abc_SclObjLoad
(
p
,
pFanin
)
->
fall
=
Vec_FltEntry
(
p
->
vLoads2
,
2
*
i
+
1
);
}
}
static
inline
void
Abc_SclLoadStore3
(
SC_Man
*
p
,
Abc_Obj_t
*
pObj
)
{
Abc_Obj_t
*
pFanin
;
int
i
;
*
Abc_SclObjLoad3
(
p
,
pObj
)
=
*
Abc_SclObjLoad
(
p
,
pObj
);
Vec_FltClear
(
p
->
vLoads3
);
Abc_ObjForEachFanin
(
pObj
,
pFanin
,
i
)
*
Abc_SclObjLoad3
(
p
,
pFanin
)
=
*
Abc_SclObjLoad
(
p
,
pFanin
);
{
Vec_FltPush
(
p
->
vLoads3
,
Abc_SclObjLoad
(
p
,
pFanin
)
->
rise
);
Vec_FltPush
(
p
->
vLoads3
,
Abc_SclObjLoad
(
p
,
pFanin
)
->
fall
);
}
Vec_FltPush
(
p
->
vLoads3
,
Abc_SclObjLoad
(
p
,
pObj
)
->
rise
);
Vec_FltPush
(
p
->
vLoads3
,
Abc_SclObjLoad
(
p
,
pObj
)
->
fall
);
}
static
inline
void
Abc_SclLoadRestore3
(
SC_Man
*
p
,
Abc_Obj_t
*
pObj
)
{
Abc_Obj_t
*
pFanin
;
int
i
;
*
Abc_SclObjLoad
(
p
,
pObj
)
=
*
Abc_SclObjLoad3
(
p
,
pObj
);
assert
(
Vec_FltSize
(
p
->
vLoads3
)
==
2
*
Abc_ObjFaninNum
(
pObj
)
+
2
);
Abc_ObjForEachFanin
(
pObj
,
pFanin
,
i
)
*
Abc_SclObjLoad
(
p
,
pFanin
)
=
*
Abc_SclObjLoad3
(
p
,
pFanin
);
{
Abc_SclObjLoad
(
p
,
pFanin
)
->
rise
=
Vec_FltEntry
(
p
->
vLoads3
,
2
*
i
);
Abc_SclObjLoad
(
p
,
pFanin
)
->
fall
=
Vec_FltEntry
(
p
->
vLoads3
,
2
*
i
+
1
);
}
Abc_SclObjLoad
(
p
,
pObj
)
->
rise
=
Vec_FltEntry
(
p
->
vLoads3
,
2
*
i
);
Abc_SclObjLoad
(
p
,
pObj
)
->
fall
=
Vec_FltEntry
(
p
->
vLoads3
,
2
*
i
+
1
);
}
/**Function*************************************************************
...
...
src/map/scl/sclUpsize.c
View file @
655dc4e7
...
...
@@ -193,7 +193,7 @@ void Abc_SclUnmarkCriticalNodeWindow( SC_Man * p, Vec_Int_t * vPath )
SeeAlso []
***********************************************************************/
void
Abc_SclFindNodesToUpdate
(
Abc_Obj_t
*
pPivot
,
Vec_Int_t
**
pvNodes
,
Vec_Int_t
**
pvEvals
)
void
Abc_SclFindNodesToUpdate
(
Abc_Obj_t
*
pPivot
,
Vec_Int_t
**
pvNodes
,
Vec_Int_t
**
pvEvals
,
Abc_Obj_t
*
pExtra
)
{
Abc_Ntk_t
*
p
=
Abc_ObjNtk
(
pPivot
);
Abc_Obj_t
*
pObj
,
*
pNext
,
*
pNext2
;
...
...
@@ -208,6 +208,8 @@ void Abc_SclFindNodesToUpdate( Abc_Obj_t * pPivot, Vec_Int_t ** pvNodes, Vec_Int
if
(
Abc_ObjIsNode
(
pNext
)
&&
Abc_ObjFaninNum
(
pNext
)
>
0
)
Vec_IntPush
(
vNodes
,
Abc_ObjId
(
pNext
)
);
Vec_IntPush
(
vNodes
,
Abc_ObjId
(
pPivot
)
);
if
(
pExtra
)
Vec_IntPush
(
vNodes
,
Abc_ObjId
(
pExtra
)
);
Abc_ObjForEachFanout
(
pPivot
,
pNext
,
i
)
if
(
Abc_ObjIsNode
(
pNext
)
&&
pNext
->
fMarkA
)
{
...
...
@@ -243,6 +245,68 @@ void Abc_SclFindNodesToUpdate( Abc_Obj_t * pPivot, Vec_Int_t ** pvNodes, Vec_Int
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int
Abc_SclFindBestCell
(
SC_Man
*
p
,
Abc_Obj_t
*
pObj
,
Vec_Int_t
*
vRecalcs
,
Vec_Int_t
*
vEvals
,
int
Notches
,
int
DelayGap
,
float
*
pGainBest
)
{
SC_Cell
*
pCellOld
,
*
pCellNew
;
Abc_Obj_t
*
pTemp
;
float
dGain
,
dGainBest
,
gGainCur
;
int
k
,
n
,
gateBest
;
// save old gate, timing, fanin load
pCellOld
=
Abc_SclObjCell
(
p
,
pObj
);
Abc_SclConeStore
(
p
,
vRecalcs
);
Abc_SclLoadStore
(
p
,
pObj
);
// try different gate sizes for this node
gateBest
=
-
1
;
dGainBest
=
-
SC_LibTimeFromPs
(
p
->
pLib
,
DelayGap
);
SC_RingForEachCell
(
pCellOld
,
pCellNew
,
k
)
{
if
(
pCellNew
==
pCellOld
)
continue
;
if
(
k
>
Notches
)
break
;
if
(
p
->
pInDrive
&&
!
Abc_SclInputDriveOk
(
p
,
pObj
,
pCellNew
)
)
continue
;
// set new cell
Abc_SclObjSetCell
(
p
,
pObj
,
pCellNew
);
Abc_SclUpdateLoad
(
p
,
pObj
,
pCellOld
,
pCellNew
);
// recompute timing
Abc_SclTimeCone
(
p
,
vRecalcs
);
// set old cell
Abc_SclObjSetCell
(
p
,
pObj
,
pCellOld
);
Abc_SclLoadRestore
(
p
,
pObj
);
// evaluate gain
dGain
=
0
.
0
;
Abc_NtkForEachObjVec
(
vEvals
,
p
->
pNtk
,
pTemp
,
n
)
{
gGainCur
=
Abc_SclObjGain
(
p
,
pTemp
);
dGain
+=
(
gGainCur
>
0
)
?
gGainCur
:
2
.
0
*
gGainCur
;
}
dGain
/=
Vec_IntSize
(
vEvals
);
// save best gain
if
(
dGainBest
<
dGain
)
{
dGainBest
=
dGain
;
gateBest
=
pCellNew
->
Id
;
}
}
// put back old cell and timing
Abc_SclObjSetCell
(
p
,
pObj
,
pCellOld
);
Abc_SclConeRestore
(
p
,
vRecalcs
);
*
pGainBest
=
dGainBest
;
return
gateBest
;
}
/**Function*************************************************************
Synopsis [Computes the set of gates to upsize.]
Description []
...
...
@@ -257,35 +321,45 @@ int Abc_SclFindBypasses( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notc
SC_Cell
*
pCellOld
,
*
pCellNew
;
Vec_Ptr_t
*
vFanouts
;
Vec_Int_t
*
vRecalcs
,
*
vEvals
;
Abc_Obj_t
*
p
Obj
,
*
pTemp
,
*
pBuffer
,
*
pFanout
;
float
dGain
,
dGainBest
,
dGainBest2
;
int
i
,
j
,
k
,
n
,
gateBest
,
gateBest2
,
fanBest
,
Counter
=
0
;
Abc_Obj_t
*
p
Buf
,
*
pFanin
,
*
pFanout
,
*
pExtra
=
NULL
;
int
i
,
j
,
iNode
,
gateBest
,
gateBest2
,
fanBest
,
Counter
=
0
;
float
dGainBest
,
dGainBest2
;
// compute savings due to bypassing buffers
vFanouts
=
Vec_PtrAlloc
(
100
);
vRecalcs
=
Vec_IntAlloc
(
100
);
vEvals
=
Vec_IntAlloc
(
100
);
Vec_QueClear
(
p
->
vNodeByGain
);
Abc_NtkForEachObjVec
(
vPathNodes
,
p
->
pNtk
,
pBuf
fer
,
i
)
Abc_NtkForEachObjVec
(
vPathNodes
,
p
->
pNtk
,
pBuf
,
i
)
{
assert
(
pBuf
fer
->
fMarkC
==
0
);
if
(
Abc_ObjFaninNum
(
pBuf
fer
)
!=
1
)
assert
(
pBuf
->
fMarkC
==
0
);
if
(
Abc_ObjFaninNum
(
pBuf
)
!=
1
)
continue
;
p
Obj
=
Abc_ObjFanin0
(
pBuffer
);
if
(
!
Abc_ObjIsNode
(
p
Obj
)
)
p
Fanin
=
Abc_ObjFanin0
(
pBuf
);
if
(
!
Abc_ObjIsNode
(
p
Fanin
)
)
continue
;
// here we have pBuffer and its fanin pObj, which is a logic node
if
(
p
->
pNtk
->
vPhases
==
NULL
)
{
if
(
Abc_SclIsInv
(
pBuf
)
)
{
if
(
!
Abc_ObjIsNode
(
pFanin
)
||
!
Abc_SclIsInv
(
pFanin
)
)
continue
;
pFanin
=
Abc_ObjFanin0
(
pFanin
);
if
(
!
Abc_ObjIsNode
(
pFanin
)
)
continue
;
pExtra
=
pBuf
;
// we make pBuf and pFanin are in the same phase and pFanin is a node
}
}
// here we have pBuf and its fanin pFanin, which is a logic node
// compute nodes to recalculate timing and nodes to evaluate afterwards
Abc_SclFindNodesToUpdate
(
p
Obj
,
&
vRecalcs
,
&
vEvals
);
Abc_SclFindNodesToUpdate
(
p
Fanin
,
&
vRecalcs
,
&
vEvals
,
pExtra
);
assert
(
Vec_IntSize
(
vEvals
)
>
0
);
//printf( "%d -> %d\n", Vec_IntSize(vRecalcs), Vec_IntSize(vEvals) );
// consider fanouts of this node
fanBest
=
-
1
;
gateBest2
=
-
1
;
dGainBest2
=
0
;
Abc_NodeCollectFanouts
(
pBuf
fer
,
vFanouts
);
fanBest
=
-
1
;
gateBest2
=
-
1
;
dGainBest2
=
0
;
Abc_NodeCollectFanouts
(
pBuf
,
vFanouts
);
Vec_PtrForEachEntry
(
Abc_Obj_t
*
,
vFanouts
,
pFanout
,
j
)
{
// skip COs
...
...
@@ -295,52 +369,19 @@ int Abc_SclFindBypasses( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notc
if
(
!
pFanout
->
fMarkA
)
continue
;
// skip if fanin already has fanout as a fanout
if
(
Abc_NodeFindFanin
(
pFanout
,
p
Obj
)
>=
0
)
if
(
Abc_NodeFindFanin
(
pFanout
,
p
Fanin
)
>=
0
)
continue
;
// prepare
Abc_SclLoadStore3
(
p
,
pBuf
fer
);
Abc_SclUpdateLoadSplit
(
p
,
pBuf
fer
,
pFanout
);
Abc_ObjPatchFanin
(
pFanout
,
pBuf
fer
,
pObj
);
Abc_SclLoadStore3
(
p
,
pBuf
);
Abc_SclUpdateLoadSplit
(
p
,
pBuf
,
pFanout
);
Abc_ObjPatchFanin
(
pFanout
,
pBuf
,
pFanin
);
// size the fanin
// save old gate, timing, fanin load
pCellOld
=
Abc_SclObjCell
(
p
,
pObj
);
Abc_SclConeStore
(
p
,
vRecalcs
);
Abc_SclLoadStore
(
p
,
pObj
);
// try different gate sizes for the fanin
gateBest
=
-
1
;
dGainBest
=
-
SC_LibTimeFromPs
(
p
->
pLib
,
(
float
)
DelayGap
);
SC_RingForEachCell
(
pCellOld
,
pCellNew
,
k
)
{
if
(
pCellNew
==
pCellOld
)
continue
;
if
(
k
>
Notches
)
break
;
if
(
p
->
pInDrive
&&
!
Abc_SclInputDriveOk
(
p
,
pObj
,
pCellNew
)
)
continue
;
// set new cell
Abc_SclObjSetCell
(
p
,
pObj
,
pCellNew
);
Abc_SclUpdateLoad
(
p
,
pObj
,
pCellOld
,
pCellNew
);
// recompute timing
Abc_SclTimeCone
(
p
,
vRecalcs
);
// set old cell
Abc_SclObjSetCell
(
p
,
pObj
,
pCellOld
);
Abc_SclLoadRestore
(
p
,
pObj
);
// evaluate gain
dGain
=
0
.
0
;
Abc_NtkForEachObjVec
(
vEvals
,
p
->
pNtk
,
pTemp
,
n
)
dGain
+=
Abc_SclObjGain
(
p
,
pTemp
);
dGain
/=
Vec_IntSize
(
vEvals
);
// save best gain
if
(
dGainBest
<
dGain
)
{
dGainBest
=
dGain
;
gateBest
=
pCellNew
->
Id
;
}
}
// put back old cell and timing
Abc_SclObjSetCell
(
p
,
pObj
,
pCellOld
);
Abc_SclConeRestore
(
p
,
vRecalcs
);
gateBest
=
Abc_SclFindBestCell
(
p
,
pFanin
,
vRecalcs
,
vEvals
,
Notches
,
DelayGap
,
&
dGainBest
);
// unprepare
Abc_SclLoadRestore3
(
p
,
pBuf
);
Abc_ObjPatchFanin
(
pFanout
,
pFanin
,
pBuf
);
if
(
gateBest
==
-
1
)
continue
;
// compare gain
if
(
dGainBest2
<
dGainBest
)
{
...
...
@@ -348,24 +389,18 @@ int Abc_SclFindBypasses( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notc
gateBest2
=
gateBest
;
fanBest
=
Abc_ObjId
(
pFanout
);
}
Abc_SclLoadRestore3
(
p
,
pBuffer
);
Abc_ObjPatchFanin
(
pFanout
,
pObj
,
pBuffer
);
}
// remember savings
if
(
gateBest2
>=
0
)
{
assert
(
dGainBest2
>
0
.
0
);
Vec_FltWriteEntry
(
p
->
vNode2Gain
,
Abc_ObjId
(
pBuf
fer
),
dGainBest2
);
Vec_IntWriteEntry
(
p
->
vNode2Gate
,
Abc_ObjId
(
pBuf
fer
),
gateBest2
);
Vec_QuePush
(
p
->
vNodeByGain
,
Abc_ObjId
(
pBuf
fer
)
);
Vec_IntWriteEntry
(
p
->
vBestFans
,
Abc_ObjId
(
pBuf
fer
),
fanBest
);
Vec_FltWriteEntry
(
p
->
vNode2Gain
,
Abc_ObjId
(
pBuf
),
dGainBest2
);
Vec_IntWriteEntry
(
p
->
vNode2Gate
,
Abc_ObjId
(
pBuf
),
gateBest2
);
Vec_QuePush
(
p
->
vNodeByGain
,
Abc_ObjId
(
pBuf
)
);
Vec_IntWriteEntry
(
p
->
vBestFans
,
Abc_ObjId
(
pBuf
),
fanBest
);
}
if
(
++
Counter
==
17
)
break
;
// if ( ++Counter == 17 )
// break;
}
Vec_PtrFree
(
vFanouts
);
Vec_IntFree
(
vRecalcs
);
...
...
@@ -379,17 +414,17 @@ int Abc_SclFindBypasses( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notc
vFanouts
=
Vec_PtrAlloc
(
100
);
while
(
Vec_QueSize
(
p
->
vNodeByGain
)
)
{
i
nt
iNode
=
Vec_QuePop
(
p
->
vNodeByGain
);
Abc_Obj_t
*
pObj
=
Abc_NtkObj
(
p
->
pNtk
,
iNode
);
Abc_Obj_t
*
pFanout
=
Abc_NtkObj
(
p
->
pNtk
,
Vec_IntEntry
(
p
->
vBestFans
,
iNode
)
);
Abc_Obj_t
*
pFanin
=
Abc_ObjFanin0
(
pObj
);
if
(
p
Obj
->
fMarkC
||
pFanout
->
fMarkC
||
pFanin
->
fMarkC
)
i
Node
=
Vec_QuePop
(
p
->
vNodeByGain
);
pFanout
=
Abc_NtkObj
(
p
->
pNtk
,
Vec_IntEntry
(
p
->
vBestFans
,
iNode
)
);
pBuf
=
Abc_NtkObj
(
p
->
pNtk
,
iNode
);
pFanin
=
Abc_ObjFanin0
(
pBuf
);
if
(
p
Fanout
->
fMarkC
||
pBuf
->
fMarkC
||
pFanin
->
fMarkC
)
continue
;
pObj
->
fMarkC
=
1
;
pFanout
->
fMarkC
=
1
;
pBuf
->
fMarkC
=
1
;
pFanin
->
fMarkC
=
1
;
Vec_PtrPush
(
vFanouts
,
pObj
);
Vec_PtrPush
(
vFanouts
,
pFanout
);
Vec_PtrPush
(
vFanouts
,
pBuf
);
Vec_PtrPush
(
vFanouts
,
pFanin
);
// remember gain
if
(
dGainBest2
==
-
1
)
...
...
@@ -397,11 +432,11 @@ int Abc_SclFindBypasses( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notc
else
if
(
dGainBest2
>
2
*
Vec_FltEntry
(
p
->
vNode2Gain
,
iNode
)
)
break
;
// redirect
Abc_ObjPatchFanin
(
pFanout
,
p
Obj
,
pFanin
);
Abc_ObjPatchFanin
(
pFanout
,
p
Buf
,
pFanin
);
// remember
Vec_IntPush
(
p
->
vUpdates2
,
Abc_ObjId
(
pFanout
)
);
Vec_IntPush
(
p
->
vUpdates2
,
Abc_ObjId
(
pFanin
)
);
Vec_IntPush
(
p
->
vUpdates2
,
Abc_ObjId
(
p
Obj
)
);
Vec_IntPush
(
p
->
vUpdates2
,
Abc_ObjId
(
p
Buf
)
);
// find old and new gates
pCellOld
=
Abc_SclObjCell
(
p
,
pFanin
);
pCellNew
=
SC_LibCell
(
p
->
pLib
,
Vec_IntEntry
(
p
->
vNode2Gate
,
iNode
)
);
...
...
@@ -413,23 +448,23 @@ int Abc_SclFindBypasses( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notc
Vec_IntPush
(
p
->
vUpdates
,
pCellNew
->
Id
);
// remember when this node was upsized
Vec_IntWriteEntry
(
p
->
vNodeIter
,
Abc_ObjId
(
pFanout
),
0
);
Vec_IntWriteEntry
(
p
->
vNodeIter
,
Abc_ObjId
(
pBuf
),
0
);
Vec_IntWriteEntry
(
p
->
vNodeIter
,
Abc_ObjId
(
pFanin
),
0
);
Vec_IntWriteEntry
(
p
->
vNodeIter
,
Abc_ObjId
(
pObj
),
0
);
// update polarity
if
(
p
->
pNtk
->
vPhases
&&
Abc_SclIsInv
(
p
Obj
)
)
if
(
p
->
pNtk
->
vPhases
&&
Abc_SclIsInv
(
p
Buf
)
)
Abc_NodeInvUpdateObjFanoutPolarity
(
pFanin
,
pFanout
);
// report
if
(
fVeryVerbose
)
printf
(
"Node %6d Redir fanout %6d to fanin %6d. Gain = %7.1f ps. Replacing gate %12s by gate %12s.
\n
"
,
Abc_ObjId
(
p
Obj
),
Abc_ObjId
(
pFanout
),
Abc_ObjId
(
pFanin
),
Abc_ObjId
(
p
Buf
),
Abc_ObjId
(
pFanout
),
Abc_ObjId
(
pFanin
),
Vec_FltEntry
(
p
->
vNode2Gain
,
iNode
),
pCellOld
->
pName
,
pCellNew
->
pName
);
/*
// check if the node became useless
if ( Abc_ObjFanoutNum(p
Obj
) == 0 )
if ( Abc_ObjFanoutNum(p
Buf
) == 0 )
{
pCellOld = Abc_SclObjCell( p, p
Obj
);
pCellOld = Abc_SclObjCell( p, p
Buf
);
p->SumArea -= pCellOld->area;
Abc_NtkDeleteObj_rec( p
Obj
, 1 );
Abc_NtkDeleteObj_rec( p
Buf
, 1 );
printf( "Removed node %d.\n", iNode );
}
*/
...
...
@@ -438,32 +473,6 @@ int Abc_SclFindBypasses( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notc
Vec_PtrForEachEntry
(
Abc_Obj_t
*
,
vFanouts
,
pFanout
,
j
)
pFanout
->
fMarkC
=
0
;
Vec_PtrFree
(
vFanouts
);
/*
Limit = Abc_MinInt( Vec_QueSize(p->vNodeByGain), Abc_MaxInt((int)(0.01 * Ratio * Vec_IntSize(vPathNodes)), 1) );
//printf( "\nSelecting %d out of %d\n", Limit, Vec_QueSize(p->vNodeByGain) );
for ( i = 0; i < Limit; i++ )
{
// get the object
pObj = Abc_NtkObj( p->pNtk, Vec_QuePop(p->vNodeByGain) );
assert( pObj->fMarkA );
// find old and new gates
pCellOld = Abc_SclObjCell( p, pObj );
pCellNew = SC_LibCell( p->pLib, Vec_IntEntry(p->vNode2Gate, Abc_ObjId(pObj)) );
assert( pCellNew != NULL );
//printf( "%6d %20s -> %20s ", Abc_ObjId(pObj), pCellOld->pName, pCellNew->pName );
//printf( "gain is %f\n", Vec_FltEntry(p->vNode2Gain, Abc_ObjId(pObj)) );
// update gate
Abc_SclUpdateLoad( p, pObj, pCellOld, pCellNew );
p->SumArea += pCellNew->area - pCellOld->area;
Abc_SclObjSetCell( p, pObj, pCellNew );
// record the update
Vec_IntPush( p->vUpdates, Abc_ObjId(pObj) );
Vec_IntPush( p->vUpdates, pCellNew->Id );
// remember when this node was upsized
Vec_IntWriteEntry( p->vNodeIter, Abc_ObjId(pObj), iIter );
}
*/
return
Counter
;
}
...
...
@@ -533,9 +542,9 @@ int Abc_SclFindUpsizes( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notch
SC_Cell
*
pCellOld
,
*
pCellNew
;
Vec_Int_t
*
vRecalcs
,
*
vEvals
;
Vec_Ptr_t
*
vFanouts
;
Abc_Obj_t
*
pObj
,
*
pTemp
;
float
dGain
,
dGain
Best
,
dGainBest2
;
int
i
,
k
,
n
,
gateBest
,
Limit
,
Counter
,
iIterLast
;
Abc_Obj_t
*
pObj
;
float
dGainBest
,
dGainBest2
;
int
i
,
gateBest
,
Limit
,
Counter
,
iIterLast
;
// compute savings due to upsizing each node
vRecalcs
=
Vec_IntAlloc
(
100
);
...
...
@@ -548,47 +557,10 @@ int Abc_SclFindUpsizes( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notch
if
(
iIterLast
>=
0
&&
iIterLast
+
5
>
iIter
)
continue
;
// compute nodes to recalculate timing and nodes to evaluate afterwards
Abc_SclFindNodesToUpdate
(
pObj
,
&
vRecalcs
,
&
vEvals
);
Abc_SclFindNodesToUpdate
(
pObj
,
&
vRecalcs
,
&
vEvals
,
NULL
);
assert
(
Vec_IntSize
(
vEvals
)
>
0
);
//printf( "%d -> %d\n", Vec_IntSize(vRecalcs), Vec_IntSize(vEvals) );
// save old gate, timing, fanin load
pCellOld
=
Abc_SclObjCell
(
p
,
pObj
);
Abc_SclConeStore
(
p
,
vRecalcs
);
Abc_SclLoadStore
(
p
,
pObj
);
// try different gate sizes for this node
gateBest
=
-
1
;
dGainBest
=
-
SC_LibTimeFromPs
(
p
->
pLib
,
(
float
)
DelayGap
);
SC_RingForEachCell
(
pCellOld
,
pCellNew
,
k
)
{
if
(
pCellNew
==
pCellOld
)
continue
;
if
(
k
>
Notches
)
break
;
if
(
p
->
pInDrive
&&
!
Abc_SclInputDriveOk
(
p
,
pObj
,
pCellNew
)
)
continue
;
// set new cell
Abc_SclObjSetCell
(
p
,
pObj
,
pCellNew
);
Abc_SclUpdateLoad
(
p
,
pObj
,
pCellOld
,
pCellNew
);
// recompute timing
Abc_SclTimeCone
(
p
,
vRecalcs
);
// set old cell
Abc_SclObjSetCell
(
p
,
pObj
,
pCellOld
);
Abc_SclLoadRestore
(
p
,
pObj
);
// evaluate gain
dGain
=
0
.
0
;
Abc_NtkForEachObjVec
(
vEvals
,
p
->
pNtk
,
pTemp
,
n
)
dGain
+=
Abc_SclObjGain
(
p
,
pTemp
);
dGain
/=
Vec_IntSize
(
vEvals
);
// save best gain
if
(
dGainBest
<
dGain
)
{
dGainBest
=
dGain
;
gateBest
=
pCellNew
->
Id
;
}
}
// put back old cell and timing
Abc_SclObjSetCell
(
p
,
pObj
,
pCellOld
);
Abc_SclConeRestore
(
p
,
vRecalcs
);
gateBest
=
Abc_SclFindBestCell
(
p
,
pObj
,
vRecalcs
,
vEvals
,
Notches
,
DelayGap
,
&
dGainBest
);
// remember savings
if
(
gateBest
>=
0
)
{
...
...
@@ -819,9 +791,8 @@ void Abc_SclUpsizeRemoveDangling( SC_Man * p, Abc_Ntk_t * pNtk )
pCell
=
Abc_SclObjCell
(
p
,
pObj
);
p
->
SumArea
-=
pCell
->
area
;
Abc_NtkDeleteObj_rec
(
pObj
,
1
);
printf
(
"Removed node %d.
\n
"
,
i
);
//
printf( "Removed node %d.\n", i );
}
}
/**Function*************************************************************
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment