Files
abc/src/map/pga/pgaUtil.c
T
2005-10-12 08:01:00 -07:00

321 lines
9.2 KiB
C

/**CFile****************************************************************
FileName [pgaUtil.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [FPGA mapper.]
Synopsis [Verious utilities.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: pgaUtil.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "pgaInt.h"
#define PGA_CO_LIST_SIZE 5
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Returns the results of mapping.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Ptr_t * Pga_MappingResults( Pga_Man_t * p )
{
Vec_Ptr_t * vResult;
Pga_Node_t * pNode;
int i;
vResult = Vec_PtrAlloc( 1000 );
Pga_ManForEachObjDirect( p, pNode, i )
{
// skip the CIs and nodes not used in the mapping
if ( !pNode->Match.pCut || !pNode->nRefs )
continue;
pNode->Match.pCut->uSign = pNode->Id;
Vec_PtrPush( vResult, pNode->Match.pCut );
}
return vResult;
}
/**Function*************************************************************
Synopsis [Computes the maximum arrival times.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
float Pga_TimeComputeArrivalMax( Pga_Man_t * p )
{
Pga_Node_t * pNode;
float ArrivalMax;
int i;
ArrivalMax = -ABC_INFINITY;
Pga_ManForEachCoDriver( p, pNode, i )
ArrivalMax = ABC_MAX( ArrivalMax, pNode->Match.Delay );
return ArrivalMax;
}
/**Function*************************************************************
Synopsis [Computes required times of all nodes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Pga_MappingComputeRequired( Pga_Man_t * p )
{
Pga_Node_t * pNode, * pFanin;
Cut_Cut_t * pCutBest;
float RequiredNew;
int i, k;
// clean the required times of all nodes
Pga_ManForEachObjDirect( p, pNode, i )
pNode->Required = ABC_INFINITY;
// get the global required times
p->AreaGlobal = Pga_TimeComputeArrivalMax( p );
p->RequiredGlobal = ABC_MAX( p->AreaGlobal, p->RequiredUser );
// set the global required times of the CO drivers
Pga_ManForEachCoDriver( p, pNode, i )
pNode->Required = p->RequiredGlobal;
// propagate the required times in the reverse topological order
Pga_ManForEachObjReverse( p, pNode, i )
{
// skip the CIs and nodes not used in the mapping
if ( !pNode->Match.pCut || !pNode->nRefs )
continue;
// get the required time for children
pCutBest = pNode->Match.pCut;
RequiredNew = pNode->Required - p->pLutDelays[pCutBest->nLeaves];
// update the required time of the children
for ( k = 0; k < (int)pCutBest->nLeaves; k++ )
{
pFanin = Pga_Node( p, pCutBest->pLeaves[k] );
pFanin->Required = ABC_MIN( pFanin->Required, RequiredNew );
}
}
// check that the required times does not contradict the arrival times
Pga_ManForEachObjDirect( p, pNode, i )
assert( !pNode->Match.pCut || pNode->Match.Delay < pNode->Required + p->Epsilon );
}
/**Function*************************************************************
Synopsis [Sets references and computes area for the current mapping.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
float Pga_MappingSetRefsAndArea( Pga_Man_t * p )
{
Pga_Node_t * pNode, * pFanin;
Cut_Cut_t * pCutBest;
float AreaTotal;
int i, k;
// clean all the references
Pga_ManForEachObjDirect( p, pNode, i )
pNode->nRefs = 0;
// set the references of the CO drivers
Pga_ManForEachCoDriver( p, pNode, i )
pNode->nRefs++;
// go through the nodes in the reverse order
AreaTotal = 0.0;
Pga_ManForEachObjReverse( p, pNode, i )
{
// skip the CIs and nodes not used in the mapping
if ( !pNode->Match.pCut || !pNode->nRefs )
continue;
// increate the reference count of the children
pCutBest = pNode->Match.pCut;
AreaTotal += p->pLutAreas[pCutBest->nLeaves];
// update the required time of the children
for ( k = 0; k < (int)pCutBest->nLeaves; k++ )
{
pFanin = Pga_Node( p, pCutBest->pLeaves[k] );
pFanin->nRefs++;
}
}
return AreaTotal;
}
/**Function*************************************************************
Synopsis [Computes switching activity of the mapping.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
float Pga_MappingGetSwitching( Pga_Man_t * p )
{
float Switching;
Pga_Node_t * pNode;
int i;
Switching = 0;
Pga_ManForEachObjDirect( p, pNode, i )
{
// skip the CIs and nodes not used in the mapping
if ( !pNode->Match.pCut || !pNode->nRefs )
continue;
Switching += pNode->Switching;
}
return Switching;
}
/**Function*************************************************************
Synopsis [Compares the outputs by their arrival times.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Pga_MappingCompareOutputDelay( Pga_Node_t ** ppNode1, Pga_Node_t ** ppNode2 )
{
Pga_Node_t * pNode1 = *ppNode1;
Pga_Node_t * pNode2 = *ppNode2;
float Arrival1 = pNode1->Match.Delay;
float Arrival2 = pNode2->Match.Delay;
if ( Arrival1 < Arrival2 )
return -1;
if ( Arrival1 > Arrival2 )
return 1;
return 0;
}
/**Function*************************************************************
Synopsis [Finds given number of latest arriving COs.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Pga_MappingFindLatest( Pga_Man_t * p, int * pNodes, int nNodesMax )
{
Pga_Node_t * pNodeI, * pNodeK;
Abc_Obj_t * pObjCo;
int nNodes, i, k, v;
assert( Abc_NtkCoNum(p->pParams->pNtk) >= nNodesMax );
pNodes[0] = 0;
nNodes = 1;
// for ( i = 1; i < p->nOutputs; i++ )
Pga_ManForEachCoDriver( p, pNodeI, i )
{
for ( k = nNodes - 1; k >= 0; k-- )
{
pObjCo = Abc_NtkCo( p->pParams->pNtk, pNodes[k] );
pNodeK = Pga_Node( p, Abc_ObjFaninId0(pObjCo) );
if ( Pga_MappingCompareOutputDelay( &pNodeK, &pNodeI ) >= 0 )
break;
}
if ( k == nNodesMax - 1 )
continue;
if ( nNodes < nNodesMax )
nNodes++;
for ( v = nNodes - 1; v > k+1; v-- )
pNodes[v] = pNodes[v-1];
pNodes[k+1] = i;
}
}
/**Function*************************************************************
Synopsis [Prints a bunch of latest arriving outputs.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Pga_MappingPrintOutputArrivals( Pga_Man_t * p )
{
int pSorted[PGA_CO_LIST_SIZE];
Abc_Ntk_t * pNtk = p->pParams->pNtk;
Abc_Obj_t * pObjCo;
Pga_Node_t * pNode;
int Limit, MaxNameSize, i;
// determine the number of nodes to print
Limit = (Abc_NtkCoNum(pNtk) < PGA_CO_LIST_SIZE)? Abc_NtkCoNum(pNtk) : PGA_CO_LIST_SIZE;
// determine the order
Pga_MappingFindLatest( p, pSorted, Limit );
// determine max size of the node's name
MaxNameSize = 0;
for ( i = 0; i < Limit; i++ )
{
pObjCo = Abc_NtkCo( pNtk, pSorted[i] );
if ( MaxNameSize < (int)strlen( Abc_ObjName(pObjCo) ) )
MaxNameSize = strlen( Abc_ObjName(pObjCo) );
}
// print the latest outputs
for ( i = 0; i < Limit; i++ )
{
// get the i-th latest output
pObjCo = Abc_NtkCo( pNtk, pSorted[i] );
pNode = Pga_Node( p, pObjCo->Id );
// print out the best arrival time
printf( "Output %-*s : ", MaxNameSize + 3, Abc_ObjName(pObjCo) );
printf( "Delay = %8.2f ", (double)pNode->Match.Delay );
if ( Abc_ObjFaninC0(pObjCo) )
printf( "NEG" );
else
printf( "POS" );
printf( "\n" );
}
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////