diff options
Diffstat (limited to 'src/map/mio/mioUtils.c')
-rw-r--r-- | src/map/mio/mioUtils.c | 531 |
1 files changed, 531 insertions, 0 deletions
diff --git a/src/map/mio/mioUtils.c b/src/map/mio/mioUtils.c new file mode 100644 index 00000000..aa373783 --- /dev/null +++ b/src/map/mio/mioUtils.c @@ -0,0 +1,531 @@ +/**CFile**************************************************************** + + FileName [mioUtils.c] + + PackageName [MVSIS 1.3: Multi-valued logic synthesis system.] + + Synopsis [File reading/writing for technology mapping.] + + Author [MVSIS Group] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - September 8, 2003.] + + Revision [$Id: mioUtils.c,v 1.6 2004/09/03 18:02:20 satrajit Exp $] + +***********************************************************************/ + +#include "mioInt.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static void Mio_WriteGate( FILE * pFile, Mio_Gate_t * pGate, int fPrintSops ); +static void Mio_WritePin( FILE * pFile, Mio_Pin_t * pPin ); +static int Mio_DelayCompare( Mio_Gate_t ** ppG1, Mio_Gate_t ** ppG2 ); +static void Mio_DeriveTruthTable_rec( DdNode * bFunc, unsigned uTruthsIn[][2], unsigned uTruthRes[] ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Mio_LibraryDelete( Mio_Library_t * pLib ) +{ + Mio_Gate_t * pGate, * pGate2; + if ( pLib == NULL ) + return; + // free the bindings of nodes to gates from this library for all networks +// Mv_FrameFreeNetworkBindings( Mv_FrameGetGlobalFrame() ); + // free the library + FREE( pLib->pName ); + Mio_LibraryForEachGateSafe( pLib, pGate, pGate2 ) + Mio_GateDelete( pGate ); + Extra_MmFlexStop( pLib->pMmFlex, 0 ); + Vec_StrFree( pLib->vCube ); + if ( pLib->tName2Gate ) + st_free_table( pLib->tName2Gate ); + if ( pLib->dd ) + Cudd_Quit( pLib->dd ); + free( pLib ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Mio_GateDelete( Mio_Gate_t * pGate ) +{ + Mio_Pin_t * pPin, * pPin2; + FREE( pGate->pOutName ); + FREE( pGate->pName ); + FREE( pGate->pForm ); + if ( pGate->bFunc ) + Cudd_RecursiveDeref( pGate->pLib->dd, pGate->bFunc ); + Mio_GateForEachPinSafe( pGate, pPin, pPin2 ) + Mio_PinDelete( pPin ); + free( pGate ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Mio_PinDelete( Mio_Pin_t * pPin ) +{ + FREE( pPin->pName ); + free( pPin ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Mio_Pin_t * Mio_PinDup( Mio_Pin_t * pPin ) +{ + Mio_Pin_t * pPinNew; + + pPinNew = ALLOC( Mio_Pin_t, 1 ); + *pPinNew = *pPin; + pPinNew->pName = (pPinNew->pName ? util_strsav(pPinNew->pName) : NULL); + pPinNew->pNext = NULL; + + return pPinNew; +} + + + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Mio_WriteLibrary( FILE * pFile, Mio_Library_t * pLib, int fPrintSops ) +{ + Mio_Gate_t * pGate; + + fprintf( pFile, "# The genlib library \"%s\".\n", pLib->pName ); + Mio_LibraryForEachGate( pLib, pGate ) + Mio_WriteGate( pFile, pGate, fPrintSops ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Mio_WriteGate( FILE * pFile, Mio_Gate_t * pGate, int fPrintSops ) +{ + Mio_Pin_t * pPin; + + fprintf( pFile, "GATE " ); + fprintf( pFile, "%12s ", pGate->pName ); + fprintf( pFile, "%10.2f ", pGate->dArea ); + fprintf( pFile, "O=%s;\n", pGate->pForm ); + // print the pins + if ( fPrintSops ) + fprintf( pFile, "%s", pGate->pSop? pGate->pSop : "unspecified\n" ); +// Extra_bddPrint( pGate->pLib->dd, pGate->bFunc ); +// fprintf( pFile, "\n" ); + Mio_GateForEachPin( pGate, pPin ) + Mio_WritePin( pFile, pPin ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Mio_WritePin( FILE * pFile, Mio_Pin_t * pPin ) +{ + char * pPhaseNames[10] = { "UNKNOWN", "INV", "NONINV" }; + fprintf( pFile, " PIN " ); + fprintf( pFile, "%9s ", pPin->pName ); + fprintf( pFile, "%10s ", pPhaseNames[pPin->Phase] ); + fprintf( pFile, "%6d ", (int)pPin->dLoadInput ); + fprintf( pFile, "%6d ", (int)pPin->dLoadMax ); + fprintf( pFile, "%6.2f ", pPin->dDelayBlockRise ); + fprintf( pFile, "%6.2f ", pPin->dDelayFanoutRise ); + fprintf( pFile, "%6.2f ", pPin->dDelayBlockFall ); + fprintf( pFile, "%6.2f", pPin->dDelayFanoutFall ); + fprintf( pFile, "\n" ); +} + +/**Function************************************************************* + + Synopsis [Collects the set of root gates.] + + Description [Only collects the gates with unique functionality, + which have fewer inputs and shorter delay than the given limits.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Mio_Gate_t ** Mio_CollectRoots( Mio_Library_t * pLib, int nInputs, float tDelay, bool fSkipInv, int * pnGates ) +{ + Mio_Gate_t * pGate; + Mio_Gate_t ** ppGates; + /* st_table * tFuncs; */ + /* st_generator * gen; */ + DdNode * bFunc; + DdManager * dd; + int nGates, iGate; + + dd = Mio_LibraryReadDd( pLib ); + nGates = Mio_LibraryReadGateNum( pLib ); + + /* + + // for each functionality select one gate; skip constants and buffers + tFuncs = st_init_table( st_ptrcmp, st_ptrhash ); + Mio_LibraryForEachGate( pLib, pGate ) + { + bFunc = Mio_GateReadFunc(pGate); + if ( pGate->nInputs > nInputs ) + continue; + if ( pGate->dDelayMax > (double)tDelay ) + continue; + if ( bFunc == b0 || bFunc == b1 ) + continue; + if ( bFunc == dd->vars[0] ) + continue; + if ( bFunc == Cudd_Not(dd->vars[0]) && fSkipInv ) + continue; + if ( st_is_member( tFuncs, (char *)bFunc ) ) + continue; + st_insert( tFuncs, (char *)bFunc, (char *)pGate ); + } + + // collect the gates into the array + ppGates = ALLOC( Mio_Gate_t *, nGates ); + iGate = 0; + st_foreach_item( tFuncs, gen, (char **)&bFunc, (char **)&pGate ) + ppGates[ iGate++ ] = pGate; + assert( iGate <= nGates ); + st_free_table( tFuncs ); + + */ + + ppGates = ALLOC( Mio_Gate_t *, nGates ); + iGate = 0; + Mio_LibraryForEachGate( pLib, pGate ) + { + bFunc = Mio_GateReadFunc(pGate); + if ( pGate->nInputs > nInputs ) + continue; + if ( pGate->dDelayMax > (double)tDelay ) + continue; + if ( bFunc == b0 || bFunc == b1 ) + continue; + if ( bFunc == dd->vars[0] ) + continue; + if ( bFunc == Cudd_Not(dd->vars[0]) && fSkipInv ) + continue; + + assert( iGate < nGates ); + ppGates[ iGate++ ] = pGate; + } + + if ( iGate > 0 ) + { + // sort the gates by delay + qsort( (void *)ppGates, iGate, sizeof(Mio_Gate_t *), + (int (*)(const void *, const void *)) Mio_DelayCompare ); + assert( Mio_DelayCompare( ppGates, ppGates + iGate - 1 ) <= 0 ); + } + + if ( pnGates ) + *pnGates = iGate; + return ppGates; +} + +/**Function************************************************************* + + Synopsis [Compares the max delay of two gates.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Mio_DelayCompare( Mio_Gate_t ** ppG1, Mio_Gate_t ** ppG2 ) +{ + if ( (*ppG1)->dDelayMax < (*ppG2)->dDelayMax ) + return -1; + if ( (*ppG1)->dDelayMax > (*ppG2)->dDelayMax ) + return 1; + return 0; +} + +/**Function************************************************************* + + Synopsis [Derives the truth table of the gate.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Mio_DeriveTruthTable( Mio_Gate_t * pGate, unsigned uTruthsIn[][2], int nSigns, int nInputs, unsigned uTruthRes[] ) +{ + Mio_DeriveTruthTable_rec( pGate->bFunc, uTruthsIn, uTruthRes ); +} + +/**Function************************************************************* + + Synopsis [Recursively derives the truth table of the gate.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Mio_DeriveTruthTable_rec( DdNode * bFunc, unsigned uTruthsIn[][2], unsigned uTruthRes[] ) +{ + unsigned uTruthsCof0[2]; + unsigned uTruthsCof1[2]; + + // complement the resulting truth table, if the function is complemented + if ( Cudd_IsComplement(bFunc) ) + { + Mio_DeriveTruthTable_rec( Cudd_Not(bFunc), uTruthsIn, uTruthRes ); + uTruthRes[0] = ~uTruthRes[0]; + uTruthRes[1] = ~uTruthRes[1]; + return; + } + + // if the function is constant 1, return the constant 1 truth table + if ( bFunc->index == CUDD_CONST_INDEX ) + { + uTruthRes[0] = MIO_FULL; + uTruthRes[1] = MIO_FULL; + return; + } + + // solve the problem for both cofactors + Mio_DeriveTruthTable_rec( cuddE(bFunc), uTruthsIn, uTruthsCof0 ); + Mio_DeriveTruthTable_rec( cuddT(bFunc), uTruthsIn, uTruthsCof1 ); + + // derive the resulting truth table using the input truth tables + uTruthRes[0] = (uTruthsCof0[0] & ~uTruthsIn[bFunc->index][0]) | + (uTruthsCof1[0] & uTruthsIn[bFunc->index][0]); + uTruthRes[1] = (uTruthsCof0[1] & ~uTruthsIn[bFunc->index][1]) | + (uTruthsCof1[1] & uTruthsIn[bFunc->index][1]); +} + +/**Function************************************************************* + + Synopsis [Derives the truth table of the root of the gate.] + + Description [Given the truth tables of the leaves of the gate, + this procedure derives the truth table of the root.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Mio_DeriveTruthTable2( Mio_Gate_t * pGate, unsigned uTruthsIn[][2], int nTruths, int nInputs, unsigned uTruthRes[] ) +{ + unsigned uSignCube[2]; + int i, nFanins; + char * pCube; + + // make sure that the number of input truth tables in equal to the number of gate inputs + assert( pGate->nInputs == nTruths ); + assert( nInputs < 7 ); + + nFanins = Abc_SopGetVarNum( pGate->pSop ); + assert( nFanins == nInputs ); + + // clean the resulting truth table + uTruthRes[0] = 0; + uTruthRes[1] = 0; + if ( nInputs < 6 ) + { +// for ( c = 0; *(pCube = pGate->pSop + c * (nFanins + 3)); c++ ) + Abc_SopForEachCube( pGate->pSop, nFanins, pCube ) + { + // add the clause + uSignCube[0] = MIO_FULL; + for ( i = 0; i < nFanins; i++ ) + { + if ( pCube[i] == '0' ) + uSignCube[0] &= ~uTruthsIn[i][0]; + else if ( pCube[i] == '1' ) + uSignCube[0] &= uTruthsIn[i][0]; + } + } + if ( nInputs < 5 ) + uTruthRes[0] &= MIO_MASK(1<<nInputs); + } + else + { + // consider the case when two unsigneds should be used +// for ( c = 0; *(pCube = pGate->pSop + c * (nFanins + 3)); c++ ) + Abc_SopForEachCube( pGate->pSop, nFanins, pCube ) + { + uSignCube[0] = MIO_FULL; + uSignCube[1] = MIO_FULL; + for ( i = 0; i < nFanins; i++ ) + { + if ( pCube[i] == '0' ) + { + uSignCube[0] &= ~uTruthsIn[i][0]; + uSignCube[1] &= ~uTruthsIn[i][1]; + } + else if ( pCube[i] == '1' ) + { + uSignCube[0] &= uTruthsIn[i][0]; + uSignCube[1] &= uTruthsIn[i][1]; + } + } + uTruthRes[0] |= uSignCube[0]; + uTruthRes[1] |= uSignCube[1]; + } + } +} + +/**Function************************************************************* + + Synopsis [Derives the area and delay of the root of the gate.] + + Description [Array of the resulting delays should be initialized + to the (negative) SUPER_NO_VAR value.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Mio_DeriveGateDelays( Mio_Gate_t * pGate, + float ** ptPinDelays, int nPins, int nInputs, float tDelayZero, + float * ptDelaysRes, float * ptPinDelayMax ) +{ + Mio_Pin_t * pPin; + float Delay, DelayMax; + int i, k; + assert( pGate->nInputs == nPins ); + // set all the delays to the unused delay + for ( i = 0; i < nInputs; i++ ) + ptDelaysRes[i] = tDelayZero; + // compute the delays for each input and the max delay at the same time + DelayMax = 0; + for ( i = 0; i < nInputs; i++ ) + { + for ( k = 0, pPin = pGate->pPins; pPin; pPin = pPin->pNext, k++ ) + { + if ( ptPinDelays[k][i] < 0 ) + continue; + Delay = ptPinDelays[k][i] + (float)pPin->dDelayBlockMax; + if ( ptDelaysRes[i] < Delay ) + ptDelaysRes[i] = Delay; + } + if ( k != nPins ) + { + printf ("DEBUG: problem gate is %s\n", Mio_GateReadName( pGate )); + } + assert( k == nPins ); + if ( DelayMax < ptDelaysRes[i] ) + DelayMax = ptDelaysRes[i]; + } + *ptPinDelayMax = DelayMax; +} + + +/**Function************************************************************* + + Synopsis [Creates a pseudo-gate.] + + Description [The pseudo-gate is a N-input gate with all info set to 0.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Mio_Gate_t * Mio_GateCreatePseudo( int nInputs ) +{ + Mio_Gate_t * pGate; + Mio_Pin_t * pPin; + int i; + // allocate the gate structure + pGate = ALLOC( Mio_Gate_t, 1 ); + memset( pGate, 0, sizeof(Mio_Gate_t) ); + pGate->nInputs = nInputs; + // create pins + for ( i = 0; i < nInputs; i++ ) + { + pPin = ALLOC( Mio_Pin_t, 1 ); + memset( pPin, 0, sizeof(Mio_Pin_t) ); + pPin->pNext = pGate->pPins; + pGate->pPins = pPin; + } + return pGate; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + |