/**CFile**************************************************************** FileName [sclUtil.c] SystemName [ABC: Logic synthesis and verification system.] PackageName [Standard-cell library representation.] Synopsis [Various utilities.] Author [Alan Mishchenko, Niklas Een] Affiliation [UC Berkeley] Date [Ver. 1.0. Started - August 24, 2012.] Revision [$Id: sclUtil.c,v 1.0 2012/08/24 00:00:00 alanmi Exp $] ***********************************************************************/ #include "sclSize.h" #include "map/mio/mio.h" #include "base/main/main.h" ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Converts pNode->pData gates into array of SC_Lit gate IDs and back.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Abc_SclMioGates2SclGates( SC_Lib * pLib, Abc_Ntk_t * p ) { Abc_Obj_t * pObj; int i, gateId, bufferId; // find buffer if ( Mio_LibraryReadBuf((Mio_Library_t *)p->pManFunc) == NULL ) { printf( "Cannot find buffer in the current library. Quitting.\n" ); return; } bufferId = Abc_SclCellFind( pLib, Mio_GateReadName(Mio_LibraryReadBuf((Mio_Library_t *)p->pManFunc)) ); assert( bufferId >= 0 ); // remap cells assert( p->vGates == NULL ); p->vGates = Vec_IntStartFull( Abc_NtkObjNumMax(p) ); Abc_NtkForEachNodeNotBarBuf1( p, pObj, i ) { gateId = Abc_SclCellFind( pLib, Mio_GateReadName((Mio_Gate_t *)pObj->pData) ); assert( gateId >= 0 ); Vec_IntWriteEntry( p->vGates, i, gateId ); } p->pSCLib = pLib; } void Abc_SclSclGates2MioGates( SC_Lib * pLib, Abc_Ntk_t * p ) { Abc_Obj_t * pObj; SC_Cell * pCell; int i, Counter = 0, CounterAll = 0; assert( p->vGates != NULL ); Abc_NtkForEachNodeNotBarBuf1( p, pObj, i ) { pCell = Abc_SclObjCell(pObj); assert( pCell->n_inputs == Abc_ObjFaninNum(pObj) ); pObj->pData = Mio_LibraryReadGateByName( (Mio_Library_t *)p->pManFunc, pCell->pName, NULL ); Counter += (pObj->pData == NULL); assert( pObj->fMarkA == 0 && pObj->fMarkB == 0 ); CounterAll++; } if ( Counter ) printf( "Could not find %d (out of %d) gates in the current library.\n", Counter, CounterAll ); Vec_IntFreeP( &p->vGates ); p->pSCLib = NULL; } /**Function************************************************************* Synopsis [Transfer gate sizes from AIG without barbufs.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Abc_SclTransferGates( Abc_Ntk_t * pOld, Abc_Ntk_t * pNew ) { Abc_Obj_t * pObj; int i; assert( pOld->nBarBufs2 > 0 ); assert( pNew->nBarBufs2 == 0 ); Abc_NtkForEachNodeNotBarBuf( pOld, pObj, i ) { if ( pObj->pCopy == NULL ) continue; assert( Abc_ObjNtk(pObj->pCopy) == pNew ); pObj->pData = pObj->pCopy->pData; } } /**Function************************************************************* Synopsis [Reports percentage of gates of each size.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ #define ABC_SCL_MAX_SIZE 64 void Abc_SclManPrintGateSizes( SC_Lib * pLib, Abc_Ntk_t * p, Vec_Int_t * vGates ) { Abc_Obj_t * pObj; SC_Cell * pCell; int i, nGates = 0, Counters[ABC_SCL_MAX_SIZE] = {0}; double TotArea = 0, Areas[ABC_SCL_MAX_SIZE] = {0}; Abc_NtkForEachNodeNotBarBuf1( p, pObj, i ) { pCell = SC_LibCell( pLib, Vec_IntEntry(vGates, Abc_ObjId(pObj)) ); assert( pCell->Order < ABC_SCL_MAX_SIZE ); Counters[pCell->Order]++; Areas[pCell->Order] += pCell->area; TotArea += pCell->area; nGates++; } printf( "Total gates = %d. Total area = %.1f\n", nGates, TotArea ); for ( i = 0; i < ABC_SCL_MAX_SIZE; i++ ) { if ( Counters[i] == 0 ) continue; printf( "Cell size = %d. ", i ); printf( "Count = %6d ", Counters[i] ); printf( "(%5.1f %%) ", 100.0 * Counters[i] / nGates ); printf( "Area = %12.1f ", Areas[i] ); printf( "(%5.1f %%) ", 100.0 * Areas[i] / TotArea ); printf( "\n" ); } } void Abc_SclPrintGateSizes( SC_Lib * pLib, Abc_Ntk_t * p ) { Abc_SclMioGates2SclGates( pLib, p ); Abc_SclManPrintGateSizes( pLib, p, p->vGates ); Abc_SclSclGates2MioGates( pLib, p ); Vec_IntFreeP( &p->vGates ); p->pSCLib = NULL; } /**Function************************************************************* Synopsis [Downsizes each gate to its minimium size.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ SC_Cell * Abc_SclFindMaxAreaCell( SC_Cell * pRepr ) { SC_Cell * pCell, * pBest = pRepr; float AreaBest = pRepr->area; int i; SC_RingForEachCell( pRepr, pCell, i ) if ( AreaBest < pCell->area ) { AreaBest = pCell->area; pBest = pCell; } return pBest; } Vec_Int_t * Abc_SclFindMinAreas( SC_Lib * pLib, int fUseMax ) { Vec_Int_t * vMinCells; SC_Cell * pCell, * pRepr = NULL, * pBest = NULL; int i, k; // map each gate in the library into its min/max-size prototype vMinCells = Vec_IntStartFull( Vec_PtrSize(pLib->vCells) ); SC_LibForEachCellClass( pLib, pRepr, i ) { pBest = fUseMax ? Abc_SclFindMaxAreaCell(pRepr) : pRepr; SC_RingForEachCell( pRepr, pCell, k ) Vec_IntWriteEntry( vMinCells, pCell->Id, pBest->Id ); } return vMinCells; } void Abc_SclMinsizePerform( SC_Lib * pLib, Abc_Ntk_t * p, int fUseMax, int fVerbose ) { Vec_Int_t * vMinCells; Abc_Obj_t * pObj; int i, gateId; vMinCells = Abc_SclFindMinAreas( pLib, fUseMax ); Abc_SclMioGates2SclGates( pLib, p ); Abc_NtkForEachNodeNotBarBuf1( p, pObj, i ) { gateId = Vec_IntEntry( p->vGates, i ); assert( gateId >= 0 && gateId < Vec_PtrSize(pLib->vCells) ); gateId = Vec_IntEntry( vMinCells, gateId ); assert( gateId >= 0 && gateId < Vec_PtrSize(pLib->vCells) ); Vec_IntWriteEntry( p->vGates, i, gateId ); } Abc_SclSclGates2MioGates( pLib, p ); Vec_IntFree( vMinCells ); } int Abc_SclCountMinSize( SC_Lib * pLib, Abc_Ntk_t * p, int fUseMax ) { Vec_Int_t * vMinCells; Abc_Obj_t * pObj; int i, gateId, Counter = 0; vMinCells = Abc_SclFindMinAreas( pLib, fUseMax ); Abc_NtkForEachNodeNotBarBuf1( p, pObj, i ) { gateId = Vec_IntEntry( p->vGates, i ); Counter += ( gateId == Vec_IntEntry(vMinCells, gateId) ); } Vec_IntFree( vMinCells ); return Counter; } /**Function************************************************************* Synopsis [Reads timing constraints.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Abc_SclReadTimingConstr( Abc_Frame_t * pAbc, char * pFileName, int fVerbose ) { char Buffer[1000], * pToken; FILE * pFile = fopen( pFileName, "rb" ); while ( fgets( Buffer, 1000, pFile ) ) { pToken = strtok( Buffer, " \t\r\n" ); if ( pToken == NULL ) continue; if ( !strcmp(pToken, "set_driving_cell") ) { Abc_FrameSetDrivingCell( Abc_UtilStrsav(strtok(NULL, " \t\r\n")) ); if ( fVerbose ) printf( "Setting driving cell to be \"%s\".\n", Abc_FrameReadDrivingCell() ); } else if ( !strcmp(pToken, "set_load") ) { Abc_FrameSetMaxLoad( atof(strtok(NULL, " \t\r\n")) ); if ( fVerbose ) printf( "Setting driving cell to be %f.\n", Abc_FrameReadMaxLoad() ); } else printf( "Unrecognized token \"%s\".\n", pToken ); } fclose( pFile ); } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Vec_Int_t * Abc_SclExtractBarBufs( Abc_Ntk_t * pNtk ) { Vec_Int_t * vBufs; Mio_Gate_t * pBuffer; Abc_Obj_t * pObj; int i; pBuffer = Mio_LibraryReadBuf( (Mio_Library_t *)pNtk->pManFunc ); if ( pBuffer == NULL ) { printf( "Cannot find buffer in the current library. Quitting.\n" ); return NULL; } vBufs = Vec_IntAlloc( 100 ); Abc_NtkForEachBarBuf( pNtk, pObj, i ) { assert( pObj->pData == NULL ); pObj->pData = pBuffer; Vec_IntPush( vBufs, i ); } return vBufs; } void Abc_SclInsertBarBufs( Abc_Ntk_t * pNtk, Vec_Int_t * vBufs ) { Abc_Obj_t * pObj; int i; Abc_NtkForEachObjVec( vBufs, pNtk, pObj, i ) pObj->pData = NULL; } //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// ABC_NAMESPACE_IMPL_END