00001
00019 #include "mioInt.h"
00020
00024
00025 static void Mio_WriteGate( FILE * pFile, Mio_Gate_t * pGate, int fPrintSops );
00026 static void Mio_WritePin( FILE * pFile, Mio_Pin_t * pPin );
00027 static int Mio_DelayCompare( Mio_Gate_t ** ppG1, Mio_Gate_t ** ppG2 );
00028 static void Mio_DeriveTruthTable_rec( DdNode * bFunc, unsigned uTruthsIn[][2], unsigned uTruthRes[] );
00029
00033
00045 void Mio_LibraryDelete( Mio_Library_t * pLib )
00046 {
00047 Mio_Gate_t * pGate, * pGate2;
00048 if ( pLib == NULL )
00049 return;
00050
00051 Abc_FrameUnmapAllNetworks( Abc_FrameGetGlobalFrame() );
00052
00053 FREE( pLib->pName );
00054 Mio_LibraryForEachGateSafe( pLib, pGate, pGate2 )
00055 Mio_GateDelete( pGate );
00056 Extra_MmFlexStop( pLib->pMmFlex );
00057 Vec_StrFree( pLib->vCube );
00058 if ( pLib->tName2Gate )
00059 st_free_table( pLib->tName2Gate );
00060 if ( pLib->dd )
00061 Cudd_Quit( pLib->dd );
00062 free( pLib );
00063 }
00064
00076 void Mio_GateDelete( Mio_Gate_t * pGate )
00077 {
00078 Mio_Pin_t * pPin, * pPin2;
00079 FREE( pGate->pOutName );
00080 FREE( pGate->pName );
00081 FREE( pGate->pForm );
00082 if ( pGate->bFunc )
00083 Cudd_RecursiveDeref( pGate->pLib->dd, pGate->bFunc );
00084 Mio_GateForEachPinSafe( pGate, pPin, pPin2 )
00085 Mio_PinDelete( pPin );
00086 free( pGate );
00087 }
00088
00100 void Mio_PinDelete( Mio_Pin_t * pPin )
00101 {
00102 FREE( pPin->pName );
00103 free( pPin );
00104 }
00105
00117 Mio_Pin_t * Mio_PinDup( Mio_Pin_t * pPin )
00118 {
00119 Mio_Pin_t * pPinNew;
00120
00121 pPinNew = ALLOC( Mio_Pin_t, 1 );
00122 *pPinNew = *pPin;
00123 pPinNew->pName = (pPinNew->pName ? Extra_UtilStrsav(pPinNew->pName) : NULL);
00124 pPinNew->pNext = NULL;
00125
00126 return pPinNew;
00127 }
00128
00129
00130
00131
00143 void Mio_WriteLibrary( FILE * pFile, Mio_Library_t * pLib, int fPrintSops )
00144 {
00145 Mio_Gate_t * pGate;
00146
00147 fprintf( pFile, "# The genlib library \"%s\".\n", pLib->pName );
00148 Mio_LibraryForEachGate( pLib, pGate )
00149 Mio_WriteGate( pFile, pGate, fPrintSops );
00150 }
00151
00163 void Mio_WriteGate( FILE * pFile, Mio_Gate_t * pGate, int fPrintSops )
00164 {
00165 Mio_Pin_t * pPin;
00166
00167 fprintf( pFile, "GATE " );
00168 fprintf( pFile, "%12s ", pGate->pName );
00169 fprintf( pFile, "%10.2f ", pGate->dArea );
00170 fprintf( pFile, "%s=%s;\n", pGate->pOutName, pGate->pForm );
00171
00172 if ( fPrintSops )
00173 fprintf( pFile, "%s", pGate->pSop? pGate->pSop : "unspecified\n" );
00174
00175
00176 Mio_GateForEachPin( pGate, pPin )
00177 Mio_WritePin( pFile, pPin );
00178 }
00179
00191 void Mio_WritePin( FILE * pFile, Mio_Pin_t * pPin )
00192 {
00193 char * pPhaseNames[10] = { "UNKNOWN", "INV", "NONINV" };
00194 fprintf( pFile, " PIN " );
00195 fprintf( pFile, "%9s ", pPin->pName );
00196 fprintf( pFile, "%10s ", pPhaseNames[pPin->Phase] );
00197 fprintf( pFile, "%6d ", (int)pPin->dLoadInput );
00198 fprintf( pFile, "%6d ", (int)pPin->dLoadMax );
00199 fprintf( pFile, "%6.2f ", pPin->dDelayBlockRise );
00200 fprintf( pFile, "%6.2f ", pPin->dDelayFanoutRise );
00201 fprintf( pFile, "%6.2f ", pPin->dDelayBlockFall );
00202 fprintf( pFile, "%6.2f", pPin->dDelayFanoutFall );
00203 fprintf( pFile, "\n" );
00204 }
00205
00218 Mio_Gate_t ** Mio_CollectRoots( Mio_Library_t * pLib, int nInputs, float tDelay, bool fSkipInv, int * pnGates )
00219 {
00220 Mio_Gate_t * pGate;
00221 Mio_Gate_t ** ppGates;
00222
00223
00224 DdNode * bFunc;
00225 DdManager * dd;
00226 int nGates, iGate;
00227
00228 dd = Mio_LibraryReadDd( pLib );
00229 nGates = Mio_LibraryReadGateNum( pLib );
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263 ppGates = ALLOC( Mio_Gate_t *, nGates );
00264 iGate = 0;
00265 Mio_LibraryForEachGate( pLib, pGate )
00266 {
00267 bFunc = Mio_GateReadFunc(pGate);
00268 if ( pGate->nInputs > nInputs )
00269 continue;
00270 if ( pGate->dDelayMax > (double)tDelay )
00271 continue;
00272 if ( bFunc == b0 || bFunc == b1 )
00273 continue;
00274 if ( bFunc == dd->vars[0] )
00275 continue;
00276 if ( bFunc == Cudd_Not(dd->vars[0]) && fSkipInv )
00277 continue;
00278
00279 assert( iGate < nGates );
00280 ppGates[ iGate++ ] = pGate;
00281 }
00282
00283 if ( iGate > 0 )
00284 {
00285
00286 qsort( (void *)ppGates, iGate, sizeof(Mio_Gate_t *),
00287 (int (*)(const void *, const void *)) Mio_DelayCompare );
00288 assert( Mio_DelayCompare( ppGates, ppGates + iGate - 1 ) <= 0 );
00289 }
00290
00291 if ( pnGates )
00292 *pnGates = iGate;
00293 return ppGates;
00294 }
00295
00307 int Mio_DelayCompare( Mio_Gate_t ** ppG1, Mio_Gate_t ** ppG2 )
00308 {
00309 if ( (*ppG1)->dDelayMax < (*ppG2)->dDelayMax )
00310 return -1;
00311 if ( (*ppG1)->dDelayMax > (*ppG2)->dDelayMax )
00312 return 1;
00313 return 0;
00314 }
00315
00327 void Mio_DeriveTruthTable( Mio_Gate_t * pGate, unsigned uTruthsIn[][2], int nSigns, int nInputs, unsigned uTruthRes[] )
00328 {
00329 Mio_DeriveTruthTable_rec( pGate->bFunc, uTruthsIn, uTruthRes );
00330 }
00331
00343 void Mio_DeriveTruthTable_rec( DdNode * bFunc, unsigned uTruthsIn[][2], unsigned uTruthRes[] )
00344 {
00345 unsigned uTruthsCof0[2];
00346 unsigned uTruthsCof1[2];
00347
00348
00349 if ( Cudd_IsComplement(bFunc) )
00350 {
00351 Mio_DeriveTruthTable_rec( Cudd_Not(bFunc), uTruthsIn, uTruthRes );
00352 uTruthRes[0] = ~uTruthRes[0];
00353 uTruthRes[1] = ~uTruthRes[1];
00354 return;
00355 }
00356
00357
00358 if ( bFunc->index == CUDD_CONST_INDEX )
00359 {
00360 uTruthRes[0] = MIO_FULL;
00361 uTruthRes[1] = MIO_FULL;
00362 return;
00363 }
00364
00365
00366 Mio_DeriveTruthTable_rec( cuddE(bFunc), uTruthsIn, uTruthsCof0 );
00367 Mio_DeriveTruthTable_rec( cuddT(bFunc), uTruthsIn, uTruthsCof1 );
00368
00369
00370 uTruthRes[0] = (uTruthsCof0[0] & ~uTruthsIn[bFunc->index][0]) |
00371 (uTruthsCof1[0] & uTruthsIn[bFunc->index][0]);
00372 uTruthRes[1] = (uTruthsCof0[1] & ~uTruthsIn[bFunc->index][1]) |
00373 (uTruthsCof1[1] & uTruthsIn[bFunc->index][1]);
00374 }
00375
00388 void Mio_DeriveTruthTable2( Mio_Gate_t * pGate, unsigned uTruthsIn[][2], int nTruths, int nInputs, unsigned uTruthRes[] )
00389 {
00390 unsigned uSignCube[2];
00391 int i, nFanins;
00392 char * pCube;
00393
00394
00395 assert( pGate->nInputs == nTruths );
00396 assert( nInputs < 7 );
00397
00398 nFanins = Abc_SopGetVarNum( pGate->pSop );
00399 assert( nFanins == nInputs );
00400
00401
00402 uTruthRes[0] = 0;
00403 uTruthRes[1] = 0;
00404 if ( nInputs < 6 )
00405 {
00406
00407 Abc_SopForEachCube( pGate->pSop, nFanins, pCube )
00408 {
00409
00410 uSignCube[0] = MIO_FULL;
00411 for ( i = 0; i < nFanins; i++ )
00412 {
00413 if ( pCube[i] == '0' )
00414 uSignCube[0] &= ~uTruthsIn[i][0];
00415 else if ( pCube[i] == '1' )
00416 uSignCube[0] &= uTruthsIn[i][0];
00417 }
00418 }
00419 if ( nInputs < 5 )
00420 uTruthRes[0] &= MIO_MASK(1<<nInputs);
00421 }
00422 else
00423 {
00424
00425
00426 Abc_SopForEachCube( pGate->pSop, nFanins, pCube )
00427 {
00428 uSignCube[0] = MIO_FULL;
00429 uSignCube[1] = MIO_FULL;
00430 for ( i = 0; i < nFanins; i++ )
00431 {
00432 if ( pCube[i] == '0' )
00433 {
00434 uSignCube[0] &= ~uTruthsIn[i][0];
00435 uSignCube[1] &= ~uTruthsIn[i][1];
00436 }
00437 else if ( pCube[i] == '1' )
00438 {
00439 uSignCube[0] &= uTruthsIn[i][0];
00440 uSignCube[1] &= uTruthsIn[i][1];
00441 }
00442 }
00443 uTruthRes[0] |= uSignCube[0];
00444 uTruthRes[1] |= uSignCube[1];
00445 }
00446 }
00447 }
00448
00461 void Mio_DeriveGateDelays( Mio_Gate_t * pGate,
00462 float ** ptPinDelays, int nPins, int nInputs, float tDelayZero,
00463 float * ptDelaysRes, float * ptPinDelayMax )
00464 {
00465 Mio_Pin_t * pPin;
00466 float Delay, DelayMax;
00467 int i, k;
00468 assert( pGate->nInputs == nPins );
00469
00470 for ( i = 0; i < nInputs; i++ )
00471 ptDelaysRes[i] = tDelayZero;
00472
00473 DelayMax = 0;
00474 for ( i = 0; i < nInputs; i++ )
00475 {
00476 for ( k = 0, pPin = pGate->pPins; pPin; pPin = pPin->pNext, k++ )
00477 {
00478 if ( ptPinDelays[k][i] < 0 )
00479 continue;
00480 Delay = ptPinDelays[k][i] + (float)pPin->dDelayBlockMax;
00481 if ( ptDelaysRes[i] < Delay )
00482 ptDelaysRes[i] = Delay;
00483 }
00484 if ( k != nPins )
00485 {
00486 printf ("DEBUG: problem gate is %s\n", Mio_GateReadName( pGate ));
00487 }
00488 assert( k == nPins );
00489 if ( DelayMax < ptDelaysRes[i] )
00490 DelayMax = ptDelaysRes[i];
00491 }
00492 *ptPinDelayMax = DelayMax;
00493 }
00494
00495
00507 Mio_Gate_t * Mio_GateCreatePseudo( int nInputs )
00508 {
00509 Mio_Gate_t * pGate;
00510 Mio_Pin_t * pPin;
00511 int i;
00512
00513 pGate = ALLOC( Mio_Gate_t, 1 );
00514 memset( pGate, 0, sizeof(Mio_Gate_t) );
00515 pGate->nInputs = nInputs;
00516
00517 for ( i = 0; i < nInputs; i++ )
00518 {
00519 pPin = ALLOC( Mio_Pin_t, 1 );
00520 memset( pPin, 0, sizeof(Mio_Pin_t) );
00521 pPin->pNext = pGate->pPins;
00522 pGate->pPins = pPin;
00523 }
00524 return pGate;
00525 }
00526
00530
00531