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
dfd6ab08
Commit
dfd6ab08
authored
Aug 25, 2012
by
Alan Mishchenko
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
New package to read/write a subset of Liberty for STA.
parent
fba0552f
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
863 additions
and
211 deletions
+863
-211
src/map/scl/scl.c
+56
-12
src/map/scl/scl.h
+6
-3
src/map/scl/sclFile.c
+475
-194
src/map/scl/sclInt.h
+14
-2
src/map/scl/sclSize.c
+1
-0
src/map/scl/sclTime.c
+311
-0
No files found.
src/map/scl/scl.c
View file @
dfd6ab08
...
...
@@ -29,6 +29,7 @@ ABC_NAMESPACE_IMPL_START
static
int
Scl_CommandRead
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
);
static
int
Scl_CommandWrite
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
);
static
int
Scl_CommandStime
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
);
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
...
...
@@ -49,19 +50,8 @@ void Scl_Init( Abc_Frame_t * pAbc )
{
Cmd_CommandAdd
(
pAbc
,
"SC mapping"
,
"read_scl"
,
Scl_CommandRead
,
0
);
Cmd_CommandAdd
(
pAbc
,
"SC mapping"
,
"write_scl"
,
Scl_CommandWrite
,
0
);
Cmd_CommandAdd
(
pAbc
,
"SC mapping"
,
"stime"
,
Scl_CommandStime
,
0
);
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
Scl_End
(
Abc_Frame_t
*
pAbc
)
{
Abc_SclLoad
(
NULL
,
&
pAbc
->
pLibScl
);
...
...
@@ -111,6 +101,7 @@ int Scl_CommandRead( Abc_Frame_t * pAbc, int argc, char ** argv )
// read new library
Abc_SclLoad
(
pFileName
,
&
pAbc
->
pLibScl
);
Abc_SclWriteText
(
"sizing
\\
scl_out.txt"
,
pAbc
->
pLibScl
);
return
0
;
usage:
...
...
@@ -177,6 +168,59 @@ usage:
return
1
;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int
Scl_CommandStime
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
)
{
int
c
;
Extra_UtilGetoptReset
();
while
(
(
c
=
Extra_UtilGetopt
(
argc
,
argv
,
"h"
)
)
!=
EOF
)
{
switch
(
c
)
{
case
'h'
:
goto
usage
;
default:
goto
usage
;
}
}
if
(
Abc_FrameReadNtk
(
pAbc
)
==
NULL
)
{
fprintf
(
pAbc
->
Err
,
"There is no current network.
\n
"
);
return
1
;
}
if
(
!
Abc_NtkHasMapping
(
Abc_FrameReadNtk
(
pAbc
))
)
{
fprintf
(
pAbc
->
Err
,
"The current network is not mapped.
\n
"
);
return
1
;
}
if
(
pAbc
->
pLibScl
==
NULL
)
{
fprintf
(
pAbc
->
Err
,
"There is no Liberty Library available.
\n
"
);
return
1
;
}
Abc_SclTimePerform
(
pAbc
->
pLibScl
,
Abc_FrameReadNtk
(
pAbc
)
);
return
0
;
usage:
fprintf
(
pAbc
->
Err
,
"usage: stime [-h]
\n
"
);
fprintf
(
pAbc
->
Err
,
"
\t
performs STA using Liberty library
\n
"
);
fprintf
(
pAbc
->
Err
,
"
\t
-h : print the help massage
\n
"
);
return
1
;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
...
...
src/map/scl/scl.h
View file @
dfd6ab08
...
...
@@ -46,9 +46,12 @@ ABC_NAMESPACE_HEADER_START
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/*=== scl.c =============================================================*/
extern
void
Abc_SclLoad
(
char
*
pFileName
,
void
**
ppScl
);
extern
void
Abc_SclSave
(
char
*
pFileName
,
void
*
pScl
);
/*=== sclFile.c =============================================================*/
extern
void
Abc_SclLoad
(
char
*
pFileName
,
void
**
ppScl
);
extern
void
Abc_SclSave
(
char
*
pFileName
,
void
*
pScl
);
/*=== sclTime.c =============================================================*/
extern
void
Abc_SclTimePerform
(
SC_Lib
*
pLib
,
void
*
pNtk
);
ABC_NAMESPACE_HEADER_END
...
...
src/map/scl/sclFile.c
View file @
dfd6ab08
...
...
@@ -25,13 +25,15 @@ ABC_NAMESPACE_IMPL_START
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
extern
void
Extra_PrintHex
(
FILE
*
pFile
,
unsigned
Sign
[],
int
nBits
);
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Binary I/O for numbers (int
, word, float
) and strings (char *).]
Synopsis [Binary I/O for numbers (int
/float/etc
) and strings (char *).]
Description []
...
...
@@ -40,13 +42,13 @@ ABC_NAMESPACE_IMPL_START
SeeAlso []
***********************************************************************/
static
inline
void
Abc_SclPutI_no_enc
(
Vec_Str_t
*
vOut
,
int
Val
)
static
inline
void
Vec_StrPutI_ne
(
Vec_Str_t
*
vOut
,
int
Val
)
{
int
i
;
for
(
i
=
0
;
i
<
4
;
i
++
)
Vec_StrPush
(
vOut
,
(
char
)(
Val
>>
(
8
*
i
))
);
}
static
inline
int
Abc_SclGetI_no_enc
(
Vec_Str_t
*
vOut
,
int
*
pPos
)
static
inline
int
Vec_StrGetI_ne
(
Vec_Str_t
*
vOut
,
int
*
pPos
)
{
int
i
;
int
Val
=
0
;
...
...
@@ -55,13 +57,13 @@ static inline int Abc_SclGetI_no_enc( Vec_Str_t * vOut, int * pPos )
return
Val
;
}
static
inline
void
Abc_Scl
PutI
(
Vec_Str_t
*
vOut
,
int
Val
)
static
inline
void
Vec_Str
PutI
(
Vec_Str_t
*
vOut
,
int
Val
)
{
for
(
;
Val
>=
0x80
;
Val
>>=
7
)
Vec_StrPush
(
vOut
,
(
unsigned
char
)(
Val
|
0x80
)
);
Vec_StrPush
(
vOut
,
(
unsigned
char
)
Val
);
}
static
inline
int
Abc_Scl
GetI
(
Vec_Str_t
*
vOut
,
int
*
pPos
)
static
inline
int
Vec_Str
GetI
(
Vec_Str_t
*
vOut
,
int
*
pPos
)
{
unsigned
char
ch
;
int
i
=
0
,
Val
=
0
;
...
...
@@ -70,13 +72,13 @@ static inline int Abc_SclGetI( Vec_Str_t * vOut, int * pPos )
return
Val
|
(
ch
<<
(
7
*
i
));
}
static
inline
void
Abc_Scl
PutW
(
Vec_Str_t
*
vOut
,
word
Val
)
static
inline
void
Vec_Str
PutW
(
Vec_Str_t
*
vOut
,
word
Val
)
{
int
i
;
for
(
i
=
0
;
i
<
8
;
i
++
)
Vec_StrPush
(
vOut
,
(
char
)(
Val
>>
(
8
*
i
))
);
}
static
inline
word
Abc_Scl
GetW
(
Vec_Str_t
*
vOut
,
int
*
pPos
)
static
inline
word
Vec_Str
GetW
(
Vec_Str_t
*
vOut
,
int
*
pPos
)
{
int
i
;
word
Val
=
0
;
...
...
@@ -85,7 +87,7 @@ static inline word Abc_SclGetW( Vec_Str_t * vOut, int * pPos )
return
Val
;
}
static
inline
void
Abc_Scl
PutF
(
Vec_Str_t
*
vOut
,
float
Val
)
static
inline
void
Vec_Str
PutF
(
Vec_Str_t
*
vOut
,
float
Val
)
{
union
{
float
num
;
unsigned
char
data
[
4
];
}
tmp
;
tmp
.
num
=
Val
;
...
...
@@ -94,7 +96,7 @@ static inline void Abc_SclPutF( Vec_Str_t * vOut, float Val )
Vec_StrPush
(
vOut
,
tmp
.
data
[
2
]
);
Vec_StrPush
(
vOut
,
tmp
.
data
[
3
]
);
}
static
inline
float
Abc_Scl
GetF
(
Vec_Str_t
*
vOut
,
int
*
pPos
)
static
inline
float
Vec_Str
GetF
(
Vec_Str_t
*
vOut
,
int
*
pPos
)
{
union
{
float
num
;
unsigned
char
data
[
4
];
}
tmp
;
tmp
.
data
[
0
]
=
Vec_StrEntry
(
vOut
,
(
*
pPos
)
++
);
...
...
@@ -104,7 +106,7 @@ static inline float Abc_SclGetF( Vec_Str_t * vOut, int * pPos )
return
tmp
.
num
;
}
static
inline
void
Abc_Scl
PutD
(
Vec_Str_t
*
vOut
,
double
Val
)
static
inline
void
Vec_Str
PutD
(
Vec_Str_t
*
vOut
,
double
Val
)
{
union
{
double
num
;
unsigned
char
data
[
8
];
}
tmp
;
int
i
,
Lim
=
sizeof
(
double
);
...
...
@@ -112,7 +114,7 @@ static inline void Abc_SclPutD( Vec_Str_t * vOut, double Val )
for
(
i
=
0
;
i
<
Lim
;
i
++
)
Vec_StrPush
(
vOut
,
tmp
.
data
[
i
]
);
}
static
inline
double
Abc_Scl
GetD
(
Vec_Str_t
*
vOut
,
int
*
pPos
)
static
inline
double
Vec_Str
GetD
(
Vec_Str_t
*
vOut
,
int
*
pPos
)
{
union
{
double
num
;
unsigned
char
data
[
8
];
}
tmp
;
int
i
,
Lim
=
sizeof
(
double
);
...
...
@@ -121,19 +123,273 @@ static inline double Abc_SclGetD( Vec_Str_t * vOut, int * pPos )
return
tmp
.
num
;
}
static
inline
void
Abc_Scl
PutS
(
Vec_Str_t
*
vOut
,
char
*
pStr
)
static
inline
void
Vec_Str
PutS
(
Vec_Str_t
*
vOut
,
char
*
pStr
)
{
while
(
*
pStr
)
Vec_StrPush
(
vOut
,
*
pStr
++
);
Vec_StrPush
(
vOut
,
(
char
)
0
);
}
static
inline
char
*
Abc_Scl
GetS
(
Vec_Str_t
*
vOut
,
int
*
pPos
)
static
inline
char
*
Vec_Str
GetS
(
Vec_Str_t
*
vOut
,
int
*
pPos
)
{
char
*
pStr
=
Vec_StrEntryP
(
vOut
,
*
pPos
);
while
(
Vec_StrEntry
(
vOut
,
(
*
pPos
)
++
)
);
return
Abc_UtilStrsav
(
pStr
);
}
static
inline
void
Vec_StrPutC
(
Vec_Str_t
*
vOut
,
char
c
)
{
Vec_StrPush
(
vOut
,
c
);
}
static
inline
char
Vec_StrGetC
(
Vec_Str_t
*
vOut
,
int
*
pPos
)
{
return
Vec_StrEntry
(
vOut
,
(
*
pPos
)
++
);
}
/**Function*************************************************************
Synopsis [Reading library from file.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static
unsigned
Abc_SclHashString
(
char
*
pName
,
int
TableSize
)
{
static
int
s_Primes
[
10
]
=
{
1291
,
1699
,
2357
,
4177
,
5147
,
5647
,
6343
,
7103
,
7873
,
8147
};
unsigned
i
,
Key
=
0
;
for
(
i
=
0
;
pName
[
i
]
!=
'\0'
;
i
++
)
Key
+=
s_Primes
[
i
%
10
]
*
pName
[
i
]
*
pName
[
i
];
return
Key
%
TableSize
;
}
int
*
Abc_SclHashLookup
(
SC_Lib
*
p
,
char
*
pName
)
{
int
i
;
for
(
i
=
Abc_SclHashString
(
pName
,
p
->
nBins
);
i
<
p
->
nBins
;
i
=
(
i
+
1
)
%
p
->
nBins
)
if
(
p
->
pBins
[
i
]
==
-
1
||
!
strcmp
(
pName
,
SC_LibCell
(
p
,
p
->
pBins
[
i
])
->
name
)
)
return
p
->
pBins
+
i
;
assert
(
0
);
return
NULL
;
}
void
Abc_SclHashGates
(
SC_Lib
*
p
)
{
SC_Cell
*
pCell
;
int
i
,
*
pPlace
;
assert
(
p
->
nBins
==
0
);
p
->
nBins
=
Abc_PrimeCudd
(
5
*
Vec_PtrSize
(
p
->
vCells
)
);
p
->
pBins
=
ABC_FALLOC
(
int
,
p
->
nBins
);
Vec_PtrForEachEntry
(
SC_Cell
*
,
p
->
vCells
,
pCell
,
i
)
{
pPlace
=
Abc_SclHashLookup
(
p
,
pCell
->
name
);
assert
(
*
pPlace
==
-
1
);
*
pPlace
=
i
;
}
}
int
Abc_SclCellFind
(
SC_Lib
*
p
,
char
*
pName
)
{
return
*
Abc_SclHashLookup
(
p
,
pName
);
}
/**Function*************************************************************
Synopsis [Reading library from file.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static
void
Abc_SclReadSurface
(
Vec_Str_t
*
vOut
,
int
*
pPos
,
SC_Surface
*
p
)
{
Vec_Flt_t
*
vVec
;
int
i
,
j
;
for
(
i
=
Vec_StrGetI
(
vOut
,
pPos
);
i
!=
0
;
i
--
)
Vec_FltPush
(
p
->
vIndex0
,
Vec_StrGetF
(
vOut
,
pPos
)
);
for
(
i
=
Vec_StrGetI
(
vOut
,
pPos
);
i
!=
0
;
i
--
)
Vec_FltPush
(
p
->
vIndex1
,
Vec_StrGetF
(
vOut
,
pPos
)
);
for
(
i
=
0
;
i
<
Vec_FltSize
(
p
->
vIndex0
);
i
++
)
{
vVec
=
Vec_FltAlloc
(
Vec_FltSize
(
p
->
vIndex1
)
);
Vec_PtrPush
(
p
->
vData
,
vVec
);
for
(
j
=
0
;
j
<
Vec_FltSize
(
p
->
vIndex1
);
j
++
)
Vec_FltPush
(
vVec
,
Vec_StrGetF
(
vOut
,
pPos
)
);
}
for
(
i
=
0
;
i
<
3
;
i
++
)
p
->
approx
[
0
][
i
]
=
Vec_StrGetF
(
vOut
,
pPos
);
for
(
i
=
0
;
i
<
4
;
i
++
)
p
->
approx
[
1
][
i
]
=
Vec_StrGetF
(
vOut
,
pPos
);
for
(
i
=
0
;
i
<
6
;
i
++
)
p
->
approx
[
2
][
i
]
=
Vec_StrGetF
(
vOut
,
pPos
);
}
static
void
Abc_SclReadLibrary
(
Vec_Str_t
*
vOut
,
int
*
pPos
,
SC_Lib
*
p
)
{
int
i
,
j
,
k
,
n
;
int
version
=
Vec_StrGetI
(
vOut
,
pPos
);
assert
(
version
==
ABC_SCL_CUR_VERSION
);
// wrong version of the file
// Read non-composite fields:
p
->
lib_name
=
Vec_StrGetS
(
vOut
,
pPos
);
p
->
default_wire_load
=
Vec_StrGetS
(
vOut
,
pPos
);
p
->
default_wire_load_sel
=
Vec_StrGetS
(
vOut
,
pPos
);
p
->
default_max_out_slew
=
Vec_StrGetF
(
vOut
,
pPos
);
p
->
unit_time
=
Vec_StrGetI
(
vOut
,
pPos
);
p
->
unit_cap_fst
=
Vec_StrGetF
(
vOut
,
pPos
);
p
->
unit_cap_snd
=
Vec_StrGetI
(
vOut
,
pPos
);
// Read 'wire_load' vector:
for
(
i
=
Vec_StrGetI
(
vOut
,
pPos
);
i
!=
0
;
i
--
)
{
SC_WireLoad
*
pWL
=
Abc_SclWireLoadAlloc
();
Vec_PtrPush
(
p
->
vWireLoads
,
pWL
);
pWL
->
name
=
Vec_StrGetS
(
vOut
,
pPos
);
pWL
->
res
=
Vec_StrGetF
(
vOut
,
pPos
);
pWL
->
cap
=
Vec_StrGetF
(
vOut
,
pPos
);
for
(
j
=
Vec_StrGetI
(
vOut
,
pPos
);
j
!=
0
;
j
--
)
{
Vec_IntPush
(
pWL
->
vFanout
,
Vec_StrGetI
(
vOut
,
pPos
)
);
Vec_FltPush
(
pWL
->
vLen
,
Vec_StrGetF
(
vOut
,
pPos
)
);
}
}
// Read 'wire_load_sel' vector:
for
(
i
=
Vec_StrGetI
(
vOut
,
pPos
);
i
!=
0
;
i
--
)
{
SC_WireLoadSel
*
pWLS
=
Abc_SclWireLoadSelAlloc
();
Vec_PtrPush
(
p
->
vWireLoadSels
,
pWLS
);
pWLS
->
name
=
Vec_StrGetS
(
vOut
,
pPos
);
for
(
j
=
Vec_StrGetI
(
vOut
,
pPos
);
j
!=
0
;
j
--
)
{
Vec_FltPush
(
pWLS
->
vAreaFrom
,
Vec_StrGetF
(
vOut
,
pPos
)
);
Vec_FltPush
(
pWLS
->
vAreaTo
,
Vec_StrGetF
(
vOut
,
pPos
)
);
Vec_PtrPush
(
pWLS
->
vWireLoadModel
,
Vec_StrGetS
(
vOut
,
pPos
)
);
}
}
for
(
i
=
Vec_StrGetI
(
vOut
,
pPos
);
i
!=
0
;
i
--
)
{
SC_Cell
*
pCell
=
Abc_SclCellAlloc
();
Vec_PtrPush
(
p
->
vCells
,
pCell
);
pCell
->
name
=
Vec_StrGetS
(
vOut
,
pPos
);
pCell
->
area
=
Vec_StrGetF
(
vOut
,
pPos
);
pCell
->
drive_strength
=
Vec_StrGetI
(
vOut
,
pPos
);
pCell
->
n_inputs
=
Vec_StrGetI
(
vOut
,
pPos
);
pCell
->
n_outputs
=
Vec_StrGetI
(
vOut
,
pPos
);
for
(
j
=
0
;
j
<
pCell
->
n_inputs
;
j
++
)
{
SC_Pin
*
pPin
=
Abc_SclPinAlloc
();
Vec_PtrPush
(
pCell
->
vPins
,
pPin
);
pPin
->
dir
=
sc_dir_Input
;
pPin
->
name
=
Vec_StrGetS
(
vOut
,
pPos
);
pPin
->
rise_cap
=
Vec_StrGetF
(
vOut
,
pPos
);
pPin
->
fall_cap
=
Vec_StrGetF
(
vOut
,
pPos
);
}
for
(
j
=
0
;
j
<
pCell
->
n_outputs
;
j
++
)
{
SC_Pin
*
pPin
=
Abc_SclPinAlloc
();
Vec_PtrPush
(
pCell
->
vPins
,
pPin
);
pPin
->
dir
=
sc_dir_Output
;
pPin
->
name
=
Vec_StrGetS
(
vOut
,
pPos
);
pPin
->
max_out_cap
=
Vec_StrGetF
(
vOut
,
pPos
);
pPin
->
max_out_slew
=
Vec_StrGetF
(
vOut
,
pPos
);
k
=
Vec_StrGetI
(
vOut
,
pPos
);
assert
(
k
==
pCell
->
n_inputs
);
// read functions
assert
(
Vec_WrdSize
(
pPin
->
vFunc
)
==
0
);
Vec_WrdGrow
(
pPin
->
vFunc
,
Abc_Truth6WordNum
(
pCell
->
n_inputs
)
);
for
(
k
=
0
;
k
<
Vec_WrdCap
(
pPin
->
vFunc
);
k
++
)
Vec_WrdPush
(
pPin
->
vFunc
,
Vec_StrGetW
(
vOut
,
pPos
)
);
// Read 'rtiming': (pin-to-pin timing tables for this particular output)
for
(
k
=
0
;
k
<
pCell
->
n_inputs
;
k
++
)
{
SC_Timings
*
pRTime
=
Abc_SclTimingsAlloc
();
Vec_PtrPush
(
pPin
->
vRTimings
,
pRTime
);
pRTime
->
name
=
Vec_StrGetS
(
vOut
,
pPos
);
n
=
Vec_StrGetI
(
vOut
,
pPos
);
assert
(
n
<=
1
);
if
(
n
==
1
)
{
SC_Timing
*
pTime
=
Abc_SclTimingAlloc
();
Vec_PtrPush
(
pRTime
->
vTimings
,
pTime
);
pTime
->
tsense
=
(
SC_TSense
)
Vec_StrGetI
(
vOut
,
pPos
);
Abc_SclReadSurface
(
vOut
,
pPos
,
pTime
->
pCellRise
);
Abc_SclReadSurface
(
vOut
,
pPos
,
pTime
->
pCellFall
);
Abc_SclReadSurface
(
vOut
,
pPos
,
pTime
->
pRiseTrans
);
Abc_SclReadSurface
(
vOut
,
pPos
,
pTime
->
pFallTrans
);
}
else
assert
(
Vec_PtrSize
(
pPin
->
vRTimings
)
==
0
);
}
}
}
}
SC_Lib
*
Abc_SclRead
(
char
*
pFileName
)
{
SC_Lib
*
p
;
FILE
*
pFile
;
Vec_Str_t
*
vOut
;
int
nFileSize
,
Pos
=
0
;
pFile
=
fopen
(
pFileName
,
"rb"
);
if
(
pFile
==
NULL
)
{
printf
(
"Cannot open file
\"
%s
\"
for reading.
\n
"
,
pFileName
);
return
NULL
;
}
// get the file size, in bytes
fseek
(
pFile
,
0
,
SEEK_END
);
nFileSize
=
ftell
(
pFile
);
rewind
(
pFile
);
// load the contents
vOut
=
Vec_StrAlloc
(
nFileSize
);
vOut
->
nSize
=
vOut
->
nCap
;
assert
(
nFileSize
==
Vec_StrSize
(
vOut
)
);
nFileSize
=
fread
(
Vec_StrArray
(
vOut
),
1
,
Vec_StrSize
(
vOut
),
pFile
);
assert
(
nFileSize
==
Vec_StrSize
(
vOut
)
);
fclose
(
pFile
);
// read the library
p
=
Abc_SclLibAlloc
();
Abc_SclReadLibrary
(
vOut
,
&
Pos
,
p
);
assert
(
Pos
==
Vec_StrSize
(
vOut
)
);
Vec_StrFree
(
vOut
);
// hash gates by name
Abc_SclHashGates
(
p
);
return
p
;
}
void
Abc_SclLoad
(
char
*
pFileName
,
void
**
ppScl
)
{
if
(
*
ppScl
)
{
Abc_SclLibFree
(
*
(
SC_Lib
**
)
ppScl
);
*
ppScl
=
NULL
;
}
assert
(
*
ppScl
==
NULL
);
if
(
pFileName
)
*
(
SC_Lib
**
)
ppScl
=
Abc_SclRead
(
pFileName
);
}
/**Function*************************************************************
...
...
@@ -152,24 +408,24 @@ static void Abc_SclWriteSurface( Vec_Str_t * vOut, SC_Surface * p )
float
Entry
;
int
i
,
k
;
Abc_Scl
PutI
(
vOut
,
Vec_FltSize
(
p
->
vIndex0
)
);
Vec_Str
PutI
(
vOut
,
Vec_FltSize
(
p
->
vIndex0
)
);
Vec_FltForEachEntry
(
p
->
vIndex0
,
Entry
,
i
)
Abc_Scl
PutF
(
vOut
,
Entry
);
Vec_Str
PutF
(
vOut
,
Entry
);
Abc_Scl
PutI
(
vOut
,
Vec_FltSize
(
p
->
vIndex1
)
);
Vec_Str
PutI
(
vOut
,
Vec_FltSize
(
p
->
vIndex1
)
);
Vec_FltForEachEntry
(
p
->
vIndex1
,
Entry
,
i
)
Abc_Scl
PutF
(
vOut
,
Entry
);
Vec_Str
PutF
(
vOut
,
Entry
);
Vec_PtrForEachEntry
(
Vec_Flt_t
*
,
p
->
vData
,
vVec
,
i
)
Vec_FltForEachEntry
(
vVec
,
Entry
,
k
)
Abc_Scl
PutF
(
vOut
,
Entry
);
Vec_Str
PutF
(
vOut
,
Entry
);
for
(
i
=
0
;
i
<
3
;
i
++
)
Abc_Scl
PutF
(
vOut
,
p
->
approx
[
0
][
i
]
);
Vec_Str
PutF
(
vOut
,
p
->
approx
[
0
][
i
]
);
for
(
i
=
0
;
i
<
4
;
i
++
)
Abc_Scl
PutF
(
vOut
,
p
->
approx
[
1
][
i
]
);
Vec_Str
PutF
(
vOut
,
p
->
approx
[
1
][
i
]
);
for
(
i
=
0
;
i
<
6
;
i
++
)
Abc_Scl
PutF
(
vOut
,
p
->
approx
[
2
][
i
]
);
Vec_Str
PutF
(
vOut
,
p
->
approx
[
2
][
i
]
);
}
static
void
Abc_SclWriteLibrary
(
Vec_Str_t
*
vOut
,
SC_Lib
*
p
)
{
...
...
@@ -180,47 +436,47 @@ static void Abc_SclWriteLibrary( Vec_Str_t * vOut, SC_Lib * p )
int
n_valid_cells
;
int
i
,
j
,
k
;
Abc_Scl
PutI
(
vOut
,
ABC_SCL_CUR_VERSION
);
Vec_Str
PutI
(
vOut
,
ABC_SCL_CUR_VERSION
);
// Write non-composite fields:
Abc_Scl
PutS
(
vOut
,
p
->
lib_name
);
Abc_Scl
PutS
(
vOut
,
p
->
default_wire_load
);
Abc_Scl
PutS
(
vOut
,
p
->
default_wire_load_sel
);
Abc_Scl
PutF
(
vOut
,
p
->
default_max_out_slew
);
Vec_Str
PutS
(
vOut
,
p
->
lib_name
);
Vec_Str
PutS
(
vOut
,
p
->
default_wire_load
);
Vec_Str
PutS
(
vOut
,
p
->
default_wire_load_sel
);
Vec_Str
PutF
(
vOut
,
p
->
default_max_out_slew
);
assert
(
p
->
unit_time
>=
0
);
assert
(
p
->
unit_cap_snd
>=
0
);
Abc_Scl
PutI
(
vOut
,
p
->
unit_time
);
Abc_Scl
PutF
(
vOut
,
p
->
unit_cap_fst
);
Abc_Scl
PutI
(
vOut
,
p
->
unit_cap_snd
);
Vec_Str
PutI
(
vOut
,
p
->
unit_time
);
Vec_Str
PutF
(
vOut
,
p
->
unit_cap_fst
);
Vec_Str
PutI
(
vOut
,
p
->
unit_cap_snd
);
// Write 'wire_load' vector:
Abc_Scl
PutI
(
vOut
,
Vec_PtrSize
(
p
->
vWireLoads
)
);
Vec_Str
PutI
(
vOut
,
Vec_PtrSize
(
p
->
vWireLoads
)
);
Vec_PtrForEachEntry
(
SC_WireLoad
*
,
p
->
vWireLoads
,
pWL
,
i
)
{
Abc_Scl
PutS
(
vOut
,
pWL
->
name
);
Abc_Scl
PutF
(
vOut
,
pWL
->
res
);
Abc_Scl
PutF
(
vOut
,
pWL
->
cap
);
Vec_Str
PutS
(
vOut
,
pWL
->
name
);
Vec_Str
PutF
(
vOut
,
pWL
->
res
);
Vec_Str
PutF
(
vOut
,
pWL
->
cap
);
Abc_Scl
PutI
(
vOut
,
Vec_IntSize
(
pWL
->
vFanout
)
);
Vec_Str
PutI
(
vOut
,
Vec_IntSize
(
pWL
->
vFanout
)
);
for
(
j
=
0
;
j
<
Vec_IntSize
(
pWL
->
vFanout
);
j
++
)
{
Abc_Scl
PutI
(
vOut
,
Vec_IntEntry
(
pWL
->
vFanout
,
j
)
);
Abc_Scl
PutF
(
vOut
,
Vec_FltEntry
(
pWL
->
vLen
,
j
)
);
Vec_Str
PutI
(
vOut
,
Vec_IntEntry
(
pWL
->
vFanout
,
j
)
);
Vec_Str
PutF
(
vOut
,
Vec_FltEntry
(
pWL
->
vLen
,
j
)
);
}
}
// Write 'wire_load_sel' vector:
Abc_Scl
PutI
(
vOut
,
Vec_PtrSize
(
p
->
vWireLoadSels
)
);
Vec_Str
PutI
(
vOut
,
Vec_PtrSize
(
p
->
vWireLoadSels
)
);
Vec_PtrForEachEntry
(
SC_WireLoadSel
*
,
p
->
vWireLoadSels
,
pWLS
,
i
)
{
Abc_Scl
PutS
(
vOut
,
pWLS
->
name
);
Abc_Scl
PutI
(
vOut
,
Vec_FltSize
(
pWLS
->
vAreaFrom
)
);
Vec_Str
PutS
(
vOut
,
pWLS
->
name
);
Vec_Str
PutI
(
vOut
,
Vec_FltSize
(
pWLS
->
vAreaFrom
)
);
for
(
j
=
0
;
j
<
Vec_FltSize
(
pWLS
->
vAreaFrom
);
j
++
)
{
Abc_Scl
PutF
(
vOut
,
Vec_FltEntry
(
pWLS
->
vAreaFrom
,
j
)
);
Abc_Scl
PutF
(
vOut
,
Vec_FltEntry
(
pWLS
->
vAreaTo
,
j
)
);
Abc_Scl
PutS
(
vOut
,
(
char
*
)
Vec_PtrEntry
(
pWLS
->
vWireLoadModel
,
j
)
);
Vec_Str
PutF
(
vOut
,
Vec_FltEntry
(
pWLS
->
vAreaFrom
,
j
)
);
Vec_Str
PutF
(
vOut
,
Vec_FltEntry
(
pWLS
->
vAreaTo
,
j
)
);
Vec_Str
PutS
(
vOut
,
(
char
*
)
Vec_PtrEntry
(
pWLS
->
vWireLoadModel
,
j
)
);
}
}
...
...
@@ -230,26 +486,26 @@ static void Abc_SclWriteLibrary( Vec_Str_t * vOut, SC_Lib * p )
if
(
!
(
pCell
->
seq
||
pCell
->
unsupp
)
)
n_valid_cells
++
;
Abc_Scl
PutI
(
vOut
,
n_valid_cells
);
Vec_Str
PutI
(
vOut
,
n_valid_cells
);
Vec_PtrForEachEntry
(
SC_Cell
*
,
p
->
vCells
,
pCell
,
i
)
{
if
(
pCell
->
seq
||
pCell
->
unsupp
)
continue
;
Abc_Scl
PutS
(
vOut
,
pCell
->
name
);
Abc_Scl
PutF
(
vOut
,
pCell
->
area
);
Abc_Scl
PutI
(
vOut
,
pCell
->
drive_strength
);
Vec_Str
PutS
(
vOut
,
pCell
->
name
);
Vec_Str
PutF
(
vOut
,
pCell
->
area
);
Vec_Str
PutI
(
vOut
,
pCell
->
drive_strength
);
// Write 'pins': (sorted at this point; first inputs, then outputs)
Abc_Scl
PutI
(
vOut
,
pCell
->
n_inputs
);
Abc_Scl
PutI
(
vOut
,
pCell
->
n_outputs
);
Vec_Str
PutI
(
vOut
,
pCell
->
n_inputs
);
Vec_Str
PutI
(
vOut
,
pCell
->
n_outputs
);
Vec_PtrForEachEntryStop
(
SC_Pin
*
,
pCell
->
vPins
,
pPin
,
j
,
pCell
->
n_inputs
)
{
assert
(
pPin
->
dir
==
sc_dir_Input
);
Abc_Scl
PutS
(
vOut
,
pPin
->
name
);
Abc_Scl
PutF
(
vOut
,
pPin
->
rise_cap
);
Abc_Scl
PutF
(
vOut
,
pPin
->
fall_cap
);
Vec_Str
PutS
(
vOut
,
pPin
->
name
);
Vec_Str
PutF
(
vOut
,
pPin
->
rise_cap
);
Vec_Str
PutF
(
vOut
,
pPin
->
fall_cap
);
}
Vec_PtrForEachEntryStart
(
SC_Pin
*
,
pCell
->
vPins
,
pPin
,
j
,
pCell
->
n_inputs
)
...
...
@@ -258,22 +514,22 @@ static void Abc_SclWriteLibrary( Vec_Str_t * vOut, SC_Lib * p )
word
uWord
;
assert
(
pPin
->
dir
==
sc_dir_Output
);
Abc_Scl
PutS
(
vOut
,
pPin
->
name
);
Abc_Scl
PutF
(
vOut
,
pPin
->
max_out_cap
);
Abc_Scl
PutF
(
vOut
,
pPin
->
max_out_slew
);
Vec_Str
PutS
(
vOut
,
pPin
->
name
);
Vec_Str
PutF
(
vOut
,
pPin
->
max_out_cap
);
Vec_Str
PutF
(
vOut
,
pPin
->
max_out_slew
);
// write function
assert
(
Vec_WrdSize
(
pPin
->
vFunc
)
==
Abc_Truth6WordNum
(
pCell
->
n_inputs
)
);
Abc_Scl
PutI
(
vOut
,
pCell
->
n_inputs
);
Vec_Str
PutI
(
vOut
,
pCell
->
n_inputs
);
Vec_WrdForEachEntry
(
pPin
->
vFunc
,
uWord
,
k
)
// -- 'size = 1u << (n_vars - 6)'
Abc_Scl
PutW
(
vOut
,
uWord
);
// -- 64-bit number, written uncompressed (low-byte first)
Vec_Str
PutW
(
vOut
,
uWord
);
// -- 64-bit number, written uncompressed (low-byte first)
// Write 'rtiming': (pin-to-pin timing tables for this particular output)
assert
(
Vec_PtrSize
(
pPin
->
vRTimings
)
==
pCell
->
n_inputs
);
Vec_PtrForEachEntry
(
SC_Timings
*
,
pPin
->
vRTimings
,
pRTime
,
k
)
{
Abc_Scl
PutS
(
vOut
,
pRTime
->
name
);
Abc_Scl
PutI
(
vOut
,
Vec_PtrSize
(
pRTime
->
vTimings
)
);
Vec_Str
PutS
(
vOut
,
pRTime
->
name
);
Vec_Str
PutI
(
vOut
,
Vec_PtrSize
(
pRTime
->
vTimings
)
);
// -- NOTE! After post-processing, the size of the 'rtiming[k]' vector is either
// 0 or 1 (in static timing, we have merged all tables to get the worst case).
// The case with size 0 should only occur for multi-output gates.
...
...
@@ -282,7 +538,7 @@ static void Abc_SclWriteLibrary( Vec_Str_t * vOut, SC_Lib * p )
SC_Timing
*
pTime
=
(
SC_Timing
*
)
Vec_PtrEntry
(
pRTime
->
vTimings
,
0
);
// -- NOTE! We don't need to save 'related_pin' string because we have sorted
// the elements on input pins.
Abc_Scl
PutI
(
vOut
,
(
int
)
pTime
->
tsense
);
Vec_Str
PutI
(
vOut
,
(
int
)
pTime
->
tsense
);
Abc_SclWriteSurface
(
vOut
,
pTime
->
pCellRise
);
Abc_SclWriteSurface
(
vOut
,
pTime
->
pCellFall
);
Abc_SclWriteSurface
(
vOut
,
pTime
->
pRiseTrans
);
...
...
@@ -321,7 +577,7 @@ void Abc_SclSave( char * pFileName, void * pScl )
/**Function*************************************************************
Synopsis [
Reading library from
file.]
Synopsis [
Writing library into text
file.]
Description []
...
...
@@ -330,188 +586,213 @@ void Abc_SclSave( char * pFileName, void * pScl )
SeeAlso []
***********************************************************************/
static
void
Abc_Scl
ReadSurface
(
Vec_Str_t
*
vOut
,
int
*
pPo
s
,
SC_Surface
*
p
)
static
void
Abc_Scl
WriteSurfaceText
(
FILE
*
s
,
SC_Surface
*
p
)
{
Vec_Flt_t
*
vVec
;
int
i
,
j
;
float
Entry
;
int
i
,
k
;
fprintf
(
s
,
"Surface:
\n
"
);
for
(
i
=
Abc_SclGetI
(
vOut
,
pPos
);
i
!=
0
;
i
--
)
Vec_FltPush
(
p
->
vIndex0
,
Abc_SclGetF
(
vOut
,
pPos
)
);
fprintf
(
s
,
"%d"
,
Vec_FltSize
(
p
->
vIndex0
)
);
fprintf
(
s
,
"
\n
"
);
Vec_FltForEachEntry
(
p
->
vIndex0
,
Entry
,
i
)
fprintf
(
s
,
"%f "
,
Entry
);
fprintf
(
s
,
"
\n
"
);
for
(
i
=
Abc_SclGetI
(
vOut
,
pPos
);
i
!=
0
;
i
--
)
Vec_FltPush
(
p
->
vIndex1
,
Abc_SclGetF
(
vOut
,
pPos
)
);
fprintf
(
s
,
"%d"
,
Vec_FltSize
(
p
->
vIndex1
)
);
fprintf
(
s
,
"
\n
"
);
Vec_FltForEachEntry
(
p
->
vIndex1
,
Entry
,
i
)
fprintf
(
s
,
"%f "
,
Entry
);
fprintf
(
s
,
"
\n
"
);
for
(
i
=
0
;
i
<
Vec_FltSize
(
p
->
vIndex0
);
i
++
)
Vec_PtrForEachEntry
(
Vec_Flt_t
*
,
p
->
vData
,
vVec
,
i
)
{
vVec
=
Vec_FltAlloc
(
Vec_FltSize
(
p
->
vIndex1
)
);
Vec_PtrPush
(
p
->
vData
,
vVec
);
for
(
j
=
0
;
j
<
Vec_FltSize
(
p
->
vIndex1
);
j
++
)
Vec_FltPush
(
vVec
,
Abc_SclGetF
(
vOut
,
pPos
)
);
Vec_FltForEachEntry
(
vVec
,
Entry
,
k
)
fprintf
(
s
,
"%f "
,
Entry
);
fprintf
(
s
,
"
\n
"
);
}
for
(
i
=
0
;
i
<
3
;
i
++
)
p
->
approx
[
0
][
i
]
=
Abc_SclGetF
(
vOut
,
pPos
);
fprintf
(
s
,
"%f "
,
p
->
approx
[
0
][
i
]
);
fprintf
(
s
,
"
\n
"
);
for
(
i
=
0
;
i
<
4
;
i
++
)
p
->
approx
[
1
][
i
]
=
Abc_SclGetF
(
vOut
,
pPos
);
fprintf
(
s
,
"%f "
,
p
->
approx
[
1
][
i
]
);
fprintf
(
s
,
"
\n
"
);
for
(
i
=
0
;
i
<
6
;
i
++
)
p
->
approx
[
2
][
i
]
=
Abc_SclGetF
(
vOut
,
pPos
);
fprintf
(
s
,
"%f "
,
p
->
approx
[
2
][
i
]
);
fprintf
(
s
,
"
\n
"
);
}
static
void
Abc_Scl
ReadLibrary
(
Vec_Str_t
*
vOut
,
int
*
pPo
s
,
SC_Lib
*
p
)
static
void
Abc_Scl
WriteLibraryText
(
FILE
*
s
,
SC_Lib
*
p
)
{
int
i
,
j
,
k
,
n
;
int
version
=
Abc_SclGetI
(
vOut
,
pPos
);
assert
(
version
==
ABC_SCL_CUR_VERSION
);
// wrong version of the file
// Read non-composite fields:
p
->
lib_name
=
Abc_SclGetS
(
vOut
,
pPos
);
p
->
default_wire_load
=
Abc_SclGetS
(
vOut
,
pPos
);
p
->
default_wire_load_sel
=
Abc_SclGetS
(
vOut
,
pPos
);
p
->
default_max_out_slew
=
Abc_SclGetF
(
vOut
,
pPos
);
SC_WireLoad
*
pWL
;
SC_WireLoadSel
*
pWLS
;
SC_Cell
*
pCell
;
SC_Pin
*
pPin
;
int
n_valid_cells
;
int
i
,
j
,
k
;
p
->
unit_time
=
Abc_SclGetI
(
vOut
,
pPos
);
p
->
unit_cap_fst
=
Abc_SclGetF
(
vOut
,
pPos
);
p
->
unit_cap_snd
=
Abc_SclGetI
(
vOut
,
pPos
);
// fprintf( s, "%d", ABC_SCL_CUR_VERSION );
fprintf
(
s
,
"Liberty:
\n
"
);
// Read 'wire_load' vector:
for
(
i
=
Abc_SclGetI
(
vOut
,
pPos
);
i
!=
0
;
i
--
)
{
SC_WireLoad
*
pWL
=
Abc_SclWireLoadAlloc
();
Vec_PtrPush
(
p
->
vWireLoads
,
pWL
);
// Write non-composite fields:
fprintf
(
s
,
"%s"
,
p
->
lib_name
);
fprintf
(
s
,
"
\n
"
);
fprintf
(
s
,
"%s"
,
p
->
default_wire_load
);
fprintf
(
s
,
"
\n
"
);
fprintf
(
s
,
"%s"
,
p
->
default_wire_load_sel
);
fprintf
(
s
,
"
\n
"
);
fprintf
(
s
,
"%f"
,
p
->
default_max_out_slew
);
fprintf
(
s
,
"
\n
"
);
pWL
->
name
=
Abc_SclGetS
(
vOut
,
pPos
);
pWL
->
res
=
Abc_SclGetF
(
vOut
,
pPos
);
pWL
->
cap
=
Abc_SclGetF
(
vOut
,
pPos
);
assert
(
p
->
unit_time
>=
0
);
assert
(
p
->
unit_cap_snd
>=
0
);
fprintf
(
s
,
"%d"
,
p
->
unit_time
);
fprintf
(
s
,
"
\n
"
);
fprintf
(
s
,
"%f"
,
p
->
unit_cap_fst
);
fprintf
(
s
,
"
\n
"
);
fprintf
(
s
,
"%d"
,
p
->
unit_cap_snd
);
fprintf
(
s
,
"
\n
"
);
for
(
j
=
Abc_SclGetI
(
vOut
,
pPos
);
j
!=
0
;
j
--
)
// Write 'wire_load' vector:
fprintf
(
s
,
"
\n
"
);
fprintf
(
s
,
"%d"
,
Vec_PtrSize
(
p
->
vWireLoads
)
);
fprintf
(
s
,
"
\n
"
);
Vec_PtrForEachEntry
(
SC_WireLoad
*
,
p
->
vWireLoads
,
pWL
,
i
)
{
fprintf
(
s
,
"WireLoad:
\n
"
);
fprintf
(
s
,
"%s "
,
pWL
->
name
);
fprintf
(
s
,
"%f "
,
pWL
->
res
);
fprintf
(
s
,
"%f"
,
pWL
->
cap
);
fprintf
(
s
,
"
\n
"
);
fprintf
(
s
,
"%d"
,
Vec_IntSize
(
pWL
->
vFanout
)
);
fprintf
(
s
,
"
\n
"
);
for
(
j
=
0
;
j
<
Vec_IntSize
(
pWL
->
vFanout
);
j
++
)
{
Vec_IntPush
(
pWL
->
vFanout
,
Abc_SclGetI
(
vOut
,
pPos
)
);
Vec_FltPush
(
pWL
->
vLen
,
Abc_SclGetF
(
vOut
,
pPos
)
);
fprintf
(
s
,
"%d "
,
Vec_IntEntry
(
pWL
->
vFanout
,
j
)
);
fprintf
(
s
,
"%f "
,
Vec_FltEntry
(
pWL
->
vLen
,
j
)
);
}
fprintf
(
s
,
"
\n
"
);
}
fprintf
(
s
,
"
\n
"
);
// Read 'wire_load_sel' vector:
for
(
i
=
Abc_SclGetI
(
vOut
,
pPos
);
i
!=
0
;
i
--
)
// Write 'wire_load_sel' vector:
fprintf
(
s
,
"%d"
,
Vec_PtrSize
(
p
->
vWireLoadSels
)
);
fprintf
(
s
,
"
\n
"
);
Vec_PtrForEachEntry
(
SC_WireLoadSel
*
,
p
->
vWireLoadSels
,
pWLS
,
i
)
{
SC_WireLoadSel
*
pWLS
=
Abc_SclWireLoadSelAlloc
();
Vec_PtrPush
(
p
->
vWireLoadSels
,
pWLS
);
pWLS
->
name
=
Abc_SclGetS
(
vOut
,
pPos
);
for
(
j
=
Abc_SclGetI
(
vOut
,
pPos
);
j
!=
0
;
j
--
)
fprintf
(
s
,
"WireLoadSel:
\n
"
);
fprintf
(
s
,
"%s"
,
pWLS
->
name
);
fprintf
(
s
,
"
\n
"
);
fprintf
(
s
,
"%d"
,
Vec_FltSize
(
pWLS
->
vAreaFrom
)
);
fprintf
(
s
,
"
\n
"
);
for
(
j
=
0
;
j
<
Vec_FltSize
(
pWLS
->
vAreaFrom
);
j
++
)
{
Vec_FltPush
(
pWLS
->
vAreaFrom
,
Abc_SclGetF
(
vOut
,
pPos
)
);
Vec_FltPush
(
pWLS
->
vAreaTo
,
Abc_SclGetF
(
vOut
,
pPos
)
);
Vec_PtrPush
(
pWLS
->
vWireLoadModel
,
Abc_SclGetS
(
vOut
,
pPos
)
);
fprintf
(
s
,
"%f"
,
Vec_FltEntry
(
pWLS
->
vAreaFrom
,
j
)
);
fprintf
(
s
,
" "
);
fprintf
(
s
,
"%f"
,
Vec_FltEntry
(
pWLS
->
vAreaTo
,
j
)
);
fprintf
(
s
,
" "
);
fprintf
(
s
,
"%s"
,
(
char
*
)
Vec_PtrEntry
(
pWLS
->
vWireLoadModel
,
j
)
);
fprintf
(
s
,
"
\n
"
);
}
}
fprintf
(
s
,
"
\n
"
);
// Write 'cells' vector:
n_valid_cells
=
0
;
Vec_PtrForEachEntry
(
SC_Cell
*
,
p
->
vCells
,
pCell
,
i
)
if
(
!
(
pCell
->
seq
||
pCell
->
unsupp
)
)
n_valid_cells
++
;
for
(
i
=
Abc_SclGetI
(
vOut
,
pPos
);
i
!=
0
;
i
--
)
fprintf
(
s
,
"%d"
,
n_valid_cells
);
fprintf
(
s
,
"
\n
"
);
Vec_PtrForEachEntry
(
SC_Cell
*
,
p
->
vCells
,
pCell
,
i
)
{
SC_Cell
*
pCell
=
Abc_SclCellAlloc
();
Vec_PtrPush
(
p
->
vCells
,
pCell
)
;
if
(
pCell
->
seq
||
pCell
->
unsupp
)
continue
;
pCell
->
name
=
Abc_SclGetS
(
vOut
,
pPos
);
pCell
->
area
=
Abc_SclGetF
(
vOut
,
pPos
);
pCell
->
drive_strength
=
Abc_SclGetI
(
vOut
,
pPos
);
fprintf
(
s
,
"
\n
Cell:
\n
"
);
fprintf
(
s
,
"%s "
,
pCell
->
name
);
fprintf
(
s
,
"%f "
,
pCell
->
area
);
fprintf
(
s
,
"%d"
,
pCell
->
drive_strength
);
fprintf
(
s
,
" "
);
pCell
->
n_inputs
=
Abc_SclGetI
(
vOut
,
pPos
);
pCell
->
n_outputs
=
Abc_SclGetI
(
vOut
,
pPos
);
// Write 'pins': (sorted at this point; first inputs, then outputs)
fprintf
(
s
,
"%d "
,
pCell
->
n_inputs
);
fprintf
(
s
,
"%d"
,
pCell
->
n_outputs
);
fprintf
(
s
,
"
\n
"
);
for
(
j
=
0
;
j
<
pCell
->
n_inputs
;
j
++
)
Vec_PtrForEachEntryStop
(
SC_Pin
*
,
pCell
->
vPins
,
pPin
,
j
,
pCell
->
n_inputs
)
{
SC_Pin
*
pPin
=
Abc_SclPinAlloc
();
Vec_PtrPush
(
pCell
->
vPins
,
pPin
);
pPin
->
dir
=
sc_dir_Input
;
pPin
->
name
=
Abc_SclGetS
(
vOut
,
pPos
);
pPin
->
rise_cap
=
Abc_SclGetF
(
vOut
,
pPos
);
pPin
->
fall_cap
=
Abc_SclGetF
(
vOut
,
pPos
);
assert
(
pPin
->
dir
==
sc_dir_Input
);
fprintf
(
s
,
"Pin:
\n
"
);
fprintf
(
s
,
"%s "
,
pPin
->
name
);
fprintf
(
s
,
"%f "
,
pPin
->
rise_cap
);
fprintf
(
s
,
"%f"
,
pPin
->
fall_cap
);
fprintf
(
s
,
"
\n
"
);
}
for
(
j
=
0
;
j
<
pCell
->
n_outputs
;
j
++
)
Vec_PtrForEachEntryStart
(
SC_Pin
*
,
pCell
->
vPins
,
pPin
,
j
,
pCell
->
n_inputs
)
{
SC_Pin
*
pPin
=
Abc_SclPinAlloc
();
Vec_PtrPush
(
pCell
->
vPins
,
pPin
);
pPin
->
dir
=
sc_dir_Output
;
pPin
->
name
=
Abc_SclGetS
(
vOut
,
pPos
);
pPin
->
max_out_cap
=
Abc_SclGetF
(
vOut
,
pPos
);
pPin
->
max_out_slew
=
Abc_SclGetF
(
vOut
,
pPos
);
k
=
Abc_SclGetI
(
vOut
,
pPos
);
assert
(
k
==
pCell
->
n_inputs
);
SC_Timings
*
pRTime
;
// word uWord;
assert
(
pPin
->
dir
==
sc_dir_Output
);
// read functions
assert
(
Vec_WrdSize
(
pPin
->
vFunc
)
==
0
);
Vec_WrdGrow
(
pPin
->
vFunc
,
Abc_Truth6WordNum
(
pCell
->
n_inputs
)
);
for
(
k
=
0
;
k
<
Vec_WrdCap
(
pPin
->
vFunc
);
k
++
)
Vec_WrdPush
(
pPin
->
vFunc
,
Abc_SclGetW
(
vOut
,
pPos
)
);
fprintf
(
s
,
"Pin:
\n
"
);
fprintf
(
s
,
"%s "
,
pPin
->
name
);
fprintf
(
s
,
"%f "
,
pPin
->
max_out_cap
);
fprintf
(
s
,
"%f"
,
pPin
->
max_out_slew
);
fprintf
(
s
,
"
\n
"
);
/*
// write function
assert( Vec_WrdSize(pPin->vFunc) == Abc_Truth6WordNum(pCell->n_inputs) );
fprintf( s, "%d", pCell->n_inputs );
Vec_WrdForEachEntry( pPin->vFunc, uWord, k ) // -- 'size = 1u << (n_vars - 6)'
Vec_StrPutW( s, uWord ); // -- 64-bit number, written uncompressed (low-byte first)
*/
Extra_PrintHex
(
s
,
(
unsigned
*
)
Vec_WrdArray
(
pPin
->
vFunc
),
pCell
->
n_inputs
);
fprintf
(
s
,
"
\n
"
);
// Read 'rtiming': (pin-to-pin timing tables for this particular output)
for
(
k
=
0
;
k
<
pCell
->
n_inputs
;
k
++
)
// Write 'rtiming': (pin-to-pin timing tables for this particular output)
assert
(
Vec_PtrSize
(
pPin
->
vRTimings
)
==
pCell
->
n_inputs
);
Vec_PtrForEachEntry
(
SC_Timings
*
,
pPin
->
vRTimings
,
pRTime
,
k
)
{
SC_Timings
*
pRTime
=
Abc_SclTimingsAlloc
();
Vec_PtrPush
(
pPin
->
vRTimings
,
pRTime
);
pRTime
->
name
=
Abc_SclGetS
(
vOut
,
pPos
);
n
=
Abc_SclGetI
(
vOut
,
pPos
);
assert
(
n
<=
1
);
if
(
n
==
1
)
fprintf
(
s
,
"%s "
,
pRTime
->
name
);
fprintf
(
s
,
"%d"
,
Vec_PtrSize
(
pRTime
->
vTimings
)
);
fprintf
(
s
,
"
\n
"
);
// -- NOTE! After post-processing, the size of the 'rtiming[k]' vector is either
// 0 or 1 (in static timing, we have merged all tables to get the worst case).
// The case with size 0 should only occur for multi-output gates.
if
(
Vec_PtrSize
(
pRTime
->
vTimings
)
==
1
)
{
SC_Timing
*
pTime
=
Abc_SclTimingAlloc
();
Vec_PtrPush
(
pRTime
->
vTimings
,
pTime
);
pTime
->
tsense
=
(
SC_TSense
)
Abc_SclGetI
(
vOut
,
pPos
);
Abc_SclReadSurface
(
vOut
,
pPos
,
pTime
->
pCellRise
);
Abc_SclReadSurface
(
vOut
,
pPos
,
pTime
->
pCellFall
);
Abc_SclReadSurface
(
vOut
,
pPos
,
pTime
->
pRiseTrans
);
Abc_SclReadSurface
(
vOut
,
pPos
,
pTime
->
pFallTrans
);
SC_Timing
*
pTime
=
(
SC_Timing
*
)
Vec_PtrEntry
(
pRTime
->
vTimings
,
0
);
// -- NOTE! We don't need to save 'related_pin' string because we have sorted
// the elements on input pins.
fprintf
(
s
,
"%d"
,
(
int
)
pTime
->
tsense
);
fprintf
(
s
,
"
\n
"
);
Abc_SclWriteSurfaceText
(
s
,
pTime
->
pCellRise
);
Abc_SclWriteSurfaceText
(
s
,
pTime
->
pCellFall
);
Abc_SclWriteSurfaceText
(
s
,
pTime
->
pRiseTrans
);
Abc_SclWriteSurfaceText
(
s
,
pTime
->
pFallTrans
);
}
else
assert
(
Vec_PtrSize
(
p
Pin
->
vR
Timings
)
==
0
);
assert
(
Vec_PtrSize
(
p
RTime
->
v
Timings
)
==
0
);
}
}
fprintf
(
s
,
"
\n
"
);
}
}
SC_Lib
*
Abc_SclRead
(
char
*
pFileName
)
void
Abc_SclWriteText
(
char
*
pFileName
,
SC_Lib
*
p
)
{
SC_Lib
*
p
;
FILE
*
pFile
;
Vec_Str_t
*
vOut
;
int
nFileSize
,
Pos
=
0
;
pFile
=
fopen
(
pFileName
,
"rb"
);
FILE
*
pFile
=
fopen
(
pFileName
,
"wb"
);
if
(
pFile
==
NULL
)
printf
(
"Cannot open text file
\"
%s
\"
for writing.
\n
"
,
pFileName
);
else
{
printf
(
"Cannot open file
\"
%s
\"
for reading.
\n
"
,
pFileName
);
return
NULL
;
}
// get the file size, in bytes
fseek
(
pFile
,
0
,
SEEK_END
);
nFileSize
=
ftell
(
pFile
);
rewind
(
pFile
);
// load the contents
vOut
=
Vec_StrAlloc
(
nFileSize
);
vOut
->
nSize
=
vOut
->
nCap
;
assert
(
nFileSize
==
Vec_StrSize
(
vOut
)
);
nFileSize
=
fread
(
Vec_StrArray
(
vOut
),
1
,
Vec_StrSize
(
vOut
),
pFile
);
assert
(
nFileSize
==
Vec_StrSize
(
vOut
)
);
fclose
(
pFile
);
// read the library
p
=
Abc_SclLibAlloc
();
Abc_SclReadLibrary
(
vOut
,
&
Pos
,
p
);
assert
(
Pos
==
Vec_StrSize
(
vOut
)
);
Vec_StrFree
(
vOut
);
return
p
;
}
void
Abc_SclLoad
(
char
*
pFileName
,
void
**
ppScl
)
{
if
(
*
ppScl
)
{
Abc_SclLibFree
(
*
(
SC_Lib
**
)
ppScl
);
*
ppScl
=
NULL
;
Abc_SclWriteLibraryText
(
pFile
,
p
);
fclose
(
pFile
);
}
assert
(
*
ppScl
==
NULL
);
if
(
pFileName
)
*
(
SC_Lib
**
)
ppScl
=
Abc_SclRead
(
pFileName
);
}
...
...
src/map/scl/sclInt.h
View file @
dfd6ab08
...
...
@@ -159,7 +159,9 @@ struct SC_Lib_
Vec_Ptr_t
*
vWireLoads
;
// NamedSet<SC_WireLoad>
Vec_Ptr_t
*
vWireLoadSels
;
// NamedSet<SC_WireLoadSel>
Vec_Ptr_t
*
vTempls
;
// NamedSet<SC_TableTempl>
Vec_Ptr_t
*
vCells
;
// NamedSet<SC_Cell>
Vec_Ptr_t
*
vCells
;
// NamedSet<SC_Cell>
int
*
pBins
;
// hashing gateName -> gateId
int
nBins
;
};
////////////////////////////////////////////////////////////////////////
...
...
@@ -170,6 +172,9 @@ struct SC_Lib_
/// MACRO DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
static
inline
SC_Cell
*
SC_LibCell
(
SC_Lib
*
p
,
int
i
)
{
return
(
SC_Cell
*
)
Vec_PtrEntry
(
p
->
vCells
,
i
);
}
static
inline
SC_Pin
*
SC_CellPin
(
SC_Cell
*
p
,
int
i
)
{
return
(
SC_Pin
*
)
Vec_PtrEntry
(
p
->
vPins
,
i
);
}
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
...
...
@@ -351,11 +356,18 @@ static inline void Abc_SclLibFree( SC_Lib * p )
ABC_FREE
(
p
->
lib_name
);
ABC_FREE
(
p
->
default_wire_load
);
ABC_FREE
(
p
->
default_wire_load_sel
);
ABC_FREE
(
p
->
pBins
);
ABC_FREE
(
p
);
}
/*=== scl.c =============================================================*/
/*=== sclFile.c =============================================================*/
extern
SC_Lib
*
Abc_SclRead
(
char
*
pFileName
);
extern
void
Abc_SclWrite
(
char
*
pFileName
,
SC_Lib
*
p
);
extern
void
Abc_SclWriteText
(
char
*
pFileName
,
SC_Lib
*
p
);
extern
int
Abc_SclCellFind
(
SC_Lib
*
p
,
char
*
pName
);
ABC_NAMESPACE_HEADER_END
...
...
src/map/scl/sclSize.c
View file @
dfd6ab08
...
...
@@ -41,6 +41,7 @@ ABC_NAMESPACE_IMPL_START
***********************************************************************/
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
...
...
src/map/scl/sclTime.c
View file @
dfd6ab08
...
...
@@ -16,6 +16,8 @@
***********************************************************************/
#include "base/abc/abc.h"
#include "map/mio/mio.h"
#include "sclInt.h"
ABC_NAMESPACE_IMPL_START
...
...
@@ -25,12 +27,297 @@ ABC_NAMESPACE_IMPL_START
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
typedef
struct
SC_Pair_
SC_Pair
;
typedef
struct
SC_Man_
SC_Man
;
struct
SC_Pair_
{
float
rise
;
float
fall
;
};
struct
SC_Man_
{
SC_Lib
*
pLib
;
// library
Abc_Ntk_t
*
pNtk
;
// network
int
nObjs
;
// allocated size
Vec_Int_t
*
vGates
;
// mapping of objId into gateId
SC_Pair
*
pLoads
;
// loads for each gate
SC_Pair
*
pArrs
;
// arrivals for each gate
SC_Pair
*
pSlews
;
// slews for each gate
char
*
pWireLoadUsed
;
// name of the used WireLoad model
};
static
inline
SC_Pair
*
Abc_SclObjLoad
(
SC_Man
*
p
,
Abc_Obj_t
*
pObj
)
{
return
p
->
pLoads
+
Abc_ObjId
(
pObj
);
}
static
inline
SC_Pair
*
Abc_SclObjArr
(
SC_Man
*
p
,
Abc_Obj_t
*
pObj
)
{
return
p
->
pArrs
+
Abc_ObjId
(
pObj
);
}
static
inline
SC_Pair
*
Abc_SclObjSlew
(
SC_Man
*
p
,
Abc_Obj_t
*
pObj
)
{
return
p
->
pSlews
+
Abc_ObjId
(
pObj
);
}
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
))
);
}
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Prepares STA manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
Abc_SclManFindGates
(
SC_Man
*
p
)
{
Abc_Obj_t
*
pObj
;
char
*
pName
;
int
i
,
gateId
;
assert
(
p
->
vGates
==
NULL
);
p
->
vGates
=
Vec_IntStartFull
(
p
->
nObjs
);
Abc_NtkForEachNode
(
p
->
pNtk
,
pObj
,
i
)
{
pName
=
Mio_GateReadName
((
Mio_Gate_t
*
)
pObj
->
pData
);
gateId
=
Abc_SclCellFind
(
p
->
pLib
,
pName
);
assert
(
gateId
>=
0
);
Vec_IntWriteEntry
(
p
->
vGates
,
i
,
gateId
);
}
}
SC_Man
*
Abc_SclManAlloc
(
SC_Lib
*
pLib
,
Abc_Ntk_t
*
pNtk
)
{
SC_Man
*
p
;
assert
(
Abc_NtkHasMapping
(
pNtk
)
);
p
=
ABC_CALLOC
(
SC_Man
,
1
);
p
->
pLib
=
pLib
;
p
->
pNtk
=
pNtk
;
p
->
nObjs
=
Abc_NtkObjNumMax
(
pNtk
);
p
->
pLoads
=
ABC_CALLOC
(
SC_Pair
,
p
->
nObjs
);
p
->
pArrs
=
ABC_CALLOC
(
SC_Pair
,
p
->
nObjs
);
p
->
pSlews
=
ABC_CALLOC
(
SC_Pair
,
p
->
nObjs
);
Abc_SclManFindGates
(
p
);
return
p
;
}
void
Abc_SclManFree
(
SC_Man
*
p
)
{
Vec_IntFree
(
p
->
vGates
);
ABC_FREE
(
p
->
pLoads
);
ABC_FREE
(
p
->
pArrs
);
ABC_FREE
(
p
->
pSlews
);
ABC_FREE
(
p
);
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
float
Abc_SclTotalArea
(
SC_Man
*
p
,
Vec_Ptr_t
*
vNodes
)
{
double
Area
=
0
;
Abc_Obj_t
*
pObj
;
int
i
;
Vec_PtrForEachEntry
(
Abc_Obj_t
*
,
vNodes
,
pObj
,
i
)
Area
+=
Abc_SclObjCell
(
p
,
pObj
)
->
area
;
return
Area
;
}
Vec_Flt_t
*
Abc_SclFindWireCaps
(
SC_Man
*
p
,
Vec_Ptr_t
*
vNodes
)
{
Vec_Flt_t
*
vCaps
=
NULL
;
SC_WireLoad
*
pWL
;
int
i
,
Entry
,
EntryPrev
,
EntryMax
;
p
->
pWireLoadUsed
=
NULL
;
if
(
p
->
pLib
->
default_wire_load_sel
)
{
float
Area
;
SC_WireLoadSel
*
pWLS
=
NULL
;
Vec_PtrForEachEntry
(
SC_WireLoadSel
*
,
p
->
pLib
->
vWireLoadSels
,
pWLS
,
i
)
if
(
!
strcmp
(
pWLS
->
name
,
p
->
pLib
->
default_wire_load_sel
)
)
break
;
if
(
i
==
Vec_PtrSize
(
p
->
pLib
->
vWireLoadSels
)
)
{
Abc_Print
(
-
1
,
"Cannot find wire load selection model
\"
%s
\"
.
\n
"
,
p
->
pLib
->
default_wire_load_sel
);
exit
(
1
);
}
Area
=
(
float
)
Abc_SclTotalArea
(
p
,
vNodes
);
for
(
i
=
0
;
i
<
Vec_FltSize
(
pWLS
->
vAreaFrom
);
i
++
)
if
(
Area
>=
Vec_FltEntry
(
pWLS
->
vAreaFrom
,
i
)
&&
Area
<
Vec_FltEntry
(
pWLS
->
vAreaTo
,
i
)
)
{
p
->
pWireLoadUsed
=
(
char
*
)
Vec_PtrEntry
(
pWLS
->
vWireLoadModel
,
i
);
break
;
}
if
(
i
==
Vec_FltSize
(
pWLS
->
vAreaFrom
)
)
p
->
pWireLoadUsed
=
(
char
*
)
Vec_PtrEntryLast
(
pWLS
->
vWireLoadModel
);
}
else
if
(
p
->
pLib
->
default_wire_load
)
p
->
pWireLoadUsed
=
p
->
pLib
->
default_wire_load
;
else
{
Abc_Print
(
0
,
"No wire model given.
\n
"
);
return
NULL
;
}
// Get the actual table and reformat it for 'wire_cap' output:
assert
(
p
->
pWireLoadUsed
!=
NULL
);
Vec_PtrForEachEntry
(
SC_WireLoad
*
,
p
->
pLib
->
vWireLoads
,
pWL
,
i
)
if
(
!
strcmp
(
pWL
->
name
,
p
->
pWireLoadUsed
)
)
break
;
if
(
i
==
Vec_PtrSize
(
p
->
pLib
->
vWireLoadSels
)
)
{
Abc_Print
(
-
1
,
"Cannot find wire load model
\"
%s
\"
.
\n
"
,
p
->
pWireLoadUsed
);
exit
(
1
);
}
// find the biggest fanout
EntryMax
=
0
;
Vec_IntForEachEntry
(
pWL
->
vFanout
,
Entry
,
i
)
EntryMax
=
Abc_MaxInt
(
EntryMax
,
Entry
);
// create the array
vCaps
=
Vec_FltStart
(
EntryMax
+
1
);
Vec_IntForEachEntry
(
pWL
->
vFanout
,
Entry
,
i
)
Vec_FltWriteEntry
(
vCaps
,
Entry
,
Vec_FltEntry
(
pWL
->
vLen
,
i
)
*
pWL
->
cap
);
// reformat
EntryPrev
=
0
;
Vec_FltForEachEntry
(
vCaps
,
Entry
,
i
)
{
if
(
Entry
)
EntryPrev
=
Entry
;
else
Vec_FltWriteEntry
(
vCaps
,
i
,
EntryPrev
);
}
return
vCaps
;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static
inline
float
Abc_SclLookup
(
SC_Surface
*
p
,
float
slew
,
float
load
)
{
float
*
pIndex0
,
*
pIndex1
,
*
pDataS
,
*
pDataS1
;
float
sfrac
,
lfrac
,
p0
,
p1
;
int
s
,
l
;
// Find closest sample points in surface:
pIndex0
=
Vec_FltArray
(
p
->
vIndex0
);
for
(
s
=
1
;
s
<
Vec_FltSize
(
p
->
vIndex0
)
-
1
;
s
++
)
if
(
pIndex0
[
s
]
>
slew
)
break
;
s
--
;
pIndex1
=
Vec_FltArray
(
p
->
vIndex1
);
for
(
l
=
1
;
l
<
Vec_FltSize
(
p
->
vIndex1
)
-
1
;
l
++
)
if
(
pIndex1
[
l
]
>
load
)
break
;
l
--
;
// Interpolate (or extrapolate) function value from sample points:
sfrac
=
(
slew
-
pIndex0
[
s
])
/
(
pIndex0
[
s
+
1
]
-
pIndex0
[
s
]);
lfrac
=
(
load
-
pIndex1
[
l
])
/
(
pIndex1
[
l
+
1
]
-
pIndex1
[
l
]);
pDataS
=
Vec_FltArray
(
(
Vec_Flt_t
*
)
Vec_PtrEntry
(
p
->
vData
,
s
)
);
pDataS1
=
Vec_FltArray
(
(
Vec_Flt_t
*
)
Vec_PtrEntry
(
p
->
vData
,
s
+
1
)
);
p0
=
pDataS
[
l
]
+
lfrac
*
(
pDataS
[
l
+
1
]
-
pDataS
[
l
]);
p1
=
pDataS1
[
l
]
+
lfrac
*
(
pDataS1
[
l
+
1
]
-
pDataS1
[
l
]);
return
p0
+
sfrac
*
(
p1
-
p0
);
// <<== multiply result with K factor here
}
void
Abc_SclTimeGate
(
SC_Man
*
p
,
SC_Timing
*
pTime
,
Abc_Obj_t
*
pObj
,
Abc_Obj_t
*
pFanin
)
{
SC_Pair
*
pArrIn
=
Abc_SclObjLoad
(
p
,
pFanin
);
SC_Pair
*
pSlewIn
=
Abc_SclObjLoad
(
p
,
pFanin
);
SC_Pair
*
pLoad
=
Abc_SclObjLoad
(
p
,
pObj
);
SC_Pair
*
pArrOut
=
Abc_SclObjLoad
(
p
,
pObj
);
// modified
SC_Pair
*
pSlewOut
=
Abc_SclObjLoad
(
p
,
pObj
);
// modified
if
(
pTime
->
tsense
==
sc_ts_Pos
||
pTime
->
tsense
==
sc_ts_Non
)
{
pArrOut
->
rise
=
Abc_MaxInt
(
pArrOut
->
rise
,
pArrIn
->
rise
+
Abc_SclLookup
(
pTime
->
pCellRise
,
pSlewIn
->
rise
,
pLoad
->
rise
)
);
pArrOut
->
fall
=
Abc_MaxInt
(
pArrOut
->
fall
,
pArrIn
->
fall
+
Abc_SclLookup
(
pTime
->
pCellFall
,
pSlewIn
->
fall
,
pLoad
->
fall
)
);
pSlewOut
->
rise
=
Abc_MaxInt
(
pSlewOut
->
rise
,
Abc_SclLookup
(
pTime
->
pRiseTrans
,
pSlewIn
->
rise
,
pLoad
->
rise
)
);
pSlewOut
->
fall
=
Abc_MaxInt
(
pSlewOut
->
fall
,
Abc_SclLookup
(
pTime
->
pFallTrans
,
pSlewIn
->
fall
,
pLoad
->
fall
)
);
}
if
(
pTime
->
tsense
==
sc_ts_Neg
||
pTime
->
tsense
==
sc_ts_Non
)
{
pArrOut
->
rise
=
Abc_MaxInt
(
pArrOut
->
rise
,
pArrIn
->
fall
+
Abc_SclLookup
(
pTime
->
pCellRise
,
pSlewIn
->
fall
,
pLoad
->
rise
)
);
pArrOut
->
fall
=
Abc_MaxInt
(
pArrOut
->
fall
,
pArrIn
->
rise
+
Abc_SclLookup
(
pTime
->
pCellFall
,
pSlewIn
->
rise
,
pLoad
->
fall
)
);
pSlewOut
->
rise
=
Abc_MaxInt
(
pSlewOut
->
rise
,
Abc_SclLookup
(
pTime
->
pRiseTrans
,
pSlewIn
->
fall
,
pLoad
->
rise
)
);
pSlewOut
->
fall
=
Abc_MaxInt
(
pSlewOut
->
fall
,
Abc_SclLookup
(
pTime
->
pFallTrans
,
pSlewIn
->
rise
,
pLoad
->
fall
)
);
}
}
void
Abc_SclComputeLoad
(
SC_Man
*
p
,
Vec_Ptr_t
*
vNodes
,
Vec_Flt_t
*
vWireCaps
)
{
Abc_Obj_t
*
pObj
,
*
pFanin
;
int
i
,
k
;
Vec_PtrForEachEntry
(
Abc_Obj_t
*
,
vNodes
,
pObj
,
i
)
{
SC_Cell
*
pCell
=
Abc_SclObjCell
(
p
,
pObj
);
Abc_ObjForEachFanin
(
pObj
,
pFanin
,
k
)
{
SC_Pin
*
pPin
=
SC_CellPin
(
pCell
,
k
);
SC_Pair
*
pLoad
=
Abc_SclObjLoad
(
p
,
pFanin
);
pLoad
->
rise
+=
pPin
->
rise_cap
;
pLoad
->
fall
+=
pPin
->
fall_cap
;
}
}
if
(
vWireCaps
)
{
Vec_PtrForEachEntry
(
Abc_Obj_t
*
,
vNodes
,
pObj
,
i
)
{
SC_Pair
*
pLoad
=
Abc_SclObjLoad
(
p
,
pObj
);
k
=
Abc_MinInt
(
Vec_FltSize
(
vWireCaps
)
-
1
,
Abc_ObjFanoutNum
(
pObj
)
);
pLoad
->
rise
+=
Vec_FltEntry
(
vWireCaps
,
k
);
pLoad
->
fall
+=
Vec_FltEntry
(
vWireCaps
,
k
);
}
}
}
void
Abc_SclTimeNtk
(
SC_Man
*
p
)
{
Vec_Flt_t
*
vWireCaps
;
Vec_Ptr_t
*
vNodes
;
Abc_Obj_t
*
pObj
;
int
i
,
k
;
vNodes
=
Abc_NtkDfs
(
p
->
pNtk
,
0
);
vWireCaps
=
Abc_SclFindWireCaps
(
p
,
vNodes
);
Abc_SclComputeLoad
(
p
,
vNodes
,
vWireCaps
);
Vec_PtrForEachEntry
(
Abc_Obj_t
*
,
vNodes
,
pObj
,
i
)
{
SC_Timings
*
pRTime
;
SC_Timing
*
pTime
;
SC_Pin
*
pPin
;
// get the library cell
SC_Cell
*
pCell
=
Abc_SclObjCell
(
p
,
pObj
);
// get the output pin
assert
(
pCell
->
n_outputs
==
1
);
pPin
=
SC_CellPin
(
pCell
,
pCell
->
n_inputs
);
// compute timing using each fanin
assert
(
Vec_PtrSize
(
pPin
->
vRTimings
)
==
pCell
->
n_inputs
);
Vec_PtrForEachEntry
(
SC_Timings
*
,
pPin
->
vRTimings
,
pRTime
,
k
)
{
assert
(
Vec_PtrSize
(
pRTime
->
vTimings
)
==
1
);
pTime
=
(
SC_Timing
*
)
Vec_PtrEntry
(
pRTime
->
vTimings
,
0
);
Abc_SclTimeGate
(
p
,
pTime
,
pObj
,
Abc_ObjFanin
(
pObj
,
k
)
);
}
}
Vec_PtrFree
(
vNodes
);
}
/**Function*************************************************************
Synopsis []
Description []
...
...
@@ -40,6 +327,30 @@ ABC_NAMESPACE_IMPL_START
SeeAlso []
***********************************************************************/
void
Abc_SclTimeNtkPrint
(
SC_Man
*
p
)
{
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
Abc_SclTimePerform
(
SC_Lib
*
pLib
,
void
*
pNtk
)
{
SC_Man
*
p
;
p
=
Abc_SclManAlloc
(
pLib
,
(
Abc_Ntk_t
*
)
pNtk
);
Abc_SclTimeNtk
(
p
);
Abc_SclTimeNtkPrint
(
p
);
Abc_SclManFree
(
p
);
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
...
...
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