summaryrefslogtreecommitdiffstats
path: root/src/map/fpga/fpgaUtils.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/fpga/fpgaUtils.c')
-rw-r--r--src/map/fpga/fpgaUtils.c493
1 files changed, 61 insertions, 432 deletions
diff --git a/src/map/fpga/fpgaUtils.c b/src/map/fpga/fpgaUtils.c
index fc67d52b..bf334afa 100644
--- a/src/map/fpga/fpgaUtils.c
+++ b/src/map/fpga/fpgaUtils.c
@@ -24,15 +24,10 @@
static void Fpga_MappingDfs_rec( Fpga_Node_t * pNode, Fpga_NodeVec_t * vNodes, int fCollectEquiv );
static void Fpga_MappingDfsCuts_rec( Fpga_Node_t * pNode, Fpga_NodeVec_t * vNodes );
-static float Fpga_MappingArea_rec( Fpga_Man_t * pMan, Fpga_Node_t * pNode, Fpga_NodeVec_t * vNodes );
-static int Fpga_MappingCountLevels_rec( Fpga_Node_t * pNode );
-static void Fpga_MappingMarkUsed_rec( Fpga_Node_t * pNode );
static int Fpga_MappingCompareOutputDelay( int * pOut1, int * pOut2 );
-static float Fpga_MappingSetRefsAndArea_rec( Fpga_Man_t * pMan, Fpga_Node_t * pNode );
-static Fpga_Man_t * s_pMan = NULL;
-
static void Fpga_DfsLim_rec( Fpga_Node_t * pNode, int Level, Fpga_NodeVec_t * vNodes );
-static int Fpga_CollectNodeTfo_rec( Fpga_Node_t * pNode, Fpga_Node_t * pPivot, Fpga_NodeVec_t * vVisited, Fpga_NodeVec_t * vTfo );
+static int Fpga_CollectNodeTfo_rec( Fpga_Node_t * pNode, Fpga_Node_t * pPivot, Fpga_NodeVec_t * vVisited, Fpga_NodeVec_t * vTfo );
+static Fpga_Man_t * s_pMan = NULL;
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFITIONS ///
@@ -131,184 +126,6 @@ Fpga_NodeVec_t * Fpga_MappingDfsNodes( Fpga_Man_t * pMan, Fpga_Node_t ** ppNodes
return vNodes;
}
-
-/**Function*************************************************************
-
- Synopsis [Computes the number of logic levels not counting PIs/POs.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-int Fpga_CountLevels( Fpga_Man_t * pMan )
-{
- int i, LevelsMax, LevelsCur;
- // perform the traversal
- LevelsMax = -1;
- for ( i = 0; i < pMan->nOutputs; i++ )
- {
- LevelsCur = Fpga_Regular(pMan->pOutputs[i])->Level;
- if ( LevelsMax < LevelsCur )
- LevelsMax = LevelsCur;
- }
- return LevelsMax;
-}
-
-/**Function*************************************************************
-
- Synopsis [Computes the number of logic levels not counting PIs/POs.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-int Fpga_CountLevelsNodes( Fpga_Man_t * pMan, Fpga_Node_t ** ppRoots, int nRoots )
-{
- int i, LevelsMax, LevelsCur;
- // perform the traversal
- LevelsMax = -1;
- for ( i = 0; i < nRoots; i++ )
- {
- LevelsCur = Fpga_Regular(ppRoots[i])->Level;
- if ( LevelsMax < LevelsCur )
- LevelsMax = LevelsCur;
- }
- return LevelsMax;
-}
-
-/**Function*************************************************************
-
- Synopsis [Computes the DFS ordering of the nodes visible in current mapping.]
-
- Description [The node is visible if it appears as a root of one of the best
- cuts (that is cuts selected for the current mapping).]
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Fpga_NodeVec_t * Fpga_MappingDfsCuts( Fpga_Man_t * pMan )
-{
- Fpga_NodeVec_t * vNodes;
- int i;
- // perform the traversal
- vNodes = Fpga_NodeVecAlloc( 100 );
- for ( i = 0; i < pMan->nOutputs; i++ )
- Fpga_MappingDfsCuts_rec( Fpga_Regular(pMan->pOutputs[i]), vNodes );
- for ( i = 0; i < vNodes->nSize; i++ )
- vNodes->pArray[i]->fMark0 = 0;
- return vNodes;
-}
-
-/**Function*************************************************************
-
- Synopsis [Computes the DFS ordering of the nodes visible in current mapping.]
-
- Description [The node is visible if it appears as a root of one of the best
- cuts (that is cuts selected for the current mapping).]
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Fpga_NodeVec_t * Fpga_MappingDfsCutsNode( Fpga_Man_t * pMan, Fpga_Node_t * pNode )
-{
- Fpga_NodeVec_t * vNodes;
- int i;
- // perform the traversal
- vNodes = Fpga_NodeVecAlloc( 100 );
- Fpga_MappingDfsCuts_rec( pNode, vNodes );
- for ( i = 0; i < vNodes->nSize; i++ )
- vNodes->pArray[i]->fMark0 = 0;
- return vNodes;
-}
-
-/**Function*************************************************************
-
- Synopsis [Recursively computes the DFS ordering of the nodes.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Fpga_MappingDfsCuts_rec( Fpga_Node_t * pNode, Fpga_NodeVec_t * vNodes )
-{
- int i;
- assert( !Fpga_IsComplement(pNode) );
- if ( !Fpga_NodeIsAnd(pNode) )
- return;
- if ( pNode->fMark0 )
- return;
- assert( pNode->pCutBest != NULL );
- // visit the transitive fanin of the selected cut
- for ( i = 0; i < pNode->pCutBest->nLeaves; i++ )
- Fpga_MappingDfsCuts_rec( pNode->pCutBest->ppLeaves[i], vNodes );
- // make sure the node is not visited through the fanin nodes
- assert( pNode->fMark0 == 0 );
- // mark the node as visited
- pNode->fMark0 = 1;
- // add the node to the list
- Fpga_NodeVecPush( vNodes, pNode );
-}
-
-
-/**Function*************************************************************
-
- Synopsis [Marks the nodes used in the mapping.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Fpga_MappingMarkUsed( Fpga_Man_t * pMan )
-{
- int i;
- for ( i = 0; i < pMan->nOutputs; i++ )
- Fpga_MappingMarkUsed_rec( Fpga_Regular(pMan->pOutputs[i]) );
-}
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Fpga_MappingMarkUsed_rec( Fpga_Node_t * pNode )
-{
- int i;
- assert( !Fpga_IsComplement(pNode) );
- if ( pNode->fUsed )
- return;
- pNode->fUsed = 1;
- if ( !Fpga_NodeIsAnd(pNode) )
- return;
- assert( pNode->pCutBest != NULL );
- // visit the transitive fanin of the selected cut
- for ( i = 0; i < pNode->pCutBest->nLeaves; i++ )
- Fpga_MappingMarkUsed_rec( pNode->pCutBest->ppLeaves[i] );
-}
-
-
-
/**Function*************************************************************
Synopsis []
@@ -346,22 +163,16 @@ float Fpga_MappingGetAreaFlow( Fpga_Man_t * p )
***********************************************************************/
float Fpga_MappingArea( Fpga_Man_t * pMan )
{
- Fpga_NodeVec_t * vNodes;
+ Fpga_Node_t * pNode;
float aTotal;
int i;
// perform the traversal
aTotal = 0;
- vNodes = Fpga_NodeVecAlloc( 100 );
- for ( i = 0; i < pMan->nOutputs; i++ )
+ for ( i = 0; i < pMan->vMapping->nSize; i++ )
{
- aTotal += Fpga_MappingArea_rec( pMan, Fpga_Regular(pMan->pOutputs[i]), vNodes );
- // add the area for single-input nodes (if any) at the POs
-// if ( Fpga_NodeIsVar(pMan->pOutputs[i]) || Fpga_IsComplement(pMan->pOutputs[i]) )
-// aTotal += pMan->pLutLib->pLutAreas[1];
+ pNode = pMan->vMapping->pArray[i];
+ aTotal += pMan->pLutLib->pLutAreas[pNode->pCutBest->nLeaves];
}
- for ( i = 0; i < vNodes->nSize; i++ )
- vNodes->pArray[i]->fMark0 = 0;
- Fpga_NodeVecFree( vNodes );
return aTotal;
}
@@ -401,10 +212,9 @@ float Fpga_MappingArea_rec( Fpga_Man_t * pMan, Fpga_Node_t * pNode, Fpga_NodeVec
return aArea;
}
-
/**Function*************************************************************
- Synopsis [Sets the correct reference counts for the mapping.]
+ Synopsis [Computes the area of the current mapping.]
Description []
@@ -413,55 +223,22 @@ float Fpga_MappingArea_rec( Fpga_Man_t * pMan, Fpga_Node_t * pNode, Fpga_NodeVec
SeeAlso []
***********************************************************************/
-float Fpga_MappingComputeCutAreas( Fpga_Man_t * pMan )
+float Fpga_MappingAreaTrav( Fpga_Man_t * pMan )
{
Fpga_NodeVec_t * vNodes;
- Fpga_Node_t * pNode;
- float Area = 0;
+ float aTotal;
int i;
- // collect nodes reachable from POs in the DFS order through the best cuts
- vNodes = Fpga_MappingDfsCuts( pMan );
+ // perform the traversal
+ aTotal = 0;
+ vNodes = Fpga_NodeVecAlloc( 100 );
+ for ( i = 0; i < pMan->nOutputs; i++ )
+ aTotal += Fpga_MappingArea_rec( pMan, Fpga_Regular(pMan->pOutputs[i]), vNodes );
for ( i = 0; i < vNodes->nSize; i++ )
- {
- pNode = vNodes->pArray[i];
- pNode->pCutBest->aFlow = Fpga_CutGetAreaRefed( pMan, pNode->pCutBest );
- Area += pMan->pLutLib->pLutAreas[pNode->pCutBest->nLeaves];
- }
+ vNodes->pArray[i]->fMark0 = 0;
Fpga_NodeVecFree( vNodes );
- return Area;
+ return aTotal;
}
-/**Function*************************************************************
-
- Synopsis [Sets the correct reference counts for the mapping.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-float Fpga_MappingSetRefsAndArea( Fpga_Man_t * pMan )
-{
- Fpga_Node_t * pNode;
- float aArea;
- int i;
- // clean all references
- for ( i = 0; i < pMan->vNodesAll->nSize; i++ )
- pMan->vNodesAll->pArray[i]->nRefs = 0;
- // collect nodes reachable from POs in the DFS order through the best cuts
- aArea = 0;
- for ( i = 0; i < pMan->nOutputs; i++ )
- {
- pNode = Fpga_Regular(pMan->pOutputs[i]);
- if ( pNode == pMan->pConst1 )
- continue;
- aArea += Fpga_MappingSetRefsAndArea_rec( pMan, pNode );
- pNode->nRefs++;
- }
- return aArea;
-}
/**Function*************************************************************
@@ -474,7 +251,7 @@ float Fpga_MappingSetRefsAndArea( Fpga_Man_t * pMan )
SeeAlso []
***********************************************************************/
-float Fpga_MappingSetRefsAndArea_rec( Fpga_Man_t * pMan, Fpga_Node_t * pNode )
+float Fpga_MappingSetRefsAndArea_rec( Fpga_Man_t * pMan, Fpga_Node_t * pNode, Fpga_Node_t ** ppStore )
{
float aArea;
int i;
@@ -484,217 +261,63 @@ float Fpga_MappingSetRefsAndArea_rec( Fpga_Man_t * pMan, Fpga_Node_t * pNode )
if ( !Fpga_NodeIsAnd(pNode) )
return 0;
assert( pNode->pCutBest != NULL );
+ // store the node in the structure by level
+ pNode->pData0 = (char *)ppStore[pNode->Level];
+ ppStore[pNode->Level] = pNode;
// visit the transitive fanin of the selected cut
aArea = pMan->pLutLib->pLutAreas[pNode->pCutBest->nLeaves];
for ( i = 0; i < pNode->pCutBest->nLeaves; i++ )
- aArea += Fpga_MappingSetRefsAndArea_rec( pMan, pNode->pCutBest->ppLeaves[i] );
+ aArea += Fpga_MappingSetRefsAndArea_rec( pMan, pNode->pCutBest->ppLeaves[i], ppStore );
return aArea;
}
/**Function*************************************************************
- Synopsis [Collect the referenced nodes.]
+ Synopsis [Sets the correct reference counts for the mapping.]
- Description []
+ Description [Collects the nodes in reverse topological order
+ and places in them in array pMan->vMapping.]
SideEffects []
SeeAlso []
***********************************************************************/
-Fpga_NodeVec_t * Fpga_MappingCollectRefed( Fpga_Man_t * pMan )
+float Fpga_MappingSetRefsAndArea( Fpga_Man_t * pMan )
{
- Fpga_NodeVec_t * vNodes;
- int i;
- vNodes = Fpga_NodeVecAlloc( 100 );
- for ( i = 0; i < pMan->vNodesAll->nSize; i++ )
- {
- if ( Fpga_NodeIsVar(pMan->vNodesAll->pArray[i]) )
- continue;
- if ( pMan->vNodesAll->pArray[i]->nRefs )
- Fpga_NodeVecPush( vNodes, pMan->vNodesAll->pArray[i] );
- }
- return vNodes;
-}
-
-/**Function*************************************************************
-
- Synopsis [Computes the number of logic levels not counting PIs/POs.]
+ Fpga_Node_t * pNode, ** ppStore;
+ float aArea;
+ int i, LevelMax;
- Description []
-
- SideEffects [Note that this procedure will reassign the levels assigned
- originally by NodeCreate() because it counts the number of levels with
- choices differently!]
+ // clean all references
+ for ( i = 0; i < pMan->vNodesAll->nSize; i++ )
+ pMan->vNodesAll->pArray[i]->nRefs = 0;
- SeeAlso []
+ // allocate place to store the nodes
+ LevelMax = Fpga_MappingMaxLevel( pMan );
+ ppStore = ALLOC( Fpga_Node_t *, LevelMax + 1 );
+ memset( ppStore, 0, sizeof(Fpga_Node_t *) * (LevelMax + 1) );
-***********************************************************************/
-int Fpga_MappingCountLevels( Fpga_Man_t * pMan )
-{
- int i, LevelsMax, LevelsCur;
- // perform the traversal
- LevelsMax = -1;
- for ( i = 0; i < pMan->nOutputs; i++ )
- {
- LevelsCur = Fpga_MappingCountLevels_rec( Fpga_Regular(pMan->pOutputs[i]) );
- if ( LevelsMax < LevelsCur )
- LevelsMax = LevelsCur;
- }
+ // collect nodes reachable from POs in the DFS order through the best cuts
+ aArea = 0;
for ( i = 0; i < pMan->nOutputs; i++ )
- Fpga_MappingUnmark_rec( Fpga_Regular(pMan->pOutputs[i]) );
- return LevelsMax;
-}
-
-/**Function*************************************************************
-
- Synopsis [Recursively computes the number of logic levels.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-int Fpga_MappingCountLevels_rec( Fpga_Node_t * pNode )
-{
- int Level1, Level2;
- assert( !Fpga_IsComplement(pNode) );
- if ( !Fpga_NodeIsAnd(pNode) )
{
- pNode->Level = 0;
- return 0;
+ pNode = Fpga_Regular(pMan->pOutputs[i]);
+ if ( pNode == pMan->pConst1 )
+ continue;
+ aArea += Fpga_MappingSetRefsAndArea_rec( pMan, pNode, ppStore );
+ pNode->nRefs++;
}
- if ( pNode->fMark0 )
- return pNode->Level;
- pNode->fMark0 = 1;
- // visit the transitive fanin
- Level1 = Fpga_MappingCountLevels_rec( Fpga_Regular(pNode->p1) );
- Level2 = Fpga_MappingCountLevels_rec( Fpga_Regular(pNode->p2) );
- // set the number of levels
- pNode->Level = 1 + ((Level1>Level2)? Level1: Level2);
- return pNode->Level;
-}
-
-/**Function*************************************************************
-
- Synopsis [Unmarks the nodes.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Fpga_MappingUnmark( Fpga_Man_t * pMan )
-{
- int i;
- for ( i = 0; i < pMan->nOutputs; i++ )
- Fpga_MappingUnmark_rec( Fpga_Regular(pMan->pOutputs[i]) );
-}
-
-/**Function*************************************************************
-
- Synopsis [Recursively unmarks the nodes.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Fpga_MappingUnmark_rec( Fpga_Node_t * pNode )
-{
- assert( !Fpga_IsComplement(pNode) );
- if ( pNode->fMark0 == 0 )
- return;
- pNode->fMark0 = 0;
- if ( !Fpga_NodeIsAnd(pNode) )
- return;
- Fpga_MappingUnmark_rec( Fpga_Regular(pNode->p1) );
- Fpga_MappingUnmark_rec( Fpga_Regular(pNode->p2) );
- // visit the equivalent nodes
- if ( pNode->pNextE )
- Fpga_MappingUnmark_rec( pNode->pNextE );
-}
-
-/**Function*************************************************************
-
- Synopsis [Recursively unmarks the nodes.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Fpga_MappingMark_rec( Fpga_Node_t * pNode )
-{
- assert( !Fpga_IsComplement(pNode) );
- if ( pNode->fMark0 == 1 )
- return;
- pNode->fMark0 = 1;
- if ( !Fpga_NodeIsAnd(pNode) )
- return;
- Fpga_MappingMark_rec( Fpga_Regular(pNode->p1) );
- Fpga_MappingMark_rec( Fpga_Regular(pNode->p2) );
-}
-
-/**Function*************************************************************
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Fpga_MappedMark_rec( Fpga_Node_t * pNode )
-{
- int i;
- assert( !Fpga_IsComplement(pNode) );
- if ( pNode->fMark0 == 1 )
- return;
- pNode->fMark0 = 1;
- if ( !Fpga_NodeIsAnd(pNode) )
- return;
- assert( pNode->pCutBest != NULL );
- // visit the transitive fanin of the selected cut
- for ( i = 0; i < pNode->pCutBest->nLeaves; i++ )
- Fpga_MappedMark_rec( pNode->pCutBest->ppLeaves[i] );
+ // reconnect the nodes in reverse topological order
+ pMan->vMapping->nSize = 0;
+ for ( i = LevelMax; i > 0; i-- )
+ for ( pNode = ppStore[i]; pNode; pNode = (Fpga_Node_t *)pNode->pData0 )
+ Fpga_NodeVecPush( pMan->vMapping, pNode );
+ free( ppStore );
+ return aArea;
}
-/**Function*************************************************************
-
- Synopsis [Recursively unmarks the nodes.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Fpga_MappedUnmark_rec( Fpga_Node_t * pNode )
-{
- int i;
- assert( !Fpga_IsComplement(pNode) );
- if ( pNode->fMark0 == 0 )
- return;
- pNode->fMark0 = 0;
- if ( !Fpga_NodeIsAnd(pNode) )
- return;
- assert( pNode->pCutBest != NULL );
- // visit the transitive fanin of the selected cut
- for ( i = 0; i < pNode->pCutBest->nLeaves; i++ )
- Fpga_MappedUnmark_rec( pNode->pCutBest->ppLeaves[i] );
-}
/**Function*************************************************************
@@ -710,7 +333,7 @@ void Fpga_MappedUnmark_rec( Fpga_Node_t * pNode )
void Fpga_MappingPrintOutputArrivals( Fpga_Man_t * p )
{
Fpga_Node_t * pNode;
- int fCompl, Limit, i;
+ int fCompl, Limit, MaxNameSize, i;
int * pSorted;
// sort outputs by arrival time
@@ -723,15 +346,21 @@ void Fpga_MappingPrintOutputArrivals( Fpga_Man_t * p )
assert( Fpga_MappingCompareOutputDelay( pSorted, pSorted + p->nOutputs - 1 ) <= 0 );
s_pMan = NULL;
- // print the latest outputs
+ // determine max size of the node's name
+ MaxNameSize = 0;
Limit = (p->nOutputs > 5)? 5 : p->nOutputs;
for ( i = 0; i < Limit; i++ )
+ if ( MaxNameSize < (int)strlen(p->ppOutputNames[pSorted[i]]) )
+ MaxNameSize = strlen(p->ppOutputNames[pSorted[i]]);
+
+ // print the latest outputs
+ for ( i = 0; i < Limit; i++ )
{
// get the i-th latest output
pNode = Fpga_Regular(p->pOutputs[pSorted[i]]);
fCompl = Fpga_IsComplement(p->pOutputs[pSorted[i]]);
// print out the best arrival time
- printf( "Output %20s : ", p->ppOutputNames[pSorted[i]] );
+ printf( "Output %-*s : ", MaxNameSize + 3, p->ppOutputNames[pSorted[i]] );
printf( "Delay = %8.2f ", (double)pNode->pCutBest->tArrival );
if ( fCompl )
printf( "NEG" );
@@ -1169,7 +798,7 @@ float Fpga_MappingPrintSwitching( Fpga_Man_t * p )
SeeAlso []
***********************************************************************/
-int Fpga_GetMaxLevel( Fpga_Man_t * pMan )
+int Fpga_MappingMaxLevel( Fpga_Man_t * pMan )
{
int nLevelMax, i;
nLevelMax = 0;
@@ -1269,11 +898,11 @@ void Fpga_ManReportChoices( Fpga_Man_t * pMan )
int i, LevelMax1, LevelMax2;
// report the number of levels
- LevelMax1 = Fpga_GetMaxLevel( pMan );
+ LevelMax1 = Fpga_MappingMaxLevel( pMan );
pMan->nTravIds++;
for ( i = 0; i < pMan->nOutputs; i++ )
Fpga_MappingUpdateLevel_rec( pMan, Fpga_Regular(pMan->pOutputs[i]), 0 );
- LevelMax2 = Fpga_GetMaxLevel( pMan );
+ LevelMax2 = Fpga_MappingMaxLevel( pMan );
// report statistics about choices
nChoiceNodes = nChoices = 0;