diff options
Diffstat (limited to 'src/base/seq/seqMapIter.c')
-rw-r--r-- | src/base/seq/seqMapIter.c | 623 |
1 files changed, 0 insertions, 623 deletions
diff --git a/src/base/seq/seqMapIter.c b/src/base/seq/seqMapIter.c deleted file mode 100644 index 30333cea..00000000 --- a/src/base/seq/seqMapIter.c +++ /dev/null @@ -1,623 +0,0 @@ -/**CFile**************************************************************** - - FileName [seqMapIter.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Construction and manipulation of sequential AIGs.] - - Synopsis [Iterative delay computation in SC mapping/retiming package.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: seqMapIter.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "seqInt.h" -#include "main.h" -#include "mio.h" -#include "mapperInt.h" - -// the internal procedures -static float Seq_MapRetimeDelayLagsInternal( Abc_Ntk_t * pNtk, int fVerbose ); -static float Seq_MapRetimeSearch_rec( Abc_Ntk_t * pNtk, float FiMin, float FiMax, float Delta, int fVerbose ); -static int Seq_MapRetimeForPeriod( Abc_Ntk_t * pNtk, float Fi, int fVerbose ); -static int Seq_MapNodeUpdateLValue( Abc_Obj_t * pObj, float Fi, float DelayInv ); -static float Seq_MapCollectNode_rec( Abc_Obj_t * pAnd, float FiBest, Vec_Ptr_t * vMapping, Vec_Vec_t * vMapCuts ); -static void Seq_MapCanonicizeTruthTables( Abc_Ntk_t * pNtk ); - -extern Cut_Man_t * Abc_NtkSeqCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Computes the retiming lags for FPGA mapping.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Seq_MapRetimeDelayLags( Abc_Ntk_t * pNtk, int fVerbose ) -{ - Abc_Seq_t * p = pNtk->pManFunc; - Cut_Params_t Params, * pParams = &Params; - Abc_Obj_t * pObj; - float TotalArea; - int i, clk; - - // set defaults for cut computation - memset( pParams, 0, sizeof(Cut_Params_t) ); - pParams->nVarsMax = p->nVarsMax; // the max cut size ("k" of the k-feasible cuts) - pParams->nKeepMax = 1000; // the max number of cuts kept at a node - pParams->fTruth = 1; // compute truth tables - pParams->fFilter = 1; // filter dominated cuts - pParams->fSeq = 1; // compute sequential cuts - pParams->fVerbose = fVerbose; // the verbosiness flag - - // compute the cuts -clk = clock(); - p->pCutMan = Abc_NtkSeqCuts( pNtk, pParams ); -p->timeCuts = clock() - clk; - if ( fVerbose ) - Cut_ManPrintStats( p->pCutMan ); - - // compute canonical forms of the truth tables of the cuts - Seq_MapCanonicizeTruthTables( pNtk ); - - // compute area flows -// Seq_MapComputeAreaFlows( pNtk, fVerbose ); - - // compute the delays -clk = clock(); - p->FiBestFloat = Seq_MapRetimeDelayLagsInternal( pNtk, fVerbose ); - if ( p->FiBestFloat == 0.0 ) - return 0; -p->timeDelay = clock() - clk; -/* - { - FILE * pTable; - pTable = fopen( "stats.txt", "a+" ); - fprintf( pTable, "%s ", pNtk->pName ); - fprintf( pTable, "%.2f ", p->FiBestFloat ); - fprintf( pTable, "%.2f ", (float)(p->timeCuts)/(float)(CLOCKS_PER_SEC) ); - fprintf( pTable, "%.2f ", (float)(p->timeDelay)/(float)(CLOCKS_PER_SEC) ); - fprintf( pTable, "\n" ); - fclose( pTable ); - } -*/ - // clean the marks - Abc_NtkForEachObj( pNtk, pObj, i ) - assert( !pObj->fMarkA && !pObj->fMarkB ); - - // collect the nodes and cuts used in the mapping - p->vMapAnds = Vec_PtrAlloc( 1000 ); - p->vMapCuts = Vec_VecAlloc( 1000 ); - TotalArea = 0.0; - Abc_NtkForEachPo( pNtk, pObj, i ) - TotalArea += Seq_MapCollectNode_rec( Abc_ObjChild0(pObj), p->FiBestFloat, p->vMapAnds, p->vMapCuts ); - - // clean the marks - Abc_NtkForEachObj( pNtk, pObj, i ) - pObj->fMarkA = pObj->fMarkB = 0; - - if ( fVerbose ) - printf( "Total area = %6.2f.\n", TotalArea ); - - // remove the cuts - Cut_ManStop( p->pCutMan ); - p->pCutMan = NULL; - return 1; -} - -/**Function************************************************************* - - Synopsis [Retimes AIG for optimal delay using Pan's algorithm.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -float Seq_MapRetimeDelayLagsInternal( Abc_Ntk_t * pNtk, int fVerbose ) -{ - Abc_Seq_t * p = pNtk->pManFunc; - Abc_Obj_t * pNode; - float FiMax, FiBest, Delta; - int i, RetValue; - char NodeLag; - - assert( Abc_NtkIsSeq( pNtk ) ); - - // assign the accuracy for min-period computation - Delta = Mio_LibraryReadDelayNand2Max(Abc_FrameReadLibGen()); - if ( Delta == 0.0 ) - { - Delta = Mio_LibraryReadDelayAnd2Max(Abc_FrameReadLibGen()); - if ( Delta == 0.0 ) - { - printf( "Cannot retime/map if the library does not have NAND2 or AND2.\n" ); - return 0.0; - } - } - - // get the upper bound on the clock period - FiMax = Delta * (5 + Seq_NtkLevelMax(pNtk)); - Delta /= 2; - - // make sure this clock period is feasible - if ( !Seq_MapRetimeForPeriod( pNtk, FiMax, fVerbose ) ) - { - Vec_StrFill( p->vLags, p->nSize, 0 ); - Vec_StrFill( p->vLagsN, p->nSize, 0 ); - printf( "Error: The upper bound on the clock period cannot be computed.\n" ); - printf( "The reason for this error may be the presence in the circuit of logic\n" ); - printf( "that is not reachable from the PIs. Mapping/retiming is not performed.\n" ); - return 0; - } - - // search for the optimal clock period between 0 and nLevelMax - FiBest = Seq_MapRetimeSearch_rec( pNtk, 0.0, FiMax, Delta, fVerbose ); - - // recompute the best l-values - RetValue = Seq_MapRetimeForPeriod( pNtk, FiBest, fVerbose ); - assert( RetValue ); - - // fix the problem with non-converged delays - Abc_AigForEachAnd( pNtk, pNode, i ) - { - if ( Seq_NodeGetLValueP(pNode) < -ABC_INFINITY/2 ) - Seq_NodeSetLValueP( pNode, 0 ); - if ( Seq_NodeGetLValueN(pNode) < -ABC_INFINITY/2 ) - Seq_NodeSetLValueN( pNode, 0 ); - } - - // write the retiming lags for both phases of each node - Vec_StrFill( p->vLags, p->nSize, 0 ); - Vec_StrFill( p->vLagsN, p->nSize, 0 ); - Abc_AigForEachAnd( pNtk, pNode, i ) - { - NodeLag = Seq_NodeComputeLagFloat( Seq_NodeGetLValueP(pNode), FiBest ); - Seq_NodeSetLag( pNode, NodeLag ); - NodeLag = Seq_NodeComputeLagFloat( Seq_NodeGetLValueN(pNode), FiBest ); - Seq_NodeSetLagN( pNode, NodeLag ); -//printf( "%6d=(%d,%d) ", pNode->Id, Seq_NodeGetLag(pNode), Seq_NodeGetLagN(pNode) ); -// if ( Seq_NodeGetLag(pNode) != Seq_NodeGetLagN(pNode) ) -// { -//printf( "%6d=(%d,%d) ", pNode->Id, Seq_NodeGetLag(pNode), Seq_NodeGetLagN(pNode) ); -// } - } -//printf( "\n\n" ); - - // print the result - if ( fVerbose ) - printf( "The best clock period after mapping/retiming is %6.2f.\n", FiBest ); - return FiBest; -} - -/**Function************************************************************* - - Synopsis [Performs binary search for the optimal clock period.] - - Description [Assumes that FiMin is infeasible while FiMax is feasible.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -float Seq_MapRetimeSearch_rec( Abc_Ntk_t * pNtk, float FiMin, float FiMax, float Delta, int fVerbose ) -{ - float Median; - assert( FiMin < FiMax ); - if ( FiMin + Delta >= FiMax ) - return FiMax; - Median = FiMin + (FiMax - FiMin)/2; - if ( Seq_MapRetimeForPeriod( pNtk, Median, fVerbose ) ) - return Seq_MapRetimeSearch_rec( pNtk, FiMin, Median, Delta, fVerbose ); // Median is feasible - else - return Seq_MapRetimeSearch_rec( pNtk, Median, FiMax, Delta, fVerbose ); // Median is infeasible -} - -/**Function************************************************************* - - Synopsis [Returns 1 if retiming with this clock period is feasible.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Seq_MapRetimeForPeriod( Abc_Ntk_t * pNtk, float Fi, int fVerbose ) -{ - Abc_Seq_t * p = pNtk->pManFunc; - Abc_Obj_t * pObj; - float DelayInv = Mio_LibraryReadDelayInvMax(Abc_FrameReadLibGen()); - 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_Float2Int( (float)-ABC_INFINITY ) ); - Vec_IntFill( p->vLValuesN, p->nSize, Abc_Float2Int( (float)-ABC_INFINITY ) ); - Vec_StrFill( p->vUses, p->nSize, 0 ); - - // set l-values of constants and PIs - pObj = Abc_NtkObj( pNtk, 0 ); - Seq_NodeSetLValueP( pObj, 0.0 ); - Seq_NodeSetLValueN( pObj, 0.0 ); - Abc_NtkForEachPi( pNtk, pObj, i ) - { - Seq_NodeSetLValueP( pObj, 0.0 ); - Seq_NodeSetLValueN( pObj, DelayInv ); - } - - // update all values iteratively - Counter = 0; - for ( c = 0; c < p->nMaxIters; c++ ) - { - fChange = 0; - Abc_AigForEachAnd( pNtk, pObj, i ) - { - Counter++; - RetValue = Seq_MapNodeUpdateLValue( pObj, Fi, DelayInv ); - if ( RetValue == SEQ_UPDATE_YES ) - fChange = 1; - } - Abc_NtkForEachPo( pNtk, pObj, i ) - { - RetValue = Seq_MapNodeUpdateLValue( pObj, Fi, DelayInv ); - if ( RetValue == SEQ_UPDATE_FAIL ) - break; - } - if ( RetValue == SEQ_UPDATE_FAIL ) - break; - if ( fChange == 0 ) - break; -//printf( "\n\n" ); - } - if ( c == p->nMaxIters ) - { - RetValue = SEQ_UPDATE_FAIL; - pReason = "(timeout)"; - } - else - c++; - - // report the results - if ( fVerbose ) - { - if ( RetValue == SEQ_UPDATE_FAIL ) - printf( "Period = %6.2f. Iterations = %3d. Updates = %10d. Infeasible %s\n", Fi, c, Counter, pReason ); - else - printf( "Period = %6.2f. Iterations = %3d. Updates = %10d. Feasible\n", Fi, c, Counter ); - } - return RetValue != SEQ_UPDATE_FAIL; -} - - - -/**Function************************************************************* - - Synopsis [Computes the l-value of the cut.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -float Seq_MapSuperGetArrival( Abc_Obj_t * pObj, float Fi, Seq_Match_t * pMatch, float DelayMax ) -{ - Abc_Seq_t * p = pObj->pNtk->pManFunc; - Abc_Obj_t * pFanin; - float lValueCur, lValueMax; - int i; - lValueMax = -ABC_INFINITY; - for ( i = pMatch->pCut->nLeaves - 1; i >= 0; i-- ) - { - // get the arrival time of the fanin - pFanin = Abc_NtkObj( pObj->pNtk, pMatch->pCut->pLeaves[i] >> 8 ); - if ( pMatch->uPhase & (1 << i) ) - lValueCur = Seq_NodeGetLValueN(pFanin) - Fi * (pMatch->pCut->pLeaves[i] & 255); - else - lValueCur = Seq_NodeGetLValueP(pFanin) - Fi * (pMatch->pCut->pLeaves[i] & 255); - // add the arrival time of this pin - if ( lValueMax < lValueCur + pMatch->pSuper->tDelaysR[i].Worst ) - lValueMax = lValueCur + pMatch->pSuper->tDelaysR[i].Worst; - if ( lValueMax < lValueCur + pMatch->pSuper->tDelaysF[i].Worst ) - lValueMax = lValueCur + pMatch->pSuper->tDelaysF[i].Worst; - if ( lValueMax > DelayMax + p->fEpsilon ) - return ABC_INFINITY; - } - return lValueMax; -} - -/**Function************************************************************* - - Synopsis [Computes the l-value of the cut.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -float Seq_MapNodeComputeCut( Abc_Obj_t * pObj, Cut_Cut_t * pCut, int fCompl, float Fi, Seq_Match_t * pMatchBest ) -{ - Seq_Match_t Match, * pMatchCur = &Match; - Abc_Seq_t * p = pObj->pNtk->pManFunc; - Map_Super_t * pSuper, * pSuperList; - unsigned uCanon[2]; - float lValueBest, lValueCur; - int i; - assert( pCut->nLeaves < 6 ); - // get the canonical truth table of this cut - uCanon[0] = uCanon[1] = (fCompl? pCut->uCanon0 : pCut->uCanon1); - if ( uCanon[0] == 0 || ~uCanon[0] == 0 ) - { - if ( pMatchBest ) - { - memset( pMatchBest, 0, sizeof(Seq_Match_t) ); - pMatchBest->pCut = pCut; - } - return (float)0.0; - } - // match the given phase of the cut - pSuperList = Map_SuperTableLookupC( p->pSuperLib, uCanon ); - // compute the arrival times of each supergate - lValueBest = ABC_INFINITY; - for ( pSuper = pSuperList; pSuper; pSuper = pSuper->pNext ) - { - // create the match - pMatchCur->pCut = pCut; - pMatchCur->pSuper = pSuper; - // get the phase - for ( i = 0; i < (int)pSuper->nPhases; i++ ) - { - pMatchCur->uPhase = (fCompl? pCut->Num0 : pCut->Num1) ^ pSuper->uPhases[i]; - // find the arrival time of this match - lValueCur = Seq_MapSuperGetArrival( pObj, Fi, pMatchCur, lValueBest ); - if ( lValueBest > lValueCur )//&& lValueCur > -ABC_INFINITY/2 ) - { - lValueBest = lValueCur; - if ( pMatchBest ) - *pMatchBest = *pMatchCur; - } - } - } -// assert( lValueBest < ABC_INFINITY/2 ); - return lValueBest; -} - -/**Function************************************************************* - - Synopsis [Computes the l-value of the node.] - - Description [The node can be internal or a PO.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -float Seq_MapNodeComputePhase( Abc_Obj_t * pObj, int fCompl, float Fi, Seq_Match_t * pMatchBest ) -{ - Seq_Match_t Match, * pMatchCur = &Match; - Cut_Cut_t * pList, * pCut; - float lValueBest, lValueCut; - // get the list of cuts - pList = Abc_NodeReadCuts( Seq_NodeCutMan(pObj), pObj ); - // get the arrival time of the best non-trivial cut - lValueBest = ABC_INFINITY; - for ( pCut = pList->pNext; pCut; pCut = pCut->pNext ) - { - lValueCut = Seq_MapNodeComputeCut( pObj, pCut, fCompl, Fi, pMatchBest? pMatchCur : NULL ); - if ( lValueBest > lValueCut ) - { - lValueBest = lValueCut; - if ( pMatchBest ) - *pMatchBest = *pMatchCur; - } - } -// assert( lValueBest < ABC_INFINITY/2 ); - return lValueBest; -} - -/**Function************************************************************* - - Synopsis [Computes the l-value of the node.] - - Description [The node can be internal or a PO.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Seq_MapNodeUpdateLValue( Abc_Obj_t * pObj, float Fi, float DelayInv ) -{ - Abc_Seq_t * p = pObj->pNtk->pManFunc; - Cut_Cut_t * pList; - char Use; - float lValueOld0, lValueOld1, lValue0, lValue1, lValue; - assert( !Abc_ObjIsPi(pObj) ); - assert( Abc_ObjFaninNum(pObj) > 0 ); - // consider the case of the PO - if ( Abc_ObjIsPo(pObj) ) - { - if ( Abc_ObjFaninC0(pObj) ) // PO requires negative polarity - lValue = Seq_NodeGetLValueN(Abc_ObjFanin0(pObj)) - Fi * Seq_ObjFaninL0(pObj); - else - lValue = Seq_NodeGetLValueP(Abc_ObjFanin0(pObj)) - Fi * Seq_ObjFaninL0(pObj); - return (lValue > Fi + p->fEpsilon)? SEQ_UPDATE_FAIL : SEQ_UPDATE_NO; - } - // get the cuts - pList = Abc_NodeReadCuts( Seq_NodeCutMan(pObj), pObj ); - if ( pList == NULL ) - return SEQ_UPDATE_NO; - // compute the arrival time of both phases - lValue0 = Seq_MapNodeComputePhase( pObj, 1, Fi, NULL ); - lValue1 = Seq_MapNodeComputePhase( pObj, 0, Fi, NULL ); - // consider the case when negative phase is too slow - if ( lValue0 > lValue1 + DelayInv + p->fEpsilon ) - lValue0 = lValue1 + DelayInv, Use = 2; - else if ( lValue1 > lValue0 + DelayInv + p->fEpsilon ) - lValue1 = lValue0 + DelayInv, Use = 1; - else - Use = 3; - // set the uses of the phases - Seq_NodeSetUses( pObj, Use ); - // get the old arrival times - lValueOld0 = Seq_NodeGetLValueN(pObj); - lValueOld1 = Seq_NodeGetLValueP(pObj); - // compare - if ( lValue0 <= lValueOld0 + p->fEpsilon && lValue1 <= lValueOld1 + p->fEpsilon ) - return SEQ_UPDATE_NO; - assert( lValue0 < ABC_INFINITY/2 ); - assert( lValue1 < ABC_INFINITY/2 ); - // update the values - if ( lValue0 > lValueOld0 + p->fEpsilon ) - Seq_NodeSetLValueN( pObj, lValue0 ); - if ( lValue1 > lValueOld1 + p->fEpsilon ) - Seq_NodeSetLValueP( pObj, lValue1 ); -//printf( "%6d=(%4.2f,%4.2f) ", pObj->Id, Seq_NodeGetLValueP(pObj), Seq_NodeGetLValueN(pObj) ); - return SEQ_UPDATE_YES; -} - - - -/**Function************************************************************* - - Synopsis [Derives the parameters of the best mapping/retiming for one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -float Seq_MapCollectNode_rec( Abc_Obj_t * pAnd, float FiBest, Vec_Ptr_t * vMapping, Vec_Vec_t * vMapCuts ) -{ - Seq_Match_t * pMatch; - Abc_Obj_t * pFanin; - int k, fCompl, Use; - float AreaInv = Mio_LibraryReadAreaInv(Abc_FrameReadLibGen()); - float Area; - - // get the polarity of the node - fCompl = Abc_ObjIsComplement(pAnd); - pAnd = Abc_ObjRegular(pAnd); - - // skip visited nodes - if ( !fCompl ) - { // need the positive polarity - if ( pAnd->fMarkA ) - return 0.0; - pAnd->fMarkA = 1; - } - else - { // need the negative polarity - if ( pAnd->fMarkB ) - return 0.0; - pAnd->fMarkB = 1; - } - - // skip if this is a PI or a constant - if ( !Abc_AigNodeIsAnd(pAnd) ) - { - if ( Abc_ObjIsPi(pAnd) && fCompl ) - return AreaInv; - return 0.0; - } - - // check the uses of this node - Use = Seq_NodeGetUses( pAnd ); - if ( !fCompl && Use == 1 ) // the pos phase is required; only the neg phase is used - { - Area = Seq_MapCollectNode_rec( Abc_ObjNot(pAnd), FiBest, vMapping, vMapCuts ); - return Area + AreaInv; - } - if ( fCompl && Use == 2 ) // the neg phase is required; only the pos phase is used - { - Area = Seq_MapCollectNode_rec( pAnd, FiBest, vMapping, vMapCuts ); - return Area + AreaInv; - } - // both phases are used; the needed one can be selected - - // get the best match - pMatch = ALLOC( Seq_Match_t, 1 ); - memset( pMatch, 1, sizeof(Seq_Match_t) ); - Seq_MapNodeComputePhase( pAnd, fCompl, FiBest, pMatch ); - pMatch->pAnd = pAnd; - pMatch->fCompl = fCompl; - pMatch->fCutInv = pMatch->pCut->fCompl; - pMatch->PolUse = Use; - - // call for the fanin cuts - Area = pMatch->pSuper? pMatch->pSuper->Area : (float)0.0; - for ( k = 0; k < (int)pMatch->pCut->nLeaves; k++ ) - { - pFanin = Abc_NtkObj( pAnd->pNtk, pMatch->pCut->pLeaves[k] >> 8 ); - if ( pMatch->uPhase & (1 << k) ) - pFanin = Abc_ObjNot( pFanin ); - Area += Seq_MapCollectNode_rec( pFanin, FiBest, vMapping, vMapCuts ); - } - - // add this node - Vec_PtrPush( vMapping, pMatch ); - for ( k = 0; k < (int)pMatch->pCut->nLeaves; k++ ) - Vec_VecPush( vMapCuts, Vec_PtrSize(vMapping)-1, (void *)pMatch->pCut->pLeaves[k] ); - - // the cut will become unavailable when the cuts are deallocated - pMatch->pCut = NULL; - - return Area; -} - -/**Function************************************************************* - - Synopsis [Computes the canonical versions of the truth tables.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Seq_MapCanonicizeTruthTables( Abc_Ntk_t * pNtk ) -{ - Abc_Obj_t * pObj; - Cut_Cut_t * pCut, * pList; - int i; - Abc_AigForEachAnd( pNtk, pObj, i ) - { - pList = Abc_NodeReadCuts( Seq_NodeCutMan(pObj), pObj ); - if ( pList == NULL ) - continue; - for ( pCut = pList->pNext; pCut; pCut = pCut->pNext ) - Cut_TruthNCanonicize( pCut ); - } -} - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// |