summaryrefslogtreecommitdiffstats
path: root/src/map/scl/sclLoad.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/scl/sclLoad.c')
-rw-r--r--src/map/scl/sclLoad.c180
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
+