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
881b2ec4
Commit
881b2ec4
authored
Aug 08, 2013
by
Alan Mishchenko
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Integrated buffering and sizing.
parent
655dc4e7
Show whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
697 additions
and
99 deletions
+697
-99
abclib.dsp
+4
-0
src/base/abc/abc.h
+3
-0
src/base/abc/abcNtk.c
+2
-0
src/map/scl/module.make
+1
-0
src/map/scl/scl.c
+104
-0
src/map/scl/sclBufSize.c
+376
-0
src/map/scl/sclBuffer.c
+5
-10
src/map/scl/sclDnsize.c
+13
-10
src/map/scl/sclLib.c
+45
-5
src/map/scl/sclLib.h
+29
-8
src/map/scl/sclLoad.c
+3
-3
src/map/scl/sclSize.c
+17
-15
src/map/scl/sclSize.h
+17
-9
src/map/scl/sclUpsize.c
+29
-15
src/map/scl/sclUtil.c
+44
-24
src/misc/vec/vecFlt.h
+5
-0
No files found.
abclib.dsp
View file @
881b2ec4
...
...
@@ -2459,6 +2459,10 @@ SOURCE=.\src\map\scl\sclBuffer.c
# End Source File
# Begin Source File
SOURCE=.\src\map\scl\sclBufSize.c
# End Source File
# Begin Source File
SOURCE=.\src\map\scl\sclDnsize.c
# End Source File
# Begin Source File
...
...
src/base/abc/abc.h
View file @
881b2ec4
...
...
@@ -204,6 +204,9 @@ struct Abc_Ntk_t_
void
*
pExcare
;
// the EXDC network (if given)
void
*
pData
;
// misc
Abc_Ntk_t
*
pCopy
;
// copy of this network
void
*
pBSMan
;
// application manager
void
*
pSCLib
;
// SC library
Vec_Int_t
*
vGates
;
// SC library gates
Vec_Int_t
*
vPhases
;
// fanins phases in the mapped netlist
char
*
pWLoadUsed
;
// wire load model used
float
*
pLutTimes
;
// arrivals/requireds/slacks using LUT-delay model
...
...
src/base/abc/abcNtk.c
View file @
881b2ec4
...
...
@@ -1351,6 +1351,8 @@ void Abc_NtkDelete( Abc_Ntk_t * pNtk )
//printf( "deleting attr\n" );
Vec_AttFree
(
(
Vec_Att_t
*
)
pAttrMan
,
1
);
}
assert
(
pNtk
->
pSCLib
==
NULL
);
Vec_IntFreeP
(
&
pNtk
->
vGates
);
Vec_PtrFree
(
pNtk
->
vAttrs
);
ABC_FREE
(
pNtk
->
pWLoadUsed
);
ABC_FREE
(
pNtk
->
pName
);
...
...
src/map/scl/module.make
View file @
881b2ec4
SRC
+=
src/map/scl/scl.c
\
src/map/scl/sclBuffer.c
\
src/map/scl/sclBufSize.c
\
src/map/scl/sclDnsize.c
\
src/map/scl/sclLib.c
\
src/map/scl/sclLoad.c
\
...
...
src/map/scl/scl.c
View file @
881b2ec4
...
...
@@ -36,6 +36,7 @@ static int Scl_CommandPrintGS ( Abc_Frame_t * pAbc, int argc, char **argv );
static
int
Scl_CommandStime
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
);
static
int
Scl_CommandTopo
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
);
static
int
Scl_CommandBuffer
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
);
static
int
Scl_CommandBufSize
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
);
static
int
Scl_CommandUnBuffer
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
);
static
int
Scl_CommandMinsize
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
);
static
int
Scl_CommandMaxsize
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
);
...
...
@@ -69,6 +70,7 @@ void Scl_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd
(
pAbc
,
"SCL mapping"
,
"stime"
,
Scl_CommandStime
,
0
);
Cmd_CommandAdd
(
pAbc
,
"SCL mapping"
,
"topo"
,
Scl_CommandTopo
,
1
);
Cmd_CommandAdd
(
pAbc
,
"SCL mapping"
,
"buffer"
,
Scl_CommandBuffer
,
1
);
Cmd_CommandAdd
(
pAbc
,
"SCL mapping"
,
"bufsize"
,
Scl_CommandBufSize
,
1
);
Cmd_CommandAdd
(
pAbc
,
"SCL mapping"
,
"unbuffer"
,
Scl_CommandUnBuffer
,
1
);
Cmd_CommandAdd
(
pAbc
,
"SCL mapping"
,
"minsize"
,
Scl_CommandMinsize
,
1
);
Cmd_CommandAdd
(
pAbc
,
"SCL mapping"
,
"maxsize"
,
Scl_CommandMaxsize
,
1
);
...
...
@@ -701,6 +703,108 @@ usage:
SeeAlso []
***********************************************************************/
int
Scl_CommandBufSize
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
)
{
Abc_Ntk_t
*
pNtk
=
Abc_FrameReadNtk
(
pAbc
);
Abc_Ntk_t
*
pNtkRes
;
int
c
,
GainRatio
,
nDegree
,
fBufPis
,
fAddBufs
,
fVerbose
;
GainRatio
=
200
;
nDegree
=
4
;
fAddBufs
=
0
;
fBufPis
=
0
;
fVerbose
=
0
;
Extra_UtilGetoptReset
();
while
(
(
c
=
Extra_UtilGetopt
(
argc
,
argv
,
"GNbpvh"
)
)
!=
EOF
)
{
switch
(
c
)
{
case
'G'
:
if
(
globalUtilOptind
>=
argc
)
{
Abc_Print
(
-
1
,
"Command line switch
\"
-G
\"
should be followed by a positive integer.
\n
"
);
goto
usage
;
}
GainRatio
=
atoi
(
argv
[
globalUtilOptind
]);
globalUtilOptind
++
;
if
(
GainRatio
<
0
)
goto
usage
;
break
;
case
'N'
:
if
(
globalUtilOptind
>=
argc
)
{
Abc_Print
(
-
1
,
"Command line switch
\"
-N
\"
should be followed by a positive integer.
\n
"
);
goto
usage
;
}
nDegree
=
atoi
(
argv
[
globalUtilOptind
]);
globalUtilOptind
++
;
if
(
nDegree
<
0
)
goto
usage
;
break
;
case
'b'
:
fAddBufs
^=
1
;
break
;
case
'p'
:
fBufPis
^=
1
;
break
;
case
'v'
:
fVerbose
^=
1
;
break
;
case
'h'
:
goto
usage
;
default:
goto
usage
;
}
}
if
(
pNtk
==
NULL
)
{
Abc_Print
(
-
1
,
"Empty network.
\n
"
);
return
1
;
}
if
(
!
Abc_NtkIsLogic
(
pNtk
)
)
{
Abc_Print
(
-
1
,
"This command can only be applied to a logic network.
\n
"
);
return
1
;
}
if
(
!
fAddBufs
&&
pNtk
->
vPhases
==
NULL
)
{
Abc_Print
(
-
1
,
"Fanin phase information is not avaiable.
\n
"
);
return
1
;
}
// modify the current network
pNtkRes
=
Abc_SclBufSizePerform
(
pNtk
,
(
SC_Lib
*
)
pAbc
->
pLibScl
,
GainRatio
,
nDegree
,
fAddBufs
,
fBufPis
,
fVerbose
);
if
(
pNtkRes
==
NULL
)
{
Abc_Print
(
-
1
,
"The command has failed.
\n
"
);
return
1
;
}
// replace the current network
Abc_FrameReplaceCurrentNetwork
(
pAbc
,
pNtkRes
);
return
0
;
usage:
fprintf
(
pAbc
->
Err
,
"usage: bufsize [-GM num] [-bpvh]
\n
"
);
fprintf
(
pAbc
->
Err
,
"
\t
performs buffering and sizing and mapped network
\n
"
);
fprintf
(
pAbc
->
Err
,
"
\t
-G <num> : target gain percentage [default = %d]
\n
"
,
GainRatio
);
fprintf
(
pAbc
->
Err
,
"
\t
-M <num> : the maximum fanout degree [default = %d]
\n
"
,
nDegree
);
fprintf
(
pAbc
->
Err
,
"
\t
-b : toggle using buffers instead of inverters [default = %s]
\n
"
,
fAddBufs
?
"yes"
:
"no"
);
fprintf
(
pAbc
->
Err
,
"
\t
-p : toggle buffering primary inputs [default = %s]
\n
"
,
fBufPis
?
"yes"
:
"no"
);
fprintf
(
pAbc
->
Err
,
"
\t
-v : toggle printing verbose information [default = %s]
\n
"
,
fVerbose
?
"yes"
:
"no"
);
fprintf
(
pAbc
->
Err
,
"
\t
-h : print the command usage
\n
"
);
return
1
;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int
Scl_CommandUnBuffer
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
)
{
Abc_Ntk_t
*
pNtkRes
,
*
pNtk
=
Abc_FrameReadNtk
(
pAbc
);
...
...
src/map/scl/sclBufSize.c
0 → 100644
View file @
881b2ec4
/**CFile****************************************************************
FileName [sclBufSize.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Standard-cell library representation.]
Synopsis [Buffering and sizing combined.]
Author [Alan Mishchenko, Niklas Een]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - August 24, 2012.]
Revision [$Id: sclBufSize.c,v 1.0 2012/08/24 00:00:00 alanmi Exp $]
***********************************************************************/
#include "sclSize.h"
#include "map/mio/mio.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
typedef
struct
Bus_Man_t_
Bus_Man_t
;
struct
Bus_Man_t_
{
// parameters
float
Gain
;
// target gain
int
nDegree
;
// max branching factor
int
fBufPis
;
// use CI buffering
int
fVerbose
;
// verbose
// user data
Abc_Ntk_t
*
pNtk
;
// user's network
// library
SC_Lib
*
pLib
;
// cell library
SC_Cell
*
pInv
;
// base interter (largest/average/???)
// internal
Vec_Flt_t
*
vCins
;
// input cap for fanouts
Vec_Flt_t
*
vLoads
;
// loads for all nodes
Vec_Flt_t
*
vDepts
;
// departure times
};
static
inline
Bus_Man_t
*
Bus_SclObjMan
(
Abc_Obj_t
*
p
)
{
return
(
Bus_Man_t
*
)
p
->
pNtk
->
pBSMan
;
}
static
inline
float
Bus_SclObjCin
(
Abc_Obj_t
*
p
)
{
return
Vec_FltEntry
(
Bus_SclObjMan
(
p
)
->
vCins
,
Abc_ObjId
(
p
)
);
}
static
inline
void
Bus_SclObjSetCin
(
Abc_Obj_t
*
p
,
float
load
)
{
Vec_FltWriteEntry
(
Bus_SclObjMan
(
p
)
->
vCins
,
Abc_ObjId
(
p
),
load
);
}
static
inline
float
Bus_SclObjLoad
(
Abc_Obj_t
*
p
)
{
return
Vec_FltEntry
(
Bus_SclObjMan
(
p
)
->
vLoads
,
Abc_ObjId
(
p
)
);
}
static
inline
void
Bus_SclObjSetLoad
(
Abc_Obj_t
*
p
,
float
load
)
{
Vec_FltWriteEntry
(
Bus_SclObjMan
(
p
)
->
vLoads
,
Abc_ObjId
(
p
),
load
);
}
static
inline
float
Bus_SclObjDept
(
Abc_Obj_t
*
p
)
{
return
Vec_FltEntry
(
Bus_SclObjMan
(
p
)
->
vDepts
,
Abc_ObjId
(
p
)
);
}
static
inline
void
Bus_SclObjUpdateDept
(
Abc_Obj_t
*
p
,
float
dept
)
{
float
*
q
=
Vec_FltEntryP
(
Bus_SclObjMan
(
p
)
->
vDepts
,
Abc_ObjId
(
p
)
);
if
(
*
q
<
dept
)
*
q
=
dept
;
}
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Bus_Man_t
*
Bus_ManStart
(
Abc_Ntk_t
*
pNtk
,
SC_Lib
*
pLib
,
int
GainRatio
,
int
nDegree
,
int
fBufPis
,
int
fVerbose
)
{
Bus_Man_t
*
p
;
p
=
ABC_CALLOC
(
Bus_Man_t
,
1
);
p
->
Gain
=
0
.
01
*
GainRatio
;
p
->
nDegree
=
nDegree
;
p
->
fBufPis
=
fBufPis
;
p
->
fVerbose
=
fVerbose
;
p
->
pNtk
=
pNtk
;
p
->
pLib
=
pLib
;
p
->
pInv
=
Abc_SclFindInvertor
(
pLib
)
->
pAve
;
p
->
vCins
=
Vec_FltStart
(
2
*
Abc_NtkObjNumMax
(
pNtk
)
);
p
->
vLoads
=
Vec_FltStart
(
2
*
Abc_NtkObjNumMax
(
pNtk
)
);
p
->
vDepts
=
Vec_FltStart
(
2
*
Abc_NtkObjNumMax
(
pNtk
)
);
pNtk
->
pBSMan
=
p
;
return
p
;
}
void
Bus_ManStop
(
Bus_Man_t
*
p
)
{
Vec_FltFree
(
p
->
vCins
);
Vec_FltFree
(
p
->
vLoads
);
Vec_FltFree
(
p
->
vDepts
);
ABC_FREE
(
p
);
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
Bus_ManReadInOutLoads
(
Bus_Man_t
*
p
)
{
Abc_Time_t
*
pTime
;
Abc_Obj_t
*
pObj
;
int
i
;
// read input load
pTime
=
Abc_NtkReadDefaultInputDrive
(
p
->
pNtk
);
if
(
Abc_MaxFloat
(
pTime
->
Rise
,
pTime
->
Fall
)
!=
0
)
{
printf
(
"Default input drive strength is specified (%.2f ff; %.2f ff).
\n
"
,
pTime
->
Rise
,
pTime
->
Fall
);
Abc_NtkForEachPi
(
p
->
pNtk
,
pObj
,
i
)
Vec_FltWriteEntry
(
p
->
vLoads
,
Abc_ObjId
(
pObj
),
0
.
5
*
SC_LibCapFromFf
(
p
->
pLib
,
pTime
->
Rise
)
+
0
.
5
*
SC_LibCapFromFf
(
p
->
pLib
,
pTime
->
Fall
)
);
}
if
(
Abc_NodeReadInputDrive
(
p
->
pNtk
,
0
)
!=
NULL
)
{
printf
(
"Input drive strengths for some primary inputs are specified.
\n
"
);
Abc_NtkForEachPi
(
p
->
pNtk
,
pObj
,
i
)
{
pTime
=
Abc_NodeReadInputDrive
(
p
->
pNtk
,
i
);
Vec_FltWriteEntry
(
p
->
vLoads
,
Abc_ObjId
(
pObj
),
0
.
5
*
SC_LibCapFromFf
(
p
->
pLib
,
pTime
->
Rise
)
+
0
.
5
*
SC_LibCapFromFf
(
p
->
pLib
,
pTime
->
Fall
)
);
}
}
// read output load
pTime
=
Abc_NtkReadDefaultOutputLoad
(
p
->
pNtk
);
if
(
Abc_MaxFloat
(
pTime
->
Rise
,
pTime
->
Fall
)
!=
0
)
{
printf
(
"Default output load is specified (%.2f ff; %.2f ff).
\n
"
,
pTime
->
Rise
,
pTime
->
Fall
);
Abc_NtkForEachPo
(
p
->
pNtk
,
pObj
,
i
)
Vec_FltWriteEntry
(
p
->
vLoads
,
Abc_ObjId
(
pObj
),
0
.
5
*
SC_LibCapFromFf
(
p
->
pLib
,
pTime
->
Rise
)
+
0
.
5
*
SC_LibCapFromFf
(
p
->
pLib
,
pTime
->
Fall
)
);
}
if
(
Abc_NodeReadOutputLoad
(
p
->
pNtk
,
0
)
!=
NULL
)
{
printf
(
"Output loads for some primary outputs are specified.
\n
"
);
Abc_NtkForEachPo
(
p
->
pNtk
,
pObj
,
i
)
{
pTime
=
Abc_NodeReadOutputLoad
(
p
->
pNtk
,
i
);
Vec_FltWriteEntry
(
p
->
vLoads
,
Abc_ObjId
(
pObj
),
0
.
5
*
SC_LibCapFromFf
(
p
->
pLib
,
pTime
->
Rise
)
+
0
.
5
*
SC_LibCapFromFf
(
p
->
pLib
,
pTime
->
Fall
)
);
}
}
// read arrival/required times
}
/**Function*************************************************************
Synopsis [Compute load and departure times of the node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
Abc_NtkComputeFanoutCins
(
Abc_Obj_t
*
pObj
)
{
Abc_Obj_t
*
pFanout
;
int
i
;
Abc_ObjForEachFanout
(
pObj
,
pFanout
,
i
)
if
(
Abc_ObjIsNode
(
pFanout
)
)
Bus_SclObjSetCin
(
pFanout
,
SC_CellPinCap
(
Abc_SclObjCell
(
pFanout
),
Abc_NodeFindFanin
(
pFanout
,
pObj
)
)
);
}
float
Abc_NtkComputeNodeLoad
(
Abc_Obj_t
*
pObj
)
{
Abc_Obj_t
*
pFanout
;
float
Load
=
0
;
int
i
;
assert
(
Bus_SclObjLoad
(
pObj
)
==
0
);
Abc_ObjForEachFanout
(
pObj
,
pFanout
,
i
)
Load
+=
Bus_SclObjCin
(
pFanout
);
Bus_SclObjSetLoad
(
pObj
,
Load
);
return
Load
;
}
float
Abc_NtkComputeNodeDept
(
Abc_Obj_t
*
pObj
)
{
Abc_Obj_t
*
pFanout
;
float
Load
,
Dept
,
Edge
;
int
i
;
assert
(
Bus_SclObjDept
(
pObj
)
==
0
);
Abc_ObjForEachFanout
(
pObj
,
pFanout
,
i
)
{
if
(
Abc_ObjIsCo
(
pFanout
)
)
// add required times here
continue
;
Load
=
Bus_SclObjLoad
(
pFanout
);
Dept
=
Bus_SclObjDept
(
pFanout
);
Edge
=
Scl_LibPinTime
(
Abc_SclObjCell
(
pFanout
),
Abc_NodeFindFanin
(
pFanout
,
pObj
),
Load
);
Bus_SclObjUpdateDept
(
pObj
,
Dept
+
Edge
);
assert
(
Edge
>
0
);
assert
(
Load
>
0
);
}
return
Bus_SclObjDept
(
pObj
);
}
/*
void Abc_NtkUpdateFaninDeparture( Bus_Man_t * p, Abc_Obj_t * pObj, float Load )
{
SC_Cell * pCell = Abc_SclObjCell( pObj );
Abc_Obj_t * pFanin;
float Dept, Edge;
int i;
Dept = Bus_SclObjDept( pObj );
Abc_ObjForEachFanin( pObj, pFanin, i )
{
Edge = Scl_LibPinTime( pCell, i, Load );
Bus_SclObjUpdateDept( pFanin, Dept + Edge );
}
}
*/
/**Function*************************************************************
Synopsis [Compare two fanouts by their departure times.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int
Bus_SclCompareFanouts
(
Abc_Obj_t
**
pp1
,
Abc_Obj_t
**
pp2
)
{
float
Espilon
=
10
;
// 10 ps
if
(
Bus_SclObjDept
(
*
pp1
)
<
Bus_SclObjDept
(
*
pp2
)
-
Espilon
)
return
-
1
;
if
(
Bus_SclObjDept
(
*
pp1
)
>
Bus_SclObjDept
(
*
pp2
)
+
Espilon
)
return
1
;
if
(
Bus_SclObjCin
(
*
pp1
)
>
Bus_SclObjCin
(
*
pp2
)
-
Espilon
)
return
-
1
;
if
(
Bus_SclObjCin
(
*
pp1
)
<
Bus_SclObjCin
(
*
pp2
)
+
Espilon
)
return
1
;
return
-
1
;
}
void
Bus_SclInsertFanout
(
Vec_Ptr_t
*
vFanouts
,
Abc_Obj_t
*
pObj
)
{
Abc_Obj_t
*
pCur
;
int
i
,
k
;
assert
(
Bus_SclObjDept
(
pObj
)
>
0
);
assert
(
Bus_SclObjLoad
(
pObj
)
>
0
);
// compact array
for
(
i
=
k
=
0
;
i
<
Vec_PtrSize
(
vFanouts
);
i
++
)
if
(
Vec_PtrEntry
(
vFanouts
,
i
)
!=
NULL
)
Vec_PtrWriteEntry
(
vFanouts
,
k
++
,
Vec_PtrEntry
(
vFanouts
,
i
)
);
Vec_PtrShrink
(
vFanouts
,
k
);
// insert new entry
Vec_PtrPush
(
vFanouts
,
pObj
);
for
(
i
=
Vec_PtrSize
(
vFanouts
)
-
1
;
i
>
0
;
i
--
)
{
pCur
=
(
Abc_Obj_t
*
)
Vec_PtrEntry
(
vFanouts
,
i
-
1
);
pObj
=
(
Abc_Obj_t
*
)
Vec_PtrEntry
(
vFanouts
,
i
);
if
(
Bus_SclCompareFanouts
(
&
pCur
,
&
pObj
)
==
-
1
)
break
;
ABC_SWAP
(
void
*
,
Vec_PtrArray
(
vFanouts
)[
i
-
1
],
Vec_PtrArray
(
vFanouts
)[
i
]
);
}
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Obj_t
*
Abc_SclAddOneInv
(
Bus_Man_t
*
p
,
Abc_Obj_t
*
pObj
,
Vec_Ptr_t
*
vFanouts
,
float
Gain
,
int
Degree
)
{
SC_Cell
*
pCellNew
;
Abc_Obj_t
*
pFanout
,
*
pInv
;
float
Target
=
SC_CellPinCap
(
p
->
pInv
,
0
)
*
Gain
;
float
Load
=
0
;
int
i
,
iStop
;
Vec_PtrForEachEntryStop
(
Abc_Obj_t
*
,
vFanouts
,
pFanout
,
iStop
,
Degree
)
{
Load
+=
Bus_SclObjCin
(
pFanout
);
if
(
Load
>
Target
)
break
;
}
// create inverter
pInv
=
Abc_NtkCreateNodeInv
(
p
->
pNtk
,
NULL
);
assert
(
(
int
)
Abc_ObjId
(
pInv
)
<
Vec_FltSize
(
p
->
vDepts
)
);
Vec_PtrForEachEntryStop
(
Abc_Obj_t
*
,
vFanouts
,
pFanout
,
i
,
iStop
)
{
Vec_PtrWriteEntry
(
vFanouts
,
i
,
NULL
);
if
(
Abc_ObjFanin0
(
pFanout
)
==
NULL
)
Abc_ObjAddFanin
(
pFanout
,
pInv
);
else
Abc_ObjPatchFanin
(
pFanout
,
pObj
,
pInv
);
}
// set the gate
pCellNew
=
Abc_SclFindSmallestGate
(
p
->
pInv
,
Load
/
Gain
);
Vec_IntSetEntry
(
p
->
pNtk
->
vGates
,
Abc_ObjId
(
pInv
),
pCellNew
->
Id
);
Bus_SclObjSetCin
(
pInv
,
SC_CellPinCap
(
pCellNew
,
0
)
);
// update timing
Abc_NtkComputeNodeLoad
(
pInv
);
Abc_NtkComputeNodeDept
(
pInv
);
// update phases
if
(
p
->
pNtk
->
vPhases
&&
Abc_SclIsInv
(
pInv
)
)
Abc_NodeInvUpdateFanPolarity
(
pInv
);
return
pInv
;
}
void
Abc_SclBufSize
(
Bus_Man_t
*
p
)
{
SC_Cell
*
pCell
,
*
pCellNew
;
Vec_Ptr_t
*
vFanouts
;
Abc_Obj_t
*
pObj
,
*
pInv
;
float
Load
,
Cin
;
int
i
;
vFanouts
=
Vec_PtrAlloc
(
100
);
Abc_SclMioGates2SclGates
(
p
->
pLib
,
p
->
pNtk
);
Abc_NtkForEachNodeReverse
(
p
->
pNtk
,
pObj
,
i
)
{
// compute load
Abc_NtkComputeFanoutCins
(
pObj
);
Load
=
Abc_NtkComputeNodeLoad
(
pObj
);
// consider the gate
pCell
=
Abc_SclObjCell
(
pObj
);
Cin
=
SC_CellPinCapAve
(
pCell
->
pAve
);
// consider upsizing the gate
if
(
Load
>
p
->
Gain
*
Cin
)
{
// add one or more inverters
Abc_NodeCollectFanouts
(
pObj
,
vFanouts
);
Vec_PtrSort
(
vFanouts
,
(
int
(
*
)(
const
void
*
,
const
void
*
))
Bus_SclCompareFanouts
);
do
{
pInv
=
Abc_SclAddOneInv
(
p
,
pObj
,
vFanouts
,
p
->
Gain
,
p
->
nDegree
);
Bus_SclInsertFanout
(
vFanouts
,
pInv
);
Load
=
Bus_SclObjCin
(
pInv
);
}
while
(
Vec_PtrSize
(
vFanouts
)
>
1
||
Load
>
p
->
Gain
*
Cin
);
// connect last inverter
assert
(
Abc_ObjFanin0
(
pInv
)
==
NULL
);
Abc_ObjAddFanin
(
pInv
,
pObj
);
Bus_SclObjSetLoad
(
pObj
,
Load
);
}
// create cell
pCellNew
=
Abc_SclFindSmallestGate
(
pCell
,
Load
/
p
->
Gain
);
Abc_SclObjSetCell
(
pObj
,
pCellNew
);
Abc_NtkComputeNodeDept
(
pObj
);
}
Abc_SclSclGates2MioGates
(
p
->
pLib
,
p
->
pNtk
);
Vec_PtrFree
(
vFanouts
);
}
Abc_Ntk_t
*
Abc_SclBufSizePerform
(
Abc_Ntk_t
*
pNtk
,
SC_Lib
*
pLib
,
int
GainRatio
,
int
nDegree
,
int
fAddBufs
,
int
fBufPis
,
int
fVerbose
)
{
Abc_Ntk_t
*
pNtkNew
;
Bus_Man_t
*
p
;
if
(
!
Abc_SclCheckNtk
(
pNtk
,
0
)
)
return
NULL
;
Abc_SclReportDupFanins
(
pNtk
);
p
=
Bus_ManStart
(
pNtk
,
pLib
,
GainRatio
,
nDegree
,
fBufPis
,
fVerbose
);
Bus_ManReadInOutLoads
(
p
);
Abc_SclBufSize
(
p
);
Bus_ManStop
(
p
);
Vec_IntFillExtra
(
pNtk
->
vPhases
,
Abc_NtkObjNumMax
(
pNtk
),
0
);
pNtkNew
=
Abc_NtkDupDfs
(
pNtk
);
return
pNtkNew
;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END
src/map/scl/sclBuffer.c
View file @
881b2ec4
...
...
@@ -315,7 +315,7 @@ int Abc_SclCheckNtk( Abc_Ntk_t * p, int fVerbose )
SeeAlso []
***********************************************************************/
void
Abc_NodeInvUpdateFanPolarity
(
Abc_Obj_t
*
pObj
,
int
fVerbose
)
void
Abc_NodeInvUpdateFanPolarity
(
Abc_Obj_t
*
pObj
)
{
Abc_Obj_t
*
pFanout
;
int
i
;
...
...
@@ -323,22 +323,17 @@ void Abc_NodeInvUpdateFanPolarity( Abc_Obj_t * pObj, int fVerbose )
Abc_ObjForEachFanout
(
pObj
,
pFanout
,
i
)
{
if
(
Abc_SclObjIsBufInv
(
pFanout
)
)
Abc_NodeInvUpdateFanPolarity
(
pFanout
,
fVerbose
);
Abc_NodeInvUpdateFanPolarity
(
pFanout
);
else
{
Abc_ObjFaninFlipPhase
(
pFanout
,
Abc_NodeFindFanin
(
pFanout
,
pObj
)
);
// if ( fVerbose )
// printf( "Flipping fanin %d of node %d.\n", Abc_NodeFindFanin(pFanout, pObj), Abc_ObjId(pFanout) );
}
}
}
void
Abc_NodeInvUpdateObjFanoutPolarity
(
Abc_Obj_t
*
pObj
,
Abc_Obj_t
*
pFanout
)
{
if
(
Abc_SclObjIsBufInv
(
pFanout
)
)
Abc_NodeInvUpdateFanPolarity
(
pFanout
,
1
);
Abc_NodeInvUpdateFanPolarity
(
pFanout
);
else
Abc_ObjFaninFlipPhase
(
pFanout
,
Abc_NodeFindFanin
(
pFanout
,
pObj
)
);
// printf( "\n" );
}
int
Abc_NodeCompareLevels
(
Abc_Obj_t
**
pp1
,
Abc_Obj_t
**
pp2
)
{
...
...
@@ -413,7 +408,7 @@ Abc_Obj_t * Abc_SclPerformBufferingOne( Abc_Obj_t * pObj, int Degree, int fUseIn
Abc_ObjAddFanin
(
pBuffer
,
pObj
);
pBuffer
->
Level
=
Abc_SclComputeReverseLevel
(
pBuffer
);
if
(
fUseInvs
)
Abc_NodeInvUpdateFanPolarity
(
pBuffer
,
0
);
Abc_NodeInvUpdateFanPolarity
(
pBuffer
);
return
pBuffer
;
}
void
Abc_SclPerformBuffering_rec
(
Abc_Obj_t
*
pObj
,
int
DegreeR
,
int
Degree
,
int
fUseInvs
,
int
fVerbose
)
...
...
@@ -451,7 +446,7 @@ void Abc_SclPerformBuffering_rec( Abc_Obj_t * pObj, int DegreeR, int Degree, int
Abc_ObjAddFanin
(
pBuffer
,
pObj
);
pBuffer
->
Level
=
Abc_SclComputeReverseLevel
(
pBuffer
);
if
(
fUseInvs
)
Abc_NodeInvUpdateFanPolarity
(
pBuffer
,
0
);
Abc_NodeInvUpdateFanPolarity
(
pBuffer
);
}
// compute the new level of the node
pObj
->
Level
=
Abc_SclComputeReverseLevel
(
pObj
);
...
...
src/map/scl/sclDnsize.c
View file @
881b2ec4
...
...
@@ -102,13 +102,13 @@ int Abc_SclCheckImprovement( SC_Man * p, Abc_Obj_t * pObj, Vec_Int_t * vNodes, V
{
Abc_Obj_t
*
pTemp
;
SC_Cell
*
pCellOld
,
*
pCellNew
;
float
dGain
,
dGainBest
;
float
dGain
,
dGainBest
,
gGainCur
;
int
i
,
k
,
gateBest
;
abctime
clk
;
clk
=
Abc_Clock
();
// printf( "%d -> %d\n", Vec_IntSize(vNodes), Vec_IntSize(vEvals) );
// save old gate, timing, fanin load
pCellOld
=
Abc_SclObjCell
(
p
,
p
Obj
);
pCellOld
=
Abc_SclObjCell
(
pObj
);
Abc_SclConeStore
(
p
,
vNodes
);
Abc_SclLoadStore
(
p
,
pObj
);
// try different gate sizes for this node
...
...
@@ -123,18 +123,21 @@ clk = Abc_Clock();
if
(
p
->
pInDrive
&&
!
Abc_SclInputDriveOk
(
p
,
pObj
,
pCellNew
)
)
continue
;
// set new cell
Abc_SclObjSetCell
(
p
,
p
Obj
,
pCellNew
);
Abc_SclObjSetCell
(
pObj
,
pCellNew
);
Abc_SclUpdateLoad
(
p
,
pObj
,
pCellOld
,
pCellNew
);
// recompute timing
Abc_SclTimeCone
(
p
,
vNodes
);
// set old cell
Abc_SclObjSetCell
(
p
,
p
Obj
,
pCellOld
);
Abc_SclObjSetCell
(
pObj
,
pCellOld
);
Abc_SclLoadRestore
(
p
,
pObj
);
// evaluate gain
dGain
=
0
.
0
;
Abc_NtkForEachObjVec
(
vEvals
,
p
->
pNtk
,
pTemp
,
k
)
if
(
Abc_SclObjLegal
(
p
,
pTemp
,
p
->
MaxDelay0
)
)
dGain
+=
Abc_SclObjGain
(
p
,
pTemp
);
{
gGainCur
=
Abc_SclObjGain
(
p
,
pTemp
);
dGain
+=
(
gGainCur
>
0
)
?
gGainCur
:
1
.
0
*
gGainCur
;
}
else
break
;
if
(
k
<
Vec_IntSize
(
vEvals
)
)
...
...
@@ -148,13 +151,13 @@ clk = Abc_Clock();
}
}
// put back old cell and timing
Abc_SclObjSetCell
(
p
,
p
Obj
,
pCellOld
);
Abc_SclObjSetCell
(
pObj
,
pCellOld
);
Abc_SclConeRestore
(
p
,
vNodes
);
p
->
timeSize
+=
Abc_Clock
()
-
clk
;
if
(
gateBest
>=
0
)
{
pCellNew
=
SC_LibCell
(
p
->
pLib
,
gateBest
);
Abc_SclObjSetCell
(
p
,
p
Obj
,
pCellNew
);
Abc_SclObjSetCell
(
pObj
,
pCellNew
);
p
->
SumArea
+=
pCellNew
->
area
-
pCellOld
->
area
;
// printf( "%f %f -> %f\n", pCellNew->area - pCellOld->area, p->SumArea - (pCellNew->area - pCellOld->area), p->SumArea );
// printf( "%6d %20s -> %20s %f -> %f\n", Abc_ObjId(pObj), pCellOld->pName, pCellNew->pName, pCellOld->area, pCellNew->area );
...
...
@@ -187,7 +190,7 @@ void Abc_NtkCollectNodesByArea( SC_Man * p, Abc_Ntk_t * pNtk )
Abc_NtkForEachNode
(
pNtk
,
pObj
,
i
)
if
(
Abc_ObjFaninNum
(
pObj
)
>
0
)
{
Vec_FltWriteEntry
(
p
->
vNode2Gain
,
Abc_ObjId
(
pObj
),
Abc_SclObjCell
(
p
,
p
Obj
)
->
area
);
Vec_FltWriteEntry
(
p
->
vNode2Gain
,
Abc_ObjId
(
pObj
),
Abc_SclObjCell
(
pObj
)
->
area
);
Vec_QuePush
(
p
->
vNodeByGain
,
Abc_ObjId
(
pObj
)
);
}
}
...
...
@@ -267,7 +270,7 @@ void Abc_SclDnsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars
p
=
Abc_SclManStart
(
pLib
,
pNtk
,
pPars
->
fUseWireLoads
,
pPars
->
fUseDept
,
SC_LibTimeFromPs
(
pLib
,
pPars
->
DelayUser
),
pPars
->
BuffTreeEst
);
p
->
timeTotal
=
Abc_Clock
();
assert
(
p
->
vGatesBest
==
NULL
);
p
->
vGatesBest
=
Vec_IntDup
(
p
->
vGates
);
p
->
vGatesBest
=
Vec_IntDup
(
p
->
pNtk
->
vGates
);
// perform upsizing
vNodes
=
Vec_IntAlloc
(
1000
);
...
...
@@ -342,7 +345,7 @@ void Abc_SclDnsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars
printf
(
"Gate sizing timed out at %d seconds.
\n
"
,
pPars
->
TimeOut
);
// save the result and quit
Abc_Scl
ManSetGates
(
pLib
,
pNtk
,
p
->
vGates
);
// updates gate pointers
Abc_Scl
SclGates2MioGates
(
pLib
,
pNtk
);
// updates gate pointers
Abc_SclManFree
(
p
);
// Abc_NtkCleanMarkAB( pNtk );
}
...
...
src/map/scl/sclLib.c
View file @
881b2ec4
...
...
@@ -749,6 +749,7 @@ static int Abc_SclCompareCells( SC_Cell ** pp1, SC_Cell ** pp2 )
}
void
Abc_SclLinkCells
(
SC_Lib
*
p
)
{
Vec_Ptr_t
*
vList
;
SC_Cell
*
pCell
,
*
pRepr
=
NULL
;
int
i
,
k
;
assert
(
Vec_PtrSize
(
p
->
vCellClasses
)
==
0
);
...
...
@@ -770,30 +771,69 @@ void Abc_SclLinkCells( SC_Lib * p )
pRepr
->
pPrev
->
pNext
=
pCell
;
pCell
->
pNext
=
pRepr
;
pCell
->
pPrev
=
pRepr
->
pPrev
;
pRepr
->
pPrev
=
pCell
;
}
// sort cells by size the
the
n by name
// sort cells by size then by name
qsort
(
(
void
*
)
Vec_PtrArray
(
p
->
vCellClasses
),
Vec_PtrSize
(
p
->
vCellClasses
),
sizeof
(
void
*
),
(
int
(
*
)(
const
void
*
,
const
void
*
))
Abc_SclCompareCells
);
// sort cell lists
vList
=
Vec_PtrAlloc
(
100
);
SC_LibForEachCellClass
(
p
,
pRepr
,
k
)
{
Vec_Ptr
_t
*
vList
=
Vec_PtrAlloc
(
100
);
Vec_Ptr
Clear
(
vList
);
SC_RingForEachCell
(
pRepr
,
pCell
,
i
)
Vec_PtrPush
(
vList
,
pCell
);
qsort
(
(
void
*
)
Vec_PtrArray
(
vList
),
Vec_PtrSize
(
vList
),
sizeof
(
void
*
),
(
int
(
*
)(
const
void
*
,
const
void
*
))
Abc_SclCompareCells
);
// create new representative
pRepr
=
(
SC_Cell
*
)
Vec_PtrEntry
(
vList
,
0
);
pRepr
->
pNext
=
pRepr
->
pPrev
=
pRepr
;
pRepr
->
pRepr
=
pRepr
;
pRepr
->
pAve
=
(
SC_Cell
*
)
Vec_PtrEntry
(
vList
,
Vec_PtrSize
(
vList
)
/
2
);
pRepr
->
Order
=
0
;
pRepr
->
nGates
=
Vec_PtrSize
(
vList
);
// relink cells
Vec_PtrForEachEntryStart
(
SC_Cell
*
,
vList
,
pCell
,
i
,
1
)
{
pRepr
->
pPrev
->
pNext
=
pCell
;
pCell
->
pNext
=
pRepr
;
pCell
->
pPrev
=
pRepr
->
pPrev
;
pRepr
->
pPrev
=
pCell
;
pCell
->
pRepr
=
pRepr
;
pCell
->
pAve
=
(
SC_Cell
*
)
Vec_PtrEntry
(
vList
,
Vec_PtrSize
(
vList
)
/
2
);
pCell
->
Order
=
i
;
pCell
->
nGates
=
Vec_PtrSize
(
vList
);
}
// update list
Vec_PtrWriteEntry
(
p
->
vCellClasses
,
k
,
pRepr
);
Vec_PtrFree
(
vList
);
}
Vec_PtrFree
(
vList
);
}
/**Function*************************************************************
Synopsis [Returns the largest inverter.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
SC_Cell
*
Abc_SclFindInvertor
(
SC_Lib
*
p
)
{
SC_Cell
*
pCell
=
NULL
;
int
k
;
SC_LibForEachCellClass
(
p
,
pCell
,
k
)
if
(
pCell
->
n_inputs
==
1
&&
Vec_WrdEntry
(
SC_CellPin
(
pCell
,
1
)
->
vFunc
,
0
)
==
ABC_CONST
(
0x5555555555555555
)
)
break
;
// take representative
return
pCell
?
pCell
->
pRepr
:
NULL
;
}
SC_Cell
*
Abc_SclFindSmallestGate
(
SC_Cell
*
p
,
float
CinMin
)
{
SC_Cell
*
pRes
=
NULL
;
int
i
;
SC_RingForEachCell
(
p
->
pRepr
,
pRes
,
i
)
if
(
SC_CellPinCapAve
(
pRes
)
>
CinMin
)
return
pRes
;
// take the largest gate
return
p
->
pRepr
->
pPrev
;
}
/**Function*************************************************************
...
...
@@ -1066,8 +1106,8 @@ void Abc_SclPrintCells( SC_Lib * p, float Slew, float Gain )
printf
(
"D =%6.0f ps "
,
0
.
01
*
ED
*
Gain
+
PD
);
printf
(
"ED =%6.0f ps "
,
ED
);
printf
(
"PD =%6.0f ps "
,
PD
);
printf
(
"C =%5.1f ff "
,
Abc_SclGatePinCapAve
(
p
,
pCell
)
);
printf
(
"Lm =%5.1f ff "
,
0
.
01
*
Gain
*
Abc_SclGatePinCapAve
(
p
,
pCell
)
);
printf
(
"C =%5.1f ff "
,
SC_CellPinCapAve
(
pCell
)
);
printf
(
"Lm =%5.1f ff "
,
0
.
01
*
Gain
*
SC_CellPinCapAve
(
pCell
)
);
// printf( "MaxS =%5.1f ps ", SC_CellPin(pCell, pCell->n_inputs)->max_out_slew );
printf
(
"Lm2 =%5.0f ff "
,
SC_CellPin
(
pCell
,
pCell
->
n_inputs
)
->
max_out_cap
);
printf
(
"
\n
"
);
...
...
src/map/scl/sclLib.h
View file @
881b2ec4
...
...
@@ -178,7 +178,10 @@ struct SC_Cell_
int
n_outputs
;
// -- 'pins[n_inputs .. n_inputs+n_outputs-1]' are output pins
SC_Cell
*
pNext
;
// same-functionality cells linked into a ring by area
SC_Cell
*
pPrev
;
// same-functionality cells linked into a ring by area
SC_Cell
*
pRepr
;
// representative of the class
SC_Cell
*
pAve
;
// average size cell of this class
int
Order
;
// order of the gate in the list
int
nGates
;
// the number of gates in the list
};
struct
SC_Lib_
...
...
@@ -211,6 +214,7 @@ static inline SC_Cell * SC_LibCell( SC_Lib * p, int i ) { return (SC
static
inline
SC_Pin
*
SC_CellPin
(
SC_Cell
*
p
,
int
i
)
{
return
(
SC_Pin
*
)
Vec_PtrEntry
(
p
->
vPins
,
i
);
}
static
inline
Vec_Wrd_t
*
SC_CellFunc
(
SC_Cell
*
p
)
{
return
SC_CellPin
(
p
,
p
->
n_inputs
)
->
vFunc
;
}
static
inline
float
SC_CellPinCap
(
SC_Cell
*
p
,
int
i
)
{
return
0
.
5
*
(
SC_CellPin
(
p
,
i
)
->
rise_cap
+
SC_CellPin
(
p
,
i
)
->
fall_cap
);
}
static
inline
float
SC_CellPinCapAve
(
SC_Cell
*
p
)
{
int
i
;
float
c
=
0
;
for
(
i
=
0
;
i
<
p
->
n_inputs
;
i
++
)
c
+=
SC_CellPinCap
(
p
,
i
);
return
c
/
p
->
n_inputs
;
}
static
inline
char
*
SC_CellPinOutFunc
(
SC_Cell
*
p
,
int
i
)
{
return
SC_CellPin
(
p
,
p
->
n_inputs
+
i
)
->
func_text
;
}
static
inline
char
*
SC_CellPinName
(
SC_Cell
*
p
,
int
i
)
{
return
SC_CellPin
(
p
,
i
)
->
pName
;
}
...
...
@@ -519,7 +523,7 @@ static inline void Scl_LibPinDeparture( SC_Timing * pTime, SC_Pair * pDepIn, SC_
/**Function*************************************************************
Synopsis [Compute
s input capacitanc
e.]
Synopsis [Compute
one timing edg
e.]
Description []
...
...
@@ -528,17 +532,32 @@ static inline void Scl_LibPinDeparture( SC_Timing * pTime, SC_Pair * pDepIn, SC_
SeeAlso []
***********************************************************************/
static
inline
float
Abc_SclGatePinCapAve
(
SC_Lib
*
p
,
SC_Cell
*
pCell
)
static
inline
float
Scl_LibPinTime
(
SC_Cell
*
pCell
,
int
iPin
,
float
load
)
{
SC_Pin
*
pPin
;
int
k
;
float
Cap
=
0
.
0
;
SC_CellForEachPinIn
(
pCell
,
pPin
,
k
)
Cap
+=
0
.
5
*
(
pPin
->
rise_cap
+
pPin
->
fall_cap
);
return
Cap
/
pCell
->
n_inputs
;
SC_Timings
*
pRTime
;
SC_Timing
*
pTime
;
SC_Pair
Load
=
{
load
,
load
};
SC_Pair
ArrIn
=
{
0
.
0
,
0
.
0
};
SC_Pair
ArrOut
=
{
0
.
0
,
0
.
0
};
SC_Pair
SlewIn
=
{
0
.
0
,
0
.
0
};
SC_Pair
SlewOut
=
{
0
.
0
,
0
.
0
};
Vec_Flt_t
*
vIndex0
;
assert
(
iPin
>=
0
&&
iPin
<
pCell
->
n_inputs
);
pPin
=
SC_CellPin
(
pCell
,
pCell
->
n_inputs
);
// find timing info for this pin
assert
(
Vec_PtrSize
(
pPin
->
vRTimings
)
==
pCell
->
n_inputs
);
pRTime
=
(
SC_Timings
*
)
Vec_PtrEntry
(
pPin
->
vRTimings
,
iPin
);
assert
(
Vec_PtrSize
(
pRTime
->
vTimings
)
==
1
);
pTime
=
(
SC_Timing
*
)
Vec_PtrEntry
(
pRTime
->
vTimings
,
0
);
// get delay points
vIndex0
=
pTime
->
pCellRise
->
vIndex0
;
// slew
SlewIn
.
fall
=
Vec_FltEntry
(
vIndex0
,
Vec_FltSize
(
vIndex0
)
/
2
);
SlewIn
.
rise
=
Vec_FltEntry
(
vIndex0
,
Vec_FltSize
(
vIndex0
)
/
2
);
Scl_LibPinArrival
(
pTime
,
&
ArrIn
,
&
SlewIn
,
&
Load
,
&
ArrOut
,
&
SlewOut
);
return
0
.
5
*
(
ArrOut
.
fall
+
ArrOut
.
rise
);
}
/*=== sclLib.c ===============================================================*/
extern
SC_Lib
*
Abc_SclRead
(
char
*
pFileName
);
extern
void
Abc_SclWrite
(
char
*
pFileName
,
SC_Lib
*
p
);
...
...
@@ -550,6 +569,8 @@ extern int Abc_SclCellFind( SC_Lib * p, char * pName );
extern
int
Abc_SclClassCellNum
(
SC_Cell
*
pClass
);
extern
void
Abc_SclLinkCells
(
SC_Lib
*
p
);
extern
void
Abc_SclPrintCells
(
SC_Lib
*
p
,
float
Slew
,
float
Gain
);
extern
SC_Cell
*
Abc_SclFindInvertor
(
SC_Lib
*
p
);
extern
SC_Cell
*
Abc_SclFindSmallestGate
(
SC_Cell
*
p
,
float
CinMin
);
extern
SC_WireLoad
*
Abc_SclFindWireLoadModel
(
SC_Lib
*
p
,
float
Area
);
extern
SC_WireLoad
*
Abc_SclFetchWireLoadModel
(
SC_Lib
*
p
,
char
*
pName
);
extern
void
Abc_SclDumpGenlib
(
char
*
pFileName
,
SC_Lib
*
p
,
float
Slew
,
float
Gain
,
int
nGatesMin
);
...
...
src/map/scl/sclLoad.c
View file @
881b2ec4
...
...
@@ -94,7 +94,7 @@ void Abc_SclComputeLoad( SC_Man * p )
// add cell load
Abc_NtkForEachNode1
(
p
->
pNtk
,
pObj
,
i
)
{
SC_Cell
*
pCell
=
Abc_SclObjCell
(
p
,
p
Obj
);
SC_Cell
*
pCell
=
Abc_SclObjCell
(
pObj
);
Abc_ObjForEachFanin
(
pObj
,
pFanin
,
k
)
{
SC_Pair
*
pLoad
=
Abc_SclObjLoad
(
p
,
pFanin
);
...
...
@@ -142,7 +142,7 @@ void Abc_SclComputeLoad( SC_Man * p )
}
}
// calculate average load
if
(
p
->
EstLoadMax
)
//
if ( p->EstLoadMax )
{
double
TotalLoad
=
0
;
int
nObjs
=
0
;
...
...
@@ -194,7 +194,7 @@ void Abc_SclUpdateLoadSplit( SC_Man * p, Abc_Obj_t * pBuffer, Abc_Obj_t * pFanou
int
iFanin
=
Abc_NodeFindFanin
(
pFanout
,
pBuffer
);
assert
(
iFanin
>=
0
);
assert
(
Abc_ObjFaninNum
(
pBuffer
)
==
1
);
pPin
=
SC_CellPin
(
Abc_SclObjCell
(
p
,
p
Fanout
),
iFanin
);
pPin
=
SC_CellPin
(
Abc_SclObjCell
(
pFanout
),
iFanin
);
// update load of the buffer
pLoad
=
Abc_SclObjLoad
(
p
,
pBuffer
);
pLoad
->
rise
-=
pPin
->
rise_cap
;
...
...
src/map/scl/sclSize.c
View file @
881b2ec4
...
...
@@ -108,7 +108,7 @@ Abc_Obj_t * Abc_SclFindMostCriticalFanin( SC_Man * p, int * pfRise, Abc_Obj_t *
***********************************************************************/
static
inline
void
Abc_SclTimeNodePrint
(
SC_Man
*
p
,
Abc_Obj_t
*
pObj
,
int
fRise
,
int
Length
,
float
maxDelay
)
{
SC_Cell
*
pCell
=
Abc_ObjIsNode
(
pObj
)
?
Abc_SclObjCell
(
p
,
p
Obj
)
:
NULL
;
SC_Cell
*
pCell
=
Abc_ObjIsNode
(
pObj
)
?
Abc_SclObjCell
(
pObj
)
:
NULL
;
printf
(
"%6d : "
,
Abc_ObjId
(
pObj
)
);
printf
(
"%d "
,
Abc_ObjFaninNum
(
pObj
)
);
printf
(
"%4d "
,
Abc_ObjFanoutNum
(
pObj
)
);
...
...
@@ -118,7 +118,7 @@ static inline void Abc_SclTimeNodePrint( SC_Man * p, Abc_Obj_t * pObj, int fRise
printf
(
"%5.0f"
,
Abc_MaxFloat
(
Abc_SclObjTimePs
(
p
,
pObj
,
0
),
Abc_SclObjTimePs
(
p
,
pObj
,
1
))
);
printf
(
"%6.0f ps "
,
-
Abc_AbsFloat
(
Abc_SclObjTimePs
(
p
,
pObj
,
0
)
-
Abc_SclObjTimePs
(
p
,
pObj
,
1
))
);
printf
(
"S =%5.0f ps "
,
Abc_SclObjSlewPs
(
p
,
pObj
,
fRise
>=
0
?
fRise
:
0
)
);
printf
(
"Cin =%4.0f ff "
,
pCell
?
Abc_SclGatePinCapAve
(
p
->
pLib
,
pCell
)
:
0
.
0
);
printf
(
"Cin =%4.0f ff "
,
pCell
?
SC_CellPinCapAve
(
pCell
)
:
0
.
0
);
printf
(
"Cout =%5.0f ff "
,
Abc_SclObjLoadFf
(
p
,
pObj
,
fRise
>=
0
?
fRise
:
0
)
);
printf
(
"Cmax =%5.0f ff "
,
pCell
?
SC_CellPin
(
pCell
,
pCell
->
n_inputs
)
->
max_out_cap
:
0
.
0
);
printf
(
"G =%5.1f "
,
pCell
?
Abc_SclObjLoadAve
(
p
,
pObj
)
/
SC_CellPinCap
(
pCell
,
0
)
:
0
.
0
);
...
...
@@ -132,10 +132,13 @@ void Abc_SclTimeNtkPrint( SC_Man * p, int fShowAll, int fPrintPath )
float
maxDelay
=
Abc_SclObjTimePs
(
p
,
pPivot
,
fRise
);
p
->
ReportDelay
=
maxDelay
;
printf
(
"WireLoad model =
\"
%s
\"
. "
,
p
->
pWLoadUsed
?
p
->
pWLoadUsed
->
pName
:
"none"
);
printf
(
"Gates = %6d. "
,
Abc_NtkNodeNum
(
p
->
pNtk
)
);
printf
(
"Area = %12.2f. "
,
Abc_SclGetTotalArea
(
p
)
);
printf
(
"Critical delay = %8.2f ps
\n
"
,
maxDelay
);
printf
(
"WireLoad model =
\"
%s
\"
"
,
p
->
pWLoadUsed
?
p
->
pWLoadUsed
->
pName
:
"none"
);
printf
(
"Gates = %6d "
,
Abc_NtkNodeNum
(
p
->
pNtk
)
);
printf
(
"Cave = %5.1f "
,
p
->
EstLoadAve
);
printf
(
"Min = %5.1f %% "
,
100
.
0
*
Abc_SclCountMinSize
(
p
->
pLib
,
p
->
pNtk
,
0
)
/
Abc_NtkNodeNum
(
p
->
pNtk
)
);
printf
(
"Area = %12.2f "
,
Abc_SclGetTotalArea
(
p
)
);
printf
(
"Delay = %8.2f ps "
,
maxDelay
);
printf
(
"Min = %5.1f %%
\n
"
,
100
.
0
*
Abc_SclCountNearCriticalNodes
(
p
)
/
Abc_NtkNodeNum
(
p
->
pNtk
)
);
if
(
!
fPrintPath
)
return
;
...
...
@@ -145,7 +148,7 @@ void Abc_SclTimeNtkPrint( SC_Man * p, int fShowAll, int fPrintPath )
// find the longest cell name
Abc_NtkForEachNodeReverse
(
p
->
pNtk
,
pObj
,
i
)
if
(
Abc_ObjFaninNum
(
pObj
)
>
0
)
nLength
=
Abc_MaxInt
(
nLength
,
strlen
(
Abc_SclObjCell
(
p
,
p
Obj
)
->
pName
)
);
nLength
=
Abc_MaxInt
(
nLength
,
strlen
(
Abc_SclObjCell
(
pObj
)
->
pName
)
);
// print timing
Abc_NtkForEachNodeReverse
(
p
->
pNtk
,
pObj
,
i
)
if
(
Abc_ObjFaninNum
(
pObj
)
>
0
)
...
...
@@ -160,7 +163,7 @@ void Abc_SclTimeNtkPrint( SC_Man * p, int fShowAll, int fPrintPath )
while
(
pObj
&&
Abc_ObjIsNode
(
pObj
)
)
{
i
++
;
nLength
=
Abc_MaxInt
(
nLength
,
strlen
(
Abc_SclObjCell
(
p
,
p
Obj
)
->
pName
)
);
nLength
=
Abc_MaxInt
(
nLength
,
strlen
(
Abc_SclObjCell
(
pObj
)
->
pName
)
);
pObj
=
Abc_SclFindMostCriticalFanin
(
p
,
&
fRise
,
pObj
);
}
// print timing
...
...
@@ -244,7 +247,7 @@ void Abc_SclTimeNode( SC_Man * p, Abc_Obj_t * pObj, int fDept )
p
->
nEstNodes
++
;
}
// get the library cell
pCell
=
Abc_SclObjCell
(
p
,
p
Obj
);
pCell
=
Abc_SclObjCell
(
pObj
);
// get the output pin
// assert( pCell->n_outputs == 1 );
pPin
=
SC_CellPin
(
pCell
,
pCell
->
n_inputs
);
...
...
@@ -287,7 +290,7 @@ void Abc_SclTimeCone( SC_Man * p, Vec_Int_t * vCone )
Abc_NtkForEachObjVec
(
vCone
,
p
->
pNtk
,
pObj
,
i
)
{
if
(
fVerbose
&&
Abc_ObjIsNode
(
pObj
)
)
printf
(
" Updating node %d with gate %s
\n
"
,
Abc_ObjId
(
pObj
),
Abc_SclObjCell
(
p
,
p
Obj
)
->
pName
);
printf
(
" Updating node %d with gate %s
\n
"
,
Abc_ObjId
(
pObj
),
Abc_SclObjCell
(
pObj
)
->
pName
);
if
(
fVerbose
&&
Abc_ObjIsNode
(
pObj
)
)
printf
(
" before (%6.1f ps %6.1f ps) "
,
Abc_SclObjTimePs
(
p
,
pObj
,
1
),
Abc_SclObjTimePs
(
p
,
pObj
,
0
)
);
Abc_SclTimeNode
(
p
,
pObj
,
0
);
...
...
@@ -439,8 +442,7 @@ SC_Man * Abc_SclManStart( SC_Lib * pLib, Abc_Ntk_t * pNtk, int fUseWireLoads, in
p
->
EstLoadMax
=
0
.
01
*
nTreeCRatio
;
// max ratio of Cout/Cave when the estimation is used
p
->
EstLinear
=
100
;
// linear coefficient
}
assert
(
p
->
vGates
==
NULL
);
p
->
vGates
=
Abc_SclManFindGates
(
pLib
,
pNtk
);
Abc_SclMioGates2SclGates
(
pLib
,
pNtk
);
Abc_SclManReadSlewAndLoad
(
p
,
pNtk
);
if
(
fUseWireLoads
)
{
...
...
@@ -605,7 +607,7 @@ float Abc_SclCountNonBufferLoadInt( SC_Man * p, Abc_Obj_t * pObj )
Abc_ObjForEachFanout
(
pObj
,
pFanout
,
i
)
Load
+=
Abc_SclCountNonBufferLoadInt
(
p
,
pFanout
);
Load
+=
0
.
5
*
Abc_SclObjLoad
(
p
,
pObj
)
->
rise
+
0
.
5
*
Abc_SclObjLoad
(
p
,
pObj
)
->
fall
;
Load
-=
0
.
5
*
SC_CellPin
(
Abc_SclObjCell
(
p
,
pObj
),
0
)
->
rise_cap
+
0
.
5
*
SC_CellPin
(
Abc_SclObjCell
(
p
,
pObj
),
0
)
->
fall_cap
;
Load
-=
0
.
5
*
SC_CellPin
(
Abc_SclObjCell
(
p
Obj
),
0
)
->
rise_cap
+
0
.
5
*
SC_CellPin
(
Abc_SclObjCell
(
pObj
),
0
)
->
fall_cap
;
return
Load
;
}
float
Abc_SclCountNonBufferLoad
(
SC_Man
*
p
,
Abc_Obj_t
*
pObj
)
...
...
@@ -631,7 +633,7 @@ void Abc_SclPrintBuffersOne( SC_Man * p, Abc_Obj_t * pObj, int nOffset )
Abc_SclCountNonBufferFanouts
(
pObj
)
);
for
(
;
i
<
4
;
i
++
)
printf
(
" "
);
printf
(
"a =%5.2f "
,
Abc_ObjIsPi
(
pObj
)
?
0
:
Abc_SclObjCell
(
p
,
p
Obj
)
->
area
);
printf
(
"a =%5.2f "
,
Abc_ObjIsPi
(
pObj
)
?
0
:
Abc_SclObjCell
(
pObj
)
->
area
);
printf
(
"d = ("
);
printf
(
"%6.0f ps; "
,
Abc_SclObjTimePs
(
p
,
pObj
,
1
)
);
printf
(
"%6.0f ps) "
,
Abc_SclObjTimePs
(
p
,
pObj
,
0
)
);
...
...
@@ -740,7 +742,7 @@ Vec_Wec_t * Abc_SclSelectSplitNodes( SC_Man * p, Abc_Ntk_t * pNtk )
/*
printf( "%d : %.0f ", i, 0.5 * (Abc_SclObjLoad(p, pObj)->fall + Abc_SclObjLoad(p, pObj)->rise) );
Abc_ObjForEachFanout( pObj, pFanout, k )
printf( "%.1f ",
Abc_SclGatePinCapAve(p->pLib, Abc_SclObjCell(p,
pFanout)) );
printf( "%.1f ",
SC_CellPinCapAve(Abc_SclObjCell(
pFanout)) );
printf( "\n" );
*/
// skip non-critical nodes
...
...
src/map/scl/sclSize.h
View file @
881b2ec4
...
...
@@ -47,7 +47,7 @@ struct SC_Man_
Abc_Ntk_t
*
pNtk
;
// network
int
nObjs
;
// allocated size
// get assignment
Vec_Int_t
*
vGates
;
// mapping of objId into gateId
//
Vec_Int_t * vGates; // mapping of objId into gateId
Vec_Int_t
*
vGatesBest
;
// best gate sizes found so far
Vec_Int_t
*
vUpdates
;
// sizing updates in this round
Vec_Int_t
*
vUpdates2
;
// sizing updates in this round
...
...
@@ -99,8 +99,9 @@ struct SC_Man_
/// MACRO DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
static
inline
SC_Cell
*
Abc_SclObjCell
(
SC_Man
*
p
,
Abc_Obj_t
*
pObj
)
{
return
SC_LibCell
(
p
->
pLib
,
Vec_IntEntry
(
p
->
vGates
,
Abc_ObjId
(
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_Lib
*
Abc_SclObjLib
(
Abc_Obj_t
*
p
)
{
return
(
SC_Lib
*
)
p
->
pNtk
->
pSCLib
;
}
static
inline
SC_Cell
*
Abc_SclObjCell
(
Abc_Obj_t
*
p
)
{
return
SC_LibCell
(
Abc_SclObjLib
(
p
),
Vec_IntEntry
(
p
->
pNtk
->
vGates
,
Abc_ObjId
(
p
))
);
}
static
inline
void
Abc_SclObjSetCell
(
Abc_Obj_t
*
p
,
SC_Cell
*
pCell
)
{
Vec_IntWriteEntry
(
p
->
pNtk
->
vGates
,
Abc_ObjId
(
p
),
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_SclObjDept
(
SC_Man
*
p
,
Abc_Obj_t
*
pObj
)
{
return
p
->
pDepts
+
Abc_ObjId
(
pObj
);
}
...
...
@@ -177,6 +178,8 @@ static inline SC_Man * Abc_SclManAlloc( SC_Lib * pLib, Abc_Ntk_t * pNtk )
}
static
inline
void
Abc_SclManFree
(
SC_Man
*
p
)
{
p
->
pNtk
->
pSCLib
=
NULL
;
Vec_IntFreeP
(
&
p
->
pNtk
->
vGates
);
Vec_IntFreeP
(
&
p
->
vNodeIter
);
Vec_QueFreeP
(
&
p
->
vNodeByGain
);
Vec_FltFreeP
(
&
p
->
vNode2Gain
);
...
...
@@ -191,7 +194,7 @@ static inline void Abc_SclManFree( SC_Man * p )
Vec_QueCheck
(
p
->
vQue
);
Vec_QueFreeP
(
&
p
->
vQue
);
Vec_FltFreeP
(
&
p
->
vTimesOut
);
Vec_IntFreeP
(
&
p
->
vGates
);
//
Vec_IntFreeP( &p->vGates );
Vec_IntFreeP
(
&
p
->
vBestFans
);
ABC_FREE
(
p
->
pLoads
);
ABC_FREE
(
p
->
pDepts
);
...
...
@@ -349,7 +352,7 @@ static inline float Abc_SclGetTotalArea( SC_Man * p )
Abc_Obj_t
*
pObj
;
int
i
;
Abc_NtkForEachNode1
(
p
->
pNtk
,
pObj
,
i
)
Area
+=
Abc_SclObjCell
(
p
,
pObj
)
->
area
;
Area
+=
Abc_SclObjCell
(
pObj
)
->
area
;
return
Area
;
}
static
inline
float
Abc_SclGetMaxDelay
(
SC_Man
*
p
)
...
...
@@ -389,7 +392,7 @@ static inline float Abc_SclReadMaxDelay( SC_Man * p )
***********************************************************************/
static
inline
SC_Cell
*
Abc_SclObjResiable
(
SC_Man
*
p
,
Abc_Obj_t
*
pObj
,
int
fUpsize
)
{
SC_Cell
*
pOld
=
Abc_SclObjCell
(
p
,
pObj
);
SC_Cell
*
pOld
=
Abc_SclObjCell
(
pObj
);
if
(
fUpsize
)
return
pOld
->
pNext
->
Order
>
pOld
->
Order
?
pOld
->
pNext
:
NULL
;
else
...
...
@@ -435,10 +438,13 @@ static inline void Abc_SclDumpStats( SC_Man * p, char * pFileName, abctime Time
fclose
(
pTable
);
}
/*=== sclBufSize.c ===============================================================*/
extern
Abc_Ntk_t
*
Abc_SclBufSizePerform
(
Abc_Ntk_t
*
pNtk
,
SC_Lib
*
pLib
,
int
GainRatio
,
int
nDegree
,
int
fAddBufs
,
int
fBufPis
,
int
fVerbose
);
/*=== sclBuffer.c ===============================================================*/
extern
int
Abc_SclIsInv
(
Abc_Obj_t
*
pObj
);
extern
void
Abc_NodeInvUpdateFanPolarity
(
Abc_Obj_t
*
pObj
);
extern
void
Abc_NodeInvUpdateObjFanoutPolarity
(
Abc_Obj_t
*
pObj
,
Abc_Obj_t
*
pFanout
);
extern
void
Abc_SclReportDupFanins
(
Abc_Ntk_t
*
pNtk
);
extern
Abc_Ntk_t
*
Abc_SclUnBufferPerform
(
Abc_Ntk_t
*
pNtk
,
int
fVerbose
);
extern
Abc_Ntk_t
*
Abc_SclUnBufferPhase
(
Abc_Ntk_t
*
pNtk
,
int
fVerbose
);
extern
Abc_Ntk_t
*
Abc_SclBufferPhase
(
Abc_Ntk_t
*
pNtk
,
int
fVerbose
);
...
...
@@ -462,12 +468,14 @@ extern void Abc_SclTimePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, int nT
extern
void
Abc_SclPrintBuffers
(
SC_Lib
*
pLib
,
Abc_Ntk_t
*
pNtk
,
int
fVerbose
);
extern
int
Abc_SclInputDriveOk
(
SC_Man
*
p
,
Abc_Obj_t
*
pObj
,
SC_Cell
*
pCell
);
/*=== sclUpsize.c ===============================================================*/
extern
int
Abc_SclCountNearCriticalNodes
(
SC_Man
*
p
);
extern
void
Abc_SclUpsizePerform
(
SC_Lib
*
pLib
,
Abc_Ntk_t
*
pNtk
,
SC_SizePars
*
pPars
);
/*=== sclUtil.c ===============================================================*/
extern
Vec_Int_t
*
Abc_SclManFind
Gates
(
SC_Lib
*
pLib
,
Abc_Ntk_t
*
p
);
extern
void
Abc_Scl
ManSetGates
(
SC_Lib
*
pLib
,
Abc_Ntk_t
*
p
,
Vec_Int_t
*
vGates
);
extern
void
Abc_SclMioGates2Scl
Gates
(
SC_Lib
*
pLib
,
Abc_Ntk_t
*
p
);
extern
void
Abc_Scl
SclGates2MioGates
(
SC_Lib
*
pLib
,
Abc_Ntk_t
*
p
);
extern
void
Abc_SclPrintGateSizes
(
SC_Lib
*
pLib
,
Abc_Ntk_t
*
p
);
extern
void
Abc_SclMinsizePerform
(
SC_Lib
*
pLib
,
Abc_Ntk_t
*
p
,
int
fUseMax
,
int
fVerbose
);
extern
int
Abc_SclCountMinSize
(
SC_Lib
*
pLib
,
Abc_Ntk_t
*
p
,
int
fUseMax
);
ABC_NAMESPACE_HEADER_END
...
...
src/map/scl/sclUpsize.c
View file @
881b2ec4
...
...
@@ -181,6 +181,20 @@ void Abc_SclUnmarkCriticalNodeWindow( SC_Man * p, Vec_Int_t * vPath )
Abc_NtkForEachObjVec
(
vPath
,
p
->
pNtk
,
pObj
,
i
)
pObj
->
fMarkA
=
0
;
}
int
Abc_SclCountNearCriticalNodes
(
SC_Man
*
p
)
{
int
RetValue
;
Vec_Int_t
*
vPathPos
,
*
vPathNodes
;
vPathPos
=
Abc_SclFindCriticalCoWindow
(
p
,
5
);
vPathNodes
=
Abc_SclFindCriticalNodeWindow
(
p
,
vPathPos
,
5
,
0
);
RetValue
=
Vec_IntSize
(
vPathNodes
);
Abc_SclUnmarkCriticalNodeWindow
(
p
,
vPathNodes
);
Abc_SclUnmarkCriticalNodeWindow
(
p
,
vPathPos
);
Vec_IntFree
(
vPathPos
);
Vec_IntFree
(
vPathNodes
);
return
RetValue
;
}
/**Function*************************************************************
...
...
@@ -261,7 +275,7 @@ int Abc_SclFindBestCell( SC_Man * p, Abc_Obj_t * pObj, Vec_Int_t * vRecalcs, Vec
float
dGain
,
dGainBest
,
gGainCur
;
int
k
,
n
,
gateBest
;
// save old gate, timing, fanin load
pCellOld
=
Abc_SclObjCell
(
p
,
p
Obj
);
pCellOld
=
Abc_SclObjCell
(
pObj
);
Abc_SclConeStore
(
p
,
vRecalcs
);
Abc_SclLoadStore
(
p
,
pObj
);
// try different gate sizes for this node
...
...
@@ -276,12 +290,12 @@ int Abc_SclFindBestCell( SC_Man * p, Abc_Obj_t * pObj, Vec_Int_t * vRecalcs, Vec
if
(
p
->
pInDrive
&&
!
Abc_SclInputDriveOk
(
p
,
pObj
,
pCellNew
)
)
continue
;
// set new cell
Abc_SclObjSetCell
(
p
,
p
Obj
,
pCellNew
);
Abc_SclObjSetCell
(
pObj
,
pCellNew
);
Abc_SclUpdateLoad
(
p
,
pObj
,
pCellOld
,
pCellNew
);
// recompute timing
Abc_SclTimeCone
(
p
,
vRecalcs
);
// set old cell
Abc_SclObjSetCell
(
p
,
p
Obj
,
pCellOld
);
Abc_SclObjSetCell
(
pObj
,
pCellOld
);
Abc_SclLoadRestore
(
p
,
pObj
);
// evaluate gain
dGain
=
0
.
0
;
...
...
@@ -299,7 +313,7 @@ int Abc_SclFindBestCell( SC_Man * p, Abc_Obj_t * pObj, Vec_Int_t * vRecalcs, Vec
}
}
// put back old cell and timing
Abc_SclObjSetCell
(
p
,
p
Obj
,
pCellOld
);
Abc_SclObjSetCell
(
pObj
,
pCellOld
);
Abc_SclConeRestore
(
p
,
vRecalcs
);
*
pGainBest
=
dGainBest
;
return
gateBest
;
...
...
@@ -438,11 +452,11 @@ int Abc_SclFindBypasses( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notc
Vec_IntPush
(
p
->
vUpdates2
,
Abc_ObjId
(
pFanin
)
);
Vec_IntPush
(
p
->
vUpdates2
,
Abc_ObjId
(
pBuf
)
);
// find old and new gates
pCellOld
=
Abc_SclObjCell
(
p
,
p
Fanin
);
pCellOld
=
Abc_SclObjCell
(
pFanin
);
pCellNew
=
SC_LibCell
(
p
->
pLib
,
Vec_IntEntry
(
p
->
vNode2Gate
,
iNode
)
);
// update cell
p
->
SumArea
+=
pCellNew
->
area
-
pCellOld
->
area
;
Abc_SclObjSetCell
(
p
,
p
Fanin
,
pCellNew
);
Abc_SclObjSetCell
(
pFanin
,
pCellNew
);
// record the update
Vec_IntPush
(
p
->
vUpdates
,
Abc_ObjId
(
pFanin
)
);
Vec_IntPush
(
p
->
vUpdates
,
pCellNew
->
Id
);
...
...
@@ -462,7 +476,7 @@ int Abc_SclFindBypasses( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notc
// check if the node became useless
if ( Abc_ObjFanoutNum(pBuf) == 0 )
{
pCellOld = Abc_SclObjCell( p
, p
Buf );
pCellOld = Abc_SclObjCell( pBuf );
p->SumArea -= pCellOld->area;
Abc_NtkDeleteObj_rec( pBuf, 1 );
printf( "Removed node %d.\n", iNode );
...
...
@@ -583,7 +597,7 @@ int Abc_SclFindUpsizes( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notch
pObj = Abc_NtkObj( p->pNtk, Vec_QuePop(p->vNodeByGain) );
assert( pObj->fMarkA );
// find old and new gates
pCellOld = Abc_SclObjCell( p
, p
Obj );
pCellOld = Abc_SclObjCell( 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 );
...
...
@@ -622,7 +636,7 @@ return Limit;
// printf( "%.1f ", Vec_FltEntry(p->vNode2Gain, iNode) );
// find old and new gates
pCellOld
=
Abc_SclObjCell
(
p
,
p
Obj
);
pCellOld
=
Abc_SclObjCell
(
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 );
...
...
@@ -630,7 +644,7 @@ return Limit;
// update gate
Abc_SclUpdateLoad
(
p
,
pObj
,
pCellOld
,
pCellNew
);
p
->
SumArea
+=
pCellNew
->
area
-
pCellOld
->
area
;
Abc_SclObjSetCell
(
p
,
p
Obj
,
pCellNew
);
Abc_SclObjSetCell
(
pObj
,
pCellNew
);
// record the update
Vec_IntPush
(
p
->
vUpdates
,
Abc_ObjId
(
pObj
)
);
Vec_IntPush
(
p
->
vUpdates
,
pCellNew
->
Id
);
...
...
@@ -788,7 +802,7 @@ void Abc_SclUpsizeRemoveDangling( SC_Man * p, Abc_Ntk_t * pNtk )
Abc_NtkForEachNode
(
pNtk
,
pObj
,
i
)
if
(
Abc_ObjFanoutNum
(
pObj
)
==
0
)
{
pCell
=
Abc_SclObjCell
(
p
,
p
Obj
);
pCell
=
Abc_SclObjCell
(
pObj
);
p
->
SumArea
-=
pCell
->
area
;
Abc_NtkDeleteObj_rec
(
pObj
,
1
);
// printf( "Removed node %d.\n", i );
...
...
@@ -834,7 +848,7 @@ void Abc_SclUpsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars
p
=
Abc_SclManStart
(
pLib
,
pNtk
,
pPars
->
fUseWireLoads
,
pPars
->
fUseDept
,
0
,
pPars
->
BuffTreeEst
);
p
->
timeTotal
=
Abc_Clock
();
assert
(
p
->
vGatesBest
==
NULL
);
p
->
vGatesBest
=
Vec_IntDup
(
p
->
vGates
);
p
->
vGatesBest
=
Vec_IntDup
(
p
->
pNtk
->
vGates
);
p
->
BestDelay
=
p
->
MaxDelay0
;
// perform upsizing
...
...
@@ -893,7 +907,7 @@ void Abc_SclUpsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars
if
(
p
->
BestDelay
>
p
->
MaxDelay
)
{
p
->
BestDelay
=
p
->
MaxDelay
;
Abc_SclApplyUpdateToBest
(
p
->
vGatesBest
,
p
->
vGates
,
p
->
vUpdates
);
Abc_SclApplyUpdateToBest
(
p
->
vGatesBest
,
p
->
pNtk
->
vGates
,
p
->
vUpdates
);
Vec_IntClear
(
p
->
vUpdates2
);
nFramesNoChange
=
0
;
}
...
...
@@ -920,7 +934,7 @@ void Abc_SclUpsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars
break
;
}
// update for best gates and recompute timing
ABC_SWAP
(
Vec_Int_t
*
,
p
->
vGatesBest
,
p
->
vGates
);
ABC_SWAP
(
Vec_Int_t
*
,
p
->
vGatesBest
,
p
->
pNtk
->
vGates
);
if
(
pPars
->
BypassFreq
!=
0
)
Abc_SclUndoRecentChanges
(
p
->
pNtk
,
p
->
vUpdates2
);
if
(
pPars
->
BypassFreq
!=
0
)
...
...
@@ -947,7 +961,7 @@ void Abc_SclUpsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars
printf
(
"Gate sizing timed out at %d seconds.
\n
"
,
pPars
->
TimeOut
);
// save the result and quit
Abc_Scl
ManSetGates
(
pLib
,
pNtk
,
p
->
vGates
);
// updates gate pointers
Abc_Scl
SclGates2MioGates
(
pLib
,
pNtk
);
// updates gate pointers
Abc_SclManFree
(
p
);
// Abc_NtkCleanMarkAB( pNtk );
}
...
...
src/map/scl/sclUtil.c
View file @
881b2ec4
...
...
@@ -44,29 +44,30 @@ ABC_NAMESPACE_IMPL_START
SeeAlso []
***********************************************************************/
Vec_Int_t
*
Abc_SclManFind
Gates
(
SC_Lib
*
pLib
,
Abc_Ntk_t
*
p
)
void
Abc_SclMioGates2Scl
Gates
(
SC_Lib
*
pLib
,
Abc_Ntk_t
*
p
)
{
Vec_Int_t
*
vVec
;
Abc_Obj_t
*
pObj
;
int
i
;
vVec
=
Vec_IntStartFull
(
Abc_NtkObjNumMax
(
p
)
);
assert
(
p
->
vGates
==
NULL
);
p
->
vGates
=
Vec_IntStartFull
(
Abc_NtkObjNumMax
(
p
)
);
Abc_NtkForEachNode1
(
p
,
pObj
,
i
)
{
char
*
pName
=
Mio_GateReadName
((
Mio_Gate_t
*
)
pObj
->
pData
);
int
gateId
=
Abc_SclCellFind
(
pLib
,
pName
);
assert
(
gateId
>=
0
);
Vec_IntWriteEntry
(
vVec
,
i
,
gateId
);
Vec_IntWriteEntry
(
p
->
vGates
,
i
,
gateId
);
//printf( "Found gate %s\n", pName );
}
return
vVec
;
p
->
pSCLib
=
pLib
;
}
void
Abc_Scl
ManSetGates
(
SC_Lib
*
pLib
,
Abc_Ntk_t
*
p
,
Vec_Int_t
*
vGates
)
void
Abc_Scl
SclGates2MioGates
(
SC_Lib
*
pLib
,
Abc_Ntk_t
*
p
)
{
Abc_Obj_t
*
pObj
;
int
i
,
Counter
=
0
,
CounterAll
=
0
;
assert
(
p
->
vGates
!=
NULL
);
Abc_NtkForEachNode1
(
p
,
pObj
,
i
)
{
SC_Cell
*
pCell
=
SC_LibCell
(
pLib
,
Vec_IntEntry
(
vGates
,
Abc_ObjId
(
pObj
))
);
SC_Cell
*
pCell
=
Abc_SclObjCell
(
pObj
);
assert
(
pCell
->
n_inputs
==
Abc_ObjFaninNum
(
pObj
)
);
pObj
->
pData
=
Mio_LibraryReadGateByName
(
(
Mio_Library_t
*
)
p
->
pManFunc
,
pCell
->
pName
,
NULL
);
Counter
+=
(
pObj
->
pData
==
NULL
);
...
...
@@ -76,6 +77,8 @@ void Abc_SclManSetGates( SC_Lib * pLib, Abc_Ntk_t * p, Vec_Int_t * vGates )
}
if
(
Counter
)
printf
(
"Could not find %d (out of %d) gates in the current library.
\n
"
,
Counter
,
CounterAll
);
Vec_IntFreeP
(
&
p
->
vGates
);
p
->
pSCLib
=
NULL
;
}
/**Function*************************************************************
...
...
@@ -119,10 +122,10 @@ void Abc_SclManPrintGateSizes( SC_Lib * pLib, Abc_Ntk_t * p, Vec_Int_t * vGates
}
void
Abc_SclPrintGateSizes
(
SC_Lib
*
pLib
,
Abc_Ntk_t
*
p
)
{
Vec_Int_t
*
vGates
;
vGates
=
Abc_SclManFindGates
(
pLib
,
p
);
Abc_SclManPrintGateSizes
(
pLib
,
p
,
vGates
);
Vec_IntFree
(
vGates
)
;
Abc_SclMioGates2SclGates
(
pLib
,
p
)
;
Abc_SclManPrintGateSizes
(
pLib
,
p
,
p
->
vGates
);
Vec_IntFreeP
(
&
p
->
vGates
);
p
->
pSCLib
=
NULL
;
}
/**Function*************************************************************
...
...
@@ -149,13 +152,12 @@ SC_Cell * Abc_SclFindMaxAreaCell( SC_Cell * pRepr )
}
return
pBest
;
}
void
Abc_SclMinsizePerform
(
SC_Lib
*
pLib
,
Abc_Ntk_t
*
p
,
int
fUseMax
,
int
fVerbose
)
Vec_Int_t
*
Abc_SclFindMinAreas
(
SC_Lib
*
pLib
,
int
fUseMax
)
{
Vec_Int_t
*
vMinCells
,
*
vGates
;
Vec_Int_t
*
vMinCells
;
SC_Cell
*
pCell
,
*
pRepr
=
NULL
,
*
pBest
=
NULL
;
Abc_Obj_t
*
pObj
;
int
i
,
k
,
gateId
;
// map each gate in the library into its min-size prototype
int
i
,
k
;
// map each gate in the library into its min/max-size prototype
vMinCells
=
Vec_IntStartFull
(
Vec_PtrSize
(
pLib
->
vCells
)
);
SC_LibForEachCellClass
(
pLib
,
pRepr
,
i
)
{
...
...
@@ -163,21 +165,39 @@ void Abc_SclMinsizePerform( SC_Lib * pLib, Abc_Ntk_t * p, int fUseMax, int fVerb
SC_RingForEachCell
(
pRepr
,
pCell
,
k
)
Vec_IntWriteEntry
(
vMinCells
,
pCell
->
Id
,
pBest
->
Id
);
}
// update each cell
vGates
=
Abc_SclManFindGates
(
pLib
,
p
);
return
vMinCells
;
}
void
Abc_SclMinsizePerform
(
SC_Lib
*
pLib
,
Abc_Ntk_t
*
p
,
int
fUseMax
,
int
fVerbose
)
{
Vec_Int_t
*
vMinCells
;
Abc_Obj_t
*
pObj
;
int
i
,
gateId
;
vMinCells
=
Abc_SclFindMinAreas
(
pLib
,
fUseMax
);
Abc_SclMioGates2SclGates
(
pLib
,
p
);
Abc_NtkForEachNode1
(
p
,
pObj
,
i
)
{
gateId
=
Vec_IntEntry
(
vGates
,
i
);
// if ( SC_LibCell(pLib, gateId)->n_outputs > 1 )
// continue;
gateId
=
Vec_IntEntry
(
p
->
vGates
,
i
);
assert
(
gateId
>=
0
&&
gateId
<
Vec_PtrSize
(
pLib
->
vCells
)
);
gateId
=
Vec_IntEntry
(
vMinCells
,
gateId
);
assert
(
gateId
>=
0
&&
gateId
<
Vec_PtrSize
(
pLib
->
vCells
)
);
Vec_IntWriteEntry
(
vGates
,
i
,
gateId
);
Vec_IntWriteEntry
(
p
->
vGates
,
i
,
gateId
);
}
Abc_SclSclGates2MioGates
(
pLib
,
p
);
Vec_IntFree
(
vMinCells
);
}
int
Abc_SclCountMinSize
(
SC_Lib
*
pLib
,
Abc_Ntk_t
*
p
,
int
fUseMax
)
{
Vec_Int_t
*
vMinCells
;
Abc_Obj_t
*
pObj
;
int
i
,
gateId
,
Counter
=
0
;
vMinCells
=
Abc_SclFindMinAreas
(
pLib
,
fUseMax
);
Abc_NtkForEachNode1
(
p
,
pObj
,
i
)
{
gateId
=
Vec_IntEntry
(
p
->
vGates
,
i
);
Counter
+=
(
gateId
==
Vec_IntEntry
(
vMinCells
,
gateId
)
);
}
Abc_SclManSetGates
(
pLib
,
p
,
vGates
);
Vec_IntFree
(
vMinCells
);
Vec_IntFree
(
vGates
)
;
return
Counter
;
}
/**Function*************************************************************
...
...
src/misc/vec/vecFlt.h
View file @
881b2ec4
...
...
@@ -336,6 +336,11 @@ static inline float Vec_FltEntry( Vec_Flt_t * p, int i )
assert
(
i
>=
0
&&
i
<
p
->
nSize
);
return
p
->
pArray
[
i
];
}
static
inline
float
*
Vec_FltEntryP
(
Vec_Flt_t
*
p
,
int
i
)
{
assert
(
i
>=
0
&&
i
<
p
->
nSize
);
return
p
->
pArray
+
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