utilBridge.c 15.3 KB
Newer Older
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    [utilBridge.c]

  SystemName  [ABC: Logic synthesis and verification system.]

  PackageName []

  Synopsis    []

  Author      [Alan Mishchenko]
  
  Affiliation [UC Berkeley]

  Date        [Ver. 1.0. Started - June 20, 2005.]

  Revision    [$Id: utilBridge.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]

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

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
25

26
#include <misc/util/abc_global.h>
27

28
#if defined(LIN) || defined(LIN64)
29 30
#include <unistd.h>
#endif
31

32
#include "aig/gia/gia.h"
33 34 35 36 37 38 39

ABC_NAMESPACE_IMPL_START

////////////////////////////////////////////////////////////////////////
///                        DECLARATIONS                              ///
////////////////////////////////////////////////////////////////////////

40 41 42 43 44 45 46 47 48 49 50 51
#define BRIDGE_TEXT_MESSAGE 999996

#define BRIDGE_ABORT        5
#define BRIDGE_PROGRESS     3
#define BRIDGE_RESULTS      101
#define BRIDGE_BAD_ABS      105
//#define BRIDGE_NETLIST      106
//#define BRIDGE_ABS_NETLIST  107

#define BRIDGE_VALUE_X 0
#define BRIDGE_VALUE_0 2
#define BRIDGE_VALUE_1 3
52 53


54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
////////////////////////////////////////////////////////////////////////
///                     FUNCTION DEFINITIONS                         ///
////////////////////////////////////////////////////////////////////////

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

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
69
Vec_Str_t * Gia_ManToBridgeVec( Gia_Man_t * p )
70
{
71
    Vec_Str_t * vStr;
72
    Gia_Obj_t * pObj;
73 74 75 76 77 78 79
    int i, uLit0, uLit1, nNodes;
    assert( Gia_ManPoNum(p) > 0 );

    // start with const1 node (number 1)
    nNodes = 1;
    // assign literals(!!!) to the value field
    Gia_ManConst0(p)->Value = Abc_Var2Lit( nNodes++, 1 );
80
    Gia_ManForEachCi( p, pObj, i )
81
        pObj->Value = Abc_Var2Lit( nNodes++, 0 );
82
    Gia_ManForEachAnd( p, pObj, i )
83 84 85 86
        pObj->Value = Abc_Var2Lit( nNodes++, 0 );

    // write header
    vStr = Vec_StrAlloc( 1000 );
87 88 89
    Gia_AigerWriteUnsigned( vStr, Gia_ManPiNum(p) );
    Gia_AigerWriteUnsigned( vStr, Gia_ManRegNum(p) );
    Gia_AigerWriteUnsigned( vStr, Gia_ManAndNum(p) );
90 91 92 93 94 95 96

    // write the nodes 
    Gia_ManForEachAnd( p, pObj, i )
    {
        uLit0 = Gia_ObjFanin0Copy( pObj );
        uLit1 = Gia_ObjFanin1Copy( pObj );
        assert( uLit0 != uLit1 );
97 98
        Gia_AigerWriteUnsigned( vStr, uLit0 << 1 );
        Gia_AigerWriteUnsigned( vStr, uLit1 );
99
    }
100 101 102 103

    // write latch drivers
    Gia_ManForEachRi( p, pObj, i )
    {
104
        uLit0 = Gia_ObjFanin0Copy( pObj );
105
        Gia_AigerWriteUnsigned( vStr, (uLit0 << 2) | BRIDGE_VALUE_0 );
106 107 108
    }

    // write PO drivers
109
    Gia_AigerWriteUnsigned( vStr, Gia_ManPoNum(p) );
110 111
    Gia_ManForEachPo( p, pObj, i )
    {
112 113
        uLit0 = Gia_ObjFanin0Copy( pObj );
        // complement property output!!!
114
        Gia_AigerWriteUnsigned( vStr, Abc_LitNot(uLit0) );
115
    }
116
    return vStr;
117 118 119 120 121 122 123 124 125 126 127 128 129
}

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

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
130 131 132 133 134 135
void Gia_CreateHeader( FILE * pFile, int Type, int Size, unsigned char * pBuffer )
{
    fprintf( pFile, "%.6d", Type );
    fprintf( pFile, " " );
    fprintf( pFile, "%.16d", Size );
    fprintf( pFile, " " );
Alan Mishchenko committed
136 137 138
#if !defined(LIN) && !defined(LIN64)
    {
    int RetValue;
139
    RetValue = fwrite( pBuffer, Size, 1, pFile );
140
    assert( RetValue == 1 || Size == 0);
141
    fflush( pFile );
Alan Mishchenko committed
142 143
    }
#else
144 145 146 147 148 149 150 151 152 153 154 155
    fflush(pFile);
    int fd = fileno(pFile);

    ssize_t bytes_written = 0;
    while (bytes_written < Size){
        ssize_t n = write(fd, &pBuffer[bytes_written], Size - bytes_written);
        if (n < 0){
            fprintf(stderr, "BridgeMode: failed to send package; aborting\n"); fflush(stderr);
            _exit(255);
        }
        bytes_written += n;
    }
Alan Mishchenko committed
156
#endif
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
}


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

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Gia_ManToBridgeText( FILE * pFile, int Size, unsigned char * pBuffer )
{
    Gia_CreateHeader( pFile, BRIDGE_TEXT_MESSAGE, Size, pBuffer );
    return 1;
}
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191


int Gia_ManToBridgeAbort( FILE * pFile, int Size, unsigned char * pBuffer )
{
    Gia_CreateHeader( pFile, BRIDGE_ABORT, Size, pBuffer );
    return 1;
}


int Gia_ManToBridgeProgress( FILE * pFile, int Size, unsigned char * pBuffer )
{
    Gia_CreateHeader( pFile, BRIDGE_PROGRESS, Size, pBuffer );
    return 1;
}


192
int Gia_ManToBridgeAbsNetlist( FILE * pFile, void * p, int pkg_type )
193 194
{
    Vec_Str_t * vBuffer;
195
    vBuffer = Gia_ManToBridgeVec( (Gia_Man_t *)p );
196
    Gia_CreateHeader( pFile, pkg_type, Vec_StrSize(vBuffer), (unsigned char *)Vec_StrArray(vBuffer) );
197
    Vec_StrFree( vBuffer );
198 199
    return 1;
}
200 201


202 203 204 205 206 207
int Gia_ManToBridgeBadAbs( FILE * pFile )
{
    Gia_CreateHeader( pFile, BRIDGE_BAD_ABS, 0, NULL );
    return 1;
}

Niklas Een committed
208 209 210 211 212 213 214 215 216 217 218 219 220

static int aigerNumSize( unsigned x )
{
    int sz = 1;
    while (x & ~0x7f)
    {
        sz++;
        x >>= 7;
    }
    return sz;
}


221 222 223 224 225 226 227 228 229 230 231
/**Function*************************************************************

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
232
void Gia_ManFromBridgeHolds( FILE * pFile, int iPoProved )
233
{
234 235
    fprintf( pFile, "%.6d", 101 /*message type = Result*/);
    fprintf( pFile, " " );
Niklas Een committed
236
    fprintf( pFile, "%.16d", 3 + aigerNumSize(iPoProved) /*size in bytes*/);
237 238
    fprintf( pFile, " " );

239
    fputc( (char)BRIDGE_VALUE_1, pFile ); // true
240
    fputc( (char)1, pFile ); // size of vector (Armin's encoding)
241
    Gia_AigerWriteUnsignedFile( pFile, iPoProved ); // number of the property (Armin's encoding)
242
    fputc( (char)0, pFile ); // no invariant
243
    fflush(pFile);
244
}
245
void Gia_ManFromBridgeUnknown( FILE * pFile, int iPoUnknown )
246
{
247 248
    fprintf( pFile, "%.6d", 101 /*message type = Result*/);
    fprintf( pFile, " " );
Niklas Een committed
249
    fprintf( pFile, "%.16d", 2 + aigerNumSize(iPoUnknown) /*size in bytes*/);
250 251
    fprintf( pFile, " " );

252
    fputc( (char)BRIDGE_VALUE_X, pFile ); // undef
253
    fputc( (char)1, pFile ); // size of vector (Armin's encoding)
254
    Gia_AigerWriteUnsignedFile( pFile, iPoUnknown ); // number of the property (Armin's encoding)
255
    fflush(pFile);
256 257 258
}
void Gia_ManFromBridgeCex( FILE * pFile, Abc_Cex_t * pCex )
{
259
    int i, f, iBit;//, RetValue;
260
    Vec_Str_t * vStr = Vec_StrAlloc( 1000 );
261
    Vec_StrPush( vStr, (char)BRIDGE_VALUE_0 ); // false
262
    Vec_StrPush( vStr, (char)1 ); // size of vector (Armin's encoding)
263
    Gia_AigerWriteUnsigned( vStr, pCex->iPo ); // number of the property (Armin's encoding)
264
    Vec_StrPush( vStr, (char)1 ); // size of vector (Armin's encoding)
265
    Gia_AigerWriteUnsigned( vStr, pCex->iFrame ); // depth
266

267 268
    Gia_AigerWriteUnsigned( vStr, 1 ); // concrete
    Gia_AigerWriteUnsigned( vStr, pCex->iFrame + 1 ); // number of frames (1 more than depth)
269 270 271
    iBit = pCex->nRegs;
    for ( f = 0; f <= pCex->iFrame; f++ )
    {
272
        Gia_AigerWriteUnsigned( vStr, pCex->nPis ); // num of inputs
273 274
        for ( i = 0; i < pCex->nPis; i++, iBit++ )
            Vec_StrPush( vStr, (char)(Abc_InfoHasBit(pCex->pData, iBit) ? BRIDGE_VALUE_1:BRIDGE_VALUE_0) ); // value
275 276 277
    }
    assert( iBit == pCex->nBits );
    Vec_StrPush( vStr, (char)1 ); // the number of frames (for a concrete counter-example)
278
    Gia_AigerWriteUnsigned( vStr, pCex->nRegs ); // num of flops
279
    for ( i = 0; i < pCex->nRegs; i++ )
280
        Vec_StrPush( vStr, (char)BRIDGE_VALUE_0 ); // always zero!!!
281 282 283
//    RetValue = fwrite( Vec_StrArray(vStr), Vec_StrSize(vStr), 1, pFile );
    Gia_CreateHeader(pFile, 101/*type=Result*/, Vec_StrSize(vStr), (unsigned char*)Vec_StrArray(vStr));

284
    Vec_StrFree( vStr );
285
    fflush(pFile);
286
}
287
int Gia_ManToBridgeResult( FILE * pFile, int Result, Abc_Cex_t * pCex, int iPoProved )
288 289 290 291
{
    if ( Result == 0 ) // sat
        Gia_ManFromBridgeCex( pFile, pCex );
    else if ( Result == 1 ) // unsat
292
        Gia_ManFromBridgeHolds( pFile, iPoProved );
293
    else if ( Result == -1 ) // undef
294
        Gia_ManFromBridgeUnknown( pFile, iPoProved );
295 296
    else assert( 0 );
    return 1;
297 298 299 300 301 302 303 304
}


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

  Synopsis    []

  Description []
305

306 307 308 309 310 311 312 313 314 315 316 317
  SideEffects []

  SeeAlso     []

***********************************************************************/
Gia_Man_t *  Gia_ManFromBridgeReadBody( int Size, unsigned char * pBuffer, Vec_Int_t ** pvInits )
{
    int fHash = 0;
    Vec_Int_t * vLits, * vInits;
    Gia_Man_t * p = NULL;
    unsigned char * pBufferPivot, * pBufferEnd = pBuffer + Size;
    int i, nInputs, nFlops, nGates, nProps;
318
    int verFairness, nFairness, nConstraints;
319 320
    unsigned iFan0, iFan1;

321 322 323
    nInputs = Gia_AigerReadUnsigned( &pBuffer );
    nFlops  = Gia_AigerReadUnsigned( &pBuffer );
    nGates  = Gia_AigerReadUnsigned( &pBuffer );
324 325

    vLits = Vec_IntAlloc( 1000 );
326
    Vec_IntPush( vLits, -999 );
327 328 329
    Vec_IntPush( vLits,  1 );

    // start the AIG package
330
    p = Gia_ManStart( nInputs + nFlops * 2 + nGates + 1 + 1 ); // PI+FO+FI+AND+PO+1
331 332 333 334 335 336 337 338 339 340 341 342 343 344 345
    p->pName = Abc_UtilStrsav( "temp" );

    // create PIs
    for ( i = 0; i < nInputs; i++ )
        Vec_IntPush( vLits, Gia_ManAppendCi( p ) );

    // create flop outputs
    for ( i = 0; i < nFlops; i++ )
        Vec_IntPush( vLits, Gia_ManAppendCi( p ) );

    // create nodes
    if ( fHash )
        Gia_ManHashAlloc( p );
    for ( i = 0; i < nGates; i++ )
    {
346 347
        iFan0 = Gia_AigerReadUnsigned( &pBuffer );
        iFan1 = Gia_AigerReadUnsigned( &pBuffer );
348
        assert( !(iFan0 & 1) );
349 350
        iFan0 >>= 1;
        iFan0 = Abc_LitNotCond( Vec_IntEntry(vLits, iFan0 >> 1), iFan0 & 1 );
351
        iFan1 = Abc_LitNotCond( Vec_IntEntry(vLits, iFan1 >> 1), iFan1 & 1 );
352 353
        if ( fHash )
            Vec_IntPush( vLits, Gia_ManHashAnd(p, iFan0, iFan1) );
354
        else
355 356 357 358 359 360 361 362
            Vec_IntPush( vLits, Gia_ManAppendAnd(p, iFan0, iFan1) );

    }
    if ( fHash )
        Gia_ManHashStop( p );

    // remember where flops begin
    pBufferPivot = pBuffer;
363
    // scroll through flops
364
    for ( i = 0; i < nFlops; i++ )
365
        Gia_AigerReadUnsigned( &pBuffer );
366 367

    // create POs
368
    nProps = Gia_AigerReadUnsigned( &pBuffer );
369
//    assert( nProps == 1 );
370 371
    for ( i = 0; i < nProps; i++ )
    {
372
        iFan0 = Gia_AigerReadUnsigned( &pBuffer );
373
        iFan0 = Abc_LitNotCond( Vec_IntEntry(vLits, iFan0 >> 1), iFan0 & 1 );
374 375
        // complement property output!!!
        Gia_ManAppendCo( p, Abc_LitNot(iFan0) );
376
    }
377 378 379 380 381 382 383 384 385 386

    verFairness = Gia_AigerReadUnsigned( &pBuffer );
    assert( verFairness == 1 );

    nFairness = Gia_AigerReadUnsigned( &pBuffer );
    assert( nFairness == 0 );

    nConstraints = Gia_AigerReadUnsigned( &pBuffer );
    assert( nConstraints == 0);

387 388 389 390 391 392 393 394
    // make sure the end of buffer is reached
    assert( pBufferEnd == pBuffer );

    // resetting to flops
    pBuffer = pBufferPivot;
    vInits = Vec_IntAlloc( nFlops );
    for ( i = 0; i < nFlops; i++ )
    {
395
        iFan0 = Gia_AigerReadUnsigned( &pBuffer );
396
        assert( (iFan0 & 3) == BRIDGE_VALUE_0 );
397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420
        Vec_IntPush( vInits, iFan0 & 3 ); // 0 = X value; 1 = not used; 2 = false; 3 = true
        iFan0 >>= 2;
        iFan0 = Abc_LitNotCond( Vec_IntEntry(vLits, iFan0 >> 1), iFan0 & 1 );
        Gia_ManAppendCo( p, iFan0 );
    }
    Gia_ManSetRegNum( p, nFlops );
    Vec_IntFree( vLits );

    // remove wholes in the node list
    if ( fHash )
    {
        Gia_Man_t * pTemp;
        p = Gia_ManCleanup( pTemp = p );
        Gia_ManStop( pTemp );
    }

    // return
    if ( pvInits )
        *pvInits = vInits;
    else
        Vec_IntFree( vInits );
    return p;
}

421

422 423 424 425 426
/**Function*************************************************************

  Synopsis    []

  Description []
427

428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Gia_ManFromBridgeReadPackage( FILE * pFile, int * pType, int * pSize, unsigned char ** ppBuffer )
{
    char Temp[24];
    int RetValue;
    RetValue = fread( Temp, 24, 1, pFile );
    if ( RetValue != 1 )
    {
        printf( "Gia_ManFromBridgeReadPackage();  Error 1: Something is wrong!\n" );
        return 0;
    }
    Temp[6] = 0;
    Temp[23]= 0;

    *pType = atoi( Temp );
    *pSize = atoi( Temp + 7 );

449
    *ppBuffer = ABC_ALLOC( unsigned char, *pSize );
450 451 452 453 454 455 456 457 458 459 460 461 462 463 464
    RetValue = fread( *ppBuffer, *pSize, 1, pFile );
    if ( RetValue != 1 && *pSize != 0 )
    {
        ABC_FREE( *ppBuffer );
        printf( "Gia_ManFromBridgeReadPackage();  Error 2: Something is wrong!\n" );
        return 0;
    }
    return 1;
}

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

  Synopsis    []

  Description []
465

466 467 468 469 470 471 472 473 474 475 476 477 478 479
  SideEffects []

  SeeAlso     []

***********************************************************************/
Gia_Man_t * Gia_ManFromBridge( FILE * pFile, Vec_Int_t ** pvInit )
{
    unsigned char * pBuffer;
    int Type, Size, RetValue;
    Gia_Man_t * p = NULL;

    RetValue = Gia_ManFromBridgeReadPackage( pFile, &Type, &Size, &pBuffer );
    ABC_FREE( pBuffer );
    if ( !RetValue )
480
        return NULL;
481 482 483 484 485

    RetValue = Gia_ManFromBridgeReadPackage( pFile, &Type, &Size, &pBuffer );
    if ( !RetValue )
        return NULL;

486
    p = Gia_ManFromBridgeReadBody( Size, pBuffer, pvInit );
487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510
    ABC_FREE( pBuffer );
    if ( p == NULL )
        return NULL;

    RetValue = Gia_ManFromBridgeReadPackage( pFile, &Type, &Size, &pBuffer );
    ABC_FREE( pBuffer );
    if ( !RetValue )
        return NULL;

    return p;
}

/*
    {
        extern void Gia_ManFromBridgeTest( char * pFileName );
        Gia_ManFromBridgeTest( "C:\\_projects\\abc\\_TEST\\bug\\65\\par.dump" );
    }
*/

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

  Synopsis    []

  Description []
511

512 513 514 515 516
  SideEffects []

  SeeAlso     []

***********************************************************************/
517
void Gia_ManToBridgeAbsNetlistTest( char * pFileName, Gia_Man_t * p, int msg_type )
518 519 520 521 522 523 524
{
    FILE * pFile = fopen( pFileName, "wb" );
    if ( pFile == NULL )
    {
        printf( "Cannot open output file \"%s\".\n", pFileName );
        return;
    }
525
    Gia_ManToBridgeAbsNetlist( pFile, p, msg_type );
526 527 528 529 530 531 532 533
    fclose ( pFile );
}

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

  Synopsis    []

  Description []
534

535 536 537 538 539
  SideEffects []

  SeeAlso     []

***********************************************************************/
540 541 542 543 544 545 546 547 548 549 550 551 552
void Gia_ManFromBridgeTest( char * pFileName )
{
    Gia_Man_t * p;
    FILE * pFile = fopen( pFileName, "rb" );
    if ( pFile == NULL )
    {
        printf( "Cannot open input file \"%s\".\n", pFileName );
        return;
    }

    p = Gia_ManFromBridge( pFile, NULL );
    fclose ( pFile );

553
    Gia_ManPrintStats( p, NULL );
554
    Gia_AigerWrite( p, "temp.aig", 0, 0 );
555

556
    Gia_ManToBridgeAbsNetlistTest( "par_.dump", p, BRIDGE_ABS_NETLIST );
557 558 559
    Gia_ManStop( p );
}

560 561


562 563 564 565 566 567
////////////////////////////////////////////////////////////////////////
///                       END OF FILE                                ///
////////////////////////////////////////////////////////////////////////


ABC_NAMESPACE_IMPL_END