diff options
Diffstat (limited to 'src/map/scl/sclLoad.c')
-rw-r--r-- | src/map/scl/sclLoad.c | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/src/map/scl/sclLoad.c b/src/map/scl/sclLoad.c new file mode 100644 index 00000000..686000a9 --- /dev/null +++ b/src/map/scl/sclLoad.c @@ -0,0 +1,180 @@ +/**CFile**************************************************************** + + FileName [sclLoad.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Standard-cell library representation.] + + Synopsis [Wire/gate load computations.] + + Author [Alan Mishchenko, Niklas Een] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - August 24, 2012.] + + Revision [$Id: sclLoad.c,v 1.0 2012/08/24 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "sclInt.h" +#include "sclMan.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Returns estimated wire capacitances for each fanout count.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Flt_t * Abc_SclFindWireCaps( SC_Man * p ) +{ + Vec_Flt_t * vCaps = NULL; + SC_WireLoad * pWL = NULL; + int i, Entry, EntryMax; + float EntryPrev, EntryCur; + p->pWLoadUsed = NULL; + if ( p->pLib->default_wire_load_sel && strlen(p->pLib->default_wire_load_sel) ) + { + float Area; + SC_WireLoadSel * pWLS = NULL; + Vec_PtrForEachEntry( SC_WireLoadSel *, p->pLib->vWireLoadSels, pWLS, i ) + if ( !strcmp(pWLS->pName, p->pLib->default_wire_load_sel) ) + break; + if ( i == Vec_PtrSize(p->pLib->vWireLoadSels) ) + { + Abc_Print( -1, "Cannot find wire load selection model \"%s\".\n", p->pLib->default_wire_load_sel ); + exit(1); + } + Area = (float)Abc_SclGetTotalArea( p ); + for ( i = 0; i < Vec_FltSize(pWLS->vAreaFrom); i++) + if ( Area >= Vec_FltEntry(pWLS->vAreaFrom, i) && Area < Vec_FltEntry(pWLS->vAreaTo, i) ) + { + p->pWLoadUsed = (char *)Vec_PtrEntry(pWLS->vWireLoadModel, i); + break; + } + if ( i == Vec_FltSize(pWLS->vAreaFrom) ) + p->pWLoadUsed = (char *)Vec_PtrEntryLast(pWLS->vWireLoadModel); + } + else if ( p->pLib->default_wire_load && strlen(p->pLib->default_wire_load) ) + p->pWLoadUsed = p->pLib->default_wire_load; + else + { + Abc_Print( 0, "No wire model given.\n" ); + return NULL; + } + // Get the actual table and reformat it for 'wire_cap' output: + assert( p->pWLoadUsed != NULL ); + Vec_PtrForEachEntry( SC_WireLoad *, p->pLib->vWireLoads, pWL, i ) + if ( !strcmp(pWL->pName, p->pWLoadUsed) ) + break; + if ( i == Vec_PtrSize(p->pLib->vWireLoadSels) ) + { + Abc_Print( -1, "Cannot find wire load model \"%s\".\n", p->pWLoadUsed ); + exit(1); + } + // find the biggest fanout + EntryMax = 0; + Vec_IntForEachEntry( pWL->vFanout, Entry, i ) + EntryMax = Abc_MaxInt( EntryMax, Entry ); + // create the array + vCaps = Vec_FltStart( EntryMax + 1 ); + Vec_IntForEachEntry( pWL->vFanout, Entry, i ) + Vec_FltWriteEntry( vCaps, Entry, Vec_FltEntry(pWL->vLen, i) * pWL->cap ); + // reformat + EntryPrev = 0; + Vec_FltForEachEntry( vCaps, EntryCur, i ) + { + if ( EntryCur ) + EntryPrev = EntryCur; + else + Vec_FltWriteEntry( vCaps, i, EntryPrev ); + } + return vCaps; +} + +/**Function************************************************************* + + Synopsis [Computes/updates load for all nodes in the network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_SclComputeLoad( SC_Man * p ) +{ + Vec_Flt_t * vWireCaps; + Abc_Obj_t * pObj, * pFanin; + int i, k; + // clear load storage + Abc_NtkForEachObj( p->pNtk, pObj, i ) + { + SC_Pair * pLoad = Abc_SclObjLoad( p, pObj ); + pLoad->rise = pLoad->fall = 0.0; + } + // add cell load + Abc_NtkForEachNode( p->pNtk, pObj, i ) + { + SC_Cell * pCell = Abc_SclObjCell( p, pObj ); + Abc_ObjForEachFanin( pObj, pFanin, k ) + { + SC_Pair * pLoad = Abc_SclObjLoad( p, pFanin ); + SC_Pin * pPin = SC_CellPin( pCell, k ); + pLoad->rise += pPin->rise_cap; + pLoad->fall += pPin->fall_cap; + } + } + // add wire load + vWireCaps = Abc_SclFindWireCaps( p ); + if ( vWireCaps ) + { + Abc_NtkForEachNode( p->pNtk, pObj, i ) + { + SC_Pair * pLoad = Abc_SclObjLoad( p, pObj ); + k = Abc_MinInt( Vec_FltSize(vWireCaps)-1, Abc_ObjFanoutNum(pObj) ); + pLoad->rise += Vec_FltEntry(vWireCaps, k); + pLoad->fall += Vec_FltEntry(vWireCaps, k); + } + } + Vec_FltFree( vWireCaps ); +} +void Abc_SclUpdateLoad( SC_Man * p, Abc_Obj_t * pObj, SC_Cell * pOld, SC_Cell * pNew ) +{ + Abc_Obj_t * pFanin; + int k; + Abc_ObjForEachFanin( pObj, pFanin, k ) + { + SC_Pair * pLoad = Abc_SclObjLoad( p, pFanin ); + SC_Pin * pPinOld = SC_CellPin( pOld, k ); + SC_Pin * pPinNew = SC_CellPin( pNew, k ); + pLoad->rise += pPinNew->rise_cap - pPinOld->rise_cap; + pLoad->fall += pPinNew->fall_cap - pPinOld->fall_cap; + } +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + |