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
ae037e45
Commit
ae037e45
authored
Dec 10, 2006
by
Alan Mishchenko
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Version abc61210
parent
b9abf9c0
Show whitespace changes
Inline
Side-by-side
Showing
24 changed files
with
828 additions
and
421 deletions
+828
-421
abc.dsp
+4
-4
abc.rc
+1
-0
src/base/abc/abcCheck.c
+2
-2
src/base/abci/abc.c
+21
-17
src/base/abci/abcFraig.c
+0
-0
src/base/abci/abcIf.c
+17
-5
src/base/abci/abcPrint.c
+6
-2
src/base/abci/abcRenode.c
+5
-2
src/base/abci/abcStrash.c
+9
-1
src/map/if/if.h
+61
-36
src/map/if/ifCore.c
+15
-3
src/map/if/ifCut.c
+27
-4
src/map/if/ifMan.c
+15
-13
src/map/if/ifMap.c
+23
-27
src/map/if/ifPrepro.c
+3
-3
src/map/if/ifReduce.c
+5
-5
src/map/if/ifSeq.c
+299
-56
src/map/if/ifTime.c
+19
-5
src/map/if/ifUtil.c
+151
-65
src/map/if/module.make
+1
-1
src/misc/nm/nmTable.c
+12
-2
src/opt/ret/retCore.c
+1
-1
src/opt/ret/retDelay.c
+4
-8
src/opt/ret/retLvalue.c
+127
-159
No files found.
abc.dsp
View file @
ae037e45
...
...
@@ -1854,10 +1854,6 @@ SOURCE=.\src\map\if\ifCut.c
# End Source File
# Begin Source File
SOURCE=.\src\map\if\ifLib.c
# End Source File
# Begin Source File
SOURCE=.\src\map\if\ifMan.c
# End Source File
# Begin Source File
...
...
@@ -1878,6 +1874,10 @@ SOURCE=.\src\map\if\ifSeq.c
# End Source File
# Begin Source File
SOURCE=.\src\map\if\ifTime.c
# End Source File
# Begin Source File
SOURCE=.\src\map\if\ifTruth.c
# End Source File
# Begin Source File
...
...
abc.rc
View file @
ae037e45
...
...
@@ -30,6 +30,7 @@ alias fs fraig_sweep
alias fsto fraig_store
alias fres fraig_restore
alias ft fraig_trust
alias ifs if -s
alias pex print_exdc -d
alias pf print_factor
alias pfan print_fanio
...
...
src/base/abc/abcCheck.c
View file @
ae037e45
...
...
@@ -111,7 +111,7 @@ bool Abc_NtkDoCheck( Abc_Ntk_t * pNtk )
return
0
;
}
}
/*
// check CI/CO numbers
if
(
Abc_NtkPiNum
(
pNtk
)
+
Abc_NtkLatchNum
(
pNtk
)
!=
Abc_NtkCiNum
(
pNtk
)
)
{
...
...
@@ -127,7 +127,7 @@ bool Abc_NtkDoCheck( Abc_Ntk_t * pNtk )
fprintf
(
stdout
,
"in procedure Abc_NtkCreateObj() and in the user's code.
\n
"
);
return
0
;
}
*/
// check the names
if
(
!
Abc_NtkCheckNames
(
pNtk
)
)
return
0
;
...
...
src/base/abci/abc.c
View file @
ae037e45
...
...
@@ -7529,25 +7529,26 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv )
memset
(
pPars
,
0
,
sizeof
(
If_Par_t
)
);
// user-controlable paramters
pPars
->
nLutSize
=
4
;
pPars
->
nCutsMax
=
10
;
pPars
->
nCutsMax
=
8
;
pPars
->
DelayTarget
=
-
1
;
pPars
->
fPreprocess
=
1
;
pPars
->
fArea
=
0
;
pPars
->
fFancy
=
0
;
pPars
->
fExpRed
=
1
;
pPars
->
fLatchPaths
=
0
;
pPars
->
fSeq
=
0
;
pPars
->
fSeq
Map
=
0
;
pPars
->
fVerbose
=
0
;
// internal parameters
pPars
->
fTruth
=
0
;
pPars
->
nLatches
=
pNtk
?
Abc_NtkLatchNum
(
pNtk
)
:
0
;
pPars
->
fLiftLeaves
=
0
;
pPars
->
pLutLib
=
NULL
;
// Abc_FrameReadLibLut();
pPars
->
pTimesArr
=
NULL
;
pPars
->
pTimesArr
=
NULL
;
pPars
->
pFuncCost
=
NULL
;
Extra_UtilGetoptReset
();
while
(
(
c
=
Extra_UtilGetopt
(
argc
,
argv
,
"KCDpaflrsvh"
)
)
!=
EOF
)
while
(
(
c
=
Extra_UtilGetopt
(
argc
,
argv
,
"KCDpaflrs
t
vh"
)
)
!=
EOF
)
{
switch
(
c
)
{
...
...
@@ -7600,7 +7601,10 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv )
pPars
->
fExpRed
^=
1
;
break
;
case
's'
:
pPars
->
fSeq
^=
1
;
pPars
->
fSeqMap
^=
1
;
break
;
case
't'
:
pPars
->
fLiftLeaves
^=
1
;
break
;
case
'v'
:
pPars
->
fVerbose
^=
1
;
...
...
@@ -7616,12 +7620,18 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv )
fprintf
(
pErr
,
"Empty network.
\n
"
);
return
1
;
}
/*
if ( pPars->fSeq )
{
fprintf( pErr, "Sequential mapping is currently being implemented.\n" );
return 1;
}
*/
if
(
pPars
->
fSeqMap
&&
pPars
->
nLatches
==
0
)
{
fprintf
(
pErr
,
"The network has no latches. Use combinational mapping instead of sequential.
\n
"
);
return
1
;
}
if
(
pPars
->
nLutSize
<
3
||
pPars
->
nLutSize
>
IF_MAX_LUTSIZE
)
{
...
...
@@ -7649,13 +7659,6 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv )
return
1
;
}
// set the latch paths
if
(
pPars
->
fLatchPaths
)
{
for
(
c
=
0
;
c
<
Abc_NtkPiNum
(
pNtk
);
c
++
)
pPars
->
pTimesArr
[
c
]
=
-
ABC_INFINITY
;
}
if
(
!
Abc_NtkIsStrash
(
pNtk
)
)
{
// strash and balance the network
...
...
@@ -7679,7 +7682,7 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv )
{
Abc_NtkDelete
(
pNtk
);
fprintf
(
pErr
,
"FPGA mapping has failed.
\n
"
);
return
1
;
return
0
;
}
Abc_NtkDelete
(
pNtk
);
}
...
...
@@ -7690,7 +7693,7 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv )
if
(
pNtkRes
==
NULL
)
{
fprintf
(
pErr
,
"FPGA mapping has failed.
\n
"
);
return
1
;
return
0
;
}
}
// replace the current network
...
...
@@ -7706,17 +7709,18 @@ usage:
sprintf
(
LutSize
,
"library"
);
else
sprintf
(
LutSize
,
"%d"
,
pPars
->
nLutSize
);
fprintf
(
pErr
,
"usage: if [-K num] [-C num] [-D float] [-pafrsvh]
\n
"
);
fprintf
(
pErr
,
"usage: if [-K num] [-C num] [-D float] [-pafrs
t
vh]
\n
"
);
fprintf
(
pErr
,
"
\t
performs FPGA technology mapping of the network
\n
"
);
fprintf
(
pErr
,
"
\t
-K num : the number of LUT inputs (2 < num < %d) [default = %s]
\n
"
,
IF_MAX_LUTSIZE
+
1
,
LutSize
);
fprintf
(
pErr
,
"
\t
-C num : the max number of cuts to use (1 < num < 2^12) [default = %d]
\n
"
,
pPars
->
nCutsMax
);
fprintf
(
pErr
,
"
\t
-D float : sets the delay constraint for the mapping [default = %s]
\n
"
,
Buffer
);
fprintf
(
pErr
,
"
\t
-p : toggles preprocessing using several starting points [default = %s]
\n
"
,
pPars
->
fPreprocess
?
"yes"
:
"no"
);
fprintf
(
pErr
,
"
\t
-a : toggles area-oriented mapping [default = %s]
\n
"
,
pPars
->
fArea
?
"yes"
:
"no"
);
fprintf
(
pErr
,
"
\t
-f : toggles one fancy feature [default = %s]
\n
"
,
pPars
->
fFancy
?
"yes"
:
"no"
);
//
fprintf( pErr, "\t-f : toggles one fancy feature [default = %s]\n", pPars->fFancy? "yes": "no" );
fprintf
(
pErr
,
"
\t
-r : enables expansion/reduction of the best cuts [default = %s]
\n
"
,
pPars
->
fExpRed
?
"yes"
:
"no"
);
fprintf
(
pErr
,
"
\t
-l : optimizes latch paths for delay, other paths for area [default = %s]
\n
"
,
pPars
->
fLatchPaths
?
"yes"
:
"no"
);
fprintf
(
pErr
,
"
\t
-s : toggles sequential mapping [default = %s]
\n
"
,
pPars
->
fSeq
?
"yes"
:
"no"
);
fprintf
(
pErr
,
"
\t
-s : toggles sequential mapping [default = %s]
\n
"
,
pPars
->
fSeqMap
?
"yes"
:
"no"
);
fprintf
(
pErr
,
"
\t
-t : toggles the use of true sequential cuts [default = %s]
\n
"
,
pPars
->
fLiftLeaves
?
"yes"
:
"no"
);
fprintf
(
pErr
,
"
\t
-v : toggles verbose output [default = %s]
\n
"
,
pPars
->
fVerbose
?
"yes"
:
"no"
);
fprintf
(
pErr
,
"
\t
-h : prints the command usage
\n
"
);
return
1
;
...
...
src/base/abci/abcFraig.c
View file @
ae037e45
src/base/abci/abcIf.c
View file @
ae037e45
...
...
@@ -58,6 +58,14 @@ Abc_Ntk_t * Abc_NtkIf( Abc_Ntk_t * pNtk, If_Par_t * pPars )
pPars
->
pTimesArr
=
Abc_NtkGetCiArrivalFloats
(
pNtk
);
pPars
->
pTimesReq
=
NULL
;
// set the latch paths
if
(
pPars
->
fLatchPaths
&&
pPars
->
pTimesArr
)
{
int
c
;
for
(
c
=
0
;
c
<
Abc_NtkPiNum
(
pNtk
);
c
++
)
pPars
->
pTimesArr
[
c
]
=
-
ABC_INFINITY
;
}
// perform FPGA mapping
pIfMan
=
Abc_NtkToIf
(
pNtk
,
pPars
);
if
(
pIfMan
==
NULL
)
...
...
@@ -117,7 +125,10 @@ If_Man_t * Abc_NtkToIf( Abc_Ntk_t * pNtk, If_Par_t * pPars )
// create PIs and remember them in the old nodes
Abc_AigConst1
(
pNtk
)
->
pCopy
=
(
Abc_Obj_t
*
)
If_ManConst1
(
pIfMan
);
Abc_NtkForEachCi
(
pNtk
,
pNode
,
i
)
pNode
->
pCopy
=
(
Abc_Obj_t
*
)
If_ManCreatePi
(
pIfMan
);
{
pNode
->
pCopy
=
(
Abc_Obj_t
*
)
If_ManCreateCi
(
pIfMan
);
//printf( "AIG CI %2d -> IF CI %2d\n", pNode->Id, ((If_Obj_t *)pNode->pCopy)->Id );
}
// load the AIG into the mapper
pProgress
=
Extra_ProgressBarStart
(
stdout
,
Abc_NtkObjNumMax
(
pNtk
)
);
...
...
@@ -136,13 +147,14 @@ If_Man_t * Abc_NtkToIf( Abc_Ntk_t * pNtk, If_Par_t * pPars )
If_ObjSetChoice
(
(
If_Obj_t
*
)
pPrev
->
pCopy
,
(
If_Obj_t
*
)
pFanin
->
pCopy
);
If_ManCreateChoice
(
pIfMan
,
(
If_Obj_t
*
)
pNode
->
pCopy
);
}
//printf( "AIG node %2d -> IF node %2d\n", pNode->Id, ((If_Obj_t *)pNode->pCopy)->Id );
}
Extra_ProgressBarStop
(
pProgress
);
Vec_PtrFree
(
vNodes
);
// set the primary outputs without copying the phase
Abc_NtkForEachCo
(
pNtk
,
pNode
,
i
)
If_ManCreate
P
o
(
pIfMan
,
(
If_Obj_t
*
)
Abc_ObjFanin0
(
pNode
)
->
pCopy
,
Abc_ObjFaninC0
(
pNode
)
);
If_ManCreate
C
o
(
pIfMan
,
(
If_Obj_t
*
)
Abc_ObjFanin0
(
pNode
)
->
pCopy
,
Abc_ObjFaninC0
(
pNode
)
);
return
pIfMan
;
}
...
...
@@ -177,15 +189,15 @@ Abc_Ntk_t * Abc_NtkFromIf( If_Man_t * pIfMan, Abc_Ntk_t * pNtk )
// make the mapper point to the new network
If_ObjSetCopy
(
If_ManConst1
(
pIfMan
),
Abc_NtkCreateNodeConst1
(
pNtkNew
)
);
Abc_NtkForEachCi
(
pNtk
,
pNode
,
i
)
If_ObjSetCopy
(
If_Man
P
i
(
pIfMan
,
i
),
pNode
->
pCopy
);
If_ObjSetCopy
(
If_Man
C
i
(
pIfMan
,
i
),
pNode
->
pCopy
);
// process the nodes in topological order
vCover
=
Vec_IntAlloc
(
1
<<
16
);
pProgress
=
Extra_ProgressBarStart
(
stdout
,
Abc_NtkCoNum
(
pNtk
)
);
Abc_NtkForEachCo
(
pNtk
,
pNode
,
i
)
{
Extra_ProgressBarUpdate
(
pProgress
,
i
,
"Final"
);
pNodeNew
=
Abc_NodeFromIf_rec
(
pNtkNew
,
pIfMan
,
If_ObjFanin0
(
If_Man
P
o
(
pIfMan
,
i
)),
vCover
);
pNodeNew
=
Abc_ObjNotCond
(
pNodeNew
,
If_ObjFaninC0
(
If_Man
P
o
(
pIfMan
,
i
))
);
pNodeNew
=
Abc_NodeFromIf_rec
(
pNtkNew
,
pIfMan
,
If_ObjFanin0
(
If_Man
C
o
(
pIfMan
,
i
)),
vCover
);
pNodeNew
=
Abc_ObjNotCond
(
pNodeNew
,
If_ObjFaninC0
(
If_Man
C
o
(
pIfMan
,
i
))
);
Abc_ObjAddFanin
(
pNode
->
pCopy
,
pNodeNew
);
}
Extra_ProgressBarStop
(
pProgress
);
...
...
src/base/abci/abcPrint.c
View file @
ae037e45
...
...
@@ -118,15 +118,19 @@ void Abc_NtkPrintStats( FILE * pFile, Abc_Ntk_t * pNtk, int fFactored )
fprintf
(
pFile
,
" lev = %3d"
,
Abc_NtkLevel
(
pNtk
)
);
fprintf
(
pFile
,
"
\n
"
);
// print the statistic into a file
/*
{
FILE * pTable;
pTable = fopen( "stats.txt", "a+" );
pTable = fopen( "
a/seqmap__
stats.txt", "a+" );
fprintf( pTable, "%s ", pNtk->pName );
fprintf( pTable, "%d ", Abc_NtkPiNum(pNtk) );
fprintf( pTable, "%d ", Abc_NtkPoNum(pNtk) );
fprintf( pTable, "%d ", Abc_NtkLatchNum(pNtk) );
fprintf( pTable, "%d ", Abc_NtkNodeNum(pNtk) );
fprintf( pTable, "%d ", Abc_
Aig
Level(pNtk) );
fprintf( pTable, "%d ", Abc_
Ntk
Level(pNtk) );
fprintf( pTable, "\n" );
fclose( pTable );
}
...
...
src/base/abci/abcRenode.c
View file @
ae037e45
...
...
@@ -56,6 +56,9 @@ Abc_Ntk_t * Abc_NtkRenode( Abc_Ntk_t * pNtk, int nFaninMax, int nCubeMax, int fA
If_Par_t
Pars
,
*
pPars
=
&
Pars
;
Abc_Ntk_t
*
pNtkNew
;
if
(
Abc_NtkGetChoiceNum
(
pNtk
)
)
printf
(
"Performing renoding with choices.
\n
"
);
// set defaults
memset
(
pPars
,
0
,
sizeof
(
If_Par_t
)
);
// user-controlable paramters
...
...
@@ -67,11 +70,11 @@ Abc_Ntk_t * Abc_NtkRenode( Abc_Ntk_t * pNtk, int nFaninMax, int nCubeMax, int fA
pPars
->
fFancy
=
0
;
pPars
->
fExpRed
=
0
;
//
pPars
->
fLatchPaths
=
0
;
pPars
->
fSeq
=
0
;
pPars
->
fSeq
Map
=
0
;
pPars
->
fVerbose
=
fVerbose
;
// internal parameters
pPars
->
fTruth
=
1
;
pPars
->
fUsePerm
=
1
;
//!fUseSops;
pPars
->
fUsePerm
=
1
;
pPars
->
nLatches
=
0
;
pPars
->
pLutLib
=
NULL
;
// Abc_FrameReadLibLut();
pPars
->
pTimesArr
=
NULL
;
...
...
src/base/abci/abcStrash.c
View file @
ae037e45
...
...
@@ -151,7 +151,8 @@ Abc_Ntk_t * Abc_NtkStrash( Abc_Ntk_t * pNtk, bool fAllNodes, bool fCleanup )
int
Abc_NtkAppend
(
Abc_Ntk_t
*
pNtk1
,
Abc_Ntk_t
*
pNtk2
,
int
fAddPos
)
{
Abc_Obj_t
*
pObj
;
int
i
;
char
*
pName
;
int
i
,
nNewCis
;
// the first network should be an AIG
assert
(
Abc_NtkIsStrash
(
pNtk1
)
);
assert
(
Abc_NtkIsLogic
(
pNtk2
)
||
Abc_NtkIsStrash
(
pNtk2
)
);
...
...
@@ -165,13 +166,20 @@ int Abc_NtkAppend( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fAddPos )
if
(
!
Abc_NtkCompareSignals
(
pNtk1
,
pNtk2
,
1
,
1
)
)
printf
(
"Abc_NtkAppend(): The union of the network PIs is computed (warning).
\n
"
);
// perform strashing
nNewCis
=
0
;
Abc_NtkCleanCopy
(
pNtk2
);
Abc_NtkForEachCi
(
pNtk2
,
pObj
,
i
)
{
pName
=
Abc_ObjName
(
pObj
);
pObj
->
pCopy
=
Abc_NtkFindCi
(
pNtk1
,
Abc_ObjName
(
pObj
));
if
(
pObj
->
pCopy
==
NULL
)
{
pObj
->
pCopy
=
Abc_NtkDupObj
(
pNtk1
,
pObj
,
1
);
nNewCis
++
;
}
}
if
(
nNewCis
)
printf
(
"Warning: Procedure Abc_NtkAppend() added %d new CIs.
\n
"
,
nNewCis
);
// add pNtk2 to pNtk1 while strashing
if
(
Abc_NtkIsLogic
(
pNtk2
)
)
Abc_NtkStrashPerform
(
pNtk2
,
pNtk1
,
1
);
...
...
src/map/if/if.h
View file @
ae037e45
...
...
@@ -50,8 +50,8 @@ extern "C" {
typedef
enum
{
IF_NONE
,
// 0: non-existent object
IF_CONST1
,
// 1: constant 1
IF_
PI
,
// 2: primary
input
IF_
PO
,
// 3: primary
output
IF_
CI
,
// 2: combinational
input
IF_
CO
,
// 3: combinational
output
IF_AND
,
// 4: AND node
IF_BI
,
// 5: box input
IF_BO
,
// 6: box output
...
...
@@ -63,9 +63,9 @@ typedef enum {
/// BASIC TYPES ///
////////////////////////////////////////////////////////////////////////
typedef
struct
If_Man_t_
If_Man_t
;
typedef
struct
If_Par_t_
If_Par_t
;
typedef
struct
If_Lib_t_
If_Lib_t
;
typedef
struct
If_Man_t_
If_Man_t
;
typedef
struct
If_Obj_t_
If_Obj_t
;
typedef
struct
If_Cut_t_
If_Cut_t
;
...
...
@@ -81,7 +81,7 @@ struct If_Par_t_
int
fFancy
;
// a fancy feature
int
fExpRed
;
// expand/reduce of the best cuts
int
fLatchPaths
;
// reset timing on latch paths
int
fSeq
;
// sequential mapping
int
fSeq
Map
;
// sequential mapping
int
fVerbose
;
// the verbosity flag
// internal parameters
int
fTruth
;
// truth table computation enabled
...
...
@@ -89,6 +89,7 @@ struct If_Par_t_
int
fUseBdds
;
// sets local BDDs at the nodes
int
fUseSops
;
// sets local SOPs at the nodes
int
nLatches
;
// the number of latches in seq mapping
int
fLiftLeaves
;
// shift the leaves for seq mapping
If_Lib_t
*
pLutLib
;
// the LUT library
float
*
pTimesArr
;
// arrival times
float
*
pTimesReq
;
// required times
...
...
@@ -113,8 +114,8 @@ struct If_Man_t_
If_Par_t
*
pPars
;
// mapping nodes
If_Obj_t
*
pConst1
;
// the constant 1 node
Vec_Ptr_t
*
v
P
is
;
// the primary inputs
Vec_Ptr_t
*
v
P
os
;
// the primary outputs
Vec_Ptr_t
*
v
C
is
;
// the primary inputs
Vec_Ptr_t
*
v
C
os
;
// the primary outputs
Vec_Ptr_t
*
vObjs
;
// all objects
Vec_Ptr_t
*
vMapped
;
// objects used in the mapping
Vec_Ptr_t
*
vTemp
;
// temporary array
...
...
@@ -126,10 +127,13 @@ struct If_Man_t_
float
AreaGlo
;
// global area
int
nCutsUsed
;
// the number of cuts currently used
int
nCutsMerged
;
// the total number of cuts merged
int
nCutsSaved
;
// the total number of cuts saved
int
nCutsMax
;
// the maximum number of cuts at a node
float
Fi
;
// the current value of the clock period (for seq mapping)
unsigned
*
puTemp
[
4
];
// used for the truth table computation
// sequential mapping
Vec_Ptr_t
*
vLatchOrder
;
// topological ordering of latches
Vec_Int_t
*
vLags
;
// sequentail lags of all nodes
int
nAttempts
;
// the number of attempts in binary search
int
nMaxIters
;
// the maximum number of iterations
int
Period
;
// the current value of the clock period (for seq mapping)
// memory management
Mem_Fixed_t
*
pMem
;
// memory manager
int
nEntrySize
;
// the size of the entry
...
...
@@ -168,7 +172,8 @@ struct If_Obj_t_
unsigned
fPhase
:
1
;
// phase of the node
unsigned
fRepr
:
1
;
// representative of the equivalence class
unsigned
fMark
:
1
;
// multipurpose mark
unsigned
Level
:
23
;
// logic level of the node
unsigned
fVisit
:
1
;
// multipurpose mark
unsigned
Level
:
22
;
// logic level of the node
int
Id
;
// integer ID
int
nRefs
;
// the number of references
int
nCuts
;
// the number of cuts
...
...
@@ -182,19 +187,21 @@ struct If_Obj_t_
};
static
inline
If_Obj_t
*
If_ManConst1
(
If_Man_t
*
p
)
{
return
p
->
pConst1
;
}
static
inline
If_Obj_t
*
If_Man
Pi
(
If_Man_t
*
p
,
int
i
)
{
return
(
If_Obj_t
*
)
Vec_PtrEntry
(
p
->
vP
is
,
i
);
}
static
inline
If_Obj_t
*
If_Man
Po
(
If_Man_t
*
p
,
int
i
)
{
return
(
If_Obj_t
*
)
Vec_PtrEntry
(
p
->
vP
os
,
i
);
}
static
inline
If_Obj_t
*
If_Man
Ci
(
If_Man_t
*
p
,
int
i
)
{
return
(
If_Obj_t
*
)
Vec_PtrEntry
(
p
->
vC
is
,
i
);
}
static
inline
If_Obj_t
*
If_Man
Co
(
If_Man_t
*
p
,
int
i
)
{
return
(
If_Obj_t
*
)
Vec_PtrEntry
(
p
->
vC
os
,
i
);
}
static
inline
If_Obj_t
*
If_ManObj
(
If_Man_t
*
p
,
int
i
)
{
return
(
If_Obj_t
*
)
Vec_PtrEntry
(
p
->
vObjs
,
i
);
}
static
inline
If_Cut_t
*
If_ManCut
(
If_Man_t
*
p
,
int
i
)
{
return
p
->
ppCuts
[
i
];
}
static
inline
int
If_Man
PiNum
(
If_Man_t
*
p
)
{
return
p
->
nObjs
[
IF_P
I
];
}
static
inline
int
If_Man
PoNum
(
If_Man_t
*
p
)
{
return
p
->
nObjs
[
IF_P
O
];
}
static
inline
int
If_Man
CiNum
(
If_Man_t
*
p
)
{
return
p
->
nObjs
[
IF_C
I
];
}
static
inline
int
If_Man
CoNum
(
If_Man_t
*
p
)
{
return
p
->
nObjs
[
IF_C
O
];
}
static
inline
int
If_ManAndNum
(
If_Man_t
*
p
)
{
return
p
->
nObjs
[
IF_AND
];
}
static
inline
int
If_ManObjNum
(
If_Man_t
*
p
)
{
return
Vec_PtrSize
(
p
->
vObjs
);
}
static
inline
int
If_ObjIsConst1
(
If_Obj_t
*
pObj
)
{
return
pObj
->
Type
==
IF_CONST1
;
}
static
inline
int
If_ObjIsPi
(
If_Obj_t
*
pObj
)
{
return
pObj
->
Type
==
IF_PI
;
}
static
inline
int
If_ObjIsPo
(
If_Obj_t
*
pObj
)
{
return
pObj
->
Type
==
IF_PO
;
}
static
inline
int
If_ObjIsCi
(
If_Obj_t
*
pObj
)
{
return
pObj
->
Type
==
IF_CI
;
}
static
inline
int
If_ObjIsCo
(
If_Obj_t
*
pObj
)
{
return
pObj
->
Type
==
IF_CO
;
}
static
inline
int
If_ObjIsPi
(
If_Obj_t
*
pObj
)
{
return
If_ObjIsCi
(
pObj
)
&&
pObj
->
pFanin0
==
NULL
;
}
static
inline
int
If_ObjIsLatch
(
If_Obj_t
*
pObj
)
{
return
If_ObjIsCi
(
pObj
)
&&
pObj
->
pFanin0
!=
NULL
;
}
static
inline
int
If_ObjIsAnd
(
If_Obj_t
*
pObj
)
{
return
pObj
->
Type
==
IF_AND
;
}
static
inline
int
If_ObjIsBi
(
If_Obj_t
*
pObj
)
{
return
pObj
->
Type
==
IF_BI
;
}
static
inline
int
If_ObjIsBo
(
If_Obj_t
*
pObj
)
{
return
pObj
->
Type
==
IF_BO
;
}
...
...
@@ -210,9 +217,12 @@ static inline void If_ObjSetChoice( If_Obj_t * pObj, If_Obj_t * pEqu ) { p
static
inline
If_Cut_t
*
If_ObjCut
(
If_Obj_t
*
pObj
,
int
iCut
)
{
return
pObj
->
Cuts
+
iCut
;
}
static
inline
If_Cut_t
*
If_ObjCutTriv
(
If_Obj_t
*
pObj
)
{
return
pObj
->
Cuts
;
}
static
inline
If_Cut_t
*
If_ObjCutBest
(
If_Obj_t
*
pObj
)
{
return
pObj
->
Cuts
+
1
;
}
static
inline
If_Cut_t
*
If_ObjCutBest
(
If_Obj_t
*
pObj
)
{
return
pObj
->
Cuts
+
(
int
)(
pObj
->
nCuts
>
1
);
}
static
inline
unsigned
If_ObjCutSign
(
unsigned
ObjId
)
{
return
(
1
<<
(
ObjId
%
31
));
}
static
inline
float
If_ObjLValue
(
If_Obj_t
*
pObj
)
{
return
If_ObjCutTriv
(
pObj
)
->
Delay
;
}
static
inline
void
If_ObjSetLValue
(
If_Obj_t
*
pObj
,
float
LValue
)
{
If_ObjCutTriv
(
pObj
)
->
Delay
=
LValue
;
}
static
inline
void
*
If_CutData
(
If_Cut_t
*
pCut
)
{
return
*
(
void
**
)
pCut
;
}
static
inline
void
If_CutSetData
(
If_Cut_t
*
pCut
,
void
*
pData
)
{
*
(
void
**
)
pCut
=
pData
;
}
...
...
@@ -236,14 +246,20 @@ static inline float If_CutLutArea( If_Man_t * p, If_Cut_t * pCut ) { r
#define IF_INT_LARGE (10000000)
// iterator over the primary inputs
#define If_ManForEachCi( p, pObj, i ) \
Vec_PtrForEachEntry( p->vCis, pObj, i )
// iterator over the primary outputs
#define If_ManForEachCo( p, pObj, i ) \
Vec_PtrForEachEntry( p->vCos, pObj, i )
// iterator over the primary inputs
#define If_ManForEachPi( p, pObj, i ) \
Vec_PtrForEachEntry
( p->vPis, pObj, i
)
Vec_PtrForEachEntry
Stop( p->vCis, pObj, i, If_ManCiNum(p) - p->pPars->nLatches
)
// iterator over the primary outputs
#define If_ManForEachPo( p, pObj, i ) \
Vec_PtrForEachEntry
( p->vPos, pObj, i
)
Vec_PtrForEachEntry
Stop( p->vCos, pObj, i, If_ManCoNum(p) - p->pPars->nLatches
)
// iterator over the latches
#define If_ManForEachLatch( p, pObj, i ) \
Vec_PtrForEachEntryStart( p->v
Pos, pObj, i, If_ManP
oNum(p) - p->pPars->nLatches )
Vec_PtrForEachEntryStart( p->v
Cos, pObj, i, If_ManC
oNum(p) - p->pPars->nLatches )
// iterator over all objects, including those currently not used
#define If_ManForEachObj( p, pObj, i ) \
Vec_PtrForEachEntry( p->vObjs, pObj, i )
...
...
@@ -256,17 +272,22 @@ static inline float If_CutLutArea( If_Man_t * p, If_Cut_t * pCut ) { r
// iterator over cuts of the node
#define If_ObjForEachCutStart( pObj, pCut, i, Start ) \
for ( i = Start; (i < (int)(pObj)->nCuts) && ((pCut) = (pObj)->Cuts + i); i++ )
// iterator leaves of the cut
// iterator over the leaves of the cut
//#define If_CutForEachLeaf( p, pCut, pLeaf, i ) \
// for ( i = 0; (i < (int)(pCut)->nLeaves) && ((pLeaf) = If_ManObj(p, (pCut)->pLeaves[i])); i++ )
#define If_CutForEachLeaf( p, pCut, pLeaf, i ) \
for ( i = 0; (i < (int)(pCut)->nLeaves) && ((pLeaf) = If_ManObj(p, (pCut)->pLeaves[i])); i++ )
for ( i = 0; (i < (int)(pCut)->nLeaves) && ((pLeaf) = If_ManObj(p, p->pPars->fLiftLeaves? (pCut)->pLeaves[i] >> 8 : (pCut)->pLeaves[i])); i++ )
// iterator over the leaves of the sequential cut
#define If_CutForEachLeafSeq( p, pCut, pLeaf, Shift, i ) \
for ( i = 0; (i < (int)(pCut)->nLeaves) && ((pLeaf) = If_ManObj(p, (pCut)->pLeaves[i] >> 8)) && (((Shift) = ((pCut)->pLeaves[i] & 255)) >= 0); i++ )
////////////////////////////////////////////////////////////////////////
/// FUNCTION DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
/*=== ifCore.c ==========================================================*/
/*=== ifCore.c ==========================================================
=
*/
extern
int
If_ManPerformMapping
(
If_Man_t
*
p
);
/*=== ifCut.c ==========================================================*/
/*=== ifCut.c ==========================================================
==
*/
extern
float
If_CutAreaDerefed
(
If_Man_t
*
p
,
If_Cut_t
*
pCut
,
int
nLevels
);
extern
float
If_CutAreaRefed
(
If_Man_t
*
p
,
If_Cut_t
*
pCut
,
int
nLevels
);
extern
float
If_CutDeref
(
If_Man_t
*
p
,
If_Cut_t
*
pCut
,
int
nLevels
);
...
...
@@ -277,35 +298,39 @@ extern float If_CutFlow( If_Man_t * p, If_Cut_t * pCut );
extern
float
If_CutAverageRefs
(
If_Man_t
*
p
,
If_Cut_t
*
pCut
);
extern
int
If_CutFilter
(
If_Man_t
*
p
,
If_Cut_t
*
pCut
);
extern
int
If_CutMerge
(
If_Cut_t
*
pCut0
,
If_Cut_t
*
pCut1
,
If_Cut_t
*
pCut
);
extern
void
If_CutLift
(
If_Cut_t
*
pCut
);
extern
void
If_CutCopy
(
If_Cut_t
*
pCutDest
,
If_Cut_t
*
pCutSrc
);
extern
void
If_ManSortCuts
(
If_Man_t
*
p
,
int
Mode
);
/*=== ifLib.c ==========================================================*/
extern
float
If_CutDelay
(
If_Man_t
*
p
,
If_Cut_t
*
pCut
);
extern
void
If_CutPropagateRequired
(
If_Man_t
*
p
,
If_Cut_t
*
pCut
,
float
Required
);
/*=== ifMan.c ==========================================================*/
/*=== ifMan.c =============================================================*/
extern
If_Man_t
*
If_ManStart
(
If_Par_t
*
pPars
);
extern
void
If_ManStop
(
If_Man_t
*
p
);
extern
If_Obj_t
*
If_ManCreate
P
i
(
If_Man_t
*
p
);
extern
If_Obj_t
*
If_ManCreate
P
o
(
If_Man_t
*
p
,
If_Obj_t
*
pDriver
,
int
fCompl0
);
extern
If_Obj_t
*
If_ManCreate
C
i
(
If_Man_t
*
p
);
extern
If_Obj_t
*
If_ManCreate
C
o
(
If_Man_t
*
p
,
If_Obj_t
*
pDriver
,
int
fCompl0
);
extern
If_Obj_t
*
If_ManCreateAnd
(
If_Man_t
*
p
,
If_Obj_t
*
pFan0
,
int
fCompl0
,
If_Obj_t
*
pFan1
,
int
fCompl1
);
extern
void
If_ManCreateChoice
(
If_Man_t
*
p
,
If_Obj_t
*
pRepr
);
/*=== ifMap.c ==========================================================*/
extern
void
If_ObjPerformMapping
(
If_Man_t
*
p
,
If_Obj_t
*
pObj
,
int
Mode
);
/*=== ifMap.c =============================================================*/
extern
void
If_ObjPerformMappingAnd
(
If_Man_t
*
p
,
If_Obj_t
*
pObj
,
int
Mode
);
extern
void
If_ObjPerformMappingChoice
(
If_Man_t
*
p
,
If_Obj_t
*
pObj
,
int
Mode
);
extern
int
If_ManPerformMappingRound
(
If_Man_t
*
p
,
int
nCutsUsed
,
int
Mode
,
int
fRequired
,
char
*
pLabel
);
/*=== ifPrepro.c ==========================================================*/
extern
void
If_ManPerformMappingPreprocess
(
If_Man_t
*
p
);
/*=== ifReduce.c ==========================================================*/
extern
void
If_ManImproveMapping
(
If_Man_t
*
p
);
/*=== ifSeq.c ==========================================================*/
/*=== ifSeq.c ==========================================================
===
*/
extern
int
If_ManPerformMappingSeq
(
If_Man_t
*
p
);
/*=== ifTruth.c ==========================================================*/
/*=== ifTime.c ============================================================*/
extern
float
If_CutDelay
(
If_Man_t
*
p
,
If_Cut_t
*
pCut
);
extern
void
If_CutPropagateRequired
(
If_Man_t
*
p
,
If_Cut_t
*
pCut
,
float
Required
);
/*=== ifTruth.c ===========================================================*/
extern
void
If_CutComputeTruth
(
If_Man_t
*
p
,
If_Cut_t
*
pCut
,
If_Cut_t
*
pCut0
,
If_Cut_t
*
pCut1
,
int
fCompl0
,
int
fCompl1
);
/*=== ifUtil.c ==========================================================*/
extern
float
If_ManDelayMax
(
If_Man_t
*
p
);
/*=== ifUtil.c ============================================================*/
extern
void
If_ManCleanNodeCopy
(
If_Man_t
*
p
);
extern
void
If_ManCleanCutData
(
If_Man_t
*
p
);
extern
void
If_ManCleanMarkV
(
If_Man_t
*
p
);
extern
float
If_ManDelayMax
(
If_Man_t
*
p
,
int
fSeq
);
extern
void
If_ManComputeRequired
(
If_Man_t
*
p
,
int
fFirstTime
);
extern
float
If_ManScanMapping
(
If_Man_t
*
p
);
extern
float
If_ManScanMappingSeq
(
If_Man_t
*
p
);
#ifdef __cplusplus
}
...
...
src/map/if/ifCore.c
View file @
ae037e45
...
...
@@ -45,13 +45,25 @@ int If_ManPerformMapping( If_Man_t * p )
int
nItersFlow
=
1
;
int
nItersArea
=
2
;
int
clkTotal
=
clock
();
int
i
;
int
RetValue
,
i
;
// try sequential mapping
if
(
p
->
pPars
->
fSeqMap
)
{
RetValue
=
If_ManPerformMappingSeq
(
p
);
if
(
p
->
pPars
->
fVerbose
)
{
PRT
(
"Total time"
,
clock
()
-
clkTotal
);
}
return
RetValue
;
}
// set arrival times and trivial cuts at const 1 and PIs
If_ManConst1
(
p
)
->
Cuts
[
0
].
Delay
=
0
.
0
;
If_ManForEach
P
i
(
p
,
pObj
,
i
)
If_ManForEach
C
i
(
p
,
pObj
,
i
)
pObj
->
Cuts
[
0
].
Delay
=
p
->
pPars
->
pTimesArr
[
i
];
// set the fanout estimates of the PIs
If_ManForEach
P
i
(
p
,
pObj
,
i
)
If_ManForEach
C
i
(
p
,
pObj
,
i
)
pObj
->
EstRefs
=
(
float
)
1
.
0
;
// delay oriented mapping
if
(
p
->
pPars
->
fPreprocess
&&
!
p
->
pPars
->
fArea
&&
p
->
pPars
->
nCutsMax
>=
4
)
...
...
src/map/if/ifCut.c
View file @
ae037e45
...
...
@@ -423,12 +423,14 @@ float If_CutFlow( If_Man_t * p, If_Cut_t * pCut )
If_Obj_t
*
pLeaf
;
float
Flow
;
int
i
;
assert
(
pCut
->
nLeaves
>
1
);
assert
(
p
->
pPars
->
fSeqMap
||
p
Cut
->
nLeaves
>
1
);
Flow
=
If_CutLutArea
(
p
,
pCut
);
If_CutForEachLeaf
(
p
,
pCut
,
pLeaf
,
i
)
{
if
(
pLeaf
->
nRefs
==
0
)
Flow
+=
If_ObjCutBest
(
pLeaf
)
->
Area
;
else
if
(
p
->
pPars
->
fSeqMap
)
// seq
Flow
+=
If_ObjCutBest
(
pLeaf
)
->
Area
/
pLeaf
->
nRefs
;
else
{
assert
(
pLeaf
->
EstRefs
>
p
->
fEpsilon
);
...
...
@@ -453,7 +455,7 @@ float If_CutAverageRefs( If_Man_t * p, If_Cut_t * pCut )
{
If_Obj_t
*
pLeaf
;
int
nRefsTotal
,
i
;
assert
(
pCut
->
nLeaves
>
1
);
assert
(
p
->
pPars
->
fSeqMap
||
p
Cut
->
nLeaves
>
1
);
nRefsTotal
=
0
;
If_CutForEachLeaf
(
p
,
pCut
,
pLeaf
,
i
)
nRefsTotal
+=
pLeaf
->
nRefs
;
...
...
@@ -569,7 +571,7 @@ void If_CutPrintTiming( If_Man_t * p, If_Cut_t * pCut )
float
If_CutAreaDerefed
(
If_Man_t
*
p
,
If_Cut_t
*
pCut
,
int
nLevels
)
{
float
aResult
,
aResult2
;
assert
(
pCut
->
nLeaves
>
1
);
assert
(
p
->
pPars
->
fSeqMap
||
p
Cut
->
nLeaves
>
1
);
aResult2
=
If_CutRef
(
p
,
pCut
,
nLevels
);
aResult
=
If_CutDeref
(
p
,
pCut
,
nLevels
);
assert
(
aResult
==
aResult2
);
...
...
@@ -590,7 +592,7 @@ float If_CutAreaDerefed( If_Man_t * p, If_Cut_t * pCut, int nLevels )
float
If_CutAreaRefed
(
If_Man_t
*
p
,
If_Cut_t
*
pCut
,
int
nLevels
)
{
float
aResult
,
aResult2
;
assert
(
pCut
->
nLeaves
>
1
);
assert
(
p
->
pPars
->
fSeqMap
||
p
Cut
->
nLeaves
>
1
);
aResult2
=
If_CutDeref
(
p
,
pCut
,
nLevels
);
aResult
=
If_CutRef
(
p
,
pCut
,
nLevels
);
assert
(
aResult
==
aResult2
);
...
...
@@ -599,6 +601,27 @@ float If_CutAreaRefed( If_Man_t * p, If_Cut_t * pCut, int nLevels )
/**Function*************************************************************
Synopsis [Moves the cut over the latch.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
If_CutLift
(
If_Cut_t
*
pCut
)
{
unsigned
i
;
for
(
i
=
0
;
i
<
pCut
->
nLeaves
;
i
++
)
{
assert
(
(
pCut
->
pLeaves
[
i
]
&
255
)
<
255
);
pCut
->
pLeaves
[
i
]
++
;
}
}
/**Function*************************************************************
Synopsis [Computes area of the first level.]
Description [The cut need to be derefed.]
...
...
src/map/if/ifMan.c
View file @
ae037e45
...
...
@@ -51,8 +51,8 @@ If_Man_t * If_ManStart( If_Par_t * pPars )
p
->
pPars
=
pPars
;
p
->
fEpsilon
=
(
float
)
0
.
001
;
// allocate arrays for nodes
p
->
v
P
is
=
Vec_PtrAlloc
(
100
);
p
->
v
P
os
=
Vec_PtrAlloc
(
100
);
p
->
v
C
is
=
Vec_PtrAlloc
(
100
);
p
->
v
C
os
=
Vec_PtrAlloc
(
100
);
p
->
vObjs
=
Vec_PtrAlloc
(
100
);
p
->
vMapped
=
Vec_PtrAlloc
(
100
);
p
->
vTemp
=
Vec_PtrAlloc
(
100
);
...
...
@@ -96,11 +96,13 @@ void If_ManStop( If_Man_t * p )
{
If_Cut_t
*
pTemp
;
int
i
;
Vec_PtrFree
(
p
->
v
P
is
);
Vec_PtrFree
(
p
->
v
P
os
);
Vec_PtrFree
(
p
->
v
C
is
);
Vec_PtrFree
(
p
->
v
C
os
);
Vec_PtrFree
(
p
->
vObjs
);
Vec_PtrFree
(
p
->
vMapped
);
Vec_PtrFree
(
p
->
vTemp
);
if
(
p
->
vLatchOrder
)
Vec_PtrFree
(
p
->
vLatchOrder
);
if
(
p
->
vLags
)
Vec_IntFree
(
p
->
vLags
);
Mem_FixedStop
(
p
->
pMem
,
0
);
// free pars memory
if
(
p
->
pPars
->
pTimesArr
)
...
...
@@ -129,13 +131,13 @@ void If_ManStop( If_Man_t * p )
SeeAlso []
***********************************************************************/
If_Obj_t
*
If_ManCreate
P
i
(
If_Man_t
*
p
)
If_Obj_t
*
If_ManCreate
C
i
(
If_Man_t
*
p
)
{
If_Obj_t
*
pObj
;
pObj
=
If_ManSetupObj
(
p
);
pObj
->
Type
=
IF_
P
I
;
Vec_PtrPush
(
p
->
v
P
is
,
pObj
);
p
->
nObjs
[
IF_
P
I
]
++
;
pObj
->
Type
=
IF_
C
I
;
Vec_PtrPush
(
p
->
v
C
is
,
pObj
);
p
->
nObjs
[
IF_
C
I
]
++
;
return
pObj
;
}
...
...
@@ -150,15 +152,15 @@ If_Obj_t * If_ManCreatePi( If_Man_t * p )
SeeAlso []
***********************************************************************/
If_Obj_t
*
If_ManCreate
P
o
(
If_Man_t
*
p
,
If_Obj_t
*
pDriver
,
int
fCompl0
)
If_Obj_t
*
If_ManCreate
C
o
(
If_Man_t
*
p
,
If_Obj_t
*
pDriver
,
int
fCompl0
)
{
If_Obj_t
*
pObj
;
pObj
=
If_ManSetupObj
(
p
);
pObj
->
Type
=
IF_
P
O
;
pObj
->
Type
=
IF_
C
O
;
pObj
->
fCompl0
=
fCompl0
;
Vec_PtrPush
(
p
->
v
P
os
,
pObj
);
Vec_PtrPush
(
p
->
v
C
os
,
pObj
);
pObj
->
pFanin0
=
pDriver
;
pDriver
->
nRefs
++
;
p
->
nObjs
[
IF_
P
O
]
++
;
p
->
nObjs
[
IF_
C
O
]
++
;
return
pObj
;
}
...
...
@@ -251,7 +253,7 @@ If_Obj_t * If_ManSetupObj( If_Man_t * p )
// assign elementary cut
pCut
=
pObj
->
Cuts
;
pCut
->
nLeaves
=
1
;
pCut
->
pLeaves
[
0
]
=
p
->
pPars
->
f
Seq
?
(
pObj
->
Id
<<
8
)
:
pObj
->
Id
;
pCut
->
pLeaves
[
0
]
=
p
->
pPars
->
f
LiftLeaves
?
(
pObj
->
Id
<<
8
)
:
pObj
->
Id
;
pCut
->
uSign
=
If_ObjCutSign
(
pCut
->
pLeaves
[
0
]
);
// set the number of cuts
pObj
->
nCuts
=
1
;
...
...
src/map/if/ifMap.c
View file @
ae037e45
...
...
@@ -69,27 +69,31 @@ static inline int If_WordCountOnes( unsigned uWord )
SeeAlso []
***********************************************************************/
void
If_ObjPerformMapping
(
If_Man_t
*
p
,
If_Obj_t
*
pObj
,
int
Mode
)
void
If_ObjPerformMapping
And
(
If_Man_t
*
p
,
If_Obj_t
*
pObj
,
int
Mode
)
{
If_Cut_t
*
pCut0
,
*
pCut1
,
*
pCut
;
int
i
,
k
,
iCut
;
assert
(
!
If_ObjIsAnd
(
pObj
->
pFanin0
)
||
pObj
->
pFanin0
->
nCuts
>
1
);
assert
(
!
If_ObjIsAnd
(
pObj
->
pFanin1
)
||
pObj
->
pFanin1
->
nCuts
>
1
);
assert
(
p
->
pPars
->
fSeqMap
||
!
If_ObjIsAnd
(
pObj
->
pFanin0
)
||
pObj
->
pFanin0
->
nCuts
>
1
);
assert
(
p
->
pPars
->
fSeqMap
||
!
If_ObjIsAnd
(
pObj
->
pFanin1
)
||
pObj
->
pFanin1
->
nCuts
>
1
);
// prepare
if
(
!
p
->
pPars
->
fSeqMap
)
{
if
(
Mode
==
0
)
pObj
->
EstRefs
=
(
float
)
pObj
->
nRefs
;
else
if
(
Mode
==
1
)
pObj
->
EstRefs
=
(
float
)((
2
.
0
*
pObj
->
EstRefs
+
pObj
->
nRefs
)
/
3
.
0
);
else
if
(
Mode
==
2
&&
pObj
->
nRefs
>
0
)
}
if
(
Mode
&&
pObj
->
nRefs
>
0
)
If_CutDeref
(
p
,
If_ObjCutBest
(
pObj
),
100
);
//
recompute the parameters of the best cut
//
save the best cut as one of the candidate cuts
p
->
nCuts
=
0
;
p
->
nCutsMerged
++
;
if
(
Mode
)
{
// recompute the parameters of the best cut
pCut
=
If_ObjCutBest
(
pObj
);
pCut
->
Delay
=
If_CutDelay
(
p
,
pCut
);
assert
(
pCut
->
Delay
<=
pObj
->
Required
+
p
->
fEpsilon
);
...
...
@@ -114,12 +118,12 @@ void If_ObjPerformMapping( If_Man_t * p, If_Obj_t * pObj, int Mode )
continue
;
// check if this cut is contained in any of the available cuts
pCut
->
uSign
=
pCut0
->
uSign
|
pCut1
->
uSign
;
pCut
->
fCompl
=
0
;
// if ( p->pPars->pFuncCost == NULL && If_CutFilter( p, pCut ) ) // do not filter functionality cuts
if
(
If_CutFilter
(
p
,
pCut
)
)
continue
;
// the cuts have been successfully merged
// compute the truth table
pCut
->
fCompl
=
0
;
if
(
p
->
pPars
->
fTruth
)
If_CutComputeTruth
(
p
,
pCut
,
pCut0
,
pCut1
,
pObj
->
fCompl0
,
pObj
->
fCompl1
);
// compute the application-specific cost and depth
...
...
@@ -149,16 +153,14 @@ void If_ObjPerformMapping( If_Man_t * p, If_Obj_t * pObj, int Mode )
If_ManSortCuts
(
p
,
Mode
);
// decide how many cuts to use
pObj
->
nCuts
=
IF_MIN
(
p
->
nCuts
+
1
,
p
->
nCutsUsed
);
//printf( "%d(%d) ", p->nCuts, pObj->nCuts );
// take the first
If_ObjForEachCutStart
(
pObj
,
pCut
,
i
,
1
)
If_CutCopy
(
pCut
,
p
->
ppCuts
[
i
-
1
]
);
assert
(
If_ObjCutBest
(
pObj
)
->
nLeaves
>
1
);
assert
(
p
->
pPars
->
fSeqMap
||
If_ObjCutBest
(
pObj
)
->
nLeaves
>
1
);
// ref the selected cut
if
(
Mode
==
2
&&
pObj
->
nRefs
>
0
)
if
(
Mode
&&
pObj
->
nRefs
>
0
)
If_CutRef
(
p
,
If_ObjCutBest
(
pObj
),
100
);
// find the largest cut
if
(
p
->
nCutsMax
<
pObj
->
nCuts
)
p
->
nCutsMax
=
pObj
->
nCuts
;
}
/**Function*************************************************************
...
...
@@ -172,14 +174,14 @@ void If_ObjPerformMapping( If_Man_t * p, If_Obj_t * pObj, int Mode )
SeeAlso []
***********************************************************************/
void
If_Obj
Merge
Choice
(
If_Man_t
*
p
,
If_Obj_t
*
pObj
,
int
Mode
)
void
If_Obj
PerformMapping
Choice
(
If_Man_t
*
p
,
If_Obj_t
*
pObj
,
int
Mode
)
{
If_Obj_t
*
pTemp
;
If_Cut_t
*
pCutTemp
,
*
pCut
;
int
i
,
iCut
;
assert
(
pObj
->
pEquiv
!=
NULL
);
// prepare
if
(
Mode
==
2
&&
pObj
->
nRefs
>
0
)
if
(
Mode
&&
pObj
->
nRefs
>
0
)
If_CutDeref
(
p
,
If_ObjCutBest
(
pObj
),
100
);
// prepare room for the next cut
p
->
nCuts
=
0
;
...
...
@@ -227,13 +229,10 @@ void If_ObjMergeChoice( If_Man_t * p, If_Obj_t * pObj, int Mode )
// take the first
If_ObjForEachCutStart
(
pObj
,
pCut
,
i
,
1
)
If_CutCopy
(
pCut
,
p
->
ppCuts
[
i
-
1
]
);
assert
(
If_ObjCutBest
(
pObj
)
->
nLeaves
>
1
);
assert
(
p
->
pPars
->
fSeqMap
||
If_ObjCutBest
(
pObj
)
->
nLeaves
>
1
);
// ref the selected cut
if
(
Mode
==
2
&&
pObj
->
nRefs
>
0
)
if
(
Mode
&&
pObj
->
nRefs
>
0
)
If_CutRef
(
p
,
If_ObjCutBest
(
pObj
),
100
);
// find the largest cut
if
(
p
->
nCutsMax
<
pObj
->
nCuts
)
p
->
nCutsMax
=
pObj
->
nCuts
;
}
/**Function*************************************************************
...
...
@@ -249,25 +248,23 @@ void If_ObjMergeChoice( If_Man_t * p, If_Obj_t * pObj, int Mode )
***********************************************************************/
int
If_ManPerformMappingRound
(
If_Man_t
*
p
,
int
nCutsUsed
,
int
Mode
,
int
fRequired
,
char
*
pLabel
)
{
ProgressBar
*
pProgress
;
//
ProgressBar * pProgress;
If_Obj_t
*
pObj
;
int
i
,
clk
=
clock
();
assert
(
Mode
>=
0
&&
Mode
<=
2
);
// set the cut number
p
->
nCutsUsed
=
nCutsUsed
;
p
->
nCutsMerged
=
0
;
p
->
nCutsSaved
=
0
;
p
->
nCutsMax
=
0
;
// map the internal nodes
pProgress
=
Extra_ProgressBarStart
(
stdout
,
If_ManObjNum
(
p
)
);
//
pProgress = Extra_ProgressBarStart( stdout, If_ManObjNum(p) );
If_ManForEachNode
(
p
,
pObj
,
i
)
{
Extra_ProgressBarUpdate
(
pProgress
,
i
,
pLabel
);
If_ObjPerformMapping
(
p
,
pObj
,
Mode
);
//
Extra_ProgressBarUpdate( pProgress, i, pLabel );
If_ObjPerformMapping
And
(
p
,
pObj
,
Mode
);
if
(
pObj
->
fRepr
)
If_Obj
Merge
Choice
(
p
,
pObj
,
Mode
);
If_Obj
PerformMapping
Choice
(
p
,
pObj
,
Mode
);
}
Extra_ProgressBarStop
(
pProgress
);
//
Extra_ProgressBarStop( pProgress );
// compute required times and stats
if
(
fRequired
)
{
...
...
@@ -278,7 +275,6 @@ int If_ManPerformMappingRound( If_Man_t * p, int nCutsUsed, int Mode, int fRequi
printf
(
"%c: Del = %6.2f. Area = %8.2f. Cuts = %8d. Lim = %2d. Ave = %5.2f. "
,
Symb
,
p
->
RequiredGlo
,
p
->
AreaGlo
,
p
->
nCutsMerged
,
p
->
nCutsUsed
,
1
.
0
*
p
->
nCutsMerged
/
If_ManAndNum
(
p
)
);
PRT
(
"T"
,
clock
()
-
clk
);
// printf( "Saved cuts = %d.\n", p->nCutsSaved );
// printf( "Max number of cuts = %d. Average number of cuts = %5.2f.\n",
// p->nCutsMax, 1.0 * p->nCutsMerged / If_ManAndNum(p) );
}
...
...
src/map/if/ifPrepro.c
View file @
ae037e45
...
...
@@ -52,7 +52,7 @@ void If_ManPerformMappingPreprocess( If_Man_t * p )
p
->
pPars
->
fArea
=
1
;
If_ManPerformMappingRound
(
p
,
p
->
pPars
->
nCutsMax
,
0
,
0
,
"Start delay"
);
p
->
pPars
->
fArea
=
0
;
delayArea
=
If_ManDelayMax
(
p
);
delayArea
=
If_ManDelayMax
(
p
,
0
);
if
(
p
->
pPars
->
DelayTarget
!=
-
1
&&
delayArea
<
p
->
pPars
->
DelayTarget
-
p
->
fEpsilon
)
delayArea
=
p
->
pPars
->
DelayTarget
;
If_ManPerformMappingMoveBestCut
(
p
,
p
->
pPars
->
nCutsMax
-
1
,
1
);
...
...
@@ -61,14 +61,14 @@ void If_ManPerformMappingPreprocess( If_Man_t * p )
p
->
pPars
->
fFancy
=
1
;
If_ManPerformMappingRound
(
p
,
p
->
pPars
->
nCutsMax
-
1
,
0
,
0
,
"Start delay-2"
);
p
->
pPars
->
fFancy
=
0
;
delayDelay
=
If_ManDelayMax
(
p
);
delayDelay
=
If_ManDelayMax
(
p
,
0
);
if
(
p
->
pPars
->
DelayTarget
!=
-
1
&&
delayDelay
<
p
->
pPars
->
DelayTarget
-
p
->
fEpsilon
)
delayDelay
=
p
->
pPars
->
DelayTarget
;
If_ManPerformMappingMoveBestCut
(
p
,
p
->
pPars
->
nCutsMax
-
2
,
1
);
// perform min-delay mapping
If_ManPerformMappingRound
(
p
,
p
->
pPars
->
nCutsMax
-
2
,
0
,
0
,
"Start flow"
);
delayPure
=
If_ManDelayMax
(
p
);
delayPure
=
If_ManDelayMax
(
p
,
0
);
if
(
p
->
pPars
->
DelayTarget
!=
-
1
&&
delayPure
<
p
->
pPars
->
DelayTarget
-
p
->
fEpsilon
)
delayPure
=
p
->
pPars
->
DelayTarget
;
...
...
src/map/if/ifReduce.c
View file @
ae037e45
...
...
@@ -361,7 +361,7 @@ int If_ManImproveNodeFaninCompact0( If_Man_t * p, If_Obj_t * pObj, int nLimit, V
int
i
;
Vec_PtrForEachEntry
(
vFront
,
pFanin
,
i
)
{
if
(
If_ObjIs
P
i
(
pFanin
)
)
if
(
If_ObjIs
C
i
(
pFanin
)
)
continue
;
if
(
If_ManImproveNodeWillGrow
(
p
,
pFanin
)
)
continue
;
...
...
@@ -391,7 +391,7 @@ int If_ManImproveNodeFaninCompact1( If_Man_t * p, If_Obj_t * pObj, int nLimit, V
int
i
;
Vec_PtrForEachEntry
(
vFront
,
pFanin
,
i
)
{
if
(
If_ObjIs
P
i
(
pFanin
)
)
if
(
If_ObjIs
C
i
(
pFanin
)
)
continue
;
if
(
If_ManImproveNodeFaninCost
(
p
,
pFanin
)
<
0
)
{
...
...
@@ -419,7 +419,7 @@ int If_ManImproveNodeFaninCompact2( If_Man_t * p, If_Obj_t * pObj, int nLimit, V
int
i
;
Vec_PtrForEachEntry
(
vFront
,
pFanin
,
i
)
{
if
(
If_ObjIs
P
i
(
pFanin
)
)
if
(
If_ObjIs
C
i
(
pFanin
)
)
continue
;
if
(
If_ManImproveNodeFaninCost
(
p
,
pFanin
)
<=
0
)
{
...
...
@@ -498,8 +498,8 @@ void If_ManImproveNodeReduce( If_Man_t * p, If_Obj_t * pObj, int nLimit )
pFanin1
=
If_ObjFanin1
(
pObj
);
// get the cuts
pCut
=
If_ObjCutBest
(
pObj
);
pCut0
=
If_ObjIs
P
i
(
pFanin0
)
?
If_ObjCutTriv
(
pFanin0
)
:
If_ObjCutBest
(
pFanin0
);
pCut1
=
If_ObjIs
P
i
(
pFanin1
)
?
If_ObjCutTriv
(
pFanin1
)
:
If_ObjCutBest
(
pFanin1
);
pCut0
=
If_ObjIs
C
i
(
pFanin0
)
?
If_ObjCutTriv
(
pFanin0
)
:
If_ObjCutBest
(
pFanin0
);
pCut1
=
If_ObjIs
C
i
(
pFanin1
)
?
If_ObjCutTriv
(
pFanin1
)
:
If_ObjCutBest
(
pFanin1
);
assert
(
pCut
->
Delay
<=
pObj
->
Required
+
p
->
fEpsilon
);
// deref the cut if the node is refed
...
...
src/map/if/ifSeq.c
View file @
ae037e45
...
...
@@ -24,9 +24,11 @@
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static
void
If_ObjPerformMappingLI
(
If_Man_t
*
p
,
If_Obj_t
*
pLatch
);
static
void
If_ObjPerformMappingLO
(
If_Man_t
*
p
,
If_Obj_t
*
pLatch
,
If_Obj_t
*
pObj
);
static
int
If_ManMappingSeqConverged
(
If_Man_t
*
p
);
static
int
If_ManBinarySearchPeriod
(
If_Man_t
*
p
,
int
Mode
);
static
int
If_ManBinarySearch_rec
(
If_Man_t
*
p
,
int
Mode
,
int
FiMin
,
int
FiMax
);
static
int
If_ManPerformMappingRoundSeq
(
If_Man_t
*
p
,
int
Mode
,
int
nIter
,
char
*
pLabel
);
static
int
If_ManPrepareMappingSeq
(
If_Man_t
*
p
);
static
int
If_ObjPerformMappingLatch
(
If_Man_t
*
p
,
If_Obj_t
*
pObj
);
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
...
...
@@ -45,46 +47,233 @@ static int If_ManMappingSeqConverged( If_Man_t * p );
***********************************************************************/
int
If_ManPerformMappingSeq
(
If_Man_t
*
p
)
{
If_Obj_t
*
pObj
,
*
pLatch
;
int
i
,
clkTotal
=
clock
();
// set the number of cuts used
int
PeriodBest
,
Mode
=
0
;
// collect nodes in the sequential order
If_ManPrepareMappingSeq
(
p
);
// perform combinational mapping to get the upper bound on the clock period
If_ManPerformMappingRound
(
p
,
2
,
0
,
0
,
NULL
);
p
->
RequiredGlo
=
If_ManDelayMax
(
p
,
0
);
// set parameters
p
->
nCutsUsed
=
p
->
pPars
->
nCutsMax
;
// set arrival times and trivial cuts at const 1 and PIs
If_ManConst1
(
p
)
->
Cuts
[
0
].
Delay
=
0
.
0
;
If_ManForEachPi
(
p
,
pObj
,
i
)
pObj
->
Cuts
[
0
].
Delay
=
p
->
pPars
->
pTimesArr
[
i
];
// set the fanout estimates of the PIs
If_ManForEachPi
(
p
,
pObj
,
i
)
pObj
->
EstRefs
=
(
float
)
1
.
0
;
// delay oriented mapping
p
->
pPars
->
fFancy
=
1
;
If_ManPerformMappingRound
(
p
,
p
->
pPars
->
nCutsMax
,
0
,
0
,
NULL
);
p
->
pPars
->
fFancy
=
0
;
// perform iterations over the circuit
while
(
!
If_ManMappingSeqConverged
(
p
)
)
{
// assign cuts to latches
If_ManForEachLatch
(
p
,
pLatch
,
i
)
If_ObjPerformMappingLI
(
p
,
pLatch
);
// assign cuts to primary inputs
If_ManForEachLatch
(
p
,
pLatch
,
i
)
If_ObjPerformMappingLO
(
p
,
pLatch
,
If_ManPi
(
p
,
If_ManPiNum
(
p
)
-
If_ManPoNum
(
p
)
+
i
)
);
// map the nodes
p
->
nAttempts
=
0
;
p
->
nMaxIters
=
50
;
p
->
Period
=
(
int
)
p
->
RequiredGlo
;
// make sure the clock period words
if
(
!
If_ManBinarySearchPeriod
(
p
,
Mode
)
)
{
printf
(
"If_ManPerformMappingSeq(): The upper bound on the clock period cannot be computed.
\n
"
);
return
0
;
}
// perform binary search
PeriodBest
=
If_ManBinarySearch_rec
(
p
,
Mode
,
0
,
p
->
Period
);
// recompute the best l-values
if
(
p
->
Period
!=
PeriodBest
)
{
p
->
Period
=
PeriodBest
;
if
(
!
If_ManBinarySearchPeriod
(
p
,
Mode
)
)
{
printf
(
"If_ManPerformMappingSeq(): The final clock period cannot be confirmed.
\n
"
);
return
0
;
}
}
/*
// fix the problem with non-converged delays
If_ManForEachNode( p, pObj, i )
if ( pObj->LValue < -ABC_INFINITY/2 )
pObj->LValue = (float)0.0;
// write the retiming lags
p->vLags = Vec_IntStart( If_ManObjNum(p) + 1 );
If_ManForEachNode( p, pObj, i )
If_ObjPerformMapping
(
p
,
pObj
,
0
);
Vec_IntWriteEntry( vLags, i, Abc_NodeComputeLag(pObj->LValue, p->Period) );
*/
/*
// print the statistic into a file
{
FILE * pTable;
pTable = fopen( "a/seqmap__stats.txt", "a+" );
fprintf( pTable, "%d ", p->Period );
fprintf( pTable, "\n" );
fclose( pTable );
}
*/
// print the result
if
(
p
->
pPars
->
fLiftLeaves
)
{
// if ( p->pPars->fVerbose )
printf
(
"The best clock period is %3d. (Currently, network is not modified, so mapping will fail.)
\n
"
,
p
->
Period
);
return
0
;
}
// if ( p->pPars->fVerbose )
printf
(
"The best clock period is %3d.
\n
"
,
p
->
Period
);
return
1
;
}
/**Function*************************************************************
Synopsis [Performs binary search for the optimal clock period.]
Description [Assumes that FiMin is infeasible while FiMax is feasible.]
SideEffects []
SeeAlso []
***********************************************************************/
int
If_ManBinarySearch_rec
(
If_Man_t
*
p
,
int
Mode
,
int
FiMin
,
int
FiMax
)
{
assert
(
FiMin
<
FiMax
);
if
(
FiMin
+
1
==
FiMax
)
return
FiMax
;
// compute the median
p
->
Period
=
FiMin
+
(
FiMax
-
FiMin
)
/
2
;
if
(
If_ManBinarySearchPeriod
(
p
,
Mode
)
)
return
If_ManBinarySearch_rec
(
p
,
Mode
,
FiMin
,
p
->
Period
);
// Median is feasible
else
return
If_ManBinarySearch_rec
(
p
,
Mode
,
p
->
Period
,
FiMax
);
// Median is infeasible
}
/**Function*************************************************************
Synopsis [Returns 1 if retiming with this clock period is feasible.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int
If_ManBinarySearchPeriod
(
If_Man_t
*
p
,
int
Mode
)
{
If_Obj_t
*
pObj
;
int
i
,
c
,
fConverged
;
int
fResetRefs
=
0
;
p
->
nAttempts
++
;
// set l-values of all nodes to be minus infinity, except PIs and constants
If_ManForEachObj
(
p
,
pObj
,
i
)
{
pObj
->
nCuts
=
1
;
If_ObjSetLValue
(
pObj
,
-
IF_FLOAT_LARGE
);
if
(
fResetRefs
)
pObj
->
nRefs
=
0
;
}
If_ObjSetLValue
(
If_ManConst1
(
p
),
(
float
)
0
.
0
);
If_ManForEachPi
(
p
,
pObj
,
i
)
If_ObjSetLValue
(
pObj
,
(
float
)
0
.
0
);
// reset references to their original state
if
(
fResetRefs
)
{
If_ManForEachObj
(
p
,
pObj
,
i
)
{
if
(
If_ObjIsCo
(
pObj
)
)
continue
;
if
(
pObj
->
pFanin0
)
pObj
->
pFanin0
->
nRefs
++
;
if
(
pObj
->
pFanin1
)
pObj
->
pFanin1
->
nRefs
++
;
}
}
// update all values iteratively
fConverged
=
0
;
for
(
c
=
1
;
c
<=
p
->
nMaxIters
;
c
++
)
{
if
(
!
If_ManPerformMappingRoundSeq
(
p
,
Mode
,
c
,
NULL
)
)
{
fConverged
=
1
;
break
;
}
p
->
RequiredGlo
=
If_ManDelayMax
(
p
,
1
);
if
(
p
->
RequiredGlo
>
p
->
Period
+
p
->
fEpsilon
)
break
;
}
// report the results
if
(
p
->
pPars
->
fVerbose
)
{
PRT
(
"Total time"
,
clock
()
-
clkTotal
);
p
->
AreaGlo
=
p
->
pPars
->
fLiftLeaves
?
If_ManScanMappingSeq
(
p
)
:
If_ManScanMapping
(
p
);
printf
(
"Attempt = %2d. Iters = %3d. Area = %10.2f. Fi = %6.2f. "
,
p
->
nAttempts
,
c
,
p
->
AreaGlo
,
(
float
)
p
->
Period
);
if
(
fConverged
)
printf
(
" Feasible"
);
else
if
(
c
>
p
->
nMaxIters
)
printf
(
"Infeasible (timeout)"
);
else
printf
(
"Infeasible"
);
printf
(
"
\n
"
);
}
return
1
;
return
fConverged
;
}
/**Function*************************************************************
Synopsis [Performs sequential mapping.]
Synopsis [Performs one pass of l-value computation over all nodes.]
Description [Experimentally it was found that checking POs changes
is not enough to detect the convergence of l-values in the network.]
SideEffects []
SeeAlso []
***********************************************************************/
int
If_ManPerformMappingRoundSeq
(
If_Man_t
*
p
,
int
Mode
,
int
nIter
,
char
*
pLabel
)
{
ProgressBar
*
pProgress
;
If_Obj_t
*
pObj
;
int
i
,
clk
=
clock
();
int
fVeryVerbose
=
0
;
int
fChange
=
0
;
assert
(
Mode
>=
0
&&
Mode
<=
2
);
if
(
!
p
->
pPars
->
fVerbose
)
pProgress
=
Extra_ProgressBarStart
(
stdout
,
If_ManObjNum
(
p
)
);
// map the internal nodes
p
->
nCutsMerged
=
0
;
If_ManForEachNode
(
p
,
pObj
,
i
)
{
if
(
!
p
->
pPars
->
fVerbose
)
Extra_ProgressBarUpdate
(
pProgress
,
i
,
pLabel
);
// consider the camse of an AND gate
assert
(
If_ObjIsAnd
(
pObj
)
);
If_ObjPerformMappingAnd
(
p
,
pObj
,
Mode
);
if
(
pObj
->
fRepr
)
If_ObjPerformMappingChoice
(
p
,
pObj
,
Mode
);
// check if updating happens
if
(
If_ObjLValue
(
pObj
)
<
If_ObjCutBest
(
pObj
)
->
Delay
-
p
->
fEpsilon
)
{
If_ObjSetLValue
(
pObj
,
If_ObjCutBest
(
pObj
)
->
Delay
);
fChange
=
1
;
}
//if ( If_ObjLValue(pObj) > -1000.0 )
//printf( "Node %d %.2f ", pObj->Id, If_ObjLValue(pObj) );
}
if
(
!
p
->
pPars
->
fVerbose
)
Extra_ProgressBarStop
(
pProgress
);
// propagate arrival times from the registers
Vec_PtrForEachEntry
(
p
->
vLatchOrder
,
pObj
,
i
)
fChange
|=
If_ObjPerformMappingLatch
(
p
,
pObj
);
//printf( "\n\n" );
// compute area and delay
if
(
fVeryVerbose
)
{
p
->
RequiredGlo
=
If_ManDelayMax
(
p
,
1
);
p
->
AreaGlo
=
p
->
pPars
->
fLiftLeaves
?
If_ManScanMappingSeq
(
p
)
:
If_ManScanMapping
(
p
);
printf
(
"S%d: Fi = %6.2f. Del = %6.2f. Area = %8.2f. Cuts = %8d. Lim = %2d. Ave = %5.2f. "
,
nIter
,
(
float
)
p
->
Period
,
p
->
RequiredGlo
,
p
->
AreaGlo
,
p
->
nCutsMerged
,
p
->
nCutsUsed
,
1
.
0
*
p
->
nCutsMerged
/
If_ManAndNum
(
p
)
);
PRT
(
"T"
,
clock
()
-
clk
);
}
return
fChange
;
}
/**Function*************************************************************
Synopsis [Collects latches in the topological order.]
Description []
...
...
@@ -93,16 +282,20 @@ int If_ManPerformMappingSeq( If_Man_t * p )
SeeAlso []
***********************************************************************/
void
If_
CutLift
(
If_Cut_t
*
pCut
)
void
If_
ManCollectLatches_rec
(
If_Obj_t
*
pObj
,
Vec_Ptr_t
*
vLatches
)
{
unsigned
i
;
for
(
i
=
0
;
i
<
pCut
->
nLeaves
;
i
++
)
pCut
->
pLeaves
[
i
]
=
((
pCut
->
pLeaves
[
i
]
>>
8
)
<<
8
)
|
((
pCut
->
pLeaves
[
i
]
&
255
)
+
1
);
if
(
!
If_ObjIsLatch
(
pObj
)
)
return
;
if
(
pObj
->
fMark
)
return
;
pObj
->
fMark
=
1
;
If_ManCollectLatches_rec
(
pObj
->
pFanin0
,
vLatches
);
Vec_PtrPush
(
vLatches
,
pObj
);
}
/**Function*************************************************************
Synopsis [
Performs sequential mapping
.]
Synopsis [
Collects latches in the topological order
.]
Description []
...
...
@@ -111,19 +304,25 @@ void If_CutLift( If_Cut_t * pCut )
SeeAlso []
***********************************************************************/
void
If_ObjPerformMappingLI
(
If_Man_t
*
p
,
If_Obj_t
*
pLatch
)
Vec_Ptr_t
*
If_ManCollectLatches
(
If_Man_t
*
p
)
{
If_Obj_t
*
pFanin
;
int
c
;
assert
(
If_ObjIsPo
(
pLatch
)
);
pFanin
=
If_ObjFanin0
(
pLatch
);
for
(
c
=
0
;
c
<
pFanin
->
nCuts
;
c
++
)
If_CutCopy
(
pLatch
->
Cuts
+
c
,
pFanin
->
Cuts
+
c
);
Vec_Ptr_t
*
vLatches
;
If_Obj_t
*
pObj
;
int
i
;
// collect latches
vLatches
=
Vec_PtrAlloc
(
p
->
pPars
->
nLatches
);
Vec_PtrForEachEntryStart
(
p
->
vCis
,
pObj
,
i
,
If_ManCiNum
(
p
)
-
p
->
pPars
->
nLatches
)
If_ManCollectLatches_rec
(
pObj
,
vLatches
);
// clean marks
Vec_PtrForEachEntry
(
vLatches
,
pObj
,
i
)
pObj
->
fMark
=
0
;
assert
(
Vec_PtrSize
(
vLatches
)
==
p
->
pPars
->
nLatches
);
return
vLatches
;
}
/**Function*************************************************************
Synopsis [P
erforms sequential mapping
.]
Synopsis [P
repares for sequential mapping by linking the latches
.]
Description []
...
...
@@ -132,23 +331,43 @@ void If_ObjPerformMappingLI( If_Man_t * p, If_Obj_t * pLatch )
SeeAlso []
***********************************************************************/
void
If_ObjPerformMappingLO
(
If_Man_t
*
p
,
If_Obj_t
*
pLatch
,
If_Obj_t
*
pObj
)
int
If_ManPrepareMappingSeq
(
If_Man_t
*
p
)
{
If_Obj_t
*
pObj
,
*
pObjLi
,
*
pObjLo
,
*
pTemp
;
If_Cut_t
*
pCut
;
int
c
,
Limit
=
IF_MIN
(
p
->
nCuts
+
1
,
p
->
nCutsUsed
);
assert
(
If_ObjIsPo
(
pLatch
)
);
for
(
c
=
1
;
c
<
Limit
;
c
++
)
int
i
;
// link the latch outputs (PIs) directly to the drivers of latch inputs (POs)
for
(
i
=
0
;
i
<
p
->
pPars
->
nLatches
;
i
++
)
{
pObjLo
=
If_ManCi
(
p
,
If_ManCiNum
(
p
)
-
p
->
pPars
->
nLatches
+
i
);
pObjLi
=
If_ManCo
(
p
,
If_ManCoNum
(
p
)
-
p
->
pPars
->
nLatches
+
i
);
pObjLo
->
pFanin0
=
If_ObjFanin0
(
pObjLi
);
pObjLo
->
fCompl0
=
If_ObjFaninC0
(
pObjLi
);
// pObjLo->pFanin0 = pObjLi;
}
// collect latches
p
->
vLatchOrder
=
If_ManCollectLatches
(
p
);
// propagate elementary cuts
if
(
p
->
pPars
->
fLiftLeaves
)
{
pCut
=
pObj
->
Cuts
+
c
;
If_CutCopy
(
pCut
,
pLatch
->
Cuts
+
c
-
1
);
Vec_PtrForEachEntry
(
p
->
vLatchOrder
,
pObj
,
i
)
{
pCut
=
If_ObjCutTriv
(
pObj
);
If_CutCopy
(
pCut
,
If_ObjFanin0
(
pObj
)
->
Cuts
);
If_CutLift
(
pCut
);
pCut
->
Delay
-=
p
->
Fi
;
pCut
->
Delay
-=
p
->
Period
;
pCut
->
fCompl
^=
pObj
->
fCompl0
;
pTemp
=
If_ManObj
(
p
,
pCut
->
pLeaves
[
0
]
>>
8
);
assert
(
!
If_ObjIsLatch
(
pTemp
)
);
}
}
return
1
;
}
/**Function*************************************************************
Synopsis [Performs
sequential mapping
.]
Synopsis [Performs
mapping of the latches
.]
Description []
...
...
@@ -157,12 +376,36 @@ void If_ObjPerformMappingLO( If_Man_t * p, If_Obj_t * pLatch, If_Obj_t * pObj )
SeeAlso []
***********************************************************************/
int
If_
ManMappingSeqConverged
(
If_Man_t
*
p
)
int
If_
ObjPerformMappingLatch
(
If_Man_t
*
p
,
If_Obj_t
*
pObj
)
{
return
0
;
If_Obj_t
*
pFanin
;
If_Cut_t
*
pCut
;
float
LValueOld
;
int
i
;
assert
(
If_ObjIsLatch
(
pObj
)
);
// save old l-value
LValueOld
=
If_ObjLValue
(
pObj
);
pFanin
=
If_ObjFanin0
(
pObj
);
assert
(
pFanin
->
nCuts
>
0
);
if
(
!
p
->
pPars
->
fLiftLeaves
)
{
pObj
->
nCuts
=
1
;
If_ObjSetLValue
(
pObj
,
If_ObjLValue
(
pFanin
)
-
p
->
Period
);
}
else
{
pObj
->
nCuts
=
pFanin
->
nCuts
;
If_ObjForEachCut
(
pObj
,
pCut
,
i
)
{
If_CutCopy
(
pCut
,
pFanin
->
Cuts
+
i
);
If_CutLift
(
pCut
);
pCut
->
Delay
-=
p
->
Period
;
pCut
->
fCompl
^=
pObj
->
fCompl0
;
}
}
return
LValueOld
!=
If_ObjLValue
(
pObj
);
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
...
...
src/map/if/if
Lib
.c
→
src/map/if/if
Time
.c
View file @
ae037e45
/**CFile****************************************************************
FileName [if
Lib
.c]
FileName [if
Time
.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [FPGA mapping based on priority cuts.]
Synopsis [Computation of
LUT
paramters depending on the library.]
Synopsis [Computation of
delay
paramters depending on the library.]
Author [Alan Mishchenko]
...
...
@@ -14,7 +14,7 @@
Date [Ver. 1.0. Started - November 21, 2006.]
Revision [$Id: if
Lib
.c,v 1.00 2006/11/21 00:00:00 alanmi Exp $]
Revision [$Id: if
Time
.c,v 1.00 2006/11/21 00:00:00 alanmi Exp $]
***********************************************************************/
...
...
@@ -48,11 +48,12 @@ float If_CutDelay( If_Man_t * p, If_Cut_t * pCut )
If_Obj_t
*
pLeaf
;
float
Delay
,
DelayCur
;
float
*
pLutDelays
;
int
i
;
assert
(
pCut
->
nLeaves
>
1
);
int
i
,
Shift
;
assert
(
p
->
pPars
->
fSeqMap
||
p
Cut
->
nLeaves
>
1
);
Delay
=
-
IF_FLOAT_LARGE
;
if
(
p
->
pPars
->
pLutLib
)
{
assert
(
!
p
->
pPars
->
fLiftLeaves
);
pLutDelays
=
p
->
pPars
->
pLutLib
->
pLutDelays
[
pCut
->
nLeaves
];
if
(
p
->
pPars
->
pLutLib
->
fVarPinDelays
)
{
...
...
@@ -77,6 +78,7 @@ float If_CutDelay( If_Man_t * p, If_Cut_t * pCut )
{
if
(
pCut
->
fUser
)
{
assert
(
!
p
->
pPars
->
fLiftLeaves
);
If_CutForEachLeaf
(
p
,
pCut
,
pLeaf
,
i
)
{
DelayCur
=
If_ObjCutBest
(
pLeaf
)
->
Delay
+
(
float
)
pCut
->
pPerm
[
i
];
...
...
@@ -85,11 +87,22 @@ float If_CutDelay( If_Man_t * p, If_Cut_t * pCut )
}
else
{
if
(
p
->
pPars
->
fLiftLeaves
)
{
If_CutForEachLeafSeq
(
p
,
pCut
,
pLeaf
,
Shift
,
i
)
{
DelayCur
=
If_ObjCutBest
(
pLeaf
)
->
Delay
-
Shift
*
p
->
Period
;
Delay
=
IF_MAX
(
Delay
,
DelayCur
);
}
}
else
{
If_CutForEachLeaf
(
p
,
pCut
,
pLeaf
,
i
)
{
DelayCur
=
If_ObjCutBest
(
pLeaf
)
->
Delay
;
Delay
=
IF_MAX
(
Delay
,
DelayCur
);
}
}
Delay
+=
1
.
0
;
}
}
...
...
@@ -115,6 +128,7 @@ void If_CutPropagateRequired( If_Man_t * p, If_Cut_t * pCut, float ObjRequired )
float
*
pLutDelays
;
float
Required
;
int
i
;
assert
(
!
p
->
pPars
->
fLiftLeaves
);
// compute the pins
if
(
p
->
pPars
->
pLutLib
)
{
...
...
src/map/if/ifUtil.c
View file @
ae037e45
...
...
@@ -30,6 +30,65 @@
/**Function*************************************************************
Synopsis [Sets all the node copy to NULL.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
If_ManCleanNodeCopy
(
If_Man_t
*
p
)
{
If_Obj_t
*
pObj
;
int
i
;
If_ManForEachObj
(
p
,
pObj
,
i
)
If_ObjSetCopy
(
pObj
,
NULL
);
}
/**Function*************************************************************
Synopsis [Sets all the cut data to NULL.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
If_ManCleanCutData
(
If_Man_t
*
p
)
{
If_Obj_t
*
pObj
;
If_Cut_t
*
pCut
;
int
i
,
k
;
If_ManForEachObj
(
p
,
pObj
,
i
)
If_ObjForEachCut
(
pObj
,
pCut
,
k
)
If_CutSetData
(
pCut
,
NULL
);
}
/**Function*************************************************************
Synopsis [Sets all visited marks to 0.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
If_ManCleanMarkV
(
If_Man_t
*
p
)
{
If_Obj_t
*
pObj
;
int
i
;
If_ManForEachObj
(
p
,
pObj
,
i
)
pObj
->
fVisit
=
0
;
}
/**Function*************************************************************
Synopsis [Returns the max delay of the POs.]
Description []
...
...
@@ -39,7 +98,7 @@
SeeAlso []
***********************************************************************/
float
If_ManDelayMax
(
If_Man_t
*
p
)
float
If_ManDelayMax
(
If_Man_t
*
p
,
int
fSeq
)
{
If_Obj_t
*
pObj
;
float
DelayBest
;
...
...
@@ -50,7 +109,14 @@ float If_ManDelayMax( If_Man_t * p )
p
->
pPars
->
fLatchPaths
=
0
;
}
DelayBest
=
-
IF_FLOAT_LARGE
;
if
(
p
->
pPars
->
fLatchPaths
)
if
(
fSeq
)
{
assert
(
p
->
pPars
->
nLatches
>
0
);
If_ManForEachPo
(
p
,
pObj
,
i
)
if
(
DelayBest
<
If_ObjCutBest
(
If_ObjFanin0
(
pObj
)
)
->
Delay
)
DelayBest
=
If_ObjCutBest
(
If_ObjFanin0
(
pObj
)
)
->
Delay
;
}
else
if
(
p
->
pPars
->
fLatchPaths
)
{
If_ManForEachLatch
(
p
,
pObj
,
i
)
if
(
DelayBest
<
If_ObjCutBest
(
If_ObjFanin0
(
pObj
)
)
->
Delay
)
...
...
@@ -58,7 +124,7 @@ float If_ManDelayMax( If_Man_t * p )
}
else
{
If_ManForEach
P
o
(
p
,
pObj
,
i
)
If_ManForEach
C
o
(
p
,
pObj
,
i
)
if
(
DelayBest
<
If_ObjCutBest
(
If_ObjFanin0
(
pObj
)
)
->
Delay
)
DelayBest
=
If_ObjCutBest
(
If_ObjFanin0
(
pObj
)
)
->
Delay
;
}
...
...
@@ -67,7 +133,7 @@ float If_ManDelayMax( If_Man_t * p )
/**Function*************************************************************
Synopsis [
Sets all the node copy to NULL
.]
Synopsis [
Computes the required times of all nodes
.]
Description []
...
...
@@ -76,33 +142,43 @@ float If_ManDelayMax( If_Man_t * p )
SeeAlso []
***********************************************************************/
void
If_ManC
leanNodeCopy
(
If_Man_t
*
p
)
void
If_ManC
omputeRequired
(
If_Man_t
*
p
,
int
fFirstTime
)
{
If_Obj_t
*
pObj
;
int
i
;
If_ManForEachObj
(
p
,
pObj
,
i
)
If_ObjSetCopy
(
pObj
,
NULL
);
}
/**Function*************************************************************
Synopsis [Sets all the cut data to NULL.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
If_ManCleanCutData
(
If_Man_t
*
p
)
{
If_Obj_t
*
pObj
;
If_Cut_t
*
pCut
;
int
i
,
k
;
If_ManForEachObj
(
p
,
pObj
,
i
)
If_ObjForEachCut
(
pObj
,
pCut
,
k
)
If_CutSetData
(
pCut
,
NULL
);
// compute area, clean required times, collect nodes used in the mapping
p
->
AreaGlo
=
If_ManScanMapping
(
p
);
// get the global required times
p
->
RequiredGlo
=
If_ManDelayMax
(
p
,
0
);
// update the required times according to the target
if
(
p
->
pPars
->
DelayTarget
!=
-
1
)
{
if
(
p
->
RequiredGlo
>
p
->
pPars
->
DelayTarget
+
p
->
fEpsilon
)
{
if
(
fFirstTime
)
printf
(
"Cannot meet the target required times (%4.2f). Mapping continues anyway.
\n
"
,
p
->
pPars
->
DelayTarget
);
}
else
if
(
p
->
RequiredGlo
<
p
->
pPars
->
DelayTarget
-
p
->
fEpsilon
)
{
if
(
fFirstTime
)
printf
(
"Relaxing the required times from (%4.2f) to the target (%4.2f).
\n
"
,
p
->
RequiredGlo
,
p
->
pPars
->
DelayTarget
);
p
->
RequiredGlo
=
p
->
pPars
->
DelayTarget
;
}
}
// set the required times for the POs
if
(
p
->
pPars
->
fLatchPaths
)
{
If_ManForEachLatch
(
p
,
pObj
,
i
)
If_ObjFanin0
(
pObj
)
->
Required
=
p
->
RequiredGlo
;
}
else
{
If_ManForEachCo
(
p
,
pObj
,
i
)
If_ObjFanin0
(
pObj
)
->
Required
=
p
->
RequiredGlo
;
}
// go through the nodes in the reverse topological order
Vec_PtrForEachEntry
(
p
->
vMapped
,
pObj
,
i
)
If_CutPropagateRequired
(
p
,
If_ObjCutBest
(
pObj
),
pObj
->
Required
);
}
/**Function*************************************************************
...
...
@@ -122,7 +198,7 @@ float If_ManScanMapping_rec( If_Man_t * p, If_Obj_t * pObj, If_Obj_t ** ppStore
If_Cut_t
*
pCutBest
;
float
aArea
;
int
i
;
if
(
pObj
->
nRefs
++
||
If_ObjIs
P
i
(
pObj
)
||
If_ObjIsConst1
(
pObj
)
)
if
(
pObj
->
nRefs
++
||
If_ObjIs
C
i
(
pObj
)
||
If_ObjIsConst1
(
pObj
)
)
return
0
.
0
;
// store the node in the structure by level
assert
(
If_ObjIsAnd
(
pObj
)
);
...
...
@@ -153,6 +229,7 @@ float If_ManScanMapping( If_Man_t * p )
If_Obj_t
*
pObj
,
**
ppStore
;
float
aArea
;
int
i
;
assert
(
!
p
->
pPars
->
fLiftLeaves
);
// clean all references
If_ManForEachObj
(
p
,
pObj
,
i
)
{
...
...
@@ -164,7 +241,7 @@ float If_ManScanMapping( If_Man_t * p )
memset
(
ppStore
,
0
,
sizeof
(
If_Obj_t
*
)
*
(
p
->
nLevelMax
+
1
)
);
// collect nodes reachable from POs in the DFS order through the best cuts
aArea
=
0
;
If_ManForEach
P
o
(
p
,
pObj
,
i
)
If_ManForEach
C
o
(
p
,
pObj
,
i
)
aArea
+=
If_ManScanMapping_rec
(
p
,
If_ObjFanin0
(
pObj
),
ppStore
);
// reconnect the nodes in reverse topological order
Vec_PtrClear
(
p
->
vMapped
);
...
...
@@ -177,7 +254,7 @@ float If_ManScanMapping( If_Man_t * p )
/**Function*************************************************************
Synopsis [Computes
the required times of all nodes
.]
Synopsis [Computes
area, references, and nodes used in the mapping
.]
Description []
...
...
@@ -186,46 +263,55 @@ float If_ManScanMapping( If_Man_t * p )
SeeAlso []
***********************************************************************/
void
If_ManComputeRequired
(
If_Man_t
*
p
,
int
fFirstTime
)
float
If_ManScanMappingSeq_rec
(
If_Man_t
*
p
,
If_Obj_t
*
pObj
,
Vec_Ptr_t
*
vMapped
)
{
If_Obj_t
*
pLeaf
;
If_Cut_t
*
pCutBest
;
float
aArea
;
int
i
,
Shift
;
if
(
pObj
->
nRefs
++
||
If_ObjIsCi
(
pObj
)
||
If_ObjIsConst1
(
pObj
)
)
return
0
.
0
;
// store the node in the structure by level
assert
(
If_ObjIsAnd
(
pObj
)
);
// visit the transitive fanin of the selected cut
pCutBest
=
If_ObjCutBest
(
pObj
);
aArea
=
If_ObjIsAnd
(
pObj
)
?
If_CutLutArea
(
p
,
pCutBest
)
:
(
float
)
0
.
0
;
If_CutForEachLeafSeq
(
p
,
pCutBest
,
pLeaf
,
Shift
,
i
)
aArea
+=
If_ManScanMappingSeq_rec
(
p
,
pLeaf
,
vMapped
);
// add the node
Vec_PtrPush
(
vMapped
,
pObj
);
return
aArea
;
}
/**Function*************************************************************
Synopsis [Computes area, references, and nodes used in the mapping.]
Description [Collects the nodes in reverse topological order in array
p->vMapping.]
SideEffects []
SeeAlso []
***********************************************************************/
float
If_ManScanMappingSeq
(
If_Man_t
*
p
)
{
If_Obj_t
*
pObj
;
float
aArea
;
int
i
;
// compute area, clean required times, collect nodes used in the mapping
p
->
AreaGlo
=
If_ManScanMapping
(
p
);
// get the global required times
p
->
RequiredGlo
=
If_ManDelayMax
(
p
);
// update the required times according to the target
if
(
p
->
pPars
->
DelayTarget
!=
-
1
)
{
if
(
p
->
RequiredGlo
>
p
->
pPars
->
DelayTarget
+
p
->
fEpsilon
)
{
if
(
fFirstTime
)
printf
(
"Cannot meet the target required times (%4.2f). Mapping continues anyway.
\n
"
,
p
->
pPars
->
DelayTarget
);
}
else
if
(
p
->
RequiredGlo
<
p
->
pPars
->
DelayTarget
-
p
->
fEpsilon
)
{
if
(
fFirstTime
)
printf
(
"Relaxing the required times from (%4.2f) to the target (%4.2f).
\n
"
,
p
->
RequiredGlo
,
p
->
pPars
->
DelayTarget
);
p
->
RequiredGlo
=
p
->
pPars
->
DelayTarget
;
}
}
// set the required times for the POs
if
(
p
->
pPars
->
fLatchPaths
)
{
If_ManForEachLatch
(
p
,
pObj
,
i
)
If_ObjFanin0
(
pObj
)
->
Required
=
p
->
RequiredGlo
;
}
else
{
assert
(
p
->
pPars
->
fLiftLeaves
);
// clean all references
If_ManForEachObj
(
p
,
pObj
,
i
)
pObj
->
nRefs
=
0
;
// collect nodes reachable from POs in the DFS order through the best cuts
aArea
=
0
;
Vec_PtrClear
(
p
->
vMapped
);
If_ManForEachPo
(
p
,
pObj
,
i
)
If_ObjFanin0
(
pObj
)
->
Required
=
p
->
RequiredGlo
;
}
// go through the nodes in the reverse topological order
Vec_PtrForEachEntry
(
p
->
vMapped
,
pObj
,
i
)
If_CutPropagateRequired
(
p
,
If_ObjCutBest
(
pObj
),
pObj
->
Required
);
aArea
+=
If_ManScanMappingSeq_rec
(
p
,
If_ObjFanin0
(
pObj
),
p
->
vMapped
);
return
aArea
;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
...
...
src/map/if/module.make
View file @
ae037e45
SRC
+=
src/map/if/ifCore.c
\
src/map/if/ifCut.c
\
src/map/if/ifLib.c
\
src/map/if/ifMan.c
\
src/map/if/ifMap.c
\
src/map/if/ifPrepro.c
\
src/map/if/ifReduce.c
\
src/map/if/ifSeq.c
\
src/map/if/ifTime.c
\
src/map/if/ifTruth.c
\
src/map/if/ifUtil.c
src/misc/nm/nmTable.c
View file @
ae037e45
...
...
@@ -187,12 +187,22 @@ Nm_Entry_t * Nm_ManTableLookupId( Nm_Man_t * p, int ObjId )
***********************************************************************/
Nm_Entry_t
*
Nm_ManTableLookupName
(
Nm_Man_t
*
p
,
char
*
pName
,
int
Type
)
{
Nm_Entry_t
*
pEntry
;
Nm_Entry_t
*
pEntry
,
*
pTemp
;
int
Counter
=
0
;
for
(
pEntry
=
p
->
pBinsN2I
[
Nm_HashString
(
pName
,
p
->
nBins
)
];
pEntry
;
pEntry
=
pEntry
->
pNextN2I
)
{
// check the entry itself
if
(
!
strcmp
(
pEntry
->
Name
,
pName
)
&&
(
Type
==
-
1
||
pEntry
->
Type
==
(
unsigned
)
Type
)
)
return
pEntry
;
return
pEntry
;
// if there is no namesakes, continue
if
(
pEntry
->
pNameSake
==
NULL
)
continue
;
// check the list of namesakes
for
(
pTemp
=
pEntry
->
pNameSake
;
pTemp
!=
pEntry
;
pTemp
=
pTemp
->
pNameSake
)
if
(
!
strcmp
(
pTemp
->
Name
,
pName
)
&&
(
Type
==
-
1
||
pTemp
->
Type
==
(
unsigned
)
Type
)
)
return
pTemp
;
}
return
NULL
;
}
/**Function*************************************************************
...
...
src/opt/ret/retCore.c
View file @
ae037e45
...
...
@@ -84,7 +84,7 @@ int Abc_NtkRetime( Abc_Ntk_t * pNtk, int Mode, int fForwardOnly, int fBackwardOn
RetValue
+=
Abc_NtkRetimeIncremental
(
pNtk
,
0
,
1
,
fVerbose
);
break
;
case
6
:
// Pan's algorithm
RetValue
=
Abc_NtkRetimeLValue
(
pNtk
,
2
00
,
fVerbose
);
RetValue
=
Abc_NtkRetimeLValue
(
pNtk
,
5
00
,
fVerbose
);
break
;
default:
printf
(
"Unknown retiming option.
\n
"
);
...
...
src/opt/ret/retDelay.c
View file @
ae037e45
...
...
@@ -90,13 +90,9 @@ int Abc_NtkRetimeMinDelayTry( Abc_Ntk_t * pNtk, int fForward, int fInitial, int
pNtkNew
=
Abc_NtkRetimeBackwardInitialStart
(
pNtk
);
}
}
if
(
fVerbose
)
{
if
(
!
fInitial
)
if
(
fVerbose
&&
!
fInitial
)
printf
(
"Performing analysis:
\n
"
);
else
printf
(
"Moving latches to the best position:
\n
"
);
}
// find the best iteration
DelayBest
=
ABC_INFINITY
;
IterBest
=
0
;
LatchesBest
=
Abc_NtkLatchNum
(
pNtk
);
vCritical
=
Vec_PtrAlloc
(
100
);
...
...
@@ -109,7 +105,7 @@ if ( fVerbose )
// record this position if it has the best delay
if
(
DelayBest
>
DelayCur
)
{
if
(
fVerbose
)
if
(
fVerbose
&&
!
fInitial
)
printf
(
"%s Iter = %3d. Delay = %3d. Latches = %5d. Delta = %6.2f. Ratio = %4.2f %%
\n
"
,
fForward
?
"Fwd"
:
"Bwd"
,
i
,
DelayCur
,
Abc_NtkLatchNum
(
pNtk
),
1
.
0
*
(
Abc_NtkLatchNum
(
pNtk
)
-
LatchesBest
)
/
(
DelayBest
-
DelayCur
),
...
...
@@ -146,7 +142,7 @@ if ( fVerbose )
Vec_IntFree
(
vValues
);
}
}
if
(
!
fInitial
&&
fVerbose
)
if
(
fVerbose
&&
!
fInitial
)
printf
(
"%s : Starting delay = %3d. Final delay = %3d. IterBest = %2d (out of %2d).
\n
"
,
fForward
?
"Forward "
:
"Backward"
,
DelayStart
,
DelayBest
,
IterBest
,
nIterLimit
);
*
pIterBest
=
IterBest
;
...
...
src/opt/ret/retLvalue.c
View file @
ae037e45
...
...
@@ -29,11 +29,12 @@ enum { ABC_RET_UPDATE_FAIL, ABC_RET_UPDATE_NO, ABC_RET_UPDATE_YES };
// the internal procedures
static
Vec_Int_t
*
Abc_NtkRetimeGetLags
(
Abc_Ntk_t
*
pNtk
,
int
nIterLimit
,
int
fVerbose
);
static
int
Abc_NtkRetimeSearch_rec
(
Abc_Ntk_t
*
pNtk
,
Vec_Ptr_t
*
vNodes
,
Vec_Ptr_t
*
vLatches
,
int
FiMin
,
int
FiMax
,
int
nMaxIters
,
int
fVerbose
);
static
int
Abc_NtkRetimeForPeriod
(
Abc_Ntk_t
*
pNtk
,
Vec_Ptr_t
*
vNodes
,
Vec_Ptr_t
*
vLatches
,
int
Fi
,
int
nMaxIters
,
int
fVerbose
);
static
int
Abc_NtkRetimeUpdateLValue
(
Abc_Ntk_t
*
pNtk
,
Vec_Ptr_t
*
vNodes
,
Vec_Ptr_t
*
vLatches
,
int
Fi
);
static
int
Abc_NtkRetimePosOverLimit
(
Abc_Ntk_t
*
pNtk
,
int
Fi
);
static
Vec_Ptr_t
*
Abc_ManCollectLatches
(
Abc_Ntk_t
*
pNtk
);
static
int
Abc_NtkRetimeUsingLags
(
Abc_Ntk_t
*
pNtk
,
Vec_Int_t
*
vLags
,
int
fVerbose
);
static
int
Abc_NtkRetimeSearch_rec
(
Abc_Ntk_t
*
pNtk
,
Vec_Ptr_t
*
vNodes
,
int
FiMin
,
int
FiMax
,
int
nMaxIters
,
int
fVerbose
);
static
int
Abc_NtkRetimeForPeriod
(
Abc_Ntk_t
*
pNtk
,
Vec_Ptr_t
*
vNodes
,
int
Fi
,
int
nMaxIters
,
int
fVerbose
);
static
int
Abc_NtkRetimeNodeUpdateLValue
(
Abc_Obj_t
*
pObj
,
int
Fi
);
static
Vec_Ptr_t
*
Abc_NtkRetimeCollect
(
Abc_Ntk_t
*
pNtk
);
static
inline
int
Abc_NodeComputeLag
(
int
LValue
,
int
Fi
)
{
return
(
LValue
+
(
1
<<
16
)
*
Fi
)
/
Fi
-
(
1
<<
16
)
-
(
int
)(
LValue
%
Fi
==
0
);
}
static
inline
int
Abc_NodeGetLValue
(
Abc_Obj_t
*
pNode
)
{
return
(
int
)
pNode
->
pCopy
;
}
...
...
@@ -87,17 +88,18 @@ int Abc_NtkRetimeLValue( Abc_Ntk_t * pNtk, int nIterLimit, int fVerbose )
Vec_Int_t
*
Abc_NtkRetimeGetLags
(
Abc_Ntk_t
*
pNtk
,
int
nIterLimit
,
int
fVerbose
)
{
Vec_Int_t
*
vLags
;
Vec_Ptr_t
*
vNodes
;
Vec_Ptr_t
*
vNodes
,
*
vLatches
;
Abc_Obj_t
*
pNode
;
int
i
,
FiMax
,
FiBest
,
RetValue
,
clk
,
clkIter
;
char
NodeLag
;
// get the upper bound on the clock period
FiMax
=
10
+
Abc_NtkLevel
(
pNtk
);
FiMax
=
Abc_NtkLevel
(
pNtk
);
// make sure this clock period is feasible
vNodes
=
Abc_NtkRetimeCollect
(
pNtk
);
if
(
!
Abc_NtkRetimeForPeriod
(
pNtk
,
vNodes
,
FiMax
,
nIterLimit
,
fVerbose
)
)
vNodes
=
Abc_NtkDfs
(
pNtk
,
0
);
vLatches
=
Abc_ManCollectLatches
(
pNtk
);
if
(
!
Abc_NtkRetimeForPeriod
(
pNtk
,
vNodes
,
vLatches
,
FiMax
,
nIterLimit
,
fVerbose
)
)
{
Vec_PtrFree
(
vNodes
);
printf
(
"Abc_NtkRetimeGetLags() error: The upper bound on the clock period cannot be computed.
\n
"
);
...
...
@@ -106,13 +108,12 @@ Vec_Int_t * Abc_NtkRetimeGetLags( Abc_Ntk_t * pNtk, int nIterLimit, int fVerbose
// search for the optimal clock period between 0 and nLevelMax
clk
=
clock
();
FiBest
=
Abc_NtkRetimeSearch_rec
(
pNtk
,
vNodes
,
0
,
FiMax
,
nIterLimit
,
fVerbose
);
FiBest
=
Abc_NtkRetimeSearch_rec
(
pNtk
,
vNodes
,
vLatches
,
0
,
FiMax
,
nIterLimit
,
fVerbose
);
clkIter
=
clock
()
-
clk
;
// recompute the best l-values
RetValue
=
Abc_NtkRetimeForPeriod
(
pNtk
,
vNodes
,
FiBest
,
nIterLimit
,
fVerbose
);
RetValue
=
Abc_NtkRetimeForPeriod
(
pNtk
,
vNodes
,
vLatches
,
FiBest
,
nIterLimit
,
fVerbose
);
assert
(
RetValue
);
Vec_PtrFree
(
vNodes
);
// fix the problem with non-converged delays
Abc_NtkForEachNode
(
pNtk
,
pNode
,
i
)
...
...
@@ -131,31 +132,16 @@ clkIter = clock() - clk;
// if ( fVerbose )
printf
(
"The best clock period is %3d. (Currently, network is not modified.)
\n
"
,
FiBest
);
/*
// print the statistic into a file
{
FILE * pTable;
pTable = fopen( "a/ret__stats.txt", "a+" );
fprintf( pTable, "%d ", FiBest );
fclose( pTable );
}
*/
/*
printf( "lvalues and lags : " );
Abc_NtkForEachNode( pNtk, pNode, i )
printf( "%d=%d(%d) ", pNode->Id, Abc_NodeGetLValue(pNode), Abc_NodeGetLag(pNode) );
printf( "\n" );
*/
/*
{
FILE * pTable;
pTable = fopen( "a/ret_stats_pan.txt", "a+" );
fprintf( pTable, "%s ", pNtk->pName );
pTable = fopen( "a/seqmap__stats.txt", "a+" );
fprintf( pTable, "%d ", FiBest );
fprintf( pTable, "\n" );
fclose( pTable );
}
*/
Vec_PtrFree
(
vNodes
);
Vec_PtrFree
(
vLatches
);
return
vLags
;
}
...
...
@@ -170,17 +156,17 @@ clkIter = clock() - clk;
SeeAlso []
***********************************************************************/
int
Abc_NtkRetimeSearch_rec
(
Abc_Ntk_t
*
pNtk
,
Vec_Ptr_t
*
vNodes
,
int
FiMin
,
int
FiMax
,
int
nMaxIters
,
int
fVerbose
)
int
Abc_NtkRetimeSearch_rec
(
Abc_Ntk_t
*
pNtk
,
Vec_Ptr_t
*
vNodes
,
Vec_Ptr_t
*
vLatches
,
int
FiMin
,
int
FiMax
,
int
nMaxIters
,
int
fVerbose
)
{
int
Median
;
assert
(
FiMin
<
FiMax
);
if
(
FiMin
+
1
==
FiMax
)
return
FiMax
;
Median
=
FiMin
+
(
FiMax
-
FiMin
)
/
2
;
if
(
Abc_NtkRetimeForPeriod
(
pNtk
,
vNodes
,
Median
,
nMaxIters
,
fVerbose
)
)
return
Abc_NtkRetimeSearch_rec
(
pNtk
,
vNodes
,
FiMin
,
Median
,
nMaxIters
,
fVerbose
);
// Median is feasible
if
(
Abc_NtkRetimeForPeriod
(
pNtk
,
vNodes
,
vLatches
,
Median
,
nMaxIters
,
fVerbose
)
)
return
Abc_NtkRetimeSearch_rec
(
pNtk
,
vNodes
,
vLatches
,
FiMin
,
Median
,
nMaxIters
,
fVerbose
);
// Median is feasible
else
return
Abc_NtkRetimeSearch_rec
(
pNtk
,
vNodes
,
Median
,
FiMax
,
nMaxIters
,
fVerbose
);
// Median is infeasible
return
Abc_NtkRetimeSearch_rec
(
pNtk
,
vNodes
,
vLatches
,
Median
,
FiMax
,
nMaxIters
,
fVerbose
);
// Median is infeasible
}
/**Function*************************************************************
...
...
@@ -194,56 +180,35 @@ int Abc_NtkRetimeSearch_rec( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, int FiMin, in
SeeAlso []
***********************************************************************/
int
Abc_NtkRetimeForPeriod
(
Abc_Ntk_t
*
pNtk
,
Vec_Ptr_t
*
vNodes
,
int
Fi
,
int
nMaxIters
,
int
fVerbose
)
int
Abc_NtkRetimeForPeriod
(
Abc_Ntk_t
*
pNtk
,
Vec_Ptr_t
*
vNodes
,
Vec_Ptr_t
*
vLatches
,
int
Fi
,
int
nMaxIters
,
int
fVerbose
)
{
Abc_Obj_t
*
pObj
;
int
i
,
c
,
fContained
,
fChange
,
RetValue
,
Counter
;
char
*
pReason
=
""
;
int
c
,
i
,
fConverged
;
// set l-values of all nodes to be minus infinity, except PIs and constants
Abc_NtkForEachObj
(
pNtk
,
pObj
,
i
)
if
(
Abc_ObjFaninNum
(
pObj
)
==
0
)
Abc_NodeSetLValue
(
pObj
,
0
);
else
Abc_NodeSetLValue
(
pObj
,
-
ABC_INFINITY
);
// update all values iteratively
Counter
=
0
;
fContained
=
1
;
fChange
=
1
;
for
(
c
=
0
;
fContained
&&
fChange
&&
c
<
nMaxIters
;
c
++
)
{
// go through the nodes and detect change
fChange
=
0
;
Vec_PtrForEachEntry
(
vNodes
,
pObj
,
i
)
fConverged
=
0
;
for
(
c
=
1
;
c
<=
nMaxIters
;
c
++
)
{
RetValue
=
Abc_NtkRetimeNodeUpdateLValue
(
pObj
,
Fi
);
if
(
RetValue
==
ABC_RET_UPDATE_FAIL
)
if
(
!
Abc_NtkRetimeUpdateLValue
(
pNtk
,
vNodes
,
vLatches
,
Fi
)
)
{
fContained
=
0
;
fConverged
=
1
;
break
;
}
if
(
RetValue
==
ABC_RET_UPDATE_NO
)
continue
;
// updating happened
fChange
=
1
;
Counter
++
;
}
}
if
(
c
==
nMaxIters
)
{
fContained
=
0
;
pReason
=
"(timeout)"
;
if
(
Abc_NtkRetimePosOverLimit
(
pNtk
,
Fi
)
)
break
;
}
else
c
++
;
// report the results
if
(
fVerbose
)
{
if
(
!
fCon
tain
ed
)
printf
(
"Period = %3d. Iterations = %3d.
Updates = %10d. Infeasible %s
\n
"
,
Fi
,
c
,
Counter
,
pReason
);
if
(
!
fCon
verg
ed
)
printf
(
"Period = %3d. Iterations = %3d.
Infeasible %s
\n
"
,
Fi
,
c
,
(
c
>
nMaxIters
)
?
"(timeout)"
:
""
);
else
printf
(
"Period = %3d. Iterations = %3d.
Updates = %10d. Feasible
\n
"
,
Fi
,
c
,
Counter
);
printf
(
"Period = %3d. Iterations = %3d.
Feasible
\n
"
,
Fi
,
c
);
}
/*
// check if any AND gates have infinite delay
...
...
@@ -253,55 +218,52 @@ int Abc_NtkRetimeForPeriod( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, int Fi, int nM
if ( Counter > 0 )
printf( "Warning: %d internal nodes have wrong l-values!\n", Counter );
*/
return
fCon
tain
ed
;
return
fCon
verg
ed
;
}
/**Function*************************************************************
Synopsis [
Computes the l-value of the node
.]
Synopsis [
Performs one iteration of l-value computation for the nodes
.]
Description [The node can be internal or a PO.]
Description [Experimentally it was found that checking POs changes
is not enough to detect the convergence of l-values in the network.]
SideEffects []
SeeAlso []
***********************************************************************/
int
Abc_NtkRetime
NodeUpdateLValue
(
Abc_Obj_t
*
pObj
,
int
Fi
)
int
Abc_NtkRetime
UpdateLValue
(
Abc_Ntk_t
*
pNtk
,
Vec_Ptr_t
*
vNodes
,
Vec_Ptr_t
*
vLatches
,
int
Fi
)
{
Abc_Obj_t
*
pFanin
;
int
lValueNew
,
i
;
// terminals
if
(
Abc_ObjFaninNum
(
pObj
)
==
0
)
return
ABC_RET_UPDATE_NO
;
// primary outputs
if
(
Abc_ObjIsPo
(
pObj
)
)
return
(
Abc_NodeGetLValue
(
Abc_ObjFanin0
(
pObj
))
>
Fi
)
?
ABC_RET_UPDATE_FAIL
:
ABC_RET_UPDATE_NO
;
// other types of objects
if
(
Abc_ObjIsBi
(
pObj
)
||
Abc_ObjIsBo
(
pObj
)
)
lValueNew
=
Abc_NodeGetLValue
(
Abc_ObjFanin0
(
pObj
));
else
if
(
Abc_ObjIsLatch
(
pObj
)
)
lValueNew
=
Abc_NodeGetLValue
(
Abc_ObjFanin0
(
pObj
))
-
Fi
;
else
Abc_Obj_t
*
pObj
,
*
pFanin
;
int
i
,
k
,
lValueNew
,
fChange
;
// go through the nodes and detect change
fChange
=
0
;
Vec_PtrForEachEntry
(
vNodes
,
pObj
,
i
)
{
assert
(
Abc_ObjIsNode
(
pObj
)
);
lValueNew
=
-
ABC_INFINITY
;
Abc_ObjForEachFanin
(
pObj
,
pFanin
,
i
)
Abc_ObjForEachFanin
(
pObj
,
pFanin
,
k
)
{
if
(
lValueNew
<
Abc_NodeGetLValue
(
pFanin
)
)
lValueNew
=
Abc_NodeGetLValue
(
pFanin
);
lValueNew
++
;
}
// check if it needs to be updated
if
(
lValueNew
<=
Abc_NodeGetLValue
(
pObj
)
)
return
ABC_RET_UPDATE_NO
;
// update if needed
lValueNew
++
;
if
(
Abc_NodeGetLValue
(
pObj
)
<
lValueNew
)
{
Abc_NodeSetLValue
(
pObj
,
lValueNew
);
return
ABC_RET_UPDATE_YES
;
fChange
=
1
;
}
}
// propagate values through the latches
Vec_PtrForEachEntry
(
vLatches
,
pObj
,
i
)
Abc_NodeSetLValue
(
Abc_ObjFanout0
(
pObj
),
Abc_NodeGetLValue
(
Abc_ObjFanin0
(
Abc_ObjFanin0
(
pObj
)))
-
Fi
);
return
fChange
;
}
/**Function*************************************************************
Synopsis [
Implements the retiming given as a set of retiming lags
.]
Synopsis [
Detects the case when l-values exceeded the limit
.]
Description []
...
...
@@ -310,74 +272,48 @@ int Abc_NtkRetimeNodeUpdateLValue( Abc_Obj_t * pObj, int Fi )
SeeAlso []
***********************************************************************/
int
Abc_NtkRetime
UsingLags
(
Abc_Ntk_t
*
pNtk
,
Vec_Int_t
*
vLags
,
int
fVerbose
)
int
Abc_NtkRetime
PosOverLimit
(
Abc_Ntk_t
*
pNtk
,
int
Fi
)
{
Abc_Obj_t
*
pObj
;
int
fChanges
,
fForward
,
nTotalMoves
,
Lag
,
Counter
,
i
;
// iterate over the nodes
nTotalMoves
=
0
;
do
{
fChanges
=
0
;
Abc_NtkForEachNode
(
pNtk
,
pObj
,
i
)
{
Lag
=
Vec_IntEntry
(
vLags
,
pObj
->
Id
);
if
(
!
Lag
)
continue
;
fForward
=
(
Lag
<
0
);
if
(
Abc_NtkRetimeNodeIsEnabled
(
pObj
,
fForward
)
)
{
Abc_NtkRetimeNode
(
pObj
,
fForward
,
0
);
fChanges
=
1
;
nTotalMoves
++
;
Vec_IntAddToEntry
(
vLags
,
pObj
->
Id
,
fForward
?
1
:
-
1
);
}
}
}
while
(
fChanges
);
if
(
fVerbose
)
printf
(
"Total latch moves = %d.
\n
"
,
nTotalMoves
);
// check if there are remaining lags
Counter
=
0
;
Abc_NtkForEachNode
(
pNtk
,
pObj
,
i
)
Counter
+=
(
Vec_IntEntry
(
vLags
,
pObj
->
Id
)
!=
0
);
if
(
Counter
)
printf
(
"Warning! The number of nodes with unrealized lag = %d.
\n
"
,
Counter
);
int
i
;
Abc_NtkForEachPo
(
pNtk
,
pObj
,
i
)
if
(
Abc_NodeGetLValue
(
Abc_ObjFanin0
(
pObj
))
>
Fi
)
return
1
;
return
0
;
}
/**Function*************************************************************
Synopsis [Collect
objects in the topological order from the latch inputs
.]
Synopsis [Collect
s latches in the topological order
.]
Description [If flag fOnlyMarked is set, collects only marked nodes.
Otherwise, collects only unmarked nodes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
Abc_
NtkRetimeCollect_rec
(
Abc_Obj_t
*
pObj
,
int
fOnlyMarked
,
Vec_Ptr_t
*
vNod
es
)
void
Abc_
ManCollectLatches_rec
(
Abc_Obj_t
*
pObj
,
Vec_Ptr_t
*
vLatch
es
)
{
Abc_Obj_t
*
pFanin
;
int
i
;
// skip collected nodes
Abc_Obj_t
*
pDriver
;
if
(
!
Abc_ObjIsLatch
(
pObj
)
)
return
;
// skip already collected latches
if
(
Abc_NodeIsTravIdCurrent
(
pObj
)
)
return
;
Abc_NodeSetTravIdCurrent
(
pObj
);
// collect recursively
if
(
fOnlyMarked
^
pObj
->
fMarkA
)
return
;
// visit the fanins
Abc_ObjForEachFanin
(
pObj
,
pFanin
,
i
)
Abc_NtkRetimeCollect_rec
(
pFanin
,
fOnlyMarked
,
vNodes
);
// collect non-trivial objects
if
(
Abc_ObjFaninNum
(
pObj
)
>
0
)
Vec_PtrPush
(
vNodes
,
pObj
);
// get the driver node feeding into the latch
pDriver
=
Abc_ObjFanin0
(
Abc_ObjFanin0
(
pObj
));
// call recursively if the driver looks like a latch output
if
(
Abc_ObjIsBo
(
pDriver
)
)
Abc_ManCollectLatches_rec
(
Abc_ObjFanin0
(
pDriver
),
vLatches
);
// collect the latch
Vec_PtrPush
(
vLatches
,
pObj
);
}
/**Function*************************************************************
Synopsis [Collect
objects in the topological order using LIs as a cut
.]
Synopsis [Collect
s latches in the topological order
.]
Description []
...
...
@@ -386,30 +322,62 @@ void Abc_NtkRetimeCollect_rec( Abc_Obj_t * pObj, int fOnlyMarked, Vec_Ptr_t * vN
SeeAlso []
***********************************************************************/
Vec_Ptr_t
*
Abc_
NtkRetimeCollect
(
Abc_Ntk_t
*
pNtk
)
Vec_Ptr_t
*
Abc_
ManCollectLatches
(
Abc_Ntk_t
*
pNtk
)
{
Vec_Ptr_t
*
vNodes
;
Abc_Obj_t
*
pObj
,
*
pFanin
;
int
i
,
k
;
vNodes
=
Vec_PtrAlloc
(
100
);
// mark the latch inputs
Abc_NtkForEachLatch
(
pNtk
,
pObj
,
i
)
Abc_ObjFanin0
(
pObj
)
->
fMarkA
=
1
;
// collect nodes in the DFS order from the marked nodes
Abc_NtkIncrementTravId
(
pNtk
);
Abc_NtkForEachPo
(
pNtk
,
pObj
,
i
)
Abc_NtkRetimeCollect_rec
(
pObj
,
0
,
vNodes
);
Abc_NtkForEachLatch
(
pNtk
,
pObj
,
i
)
Abc_ObjForEachFanin
(
Abc_ObjFanin0
(
pObj
),
pFanin
,
k
)
Abc_NtkRetimeCollect_rec
(
pFanin
,
0
,
vNodes
);
// collect marked nodes
Abc_NtkIncrementTravId
(
pNtk
);
Abc_NtkForEachLatch
(
pNtk
,
pObj
,
i
)
Abc_NtkRetimeCollect_rec
(
Abc_ObjFanin0
(
pObj
),
1
,
vNodes
);
// clean the marks
Vec_Ptr_t
*
vLatches
;
Abc_Obj_t
*
pObj
;
int
i
;
vLatches
=
Vec_PtrAlloc
(
Abc_NtkLatchNum
(
pNtk
)
);
Abc_NtkIncrementTravId
(
pNtk
);
Abc_NtkForEachLatch
(
pNtk
,
pObj
,
i
)
Abc_ObjFanin0
(
pObj
)
->
fMarkA
=
0
;
return
vNodes
;
Abc_ManCollectLatches_rec
(
pObj
,
vLatches
);
assert
(
Vec_PtrSize
(
vLatches
)
==
Abc_NtkLatchNum
(
pNtk
)
);
return
vLatches
;
}
/**Function*************************************************************
Synopsis [Implements the retiming given as the array of retiming lags.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int
Abc_NtkRetimeUsingLags
(
Abc_Ntk_t
*
pNtk
,
Vec_Int_t
*
vLags
,
int
fVerbose
)
{
Abc_Obj_t
*
pObj
;
int
fChanges
,
fForward
,
nTotalMoves
,
Lag
,
Counter
,
i
;
// iterate over the nodes
nTotalMoves
=
0
;
do
{
fChanges
=
0
;
Abc_NtkForEachNode
(
pNtk
,
pObj
,
i
)
{
Lag
=
Vec_IntEntry
(
vLags
,
pObj
->
Id
);
if
(
!
Lag
)
continue
;
fForward
=
(
Lag
<
0
);
if
(
Abc_NtkRetimeNodeIsEnabled
(
pObj
,
fForward
)
)
{
Abc_NtkRetimeNode
(
pObj
,
fForward
,
0
);
fChanges
=
1
;
nTotalMoves
++
;
Vec_IntAddToEntry
(
vLags
,
pObj
->
Id
,
fForward
?
1
:
-
1
);
}
}
}
while
(
fChanges
);
if
(
fVerbose
)
printf
(
"Total latch moves = %d.
\n
"
,
nTotalMoves
);
// check if there are remaining lags
Counter
=
0
;
Abc_NtkForEachNode
(
pNtk
,
pObj
,
i
)
Counter
+=
(
Vec_IntEntry
(
vLags
,
pObj
->
Id
)
!=
0
);
if
(
Counter
)
printf
(
"Warning! The number of nodes with unrealized lag = %d.
\n
"
,
Counter
);
return
1
;
}
////////////////////////////////////////////////////////////////////////
...
...
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