From ba597f67874f225aae84cc9ab19976538b5dc926 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 1 Sep 2012 13:47:41 -0700 Subject: New package to read/write a subset of Liberty for STA. --- src/map/scl/sclFile.c | 28 +++++++++++++-------------- src/map/scl/sclInt.h | 33 ++++++++++++++++++-------------- src/map/scl/sclLoad.c | 4 ++-- src/map/scl/sclTime.c | 2 +- src/map/scl/sclUtil.c | 52 +++++++++++++++++++++++++++++++++------------------ 5 files changed, 70 insertions(+), 49 deletions(-) (limited to 'src') diff --git a/src/map/scl/sclFile.c b/src/map/scl/sclFile.c index 97990233..dd5dff47 100644 --- a/src/map/scl/sclFile.c +++ b/src/map/scl/sclFile.c @@ -408,7 +408,7 @@ static void Abc_SclWriteLibrary( Vec_Str_t * vOut, SC_Lib * p ) // Write 'wire_load' vector: Vec_StrPutI( vOut, Vec_PtrSize(p->vWireLoads) ); - Vec_PtrForEachEntry( SC_WireLoad *, p->vWireLoads, pWL, i ) + SC_LibForEachWireLoad( p, pWL, i ) { Vec_StrPutS( vOut, pWL->pName ); Vec_StrPutF( vOut, pWL->res ); @@ -424,7 +424,7 @@ static void Abc_SclWriteLibrary( Vec_Str_t * vOut, SC_Lib * p ) // Write 'wire_load_sel' vector: Vec_StrPutI( vOut, Vec_PtrSize(p->vWireLoadSels) ); - Vec_PtrForEachEntry( SC_WireLoadSel *, p->vWireLoadSels, pWLS, i ) + SC_LibForEachWireLoadSel( p, pWLS, i ) { Vec_StrPutS( vOut, pWLS->pName ); Vec_StrPutI( vOut, Vec_FltSize(pWLS->vAreaFrom) ); @@ -438,12 +438,12 @@ static void Abc_SclWriteLibrary( Vec_Str_t * vOut, SC_Lib * p ) // Write 'cells' vector: n_valid_cells = 0; - SC_LitForEachCell( p, pCell, i ) + SC_LibForEachCell( p, pCell, i ) if ( !(pCell->seq || pCell->unsupp) ) n_valid_cells++; Vec_StrPutI( vOut, n_valid_cells ); - SC_LitForEachCell( p, pCell, i ) + SC_LibForEachCell( p, pCell, i ) { if ( pCell->seq || pCell->unsupp ) continue; @@ -456,7 +456,7 @@ static void Abc_SclWriteLibrary( Vec_Str_t * vOut, SC_Lib * p ) Vec_StrPutI( vOut, pCell->n_inputs); Vec_StrPutI( vOut, pCell->n_outputs); - Vec_PtrForEachEntryStop( SC_Pin *, pCell->vPins, pPin, j, pCell->n_inputs ) + SC_CellForEachPinIn( pCell, pPin, j ) { assert(pPin->dir == sc_dir_Input); Vec_StrPutS( vOut, pPin->pName ); @@ -464,7 +464,7 @@ static void Abc_SclWriteLibrary( Vec_Str_t * vOut, SC_Lib * p ) Vec_StrPutF( vOut, pPin->fall_cap ); } - Vec_PtrForEachEntryStart( SC_Pin *, pCell->vPins, pPin, j, pCell->n_inputs ) + SC_CellForEachPinOut( pCell, pPin, j ) { SC_Timings * pRTime; word uWord; @@ -482,7 +482,7 @@ static void Abc_SclWriteLibrary( Vec_Str_t * vOut, SC_Lib * p ) // Write 'rtiming': (pin-to-pin timing tables for this particular output) assert( Vec_PtrSize(pPin->vRTimings) == pCell->n_inputs ); - Vec_PtrForEachEntry( SC_Timings *, pPin->vRTimings, pRTime, k ) + SC_PinForEachRTiming( pPin, pRTime, k ) { Vec_StrPutS( vOut, pRTime->pName ); Vec_StrPutI( vOut, Vec_PtrSize(pRTime->vTimings) ); @@ -618,7 +618,7 @@ static void Abc_SclWriteLibraryText( FILE * s, SC_Lib * p ) fprintf( s, "\n" ); // Write 'wire_load' vector: - Vec_PtrForEachEntry( SC_WireLoad *, p->vWireLoads, pWL, i ) + SC_LibForEachWireLoad( p, pWL, i ) { fprintf( s, " wire_load(\"%s\") {\n", pWL->pName ); fprintf( s, " capacitance : %f;\n", pWL->cap ); @@ -629,7 +629,7 @@ static void Abc_SclWriteLibraryText( FILE * s, SC_Lib * p ) } // Write 'wire_load_sel' vector: - Vec_PtrForEachEntry( SC_WireLoadSel *, p->vWireLoadSels, pWLS, i ) + SC_LibForEachWireLoadSel( p, pWLS, i ) { fprintf( s, " wire_load_selection(\"%s\") {\n", pWLS->pName ); for ( j = 0; j < Vec_FltSize(pWLS->vAreaFrom); j++) @@ -642,11 +642,11 @@ static void Abc_SclWriteLibraryText( FILE * s, SC_Lib * p ) // Write 'cells' vector: n_valid_cells = 0; - SC_LitForEachCell( p, pCell, i ) + SC_LibForEachCell( p, pCell, i ) if ( !(pCell->seq || pCell->unsupp) ) n_valid_cells++; - SC_LitForEachCell( p, pCell, i ) + SC_LibForEachCell( p, pCell, i ) { if ( pCell->seq || pCell->unsupp ) continue; @@ -657,7 +657,7 @@ static void Abc_SclWriteLibraryText( FILE * s, SC_Lib * p ) fprintf( s, " area : %f;\n", pCell->area ); fprintf( s, " drive_strength : %d;\n", pCell->drive_strength ); - Vec_PtrForEachEntryStop( SC_Pin *, pCell->vPins, pPin, j, pCell->n_inputs ) + SC_CellForEachPinIn( pCell, pPin, j ) { assert(pPin->dir == sc_dir_Input); fprintf( s, " pin(%s) {\n", pPin->pName ); @@ -667,7 +667,7 @@ static void Abc_SclWriteLibraryText( FILE * s, SC_Lib * p ) fprintf( s, " }\n" ); } - Vec_PtrForEachEntryStart( SC_Pin *, pCell->vPins, pPin, j, pCell->n_inputs ) + SC_CellForEachPinOut( pCell, pPin, j ) { SC_Timings * pRTime; // word uWord; @@ -683,7 +683,7 @@ static void Abc_SclWriteLibraryText( FILE * s, SC_Lib * p ) // Write 'rtiming': (pin-to-pin timing tables for this particular output) assert( Vec_PtrSize(pPin->vRTimings) == pCell->n_inputs ); - Vec_PtrForEachEntry( SC_Timings *, pPin->vRTimings, pRTime, k ) + SC_PinForEachRTiming( pPin, pRTime, k ) { if ( Vec_PtrSize(pRTime->vTimings) == 1 ) { diff --git a/src/map/scl/sclInt.h b/src/map/scl/sclInt.h index da2569ba..be9b49b0 100644 --- a/src/map/scl/sclInt.h +++ b/src/map/scl/sclInt.h @@ -166,7 +166,7 @@ struct SC_Lib_ Vec_Ptr_t * vWireLoadSels; // NamedSet Vec_Ptr_t * vTempls; // NamedSet Vec_Ptr_t * vCells; // NamedSet - Vec_Ptr_t * vCellOrder; // NamedSet + Vec_Ptr_t * vCellClasses; // NamedSet int * pBins; // hashing gateName -> gateId int nBins; }; @@ -186,12 +186,17 @@ static inline Vec_Wrd_t * SC_CellFunc( SC_Cell * p ) { return SC_C static inline double SC_LibCapFf( SC_Lib * p, double cap ) { return cap * p->unit_cap_fst * pow(10, 15 - p->unit_cap_snd); } static inline double SC_LibTimePs( SC_Lib * p, double time ) { return time * pow(10, 12 - p->unit_time); } -#define SC_LitForEachCell( p, pCell, i ) Vec_PtrForEachEntry( SC_Cell *, p->vCells, pCell, i ) -#define SC_CellForEachPin( p, pPin, i ) Vec_PtrForEachEntry( SC_Pin *, pCell->vPins, pPin, i ) -#define SC_CellForEachPinIn( p, pPin, i ) Vec_PtrForEachEntryStop( SC_Pin *, pCell->vPins, pPin, i, pCell->n_inputs ) -#define SC_CellForEachPinOut( p, pPin, i ) Vec_PtrForEachEntryStart( SC_Pin *, pCell->vPins, pPin, i, pCell->n_inputs ) +#define SC_LibForEachCell( p, pCell, i ) Vec_PtrForEachEntry( SC_Cell *, p->vCells, pCell, i ) +#define SC_LibForEachCellClass( p, pCell, i ) Vec_PtrForEachEntry( SC_Cell *, p->vCellClasses, pCell, i ) +#define SC_LibForEachWireLoad( p, pWL, i ) Vec_PtrForEachEntry( SC_WireLoad *, p->vWireLoads, pWL, i ) +#define SC_LibForEachWireLoadSel( p, pWLS, i ) Vec_PtrForEachEntry( SC_WireLoadSel *, p->vWireLoadSels, pWLS, i ) +#define SC_LibForEachTempl( p, pTempl, i ) Vec_PtrForEachEntry( SC_TableTempl *, p->vTempls, pTempl, i ) +#define SC_CellForEachPin( p, pPin, i ) Vec_PtrForEachEntry( SC_Pin *, p->vPins, pPin, i ) +#define SC_CellForEachPinIn( p, pPin, i ) Vec_PtrForEachEntryStop( SC_Pin *, p->vPins, pPin, i, p->n_inputs ) +#define SC_CellForEachPinOut( p, pPin, i ) Vec_PtrForEachEntryStart( SC_Pin *, p->vPins, pPin, i, p->n_inputs ) +#define SC_RingForEachCell( pRing, pCell, i ) for ( i = 0, pCell = pRing; i == 0 || pCell != pRing; pCell = pCell->pNext, i++ ) +#define SC_PinForEachRTiming( p, pRTime, i ) Vec_PtrForEachEntry( SC_Timings *, p->vRTimings, pRTime, i ) -#define SC_RingForEachCell( pRing, pCell, i ) for ( i = 0, pCell = pRing; i == 0 || pCell != pRing; pCell = pCell->pNext, i++ ) //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// @@ -287,7 +292,7 @@ static inline SC_Lib * Abc_SclLibAlloc() p->vWireLoadSels = Vec_PtrAlloc( 0 ); p->vTempls = Vec_PtrAlloc( 0 ); p->vCells = Vec_PtrAlloc( 0 ); - p->vCellOrder = Vec_PtrAlloc( 0 ); + p->vCellClasses = Vec_PtrAlloc( 0 ); return p; } @@ -357,7 +362,7 @@ static inline void Abc_SclPinFree( SC_Pin * p ) { SC_Timings * pTemp; int i; - Vec_PtrForEachEntry( SC_Timings *, p->vRTimings, pTemp, i ) + SC_PinForEachRTiming( p, pTemp, i ) Abc_SclTimingsFree( pTemp ); Vec_PtrFree( p->vRTimings ); Vec_WrdFree( p->vFunc ); @@ -369,7 +374,7 @@ static inline void Abc_SclCellFree( SC_Cell * p ) { SC_Pin * pTemp; int i; - Vec_PtrForEachEntry( SC_Pin *, p->vPins, pTemp, i ) + SC_CellForEachPin( p, pTemp, i ) Abc_SclPinFree( pTemp ); Vec_PtrFree( p->vPins ); ABC_FREE( p->pName ); @@ -382,19 +387,19 @@ static inline void Abc_SclLibFree( SC_Lib * p ) SC_TableTempl * pTempl; SC_Cell * pCell; int i; - Vec_PtrForEachEntry( SC_WireLoad *, p->vWireLoads, pWL, i ) + SC_LibForEachWireLoad( p, pWL, i ) Abc_SclWireLoadFree( pWL ); Vec_PtrFree( p->vWireLoads ); - Vec_PtrForEachEntry( SC_WireLoadSel *, p->vWireLoadSels, pWLS, i ) + SC_LibForEachWireLoadSel( p, pWLS, i ) Abc_SclWireLoadSelFree( pWLS ); Vec_PtrFree( p->vWireLoadSels ); - Vec_PtrForEachEntry( SC_TableTempl *, p->vTempls, pTempl, i ) + SC_LibForEachTempl( p, pTempl, i ) Abc_SclTableTemplFree( pTempl ); Vec_PtrFree( p->vTempls ); - SC_LitForEachCell( p, pCell, i ) + SC_LibForEachCell( p, pCell, i ) Abc_SclCellFree( pCell ); Vec_PtrFree( p->vCells ); - Vec_PtrFree( p->vCellOrder ); + Vec_PtrFree( p->vCellClasses ); ABC_FREE( p->pName ); ABC_FREE( p->default_wire_load ); ABC_FREE( p->default_wire_load_sel ); diff --git a/src/map/scl/sclLoad.c b/src/map/scl/sclLoad.c index 29f73a60..3dd66f6a 100644 --- a/src/map/scl/sclLoad.c +++ b/src/map/scl/sclLoad.c @@ -54,7 +54,7 @@ Vec_Flt_t * Abc_SclFindWireCaps( SC_Man * p ) { float Area; SC_WireLoadSel * pWLS = NULL; - Vec_PtrForEachEntry( SC_WireLoadSel *, p->pLib->vWireLoadSels, pWLS, i ) + SC_LibForEachWireLoadSel( p->pLib, pWLS, i ) if ( !strcmp(pWLS->pName, p->pLib->default_wire_load_sel) ) break; if ( i == Vec_PtrSize(p->pLib->vWireLoadSels) ) @@ -81,7 +81,7 @@ Vec_Flt_t * Abc_SclFindWireCaps( SC_Man * p ) } // Get the actual table and reformat it for 'wire_cap' output: assert( p->pWLoadUsed != NULL ); - Vec_PtrForEachEntry( SC_WireLoad *, p->pLib->vWireLoads, pWL, i ) + SC_LibForEachWireLoad( p->pLib, pWL, i ) if ( !strcmp(pWL->pName, p->pWLoadUsed) ) break; if ( i == Vec_PtrSize(p->pLib->vWireLoadSels) ) diff --git a/src/map/scl/sclTime.c b/src/map/scl/sclTime.c index 5556ec55..c132fe5e 100644 --- a/src/map/scl/sclTime.c +++ b/src/map/scl/sclTime.c @@ -210,7 +210,7 @@ void Abc_SclTimeGate( SC_Man * p, Abc_Obj_t * pObj ) pPin = SC_CellPin( pCell, pCell->n_inputs ); // compute timing using each fanin assert( Vec_PtrSize(pPin->vRTimings) == pCell->n_inputs ); - Vec_PtrForEachEntry( SC_Timings *, pPin->vRTimings, pRTime, k ) + SC_PinForEachRTiming( pPin, pRTime, k ) { assert( Vec_PtrSize(pRTime->vTimings) == 1 ); pTime = (SC_Timing *)Vec_PtrEntry( pRTime->vTimings, 0 ); diff --git a/src/map/scl/sclUtil.c b/src/map/scl/sclUtil.c index b0fdda05..a9b94902 100644 --- a/src/map/scl/sclUtil.c +++ b/src/map/scl/sclUtil.c @@ -67,7 +67,7 @@ void Abc_SclHashCells( SC_Lib * p ) assert( p->nBins == 0 ); p->nBins = Abc_PrimeCudd( 5 * Vec_PtrSize(p->vCells) ); p->pBins = ABC_FALLOC( int, p->nBins ); - SC_LitForEachCell( p, pCell, i ) + SC_LibForEachCell( p, pCell, i ) { pPlace = Abc_SclHashLookup( p, pCell->pName ); assert( *pPlace == -1 ); @@ -106,18 +106,18 @@ void Abc_SclLinkCells( SC_Lib * p ) { SC_Cell * pCell, * pRepr = NULL; int i, k; - assert( Vec_PtrSize(p->vCellOrder) == 0 ); - SC_LitForEachCell( p, pCell, i ) + assert( Vec_PtrSize(p->vCellClasses) == 0 ); + SC_LibForEachCell( p, pCell, i ) { // find gate with the same function - Vec_PtrForEachEntry( SC_Cell *, p->vCellOrder, pRepr, k ) + SC_LibForEachCellClass( p, pRepr, k ) if ( pCell->n_inputs == pRepr->n_inputs && pCell->n_outputs == pRepr->n_outputs && Vec_WrdEqual(SC_CellFunc(pCell), SC_CellFunc(pRepr)) ) break; - if ( k == Vec_PtrSize(p->vCellOrder) ) + if ( k == Vec_PtrSize(p->vCellClasses) ) { - Vec_PtrPush( p->vCellOrder, pCell ); + Vec_PtrPush( p->vCellClasses, pCell ); pCell->pNext = pCell->pPrev = pCell; continue; } @@ -126,9 +126,9 @@ void Abc_SclLinkCells( SC_Lib * p ) pCell->pPrev = pRepr->pPrev; pRepr->pPrev = pCell; } // sort cells by size the then by name - qsort( (void *)Vec_PtrArray(p->vCellOrder), Vec_PtrSize(p->vCellOrder), sizeof(void *), (int(*)(const void *,const void *))Abc_SclCompareCells ); + qsort( (void *)Vec_PtrArray(p->vCellClasses), Vec_PtrSize(p->vCellClasses), sizeof(void *), (int(*)(const void *,const void *))Abc_SclCompareCells ); // sort cell lists - Vec_PtrForEachEntry( SC_Cell *, p->vCellOrder, pRepr, k ) + SC_LibForEachCellClass( p, pRepr, k ) { Vec_Ptr_t * vList = Vec_PtrAlloc( 100 ); SC_RingForEachCell( pRepr, pCell, i ) @@ -146,7 +146,7 @@ void Abc_SclLinkCells( SC_Lib * p ) pCell->Order = i; } // update list - Vec_PtrWriteEntry( p->vCellOrder, k, pRepr ); + Vec_PtrWriteEntry( p->vCellClasses, k, pRepr ); Vec_PtrFree( vList ); } } @@ -154,16 +154,21 @@ void Abc_SclPrintCells( SC_Lib * p ) { extern void Kit_DsdPrintFromTruth( unsigned * pTruth, int nVars ); SC_Cell * pCell, * pRepr; - int i, k; - assert( Vec_PtrSize(p->vCellOrder) > 0 ); + int i, k, j, nLength = 0; + assert( Vec_PtrSize(p->vCellClasses) > 0 ); printf( "Library \"%s\" ", p->pName ); printf( "containing %d cells in %d classes.\n", - Vec_PtrSize(p->vCells), Vec_PtrSize(p->vCellOrder) ); - Vec_PtrForEachEntry( SC_Cell *, p->vCellOrder, pRepr, k ) + Vec_PtrSize(p->vCells), Vec_PtrSize(p->vCellClasses) ); + // find the longest name + SC_LibForEachCellClass( p, pRepr, k ) + SC_RingForEachCell( pRepr, pCell, i ) + nLength = Abc_MaxInt( nLength, strlen(pRepr->pName) ); + // print cells + SC_LibForEachCellClass( p, pRepr, k ) { printf( "Class%3d : ", k ); printf( "Ins = %d ", pRepr->n_inputs ); - printf( "Outs = %d", pRepr->n_outputs ); + printf( "Outs = %d", pRepr->n_outputs ); for ( i = 0; i < pRepr->n_outputs; i++ ) { printf( " " ); @@ -172,10 +177,21 @@ void Abc_SclPrintCells( SC_Lib * p ) printf( "\n" ); SC_RingForEachCell( pRepr, pCell, i ) { - printf( " %3d : ", i+1 ); - printf( "%-12s ", pCell->pName ); - printf( "%2d ", pCell->drive_strength ); - printf( "A =%8.3f", pCell->area ); + printf( " %3d : ", i+1 ); + printf( "%-*s ", nLength, pCell->pName ); + printf( "%2d ", pCell->drive_strength ); + printf( "A =%8.3f D =", pCell->area ); + // print linear approximation + for ( j = 0; j < 3; j++ ) + { + SC_Pin * pPin = SC_CellPin( pCell, pCell->n_inputs ); + if ( Vec_PtrSize(pPin->vRTimings) > 0 ) + { + SC_Timings * pRTime = (SC_Timings *)Vec_PtrEntry( pPin->vRTimings, 0 ); + SC_Timing * pTime = (SC_Timing *)Vec_PtrEntry( pRTime->vTimings, 0 ); + printf( "%7.3f ", pTime->pCellRise->approx[0][j] ); + } + } printf( "\n" ); } } -- cgit v1.2.3