mirror of https://github.com/YosysHQ/abc.git
227 lines
7.1 KiB
C
227 lines
7.1 KiB
C
|
|
/**CFile****************************************************************
|
||
|
|
|
||
|
|
FileName [seqRetIter.c]
|
||
|
|
|
||
|
|
SystemName [ABC: Logic synthesis and verification system.]
|
||
|
|
|
||
|
|
PackageName [Construction and manipulation of sequential AIGs.]
|
||
|
|
|
||
|
|
Synopsis []
|
||
|
|
|
||
|
|
Author [Alan Mishchenko]
|
||
|
|
|
||
|
|
Affiliation [UC Berkeley]
|
||
|
|
|
||
|
|
Date [Ver. 1.0. Started - June 20, 2005.]
|
||
|
|
|
||
|
|
Revision [$Id: seqRetIter.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||
|
|
|
||
|
|
***********************************************************************/
|
||
|
|
|
||
|
|
#include "seqInt.h"
|
||
|
|
|
||
|
|
////////////////////////////////////////////////////////////////////////
|
||
|
|
/// DECLARATIONS ///
|
||
|
|
////////////////////////////////////////////////////////////////////////
|
||
|
|
|
||
|
|
// the internal procedures
|
||
|
|
static int Seq_RetimeSearch_rec( Abc_Ntk_t * pNtk, int FiMin, int FiMax, int fVerbose );
|
||
|
|
static int Seq_RetimeForPeriod( Abc_Ntk_t * pNtk, int Fi, int fVerbose );
|
||
|
|
static int Seq_NodeUpdateLValue( Abc_Obj_t * pObj, int Fi );
|
||
|
|
|
||
|
|
// node status after updating its arrival time
|
||
|
|
enum { SEQ_UPDATE_FAIL, SEQ_UPDATE_NO, SEQ_UPDATE_YES };
|
||
|
|
|
||
|
|
////////////////////////////////////////////////////////////////////////
|
||
|
|
/// FUNCTION DEFINITIONS ///
|
||
|
|
////////////////////////////////////////////////////////////////////////
|
||
|
|
|
||
|
|
/**Function*************************************************************
|
||
|
|
|
||
|
|
Synopsis [Retimes AIG for optimal delay using Pan's algorithm.]
|
||
|
|
|
||
|
|
Description []
|
||
|
|
|
||
|
|
SideEffects []
|
||
|
|
|
||
|
|
SeeAlso []
|
||
|
|
|
||
|
|
***********************************************************************/
|
||
|
|
void Seq_NtkSeqRetimeDelayLags( Abc_Ntk_t * pNtk, int fVerbose )
|
||
|
|
{
|
||
|
|
Abc_Seq_t * p = pNtk->pManFunc;
|
||
|
|
Abc_Obj_t * pNode;
|
||
|
|
int i, FiMax, FiBest, RetValue;
|
||
|
|
|
||
|
|
assert( Abc_NtkIsSeq( pNtk ) );
|
||
|
|
|
||
|
|
// get the upper bound on the clock period
|
||
|
|
// FiMax = Abc_NtkNodeNum(pNtk);
|
||
|
|
FiMax = 0;
|
||
|
|
Abc_AigForEachAnd( pNtk, pNode, i )
|
||
|
|
if ( FiMax < (int)pNode->Level )
|
||
|
|
FiMax = pNode->Level;
|
||
|
|
FiMax += 2;
|
||
|
|
|
||
|
|
// make sure this clock period is feasible
|
||
|
|
assert( Seq_RetimeForPeriod( pNtk, FiMax, fVerbose ) );
|
||
|
|
|
||
|
|
// search for the optimal clock period between 0 and nLevelMax
|
||
|
|
FiBest = Seq_RetimeSearch_rec( pNtk, 0, FiMax, fVerbose );
|
||
|
|
|
||
|
|
// recompute the best LValues
|
||
|
|
RetValue = Seq_RetimeForPeriod( pNtk, FiBest, fVerbose );
|
||
|
|
assert( RetValue );
|
||
|
|
|
||
|
|
// write the retiming lags
|
||
|
|
Vec_StrFill( p->vLags, p->nSize, 0 );
|
||
|
|
Abc_AigForEachAnd( pNtk, pNode, i )
|
||
|
|
Seq_NodeSetLag( pNode, (char)Seq_NodeComputeLag(Seq_NodeGetLValue(pNode), FiBest) );
|
||
|
|
|
||
|
|
// print the result
|
||
|
|
if ( fVerbose )
|
||
|
|
printf( "The best clock period is %3d.\n", FiBest );
|
||
|
|
|
||
|
|
/*
|
||
|
|
printf( "LValues : " );
|
||
|
|
Abc_AigForEachAnd( pNtk, pNode, i )
|
||
|
|
printf( "%d=%d ", i, Seq_NodeGetLValue(pNode) );
|
||
|
|
printf( "\n" );
|
||
|
|
printf( "Lags : " );
|
||
|
|
Abc_AigForEachAnd( pNtk, pNode, i )
|
||
|
|
if ( Vec_StrEntry(p->vLags,i) != 0 )
|
||
|
|
printf( "%d=%d(%d)(%d) ", i, Vec_StrEntry(p->vLags,i), Seq_NodeGetLValue(pNode), Seq_NodeGetLValue(pNode) - FiBest * Vec_StrEntry(p->vLags,i) );
|
||
|
|
printf( "\n" );
|
||
|
|
*/
|
||
|
|
}
|
||
|
|
|
||
|
|
/**Function*************************************************************
|
||
|
|
|
||
|
|
Synopsis [Performs binary search for the optimal clock period.]
|
||
|
|
|
||
|
|
Description [Assumes that FiMin is infeasible while FiMax is feasible.]
|
||
|
|
|
||
|
|
SideEffects []
|
||
|
|
|
||
|
|
SeeAlso []
|
||
|
|
|
||
|
|
***********************************************************************/
|
||
|
|
int Seq_RetimeSearch_rec( Abc_Ntk_t * pNtk, int FiMin, int FiMax, int fVerbose )
|
||
|
|
{
|
||
|
|
int Median;
|
||
|
|
assert( FiMin < FiMax );
|
||
|
|
if ( FiMin + 1 == FiMax )
|
||
|
|
return FiMax;
|
||
|
|
Median = FiMin + (FiMax - FiMin)/2;
|
||
|
|
if ( Seq_RetimeForPeriod( pNtk, Median, fVerbose ) )
|
||
|
|
return Seq_RetimeSearch_rec( pNtk, FiMin, Median, fVerbose ); // Median is feasible
|
||
|
|
else
|
||
|
|
return Seq_RetimeSearch_rec( pNtk, Median, FiMax, fVerbose ); // Median is infeasible
|
||
|
|
}
|
||
|
|
|
||
|
|
/**Function*************************************************************
|
||
|
|
|
||
|
|
Synopsis [Returns 1 if retiming with this clock period is feasible.]
|
||
|
|
|
||
|
|
Description []
|
||
|
|
|
||
|
|
SideEffects []
|
||
|
|
|
||
|
|
SeeAlso []
|
||
|
|
|
||
|
|
***********************************************************************/
|
||
|
|
int Seq_RetimeForPeriod( Abc_Ntk_t * pNtk, int Fi, int fVerbose )
|
||
|
|
{
|
||
|
|
Abc_Seq_t * p = pNtk->pManFunc;
|
||
|
|
Abc_Obj_t * pObj;
|
||
|
|
int i, c, RetValue, fChange, Counter;
|
||
|
|
char * pReason = "";
|
||
|
|
|
||
|
|
// set l-values of all nodes to be minus infinity
|
||
|
|
Vec_IntFill( p->vLValues, p->nSize, -ABC_INFINITY );
|
||
|
|
|
||
|
|
// set l-values for the constant and PIs
|
||
|
|
pObj = Abc_NtkObj( pNtk, 0 );
|
||
|
|
Seq_NodeSetLValue( pObj, 0 );
|
||
|
|
Abc_NtkForEachPi( pNtk, pObj, i )
|
||
|
|
Seq_NodeSetLValue( pObj, 0 );
|
||
|
|
|
||
|
|
// update all values iteratively
|
||
|
|
Counter = 0;
|
||
|
|
for ( c = 0; c < 20; c++ )
|
||
|
|
{
|
||
|
|
fChange = 0;
|
||
|
|
Abc_NtkForEachObj( pNtk, pObj, i )
|
||
|
|
{
|
||
|
|
if ( Abc_ObjIsPi(pObj) )
|
||
|
|
continue;
|
||
|
|
if ( Abc_ObjFaninNum(pObj) == 0 )
|
||
|
|
continue;
|
||
|
|
RetValue = Seq_NodeUpdateLValue( pObj, Fi );
|
||
|
|
Counter++;
|
||
|
|
if ( RetValue == SEQ_UPDATE_FAIL )
|
||
|
|
break;
|
||
|
|
if ( RetValue == SEQ_UPDATE_NO )
|
||
|
|
continue;
|
||
|
|
fChange = 1;
|
||
|
|
}
|
||
|
|
if ( RetValue == SEQ_UPDATE_FAIL )
|
||
|
|
break;
|
||
|
|
if ( fChange == 0 )
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
if ( c == 20 )
|
||
|
|
{
|
||
|
|
RetValue = SEQ_UPDATE_FAIL;
|
||
|
|
pReason = "(timeout)";
|
||
|
|
}
|
||
|
|
|
||
|
|
// report the results
|
||
|
|
if ( fVerbose )
|
||
|
|
{
|
||
|
|
if ( RetValue == SEQ_UPDATE_FAIL )
|
||
|
|
printf( "Period = %3d. Iterations = %3d. Updates = %10d. Infeasible %s\n", Fi, c, Counter, pReason );
|
||
|
|
else
|
||
|
|
printf( "Period = %3d. Iterations = %3d. Updates = %10d. Feasible\n", Fi, c, Counter );
|
||
|
|
}
|
||
|
|
return RetValue != SEQ_UPDATE_FAIL;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**Function*************************************************************
|
||
|
|
|
||
|
|
Synopsis [Computes the l-value of the node.]
|
||
|
|
|
||
|
|
Description [The node can be internal or a PO.]
|
||
|
|
|
||
|
|
SideEffects []
|
||
|
|
|
||
|
|
SeeAlso []
|
||
|
|
|
||
|
|
***********************************************************************/
|
||
|
|
int Seq_NodeUpdateLValue( Abc_Obj_t * pObj, int Fi )
|
||
|
|
{
|
||
|
|
int lValueNew, lValueOld, lValue0, lValue1;
|
||
|
|
assert( !Abc_ObjIsPi(pObj) );
|
||
|
|
assert( Abc_ObjFaninNum(pObj) > 0 );
|
||
|
|
lValue0 = Seq_NodeGetLValue(Abc_ObjFanin0(pObj)) - Fi * Abc_ObjFaninL0(pObj);
|
||
|
|
if ( Abc_ObjIsPo(pObj) )
|
||
|
|
return (lValue0 > Fi)? SEQ_UPDATE_FAIL : SEQ_UPDATE_NO;
|
||
|
|
if ( Abc_ObjFaninNum(pObj) == 2 )
|
||
|
|
lValue1 = Seq_NodeGetLValue(Abc_ObjFanin1(pObj)) - Fi * Abc_ObjFaninL1(pObj);
|
||
|
|
else
|
||
|
|
lValue1 = -ABC_INFINITY;
|
||
|
|
lValueNew = 1 + ABC_MAX( lValue0, lValue1 );
|
||
|
|
lValueOld = Seq_NodeGetLValue(pObj);
|
||
|
|
// if ( lValueNew == lValueOld )
|
||
|
|
if ( lValueNew <= lValueOld )
|
||
|
|
return SEQ_UPDATE_NO;
|
||
|
|
Seq_NodeSetLValue( pObj, lValueNew );
|
||
|
|
return SEQ_UPDATE_YES;
|
||
|
|
}
|
||
|
|
|
||
|
|
////////////////////////////////////////////////////////////////////////
|
||
|
|
/// END OF FILE ///
|
||
|
|
////////////////////////////////////////////////////////////////////////
|
||
|
|
|
||
|
|
|