mapperTree.c 35.8 KB
Newer Older
Alan Mishchenko committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
/**CFile****************************************************************

  FileName    [mapperTree.c]

  PackageName [MVSIS 1.3: Multi-valued logic synthesis system.]

  Synopsis    [Generic technology mapping engine.]

  Author      [MVSIS Group]
  
  Affiliation [UC Berkeley]

  Date        [Ver. 2.0. Started - June 1, 2004.]

  Revision    [$Id: mapperTree.c,v 1.9 2005/01/23 06:59:45 alanmi Exp $]

***********************************************************************/

#ifdef __linux__
#include <libgen.h>
#endif

#include "mapperInt.h"

25 26 27
ABC_NAMESPACE_IMPL_START


Alan Mishchenko committed
28 29 30 31
////////////////////////////////////////////////////////////////////////
///                        DECLARATIONS                              ///
////////////////////////////////////////////////////////////////////////

32 33 34
static void      Map_LibraryAddFaninDelays( Map_SuperLib_t * pLib, Map_Super_t * pGate, Map_Super_t * pFanin, Mio_Pin_t * pPin );
static int       Map_LibraryGetMaxSuperPi_rec( Map_Super_t * pGate );
static unsigned  Map_LibraryGetGateSupp_rec( Map_Super_t * pGate );
Alan Mishchenko committed
35 36

// fanout limits
37
static const int s_MapFanoutLimits[10] = { 1/*0*/, 10/*1*/, 5/*2*/, 2/*3*/, 1/*4*/, 1/*5*/, 1/*6*/ };
Alan Mishchenko committed
38 39

////////////////////////////////////////////////////////////////////////
Alan Mishchenko committed
40
///                     FUNCTION DEFINITIONS                         ///
Alan Mishchenko committed
41 42 43 44
////////////////////////////////////////////////////////////////////////

/**Function*************************************************************

45
  Synopsis    [Reads one gate.]
Alan Mishchenko committed
46 47 48 49 50 51 52 53

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
54
Map_Super_t * Map_LibraryReadGateTree( Map_SuperLib_t * pLib, char * pBuffer, int Number, int nVarsMax )
Alan Mishchenko committed
55
{
56 57 58
    Map_Super_t * pGate;
    char * pTemp;
    int i, Num;
Alan Mishchenko committed
59

60 61 62 63 64 65 66 67 68 69
    // start and clean the gate
    pGate = (Map_Super_t *)Extra_MmFixedEntryFetch( pLib->mmSupers );
    memset( pGate, 0, sizeof(Map_Super_t) );

    // set the gate number
    pGate->Num = Number;

    // read the mark
    pTemp = strtok( pBuffer, " " );
    if ( pTemp[0] == '*' )
Alan Mishchenko committed
70
    {
71 72
        pGate->fSuper = 1;
        pTemp = strtok( NULL, " " );
Alan Mishchenko committed
73 74
    }

75 76 77
    // read the root gate
    pGate->pRoot = Mio_LibraryReadGateByName( pLib->pGenlib, pTemp, NULL );
    if ( pGate->pRoot == NULL )
Alan Mishchenko committed
78
    {
79 80 81 82 83 84 85 86 87 88 89 90
        printf( "Cannot read the root gate names %s.\n", pTemp );
        return NULL;
    }
    // set the max number of fanouts
    pGate->nFanLimit = s_MapFanoutLimits[ Mio_GateReadPinNum(pGate->pRoot) ];

    // read the pin-to-pin delay
    for ( i = 0; ( pTemp = strtok( NULL, " \n\0" ) ); i++ )
    {
        if ( pTemp[0] == '#' )
            break;
        if ( i == nVarsMax )
Alan Mishchenko committed
91
        {
92 93
            printf( "There are too many entries on the line.\n" );
            return NULL;
Alan Mishchenko committed
94
        }
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
        Num = atoi(pTemp);
        if ( Num < 0 )
        {
            printf( "The number of a child supergate is negative.\n" );
            return NULL;
        }
        if ( Num > pLib->nLines )
        {
            printf( "The number of a child supergate (%d) exceeded the number of lines (%d).\n", 
                Num, pLib->nLines );
            return NULL;
        }
        pGate->pFanins[i] = pLib->ppSupers[Num];
    }
    pGate->nFanins = i;
    if ( pGate->nFanins != (unsigned)Mio_GateReadPinNum(pGate->pRoot) )
    {
        printf( "The number of fanins of a root gate is wrong.\n" );
        return NULL;
    }
Alan Mishchenko committed
115

116 117 118 119 120 121 122 123 124 125
    // save the gate name, just in case
    if ( pTemp && pTemp[0] == '#' )
    {
        if ( pTemp[1] == 0 )
            pTemp = strtok( NULL, " \n\0" );
        else // skip spaces
            for ( pTemp++; *pTemp == ' '; pTemp++ );
        // save the formula
        pGate->pFormula = Extra_MmFlexEntryFetch( pLib->mmForms, strlen(pTemp)+1 );
        strcpy( pGate->pFormula, pTemp );
Alan Mishchenko committed
126
    }
127 128 129 130 131
    // check the rest of the string
    pTemp = strtok( NULL, " \n\0" );
    if ( pTemp != NULL )
        printf( "The following trailing symbols found \"%s\".\n", pTemp );
    return pGate;
Alan Mishchenko committed
132 133 134 135
}

/**Function*************************************************************

136
  Synopsis    [Reads the supergate library from file.]
Alan Mishchenko committed
137 138 139 140 141 142 143 144 145 146 147

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Map_LibraryReadFileTree( Map_SuperLib_t * pLib, FILE * pFile, char *pFileName )
{
    ProgressBar * pProgress;
148
    char pBuffer[5000];
Alan Mishchenko committed
149 150 151
    Map_Super_t * pGate;
    char * pTemp = 0, * pLibName;
    int nCounter, k, i;
152
    int RetValue;
Alan Mishchenko committed
153 154 155 156 157 158 159 160 161 162

    // skip empty and comment lines
    while ( fgets( pBuffer, 5000, pFile ) != NULL )
    {
        // skip leading spaces
        for ( pTemp = pBuffer; *pTemp == ' ' || *pTemp == '\r' || *pTemp == '\n'; pTemp++ );
        // skip comment lines and empty lines
        if ( *pTemp != 0 && *pTemp != '#' )
            break;
    }
163

164
    pLibName = strtok( pTemp, " \t\r\n" );
165
    pLib->pGenlib = (Mio_Library_t *)Abc_FrameReadLibGen();
166
    if ( pLib->pGenlib == NULL || strcmp( Mio_LibraryReadName(pLib->pGenlib), pLibName ) )
Alan Mishchenko committed
167
    {
168
        printf( "Supergate library \"%s\" requires the use of genlib library \"%s\".\n", pFileName, pLibName );
Alan Mishchenko committed
169 170 171 172
        return 0;
    }

    // read the number of variables
173
    RetValue = fscanf( pFile, "%d\n", &pLib->nVarsMax );
Alan Mishchenko committed
174 175 176 177 178 179 180
    if ( pLib->nVarsMax < 2 || pLib->nVarsMax > 10 )
    {
        printf( "Suspicious number of variables (%d).\n", pLib->nVarsMax );
        return 0;
    }

    // read the number of gates
181
    RetValue = fscanf( pFile, "%d\n", &pLib->nSupersReal );
Alan Mishchenko committed
182 183 184 185 186 187 188
    if ( pLib->nSupersReal < 1 || pLib->nSupersReal > 10000000 )
    {
        printf( "Suspicious number of gates (%d).\n", pLib->nSupersReal );
        return 0;
    }

    // read the number of lines
189
    RetValue = fscanf( pFile, "%d\n", &pLib->nLines );
Alan Mishchenko committed
190 191 192 193 194 195 196
    if ( pLib->nLines < 1 || pLib->nLines > 10000000 )
    {
        printf( "Suspicious number of lines (%d).\n", pLib->nLines );
        return 0;
    }

    // allocate room for supergate pointers
Alan Mishchenko committed
197
    pLib->ppSupers = ABC_ALLOC( Map_Super_t *, pLib->nLines + 10000 );
Alan Mishchenko committed
198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262

    // create the elementary supergates
    for ( i = 0; i < pLib->nVarsMax; i++ )
    {
        // get a new gate
        pGate = (Map_Super_t *)Extra_MmFixedEntryFetch( pLib->mmSupers );
        memset( pGate, 0, sizeof(Map_Super_t) );
        // assign the elementary variable, the truth table, and the delays
        pGate->Num = i;
        // set the truth table
        pGate->uTruth[0] = pLib->uTruths[i][0];
        pGate->uTruth[1] = pLib->uTruths[i][1];
        // set the arrival times of all input to non-existent delay
        for ( k = 0; k < pLib->nVarsMax; k++ )
        {
            pGate->tDelaysR[k].Rise = pGate->tDelaysR[k].Fall = MAP_NO_VAR;
            pGate->tDelaysF[k].Rise = pGate->tDelaysF[k].Fall = MAP_NO_VAR;
        }
        // set an existent arrival time for rise and fall
        pGate->tDelaysR[i].Rise = 0.0;
        pGate->tDelaysF[i].Fall = 0.0;
        // set the gate
        pLib->ppSupers[i] = pGate;
    }

    // read the lines
    nCounter = pLib->nVarsMax;
    pProgress = Extra_ProgressBarStart( stdout, pLib->nLines );
    while ( fgets( pBuffer, 5000, pFile ) != NULL )
    {
        for ( pTemp = pBuffer; *pTemp == ' ' || *pTemp == '\r' || *pTemp == '\n'; pTemp++ );
        if ( pTemp[0] == '\0' )
            continue;
//        if ( pTemp[0] == 'a' || pTemp[2] == 'a' )
//        {
//            pLib->nLines--;
//            continue;
//        }

        // get the gate
        pGate = Map_LibraryReadGateTree( pLib, pTemp, nCounter, pLib->nVarsMax );
        if ( pGate == NULL )
        {
            Extra_ProgressBarStop( pProgress );
            return 0;
        }
        pLib->ppSupers[nCounter++] = pGate;
        // later we will derive: truth table, delays, area, number of component gates, etc

        // update the progress bar
        Extra_ProgressBarUpdate( pProgress, nCounter, NULL );
    }
    Extra_ProgressBarStop( pProgress );
    if ( nCounter != pLib->nLines )
        printf( "The number of lines read (%d) is different what the file says (%d).\n", nCounter, pLib->nLines );
    pLib->nSupersAll = nCounter;
    // count the number of real supergates
    nCounter = 0;
    for ( k = 0; k < pLib->nLines; k++ )
        nCounter += pLib->ppSupers[k]->fSuper;
    if ( nCounter != pLib->nSupersReal )
        printf( "The number of gates read (%d) is different what the file says (%d).\n", nCounter, pLib->nSupersReal );
    pLib->nSupersReal = nCounter;
    return 1;
}
263 264 265 266 267
int Map_LibraryReadTree2( Map_SuperLib_t * pLib, char * pFileName, char * pExcludeFile )
{
    FILE * pFile;
    int Status, num;
    Abc_Frame_t * pAbc;
268
    st__table * tExcludeGate = 0;
269 270 271 272 273 274 275 276 277 278 279 280 281 282 283

    // read the beginning of the file
    assert( pLib->pGenlib == NULL );
    pFile = Io_FileOpen( pFileName, "open_path", "r", 1 );
//    pFile = fopen( pFileName, "r" ); 
    if ( pFile == NULL )
    {
        printf( "Cannot open input file \"%s\".\n", pFileName );
        return 0;
    }

    if ( pExcludeFile )
    {
        pAbc = Abc_FrameGetGlobalFrame();
        
284
        tExcludeGate = st__init_table(strcmp, st__strhash);
285 286
        if ( (num = Mio_LibraryReadExclude( pExcludeFile, tExcludeGate )) == -1 )
        {
287
            st__free_table( tExcludeGate );
288 289 290 291 292 293 294 295 296 297 298 299 300 301
            tExcludeGate = 0;
            return 0;
        }

        fprintf ( Abc_FrameReadOut( pAbc ), "Read %d gates from exclude file\n", num );
    }
    
    Status = Map_LibraryReadFileTree( pLib, pFile, pFileName );
    fclose( pFile );
    if ( Status == 0 )
        return 0;
    // prepare the info about the library
    return Map_LibraryDeriveGateInfo( pLib, tExcludeGate );
}
Alan Mishchenko committed
302 303 304

/**Function*************************************************************

305
  Synopsis    [Similar to fgets.]
Alan Mishchenko committed
306 307 308 309 310 311 312 313

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
314
int Vec_StrGets( char * pBuffer, int nBufferSize, Vec_Str_t * vStr, int * pPos )
Alan Mishchenko committed
315
{
316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392
    char * pCur;
    char * pBeg = Vec_StrArray(vStr) + *pPos;
    char * pEnd = Vec_StrArray(vStr) + Vec_StrSize(vStr);
    assert( nBufferSize > 1 );
    if ( pBeg == pEnd )
    {
        *pBuffer = 0;
        return 0;
    }
    assert( pBeg < pEnd );
    for ( pCur = pBeg; pCur < pEnd; pCur++ )
    {
        *pBuffer++ = *pCur;
        if ( *pCur == 0 )
        {
            *pPos += pCur - pBeg;
            return 0;
        }
        if ( *pCur == '\n' )
        {
            *pPos += pCur - pBeg + 1;
            *pBuffer = 0;
            return 1;
        }
        if ( pCur - pBeg == nBufferSize-1 )
        {
            *pPos += pCur - pBeg + 1;
            *pBuffer = 0;
            return 1;
        }
    }
    return 0;
}

/**Function*************************************************************

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Map_LibraryCompareLibNames( char * pName1, char * pName2 )
{
    char * p1 = Abc_UtilStrsav( pName1 );
    char * p2 = Abc_UtilStrsav( pName2 );
    int i, RetValue;
    for ( i = 0; p1[i]; i++ )
        if ( p1[i] == '>' || p1[i] == '\\' || p1[i] == '/' )
            p1[i] = '/';
    for ( i = 0; p2[i]; i++ )
        if ( p2[i] == '>' || p2[i] == '\\' || p2[i] == '/' )
            p2[i] = '/';
    RetValue = strcmp( p1, p2 );
    ABC_FREE( p1 );
    ABC_FREE( p2 );
    return RetValue; 
}

/**Function*************************************************************

  Synopsis    [Reads the supergate library from file.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Map_LibraryReadFileTreeStr( Map_SuperLib_t * pLib, Vec_Str_t * vStr, char * pFileName )
{
    ProgressBar * pProgress;
    char pBuffer[5000];
Alan Mishchenko committed
393
    Map_Super_t * pGate;
394 395 396
    char * pTemp = 0, * pLibName;
    int nCounter, k, i;
    int RetValue, nPos = 0;
Alan Mishchenko committed
397

398 399 400 401 402 403 404 405 406 407 408 409 410
    // skip empty and comment lines
//    while ( fgets( pBuffer, 5000, pFile ) != NULL )
    while ( 1 )
    {
        RetValue = Vec_StrGets( pBuffer, 5000, vStr, &nPos );
        if ( RetValue == 0 )
            return 0;
        // skip leading spaces
        for ( pTemp = pBuffer; *pTemp == ' ' || *pTemp == '\r' || *pTemp == '\n'; pTemp++ );
        // skip comment lines and empty lines
        if ( *pTemp != 0 && *pTemp != '#' )
            break;
    }
Alan Mishchenko committed
411

412
    pLibName = strtok( pTemp, " \t\r\n" );
413
    pLib->pGenlib = (Mio_Library_t *)Abc_FrameReadLibGen();
414 415 416 417 418 419
//    if ( pLib->pGenlib == NULL || strcmp( , pLibName ) )
    if ( pLib->pGenlib == NULL || Map_LibraryCompareLibNames(Mio_LibraryReadName(pLib->pGenlib), pLibName) )
    {
        printf( "Supergate library \"%s\" requires the use of genlib library \"%s\".\n", pFileName, pLibName );
        return 0;
    }
Alan Mishchenko committed
420

421 422 423 424 425 426
    // read the number of variables
    RetValue = Vec_StrGets( pBuffer, 5000, vStr, &nPos );
    if ( RetValue == 0 )
        return 0;
    RetValue = sscanf( pBuffer, "%d\n", &pLib->nVarsMax );
    if ( pLib->nVarsMax < 2 || pLib->nVarsMax > 10 )
Alan Mishchenko committed
427
    {
428 429
        printf( "Suspicious number of variables (%d).\n", pLib->nVarsMax );
        return 0;
Alan Mishchenko committed
430 431
    }

432 433 434 435 436 437
    // read the number of gates
    RetValue = Vec_StrGets( pBuffer, 5000, vStr, &nPos );
    if ( RetValue == 0 )
        return 0;
    RetValue = sscanf( pBuffer, "%d\n", &pLib->nSupersReal );
    if ( pLib->nSupersReal < 1 || pLib->nSupersReal > 10000000 )
Alan Mishchenko committed
438
    {
439 440
        printf( "Suspicious number of gates (%d).\n", pLib->nSupersReal );
        return 0;
Alan Mishchenko committed
441 442
    }

443 444 445 446 447 448
    // read the number of lines
    RetValue = Vec_StrGets( pBuffer, 5000, vStr, &nPos );
    if ( RetValue == 0 )
        return 0;
    RetValue = sscanf( pBuffer, "%d\n", &pLib->nLines );
    if ( pLib->nLines < 1 || pLib->nLines > 10000000 )
Alan Mishchenko committed
449
    {
450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469
        printf( "Suspicious number of lines (%d).\n", pLib->nLines );
        return 0;
    }

    // allocate room for supergate pointers
    pLib->ppSupers = ABC_ALLOC( Map_Super_t *, pLib->nLines + 10000 );

    // create the elementary supergates
    for ( i = 0; i < pLib->nVarsMax; i++ )
    {
        // get a new gate
        pGate = (Map_Super_t *)Extra_MmFixedEntryFetch( pLib->mmSupers );
        memset( pGate, 0, sizeof(Map_Super_t) );
        // assign the elementary variable, the truth table, and the delays
        pGate->Num = i;
        // set the truth table
        pGate->uTruth[0] = pLib->uTruths[i][0];
        pGate->uTruth[1] = pLib->uTruths[i][1];
        // set the arrival times of all input to non-existent delay
        for ( k = 0; k < pLib->nVarsMax; k++ )
Alan Mishchenko committed
470
        {
471 472
            pGate->tDelaysR[k].Rise = pGate->tDelaysR[k].Fall = MAP_NO_VAR;
            pGate->tDelaysF[k].Rise = pGate->tDelaysF[k].Fall = MAP_NO_VAR;
Alan Mishchenko committed
473
        }
474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498
        // set an existent arrival time for rise and fall
        pGate->tDelaysR[i].Rise = 0.0;
        pGate->tDelaysF[i].Fall = 0.0;
        // set the gate
        pLib->ppSupers[i] = pGate;
    }

    // read the lines
    nCounter = pLib->nVarsMax;
    pProgress = Extra_ProgressBarStart( stdout, pLib->nLines );
//    while ( fgets( pBuffer, 5000, pFile ) != NULL )
    while ( Vec_StrGets( pBuffer, 5000, vStr, &nPos ) )
    {
        for ( pTemp = pBuffer; *pTemp == ' ' || *pTemp == '\r' || *pTemp == '\n'; pTemp++ );
        if ( pTemp[0] == '\0' )
            continue;
//        if ( pTemp[0] == 'a' || pTemp[2] == 'a' )
//        {
//            pLib->nLines--;
//            continue;
//        }

        // get the gate
        pGate = Map_LibraryReadGateTree( pLib, pTemp, nCounter, pLib->nVarsMax );
        if ( pGate == NULL )
Alan Mishchenko committed
499
        {
500 501
            Extra_ProgressBarStop( pProgress );
            return 0;
Alan Mishchenko committed
502
        }
503 504 505 506 507
        pLib->ppSupers[nCounter++] = pGate;
        // later we will derive: truth table, delays, area, number of component gates, etc

        // update the progress bar
        Extra_ProgressBarUpdate( pProgress, nCounter, NULL );
Alan Mishchenko committed
508
    }
509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527
    Extra_ProgressBarStop( pProgress );
    if ( nCounter != pLib->nLines )
        printf( "The number of lines read (%d) is different from what the file says (%d).\n", nCounter, pLib->nLines );
    pLib->nSupersAll = nCounter;
    // count the number of real supergates
    nCounter = 0;
    for ( k = 0; k < pLib->nLines; k++ )
        nCounter += pLib->ppSupers[k]->fSuper;
    if ( nCounter != pLib->nSupersReal )
        printf( "The number of gates read (%d) is different what the file says (%d).\n", nCounter, pLib->nSupersReal );
    pLib->nSupersReal = nCounter;
    return 1;
}
int Map_LibraryReadTree( Map_SuperLib_t * pLib, char * pFileName, char * pExcludeFile )
{
    char * pBuffer;
    Vec_Str_t * vStr;
    int Status, num;
    Abc_Frame_t * pAbc;
528
    st__table * tExcludeGate = 0;
529 530 531 532 533 534

    // read the beginning of the file
    assert( pLib->pGenlib == NULL );
//    pFile = Io_FileOpen( pFileName, "open_path", "r", 1 );
    pBuffer = Mio_ReadFile( pFileName, 0 );
    if ( pBuffer == NULL )
Alan Mishchenko committed
535
    {
536 537
        printf( "Cannot open input file \"%s\".\n", pFileName );
        return 0;
Alan Mishchenko committed
538
    }
539
    vStr = Vec_StrAllocArray( pBuffer, strlen(pBuffer) );
Alan Mishchenko committed
540

541
    if ( pExcludeFile )
Alan Mishchenko committed
542
    {
543 544
        pAbc = Abc_FrameGetGlobalFrame();
        
545
        tExcludeGate = st__init_table(strcmp, st__strhash);
546 547
        if ( (num = Mio_LibraryReadExclude( pExcludeFile, tExcludeGate )) == -1 )
        {
548
            st__free_table( tExcludeGate );
549 550 551 552 553 554
            tExcludeGate = 0;
            Vec_StrFree( vStr );
            return 0;
        }

        fprintf ( Abc_FrameReadOut( pAbc ), "Read %d gates from exclude file\n", num );
Alan Mishchenko committed
555
    }
556 557 558 559 560 561 562
    
    Status = Map_LibraryReadFileTreeStr( pLib, vStr, pFileName );
    Vec_StrFree( vStr );
    if ( Status == 0 )
        return 0;
    // prepare the info about the library
    return Map_LibraryDeriveGateInfo( pLib, tExcludeGate );
Alan Mishchenko committed
563 564 565
}


566 567 568 569 570 571






Alan Mishchenko committed
572 573 574 575 576 577 578 579 580 581 582
/**Function*************************************************************

  Synopsis    [Derives information about the library.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
583
int Map_LibraryDeriveGateInfo( Map_SuperLib_t * pLib, st__table * tExcludeGate )
Alan Mishchenko committed
584 585 586 587 588 589 590 591 592 593 594 595 596 597
{
    Map_Super_t * pGate, * pFanin;
    Mio_Pin_t * pPin;
    unsigned uCanon[2];
    unsigned uTruths[6][2];
    int i, k, nRealVars;

    // set all the derivable info related to the supergates
    for ( i = pLib->nVarsMax; i < (int)pLib->nLines; i++ )
    {
        pGate = pLib->ppSupers[i];

        if ( tExcludeGate )
        {
598
            if ( st__is_member( tExcludeGate, Mio_GateReadName( pGate->pRoot ) ) )
Alan Mishchenko committed
599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660
                pGate->fExclude = 1;
            for ( k = 0; k < (int)pGate->nFanins; k++ )
            {
                pFanin = pGate->pFanins[k];
                if ( pFanin->fExclude )
                {
                    pGate->fExclude = 1;
                    continue;
                }
            }
        }
        
        // collect the truth tables of the fanins
        for ( k = 0; k < (int)pGate->nFanins; k++ )
        {
            pFanin = pGate->pFanins[k];
            uTruths[k][0] = pFanin->uTruth[0];
            uTruths[k][1] = pFanin->uTruth[1];
        }
        // derive the new truth table
        Mio_DeriveTruthTable( pGate->pRoot, uTruths, pGate->nFanins, 6, pGate->uTruth );

        // set the initial delays of the supergate
        for ( k = 0; k < pLib->nVarsMax; k++ )
        {
            pGate->tDelaysR[k].Rise = pGate->tDelaysR[k].Fall = MAP_NO_VAR;
            pGate->tDelaysF[k].Rise = pGate->tDelaysF[k].Fall = MAP_NO_VAR;
        }
        // get the linked list of pins for the given root gate
        pPin = Mio_GateReadPins( pGate->pRoot );
        // update the initial delay of the supergate using info from the corresponding pin
        for ( k = 0; k < (int)pGate->nFanins; k++, pPin = Mio_PinReadNext(pPin) )
        {
            // if there is no corresponding pin, this is a bug, return fail
            if ( pPin == NULL )
            {
                printf( "There are less pins than gate inputs.\n" );
                return 0;
            }
            // update the delay information of k-th fanins info from the corresponding pin
            Map_LibraryAddFaninDelays( pLib, pGate, pGate->pFanins[k], pPin );
        }
        // if there are some pins left, this is a bug, return fail
        if ( pPin != NULL )
        {
            printf( "There are more pins than gate inputs.\n" );
            return 0;
        }
        // find the max delay
        pGate->tDelayMax.Rise = pGate->tDelayMax.Fall = MAP_NO_VAR;
        for ( k = 0; k < pLib->nVarsMax; k++ )
        {
            // the rise of the output depends on the rise and fall of the output
            if ( pGate->tDelayMax.Rise < pGate->tDelaysR[k].Rise )
                pGate->tDelayMax.Rise = pGate->tDelaysR[k].Rise;
            if ( pGate->tDelayMax.Rise < pGate->tDelaysR[k].Fall )
                pGate->tDelayMax.Rise = pGate->tDelaysR[k].Fall;
            // the fall of the output depends on the rise and fall of the output
            if ( pGate->tDelayMax.Fall < pGate->tDelaysF[k].Rise )
                pGate->tDelayMax.Fall = pGate->tDelaysF[k].Rise;
            if ( pGate->tDelayMax.Fall < pGate->tDelaysF[k].Fall )
                pGate->tDelayMax.Fall = pGate->tDelaysF[k].Fall;
Alan Mishchenko committed
661 662 663

            pGate->tDelaysF[k].Worst = MAP_MAX( pGate->tDelaysF[k].Fall, pGate->tDelaysF[k].Rise );
            pGate->tDelaysR[k].Worst = MAP_MAX( pGate->tDelaysR[k].Fall, pGate->tDelaysR[k].Rise );
Alan Mishchenko committed
664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691
        }

        // count gates and area of the supergate
        pGate->nGates = 1;
        pGate->Area   = (float)Mio_GateReadArea(pGate->pRoot);
        for ( k = 0; k < (int)pGate->nFanins; k++ )
        {
            pGate->nGates += pGate->pFanins[k]->nGates;
            pGate->Area   += pGate->pFanins[k]->Area;
        }
        // do not add the gate to the table, if this gate is an internal gate
        // of some supegate and does not correspond to a supergate output
        if ( ( !pGate->fSuper ) || pGate->fExclude )
            continue;

        // find the maximum index of a variable in the support of the supergates
        // this is important for two reasons:
        // (1) to limit the number of permutations considered for canonicization
        // (2) to get rid of equivalence phases to speed-up matching
        nRealVars = Map_LibraryGetMaxSuperPi_rec( pGate ) + 1;
        assert( nRealVars > 0 && nRealVars <= pLib->nVarsMax );
        // if there are some problems with this code, try this instead
//        nRealVars = pLib->nVarsMax;

        // find the N-canonical form of this supergate
        pGate->nPhases = Map_CanonComputeSlow( pLib->uTruths, pLib->nVarsMax, nRealVars, pGate->uTruth, pGate->uPhases, uCanon );
        // add the supergate into the table by its N-canonical table
        Map_SuperTableInsertC( pLib->tTableC, uCanon, pGate );
Alan Mishchenko committed
692 693 694 695 696 697 698 699 700 701 702
/*
        {
            int uCanon1, uCanon2;
            uCanon1 = uCanon[0];
            pGate->uTruth[0] = ~pGate->uTruth[0];
            pGate->uTruth[1] = ~pGate->uTruth[1];
            Map_CanonComputeSlow( pLib->uTruths, pLib->nVarsMax, nRealVars, pGate->uTruth, pGate->uPhases, uCanon );
            uCanon2 = uCanon[0];
Rwt_Man5ExploreCount( uCanon1 < uCanon2 ? uCanon1 : uCanon2 );
        }
*/
Alan Mishchenko committed
703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774
    }
    // sort the gates in each line
    Map_SuperTableSortSupergatesByDelay( pLib->tTableC, pLib->nSupersAll );

    // let the glory be manifest
//    Map_LibraryPrintTree( pLib );
    return 1;
}

/**Function*************************************************************

  Synopsis    [Finds the largest PI number in the support of the supergate.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Map_LibraryGetMaxSuperPi_rec( Map_Super_t * pGate )
{
    int i, VarCur, VarMax = 0;
    if ( pGate->pRoot == NULL )
        return pGate->Num;
    for ( i = 0; i < (int)pGate->nFanins; i++ )
    {
        VarCur = Map_LibraryGetMaxSuperPi_rec( pGate->pFanins[i] );
        if ( VarMax < VarCur )
            VarMax = VarCur;
    }
    return VarMax;
}

/**Function*************************************************************

  Synopsis    [Finds the largest PI number in the support of the supergate.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
unsigned Map_LibraryGetGateSupp_rec( Map_Super_t * pGate )
{
    unsigned uSupport;
    int i;
    if ( pGate->pRoot == NULL )
        return (unsigned)(1 << (pGate->Num));
    uSupport = 0;
    for ( i = 0; i < (int)pGate->nFanins; i++ )
        uSupport |= Map_LibraryGetGateSupp_rec( pGate->pFanins[i] );
    return uSupport;
}

/**Function*************************************************************

  Synopsis    [Derives the pin-to-pin delay constraints for the supergate.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Map_LibraryAddFaninDelays( Map_SuperLib_t * pLib, Map_Super_t * pGate, Map_Super_t * pFanin, Mio_Pin_t * pPin )
{
    Mio_PinPhase_t PinPhase;
    float tDelayBlockRise, tDelayBlockFall, tDelayPin;
775
    int fMaxDelay = 0;
Alan Mishchenko committed
776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037
    int i;

    // use this node to enable max-delay model
    if ( fMaxDelay )
    {
        float tDelayBlockMax;
        // get the maximum delay
        tDelayBlockMax = (float)Mio_PinReadDelayBlockMax(pPin);
        // go through the supergate inputs
        for ( i = 0; i < pLib->nVarsMax; i++ )
        {
            if ( pFanin->tDelaysR[i].Rise < 0 )
                continue;
            tDelayPin = pFanin->tDelaysR[i].Rise + tDelayBlockMax;
            if ( pGate->tDelaysR[i].Rise < tDelayPin )
                pGate->tDelaysR[i].Rise = tDelayPin;
        }
        // go through the supergate inputs
        for ( i = 0; i < pLib->nVarsMax; i++ )
        {
            if ( pFanin->tDelaysF[i].Fall < 0 )
                continue;
            tDelayPin = pFanin->tDelaysF[i].Fall + tDelayBlockMax;
            if ( pGate->tDelaysF[i].Fall < tDelayPin )
                pGate->tDelaysF[i].Fall = tDelayPin;
        }
        return;
    }

    // get the interesting parameters of this pin
    PinPhase = Mio_PinReadPhase(pPin);
    tDelayBlockRise = (float)Mio_PinReadDelayBlockRise( pPin );  
    tDelayBlockFall = (float)Mio_PinReadDelayBlockFall( pPin );  

    // update the rise and fall of the output depending on the phase of the pin 
    if ( PinPhase != MIO_PHASE_INV )  // NONINV phase is present
    {
        // the rise of the gate is determined by the rise of the fanin
        // the fall of the gate is determined by the fall of the fanin
        for ( i = 0; i < pLib->nVarsMax; i++ )
        {
            ////////////////////////////////////////////////////////
            // consider the rise of the gate
            ////////////////////////////////////////////////////////
            // check two types of constraints on the rise of the fanin:
            // (1) the constraints related to the rise of the PIs
            // (2) the constraints related to the fall of the PIs
            if ( pFanin->tDelaysR[i].Rise >= 0 ) // case (1)
            { // fanin's rise depends on the rise of i-th PI
                // update the rise of the gate's output
                if ( pGate->tDelaysR[i].Rise < pFanin->tDelaysR[i].Rise + tDelayBlockRise )
                    pGate->tDelaysR[i].Rise = pFanin->tDelaysR[i].Rise + tDelayBlockRise;
            }
            if ( pFanin->tDelaysR[i].Fall >= 0 ) // case (2)
            { // fanin's rise depends on the fall of i-th PI
                // update the rise of the gate's output
                if ( pGate->tDelaysR[i].Fall < pFanin->tDelaysR[i].Fall + tDelayBlockRise )
                    pGate->tDelaysR[i].Fall = pFanin->tDelaysR[i].Fall + tDelayBlockRise;
            }
            ////////////////////////////////////////////////////////

            ////////////////////////////////////////////////////////
            // consider the fall of the gate (similar)
            ////////////////////////////////////////////////////////
            // check two types of constraints on the fall of the fanin:
            // (1) the constraints related to the rise of the PIs
            // (2) the constraints related to the fall of the PIs
            if ( pFanin->tDelaysF[i].Rise >= 0 ) // case (1) 
            { 
                if ( pGate->tDelaysF[i].Rise < pFanin->tDelaysF[i].Rise + tDelayBlockFall )
                    pGate->tDelaysF[i].Rise = pFanin->tDelaysF[i].Rise + tDelayBlockFall;
            }
            if ( pFanin->tDelaysF[i].Fall >= 0 ) // case (2) 
            { 
                if ( pGate->tDelaysF[i].Fall < pFanin->tDelaysF[i].Fall + tDelayBlockFall )
                    pGate->tDelaysF[i].Fall = pFanin->tDelaysF[i].Fall + tDelayBlockFall;
            }
            ////////////////////////////////////////////////////////
        }
    }
    if ( PinPhase != MIO_PHASE_NONINV )  // INV phase is present
    {
        // the rise of the gate is determined by the fall of the fanin
        // the fall of the gate is determined by the rise of the fanin
        for ( i = 0; i < pLib->nVarsMax; i++ )
        {
            ////////////////////////////////////////////////////////
            // consider the rise of the gate's output
            ////////////////////////////////////////////////////////
            // check two types of constraints on the fall of the fanin:
            // (1) the constraints related to the rise of the PIs
            // (2) the constraints related to the fall of the PIs
            if ( pFanin->tDelaysF[i].Rise >= 0 ) // case (1)
            { // fanin's rise depends on the rise of i-th PI
                // update the rise of the gate
                if ( pGate->tDelaysR[i].Rise < pFanin->tDelaysF[i].Rise + tDelayBlockRise )
                    pGate->tDelaysR[i].Rise = pFanin->tDelaysF[i].Rise + tDelayBlockRise;
            }
            if ( pFanin->tDelaysF[i].Fall >= 0 ) // case (2)
            { // fanin's rise depends on the fall of i-th PI
                // update the rise of the gate
                if ( pGate->tDelaysR[i].Fall < pFanin->tDelaysF[i].Fall + tDelayBlockRise )
                    pGate->tDelaysR[i].Fall = pFanin->tDelaysF[i].Fall + tDelayBlockRise;
            }
            ////////////////////////////////////////////////////////

            ////////////////////////////////////////////////////////
            // consider the fall of the gate (similar)
            ////////////////////////////////////////////////////////
            // check two types of constraints on the rise of the fanin:
            // (1) the constraints related to the rise of the PIs
            // (2) the constraints related to the fall of the PIs
            if ( pFanin->tDelaysR[i].Rise >= 0 ) // case (1) 
            { 
                if ( pGate->tDelaysF[i].Rise < pFanin->tDelaysR[i].Rise + tDelayBlockFall )
                    pGate->tDelaysF[i].Rise = pFanin->tDelaysR[i].Rise + tDelayBlockFall;
            }
            if ( pFanin->tDelaysR[i].Fall >= 0 ) // case (2) 
            { 
                if ( pGate->tDelaysF[i].Fall < pFanin->tDelaysR[i].Fall + tDelayBlockFall )
                    pGate->tDelaysF[i].Fall = pFanin->tDelaysR[i].Fall + tDelayBlockFall;
            }
            ////////////////////////////////////////////////////////
        }
    }
}


/**Function*************************************************************

  Synopsis    [Performs phase transformation for one function.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
unsigned Map_CalculatePhase( unsigned uTruths[][2], int nVars, unsigned uTruth, unsigned uPhase )
{
    int v, Shift;
    for ( v = 0, Shift = 1; v < nVars; v++, Shift <<= 1 )
        if ( uPhase & Shift )
            uTruth = (((uTruth & ~uTruths[v][0]) << Shift) | ((uTruth & uTruths[v][0]) >> Shift));
    return uTruth;
}

/**Function*************************************************************

  Synopsis    [Performs phase transformation for one function.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Map_CalculatePhase6( unsigned uTruths[][2], int nVars, unsigned uTruth[], unsigned uPhase, unsigned uTruthRes[] )
{
    unsigned uTemp;
    int v, Shift;

    // initialize the result
    uTruthRes[0] = uTruth[0];
    uTruthRes[1] = uTruth[1];
    if ( uPhase == 0 )
        return;
    // compute the phase 
    for ( v = 0, Shift = 1; v < nVars; v++, Shift <<= 1 )
        if ( uPhase & Shift )
        {
            if ( Shift < 32 )
            {
                uTruthRes[0] = (((uTruthRes[0] & ~uTruths[v][0]) << Shift) | ((uTruthRes[0] & uTruths[v][0]) >> Shift));
                uTruthRes[1] = (((uTruthRes[1] & ~uTruths[v][1]) << Shift) | ((uTruthRes[1] & uTruths[v][1]) >> Shift));
            }
            else
            {
                uTemp        = uTruthRes[0];
                uTruthRes[0] = uTruthRes[1];
                uTruthRes[1] = uTemp;
            }
        }
}

/**Function*************************************************************

  Synopsis    [Prints the supergate library after deriving parameters.]

  Description [This procedure is very useful to see the library after
  it has been read into the mapper by "read_super" and all the information
  about the supergates derived.]
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Map_LibraryPrintTree( Map_SuperLib_t * pLib )
{
    Map_Super_t * pGate;
    int i, k;

    // print all the info related to the supergates
//    for ( i = pLib->nVarsMax; i < (int)pLib->nLines; i++ )
    for ( i = pLib->nVarsMax; i < 20; i++ )
    {
        pGate = pLib->ppSupers[i];

        // write the gate's fanin info and formula
        printf( "%6d  ", pGate->Num );
        printf( "%c ", pGate->fSuper? '*' : ' ' );
        printf( "%6s", Mio_GateReadName(pGate->pRoot) );
        for ( k = 0; k < (int)pGate->nFanins; k++ )
            printf( " %6d", pGate->pFanins[k]->Num );
        printf( "  %s", pGate->pFormula );
        printf( "\n" );

        // write the gate's derived info
        Extra_PrintBinary( stdout, pGate->uTruth, 64 );
        printf( "  %3d",   pGate->nGates );
        printf( "  %6.2f", pGate->Area );
        printf( "  (%4.2f, %4.2f)", pGate->tDelayMax.Rise, pGate->tDelayMax.Fall );
        printf( "\n" );
        for ( k = 0; k < pLib->nVarsMax; k++ )
        {
            // print the constraint on the rise of the gate in the form (D1, D2), 
            // where D1 is the constraint related to the rise of the k-th PI
            // where D2 is the constraint related to the fall of the k-th PI
            if ( pGate->tDelaysR[k].Rise < 0 && pGate->tDelaysR[k].Fall < 0 )
                printf( " (----, ----)" );
            else if ( pGate->tDelaysR[k].Fall < 0 )
                printf( " (%4.2f, ----)", pGate->tDelaysR[k].Rise );
            else if ( pGate->tDelaysR[k].Rise < 0 )
                printf( " (----, %4.2f)", pGate->tDelaysR[k].Fall );
            else
                printf( " (%4.2f, %4.2f)", pGate->tDelaysR[k].Rise, pGate->tDelaysR[k].Fall );

            // print the constraint on the fall of the gate in the form (D1, D2), 
            // where D1 is the constraint related to the rise of the k-th PI
            // where D2 is the constraint related to the fall of the k-th PI
            if ( pGate->tDelaysF[k].Rise < 0 && pGate->tDelaysF[k].Fall < 0 )
                printf( " (----, ----)" );
            else if ( pGate->tDelaysF[k].Fall < 0 )
                printf( " (%4.2f, ----)", pGate->tDelaysF[k].Rise );
            else if ( pGate->tDelaysF[k].Rise < 0 )
                printf( " (----, %4.2f)", pGate->tDelaysF[k].Fall );
            else
                printf( " (%4.2f, %4.2f)", pGate->tDelaysF[k].Rise, pGate->tDelaysF[k].Fall );
            printf( "\n" );
        }
        printf( "\n" );
    }
}

////////////////////////////////////////////////////////////////////////
///                       END OF FILE                                ///
////////////////////////////////////////////////////////////////////////


1038 1039
ABC_NAMESPACE_IMPL_END