mirror of
https://github.com/YosysHQ/abc.git
synced 2026-09-03 08:25:20 +02:00
Version abc51114
This commit is contained in:
@@ -0,0 +1,226 @@
|
||||
/**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 ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
Reference in New Issue
Block a user