mirror of https://github.com/YosysHQ/abc.git
263 lines
8.2 KiB
C
263 lines
8.2 KiB
C
/**CFile****************************************************************
|
|
|
|
FileName [fpgaTime.c]
|
|
|
|
PackageName [MVSIS 1.3: Multi-valued logic synthesis system.]
|
|
|
|
Synopsis [Technology mapping for variable-size-LUT FPGAs.]
|
|
|
|
Author [MVSIS Group]
|
|
|
|
Affiliation [UC Berkeley]
|
|
|
|
Date [Ver. 2.0. Started - August 18, 2004.]
|
|
|
|
Revision [$Id: fpgaTime.c,v 1.1 2005/01/23 06:59:42 alanmi Exp $]
|
|
|
|
***********************************************************************/
|
|
|
|
#include "fpgaInt.h"
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// DECLARATIONS ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// FUNCTION DEFINITIONS ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Computes the arrival times of the cut.]
|
|
|
|
Description [Computes the maximum arrival time of the cut leaves and
|
|
adds the delay of the LUT.]
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
float Fpga_TimeCutComputeArrival( Fpga_Man_t * pMan, Fpga_Cut_t * pCut )
|
|
{
|
|
int i;
|
|
float tArrival;
|
|
tArrival = -FPGA_FLOAT_LARGE;
|
|
for ( i = 0; i < pCut->nLeaves; i++ )
|
|
if ( tArrival < pCut->ppLeaves[i]->pCutBest->tArrival )
|
|
tArrival = pCut->ppLeaves[i]->pCutBest->tArrival;
|
|
tArrival += pMan->pLutLib->pLutDelays[pCut->nLeaves];
|
|
return tArrival;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Computes the arrival times of the cut recursively.]
|
|
|
|
Description [When computing the arrival time for the previously unused
|
|
cuts, their arrival time may be incorrect because their fanins have
|
|
incorrect arrival time. This procedure is called to fix this problem.]
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
float Fpga_TimeCutComputeArrival_rec( Fpga_Man_t * pMan, Fpga_Cut_t * pCut )
|
|
{
|
|
int i;
|
|
for ( i = 0; i < pCut->nLeaves; i++ )
|
|
if ( pCut->ppLeaves[i]->nRefs == 0 )
|
|
Fpga_TimeCutComputeArrival_rec( pMan, pCut->ppLeaves[i]->pCutBest );
|
|
return Fpga_TimeCutComputeArrival( pMan, pCut );
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Computes the maximum arrival times.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
float Fpga_TimeComputeArrivalMax( Fpga_Man_t * p )
|
|
{
|
|
float fRequired;
|
|
int i;
|
|
if ( p->fLatchPaths && p->nLatches == 0 )
|
|
{
|
|
printf( "Delay optimization of latch path is not performed because there is no latches.\n" );
|
|
p->fLatchPaths = 0;
|
|
}
|
|
// get the critical PO arrival time
|
|
fRequired = -FPGA_FLOAT_LARGE;
|
|
if ( p->fLatchPaths )
|
|
{
|
|
for ( i = p->nOutputs - p->nLatches; i < p->nOutputs; i++ )
|
|
{
|
|
if ( Fpga_NodeIsConst(p->pOutputs[i]) )
|
|
continue;
|
|
fRequired = FPGA_MAX( fRequired, Fpga_Regular(p->pOutputs[i])->pCutBest->tArrival );
|
|
// printf( " %5.1f", Fpga_Regular(p->pOutputs[i])->pCutBest->tArrival );
|
|
}
|
|
// printf( "Required latches = %5.1f\n", fRequired );
|
|
}
|
|
else
|
|
{
|
|
for ( i = 0; i < p->nOutputs; i++ )
|
|
{
|
|
if ( Fpga_NodeIsConst(p->pOutputs[i]) )
|
|
continue;
|
|
fRequired = FPGA_MAX( fRequired, Fpga_Regular(p->pOutputs[i])->pCutBest->tArrival );
|
|
// printf( " %5.1f", Fpga_Regular(p->pOutputs[i])->pCutBest->tArrival );
|
|
}
|
|
// printf( "Required outputs = %5.1f\n", fRequired );
|
|
}
|
|
return fRequired;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Computes the required times of all nodes.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Fpga_TimeComputeRequiredGlobal( Fpga_Man_t * p, int fFirstTime )
|
|
{
|
|
p->fRequiredGlo = Fpga_TimeComputeArrivalMax( p );
|
|
// update the required times according to the target
|
|
if ( p->DelayTarget != -1 )
|
|
{
|
|
if ( p->fRequiredGlo > p->DelayTarget + p->fEpsilon )
|
|
{
|
|
if ( fFirstTime )
|
|
printf( "Cannot meet the target required times (%4.2f). Mapping continues anyway.\n", p->DelayTarget );
|
|
}
|
|
else if ( p->fRequiredGlo < p->DelayTarget - p->fEpsilon )
|
|
{
|
|
if ( fFirstTime )
|
|
printf( "Relaxing the required times from (%4.2f) to the target (%4.2f).\n", p->fRequiredGlo, p->DelayTarget );
|
|
p->fRequiredGlo = p->DelayTarget;
|
|
}
|
|
}
|
|
Fpga_TimeComputeRequired( p, p->fRequiredGlo );
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Computes the required times of all nodes.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Fpga_TimeComputeRequired( Fpga_Man_t * p, float fRequired )
|
|
{
|
|
int i;
|
|
// clean the required times and the fanout counts for all nodes
|
|
for ( i = 0; i < p->vAnds->nSize; i++ )
|
|
p->vAnds->pArray[i]->tRequired = FPGA_FLOAT_LARGE;
|
|
// set the required times for the POs
|
|
if ( p->fLatchPaths )
|
|
for ( i = p->nOutputs - p->nLatches; i < p->nOutputs; i++ )
|
|
Fpga_Regular(p->pOutputs[i])->tRequired = fRequired;
|
|
else
|
|
for ( i = 0; i < p->nOutputs; i++ )
|
|
Fpga_Regular(p->pOutputs[i])->tRequired = fRequired;
|
|
// collect nodes reachable from POs in the DFS order through the best cuts
|
|
Fpga_TimePropagateRequired( p, p->vMapping );
|
|
/*
|
|
{
|
|
int Counter = 0;
|
|
for ( i = 0; i < p->vAnds->nSize; i++ )
|
|
if ( p->vAnds->pArray[i]->tRequired > FPGA_FLOAT_LARGE - 100 )
|
|
Counter++;
|
|
printf( "The number of nodes with large required times = %d.\n", Counter );
|
|
}
|
|
*/
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Computes the required times of the given nodes.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Fpga_TimePropagateRequired( Fpga_Man_t * p, Fpga_NodeVec_t * vNodes )
|
|
{
|
|
Fpga_Node_t * pNode, * pChild;
|
|
float fRequired;
|
|
int i, k;
|
|
|
|
// sorts the nodes in the decreasing order of levels
|
|
// Fpga_MappingSortByLevel( p, vNodes, 0 );
|
|
// the nodes area already sorted in Fpga_MappingSetRefsAndArea()
|
|
|
|
// go through the nodes in the reverse topological order
|
|
for ( k = 0; k < vNodes->nSize; k++ )
|
|
{
|
|
pNode = vNodes->pArray[k];
|
|
if ( !Fpga_NodeIsAnd(pNode) )
|
|
continue;
|
|
// get the required time for children
|
|
fRequired = pNode->tRequired - p->pLutLib->pLutDelays[pNode->pCutBest->nLeaves];
|
|
// update the required time of the children
|
|
for ( i = 0; i < pNode->pCutBest->nLeaves; i++ )
|
|
{
|
|
pChild = pNode->pCutBest->ppLeaves[i];
|
|
pChild->tRequired = FPGA_MIN( pChild->tRequired, fRequired );
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Computes the required times of all nodes.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Fpga_TimePropagateArrival( Fpga_Man_t * p )
|
|
{
|
|
Fpga_Node_t * pNode;
|
|
Fpga_Cut_t * pCut;
|
|
int i;
|
|
|
|
// clean the required times and the fanout counts for all nodes
|
|
for ( i = 0; i < p->vAnds->nSize; i++ )
|
|
{
|
|
pNode = p->vAnds->pArray[i];
|
|
for ( pCut = pNode->pCuts->pNext; pCut; pCut = pCut->pNext )
|
|
pCut->tArrival = Fpga_TimeCutComputeArrival( p, pCut );
|
|
}
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// END OF FILE ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|