hopUtil.c 18.4 KB
Newer Older
Alan Mishchenko committed
1 2
/**CFile****************************************************************

Alan Mishchenko committed
3
  FileName    [hopUtil.c]
Alan Mishchenko committed
4 5 6 7 8 9 10 11 12 13 14 15 16

  SystemName  [ABC: Logic synthesis and verification system.]

  PackageName [And-Inverter Graph package.]

  Synopsis    [Various procedures.]

  Author      [Alan Mishchenko]
  
  Affiliation [UC Berkeley]

  Date        [Ver. 1.0. Started - May 11, 2006.]

Alan Mishchenko committed
17
  Revision    [$Id: hopUtil.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
Alan Mishchenko committed
18 19 20

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

Alan Mishchenko committed
21
#include "hop.h"
Alan Mishchenko committed
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41

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

////////////////////////////////////////////////////////////////////////
///                     FUNCTION DEFINITIONS                         ///
////////////////////////////////////////////////////////////////////////

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

  Synopsis    [Increments the current traversal ID of the network.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
42
void Hop_ManIncrementTravId( Hop_Man_t * p )
Alan Mishchenko committed
43 44
{
    if ( p->nTravIds >= (1<<30)-1 )
Alan Mishchenko committed
45
        Hop_ManCleanData( p );
Alan Mishchenko committed
46 47 48 49 50
    p->nTravIds++;
}

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

Alan Mishchenko committed
51
  Synopsis    [Cleans the data pointers for the nodes.]
Alan Mishchenko committed
52 53 54 55 56 57 58 59

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
60
void Hop_ManCleanData( Hop_Man_t * p )
Alan Mishchenko committed
61
{
Alan Mishchenko committed
62
    Hop_Obj_t * pObj;
Alan Mishchenko committed
63 64
    int i;
    p->nTravIds = 1;
Alan Mishchenko committed
65 66
    Hop_ManConst1(p)->pData = NULL;
    Hop_ManForEachPi( p, pObj, i )
Alan Mishchenko committed
67
        pObj->pData = NULL;
Alan Mishchenko committed
68
    Hop_ManForEachPo( p, pObj, i )
Alan Mishchenko committed
69
        pObj->pData = NULL;
Alan Mishchenko committed
70
    Hop_ManForEachNode( p, pObj, i )
Alan Mishchenko committed
71 72 73 74 75
        pObj->pData = NULL;
}

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

Alan Mishchenko committed
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
  Synopsis    [Recursively cleans the data pointers in the cone of the node.]

  Description [Applicable to small AIGs only because no caching is performed.]
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Hop_ObjCleanData_rec( Hop_Obj_t * pObj )
{
    assert( !Hop_IsComplement(pObj) );
    assert( !Hop_ObjIsPo(pObj) );
    if ( Hop_ObjIsAnd(pObj) )
    {
        Hop_ObjCleanData_rec( Hop_ObjFanin0(pObj) );
        Hop_ObjCleanData_rec( Hop_ObjFanin1(pObj) );
    }
    pObj->pData = NULL;
}

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

Alan Mishchenko committed
99 100 101 102 103 104 105 106 107
  Synopsis    [Detects multi-input gate rooted at this node.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
108
void Hop_ObjCollectMulti_rec( Hop_Obj_t * pRoot, Hop_Obj_t * pObj, Vec_Ptr_t * vSuper )
Alan Mishchenko committed
109
{
Alan Mishchenko committed
110
    if ( pRoot != pObj && (Hop_IsComplement(pObj) || Hop_ObjIsPi(pObj) || Hop_ObjType(pRoot) != Hop_ObjType(pObj)) )
Alan Mishchenko committed
111 112 113 114
    {
        Vec_PtrPushUnique(vSuper, pObj);
        return;
    }
Alan Mishchenko committed
115 116
    Hop_ObjCollectMulti_rec( pRoot, Hop_ObjChild0(pObj), vSuper );
    Hop_ObjCollectMulti_rec( pRoot, Hop_ObjChild1(pObj), vSuper );
Alan Mishchenko committed
117 118 119 120 121 122 123 124 125 126 127 128 129
}

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

  Synopsis    [Detects multi-input gate rooted at this node.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
130
void Hop_ObjCollectMulti( Hop_Obj_t * pRoot, Vec_Ptr_t * vSuper )
Alan Mishchenko committed
131
{
Alan Mishchenko committed
132
    assert( !Hop_IsComplement(pRoot) );
Alan Mishchenko committed
133
    Vec_PtrClear( vSuper );
Alan Mishchenko committed
134
    Hop_ObjCollectMulti_rec( pRoot, pRoot, vSuper );
Alan Mishchenko committed
135 136 137 138
}

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

Alan Mishchenko committed
139 140 141 142 143 144 145 146 147
  Synopsis    [Returns 1 if the node is the root of MUX or EXOR/NEXOR.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
148
int Hop_ObjIsMuxType( Hop_Obj_t * pNode )
Alan Mishchenko committed
149
{
Alan Mishchenko committed
150
    Hop_Obj_t * pNode0, * pNode1;
Alan Mishchenko committed
151
    // check that the node is regular
Alan Mishchenko committed
152
    assert( !Hop_IsComplement(pNode) );
Alan Mishchenko committed
153
    // if the node is not AND, this is not MUX
Alan Mishchenko committed
154
    if ( !Hop_ObjIsAnd(pNode) )
Alan Mishchenko committed
155 156
        return 0;
    // if the children are not complemented, this is not MUX
Alan Mishchenko committed
157
    if ( !Hop_ObjFaninC0(pNode) || !Hop_ObjFaninC1(pNode) )
Alan Mishchenko committed
158 159
        return 0;
    // get children
Alan Mishchenko committed
160 161
    pNode0 = Hop_ObjFanin0(pNode);
    pNode1 = Hop_ObjFanin1(pNode);
Alan Mishchenko committed
162
    // if the children are not ANDs, this is not MUX
Alan Mishchenko committed
163
    if ( !Hop_ObjIsAnd(pNode0) || !Hop_ObjIsAnd(pNode1) )
Alan Mishchenko committed
164 165
        return 0;
    // otherwise the node is MUX iff it has a pair of equal grandchildren
Alan Mishchenko committed
166 167 168 169
    return (Hop_ObjFanin0(pNode0) == Hop_ObjFanin0(pNode1) && (Hop_ObjFaninC0(pNode0) ^ Hop_ObjFaninC0(pNode1))) || 
           (Hop_ObjFanin0(pNode0) == Hop_ObjFanin1(pNode1) && (Hop_ObjFaninC0(pNode0) ^ Hop_ObjFaninC1(pNode1))) ||
           (Hop_ObjFanin1(pNode0) == Hop_ObjFanin0(pNode1) && (Hop_ObjFaninC1(pNode0) ^ Hop_ObjFaninC0(pNode1))) ||
           (Hop_ObjFanin1(pNode0) == Hop_ObjFanin1(pNode1) && (Hop_ObjFaninC1(pNode0) ^ Hop_ObjFaninC1(pNode1)));
Alan Mishchenko committed
170 171
}

Alan Mishchenko committed
172 173 174 175 176 177 178 179 180 181 182 183

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

  Synopsis    [Recognizes what nodes are inputs of the EXOR.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
184
int Hop_ObjRecognizeExor( Hop_Obj_t * pObj, Hop_Obj_t ** ppFan0, Hop_Obj_t ** ppFan1 )
Alan Mishchenko committed
185
{
Alan Mishchenko committed
186 187 188
    Hop_Obj_t * p0, * p1;
    assert( !Hop_IsComplement(pObj) );
    if ( !Hop_ObjIsNode(pObj) )
Alan Mishchenko committed
189
        return 0;
Alan Mishchenko committed
190
    if ( Hop_ObjIsExor(pObj) )
Alan Mishchenko committed
191
    {
Alan Mishchenko committed
192 193
        *ppFan0 = Hop_ObjChild0(pObj);
        *ppFan1 = Hop_ObjChild1(pObj);
Alan Mishchenko committed
194 195
        return 1;
    }
Alan Mishchenko committed
196 197 198 199
    assert( Hop_ObjIsAnd(pObj) );
    p0 = Hop_ObjChild0(pObj);
    p1 = Hop_ObjChild1(pObj);
    if ( !Hop_IsComplement(p0) || !Hop_IsComplement(p1) )
Alan Mishchenko committed
200
        return 0;
Alan Mishchenko committed
201 202 203
    p0 = Hop_Regular(p0);
    p1 = Hop_Regular(p1);
    if ( !Hop_ObjIsAnd(p0) || !Hop_ObjIsAnd(p1) )
Alan Mishchenko committed
204
        return 0;
Alan Mishchenko committed
205
    if ( Hop_ObjFanin0(p0) != Hop_ObjFanin0(p1) || Hop_ObjFanin1(p0) != Hop_ObjFanin1(p1) )
Alan Mishchenko committed
206
        return 0;
Alan Mishchenko committed
207
    if ( Hop_ObjFaninC0(p0) == Hop_ObjFaninC0(p1) || Hop_ObjFaninC1(p0) == Hop_ObjFaninC1(p1) )
Alan Mishchenko committed
208
        return 0;
Alan Mishchenko committed
209 210
    *ppFan0 = Hop_ObjChild0(p0);
    *ppFan1 = Hop_ObjChild1(p0);
Alan Mishchenko committed
211 212 213
    return 1;
}

Alan Mishchenko committed
214 215 216 217 218 219 220 221 222 223 224 225 226 227
/**Function*************************************************************

  Synopsis    [Recognizes what nodes are control and data inputs of a MUX.]

  Description [If the node is a MUX, returns the control variable C.
  Assigns nodes T and E to be the then and else variables of the MUX. 
  Node C is never complemented. Nodes T and E can be complemented.
  This function also recognizes EXOR/NEXOR gates as MUXes.]
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
228
Hop_Obj_t * Hop_ObjRecognizeMux( Hop_Obj_t * pNode, Hop_Obj_t ** ppNodeT, Hop_Obj_t ** ppNodeE )
Alan Mishchenko committed
229
{
Alan Mishchenko committed
230 231 232
    Hop_Obj_t * pNode0, * pNode1;
    assert( !Hop_IsComplement(pNode) );
    assert( Hop_ObjIsMuxType(pNode) );
Alan Mishchenko committed
233
    // get children
Alan Mishchenko committed
234 235
    pNode0 = Hop_ObjFanin0(pNode);
    pNode1 = Hop_ObjFanin1(pNode);
Alan Mishchenko committed
236 237

    // find the control variable
Alan Mishchenko committed
238
    if ( Hop_ObjFanin1(pNode0) == Hop_ObjFanin1(pNode1) && (Hop_ObjFaninC1(pNode0) ^ Hop_ObjFaninC1(pNode1)) )
Alan Mishchenko committed
239 240
    {
//        if ( Fraig_IsComplement(pNode1->p2) )
Alan Mishchenko committed
241
        if ( Hop_ObjFaninC1(pNode0) )
Alan Mishchenko committed
242
        { // pNode2->p2 is positive phase of C
Alan Mishchenko committed
243 244 245
            *ppNodeT = Hop_Not(Hop_ObjChild0(pNode1));//pNode2->p1);
            *ppNodeE = Hop_Not(Hop_ObjChild0(pNode0));//pNode1->p1);
            return Hop_ObjChild1(pNode1);//pNode2->p2;
Alan Mishchenko committed
246 247 248
        }
        else
        { // pNode1->p2 is positive phase of C
Alan Mishchenko committed
249 250 251
            *ppNodeT = Hop_Not(Hop_ObjChild0(pNode0));//pNode1->p1);
            *ppNodeE = Hop_Not(Hop_ObjChild0(pNode1));//pNode2->p1);
            return Hop_ObjChild1(pNode0);//pNode1->p2;
Alan Mishchenko committed
252 253
        }
    }
Alan Mishchenko committed
254
    else if ( Hop_ObjFanin0(pNode0) == Hop_ObjFanin0(pNode1) && (Hop_ObjFaninC0(pNode0) ^ Hop_ObjFaninC0(pNode1)) )
Alan Mishchenko committed
255 256
    {
//        if ( Fraig_IsComplement(pNode1->p1) )
Alan Mishchenko committed
257
        if ( Hop_ObjFaninC0(pNode0) )
Alan Mishchenko committed
258
        { // pNode2->p1 is positive phase of C
Alan Mishchenko committed
259 260 261
            *ppNodeT = Hop_Not(Hop_ObjChild1(pNode1));//pNode2->p2);
            *ppNodeE = Hop_Not(Hop_ObjChild1(pNode0));//pNode1->p2);
            return Hop_ObjChild0(pNode1);//pNode2->p1;
Alan Mishchenko committed
262 263 264
        }
        else
        { // pNode1->p1 is positive phase of C
Alan Mishchenko committed
265 266 267
            *ppNodeT = Hop_Not(Hop_ObjChild1(pNode0));//pNode1->p2);
            *ppNodeE = Hop_Not(Hop_ObjChild1(pNode1));//pNode2->p2);
            return Hop_ObjChild0(pNode0);//pNode1->p1;
Alan Mishchenko committed
268 269
        }
    }
Alan Mishchenko committed
270
    else if ( Hop_ObjFanin0(pNode0) == Hop_ObjFanin1(pNode1) && (Hop_ObjFaninC0(pNode0) ^ Hop_ObjFaninC1(pNode1)) )
Alan Mishchenko committed
271 272
    {
//        if ( Fraig_IsComplement(pNode1->p1) )
Alan Mishchenko committed
273
        if ( Hop_ObjFaninC0(pNode0) )
Alan Mishchenko committed
274
        { // pNode2->p2 is positive phase of C
Alan Mishchenko committed
275 276 277
            *ppNodeT = Hop_Not(Hop_ObjChild0(pNode1));//pNode2->p1);
            *ppNodeE = Hop_Not(Hop_ObjChild1(pNode0));//pNode1->p2);
            return Hop_ObjChild1(pNode1);//pNode2->p2;
Alan Mishchenko committed
278 279 280
        }
        else
        { // pNode1->p1 is positive phase of C
Alan Mishchenko committed
281 282 283
            *ppNodeT = Hop_Not(Hop_ObjChild1(pNode0));//pNode1->p2);
            *ppNodeE = Hop_Not(Hop_ObjChild0(pNode1));//pNode2->p1);
            return Hop_ObjChild0(pNode0);//pNode1->p1;
Alan Mishchenko committed
284 285
        }
    }
Alan Mishchenko committed
286
    else if ( Hop_ObjFanin1(pNode0) == Hop_ObjFanin0(pNode1) && (Hop_ObjFaninC1(pNode0) ^ Hop_ObjFaninC0(pNode1)) )
Alan Mishchenko committed
287 288
    {
//        if ( Fraig_IsComplement(pNode1->p2) )
Alan Mishchenko committed
289
        if ( Hop_ObjFaninC1(pNode0) )
Alan Mishchenko committed
290
        { // pNode2->p1 is positive phase of C
Alan Mishchenko committed
291 292 293
            *ppNodeT = Hop_Not(Hop_ObjChild1(pNode1));//pNode2->p2);
            *ppNodeE = Hop_Not(Hop_ObjChild0(pNode0));//pNode1->p1);
            return Hop_ObjChild0(pNode1);//pNode2->p1;
Alan Mishchenko committed
294 295 296
        }
        else
        { // pNode1->p2 is positive phase of C
Alan Mishchenko committed
297 298 299
            *ppNodeT = Hop_Not(Hop_ObjChild0(pNode0));//pNode1->p1);
            *ppNodeE = Hop_Not(Hop_ObjChild1(pNode1));//pNode2->p2);
            return Hop_ObjChild1(pNode0);//pNode1->p2;
Alan Mishchenko committed
300 301 302 303 304 305
        }
    }
    assert( 0 ); // this is not MUX
    return NULL;
}

Alan Mishchenko committed
306 307 308

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

Alan Mishchenko committed
309 310 311 312 313 314 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
  Synopsis    [Prints Eqn formula for the AIG rooted at this node.]

  Description [The formula is in terms of PIs, which should have
  their names assigned in pObj->pData fields.]
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Hop_ObjPrintEqn( FILE * pFile, Hop_Obj_t * pObj, Vec_Vec_t * vLevels, int Level )
{
    Vec_Ptr_t * vSuper;
    Hop_Obj_t * pFanin;
    int fCompl, i;
    // store the complemented attribute
    fCompl = Hop_IsComplement(pObj);
    pObj = Hop_Regular(pObj);
    // constant case
    if ( Hop_ObjIsConst1(pObj) )
    {
        fprintf( pFile, "%d", !fCompl );
        return;
    }
    // PI case
    if ( Hop_ObjIsPi(pObj) )
    {
        fprintf( pFile, "%s%s", fCompl? "!" : "", pObj->pData );
        return;
    }
    // AND case
    Vec_VecExpand( vLevels, Level );
    vSuper = Vec_VecEntry(vLevels, Level);
    Hop_ObjCollectMulti( pObj, vSuper );
    fprintf( pFile, "%s", (Level==0? "" : "(") );
    Vec_PtrForEachEntry( vSuper, pFanin, i )
    {
        Hop_ObjPrintEqn( pFile, Hop_NotCond(pFanin, fCompl), vLevels, Level+1 );
        if ( i < Vec_PtrSize(vSuper) - 1 )
            fprintf( pFile, " %s ", fCompl? "+" : "*" );
    }
    fprintf( pFile, "%s", (Level==0? "" : ")") );
    return;
}

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

Alan Mishchenko committed
356 357 358 359 360 361 362 363 364 365
  Synopsis    [Prints Verilog formula for the AIG rooted at this node.]

  Description [The formula is in terms of PIs, which should have
  their names assigned in pObj->pData fields.]
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
366
void Hop_ObjPrintVerilog( FILE * pFile, Hop_Obj_t * pObj, Vec_Vec_t * vLevels, int Level )
Alan Mishchenko committed
367 368
{
    Vec_Ptr_t * vSuper;
Alan Mishchenko committed
369
    Hop_Obj_t * pFanin, * pFanin0, * pFanin1, * pFaninC;
Alan Mishchenko committed
370 371
    int fCompl, i;
    // store the complemented attribute
Alan Mishchenko committed
372 373
    fCompl = Hop_IsComplement(pObj);
    pObj = Hop_Regular(pObj);
Alan Mishchenko committed
374
    // constant case
Alan Mishchenko committed
375
    if ( Hop_ObjIsConst1(pObj) )
Alan Mishchenko committed
376
    {
Alan Mishchenko committed
377
        fprintf( pFile, "1\'b%d", !fCompl );
Alan Mishchenko committed
378 379 380
        return;
    }
    // PI case
Alan Mishchenko committed
381
    if ( Hop_ObjIsPi(pObj) )
Alan Mishchenko committed
382 383 384 385 386
    {
        fprintf( pFile, "%s%s", fCompl? "~" : "", pObj->pData );
        return;
    }
    // EXOR case
Alan Mishchenko committed
387
    if ( Hop_ObjIsExor(pObj) )
Alan Mishchenko committed
388 389 390
    {
        Vec_VecExpand( vLevels, Level );
        vSuper = Vec_VecEntry( vLevels, Level );
Alan Mishchenko committed
391
        Hop_ObjCollectMulti( pObj, vSuper );
Alan Mishchenko committed
392 393 394
        fprintf( pFile, "%s", (Level==0? "" : "(") );
        Vec_PtrForEachEntry( vSuper, pFanin, i )
        {
Alan Mishchenko committed
395
            Hop_ObjPrintVerilog( pFile, Hop_NotCond(pFanin, (fCompl && i==0)), vLevels, Level+1 );
Alan Mishchenko committed
396 397 398 399 400 401 402
            if ( i < Vec_PtrSize(vSuper) - 1 )
                fprintf( pFile, " ^ " );
        }
        fprintf( pFile, "%s", (Level==0? "" : ")") );
        return;
    }
    // MUX case
Alan Mishchenko committed
403
    if ( Hop_ObjIsMuxType(pObj) )
Alan Mishchenko committed
404
    {
Alan Mishchenko committed
405
        if ( Hop_ObjRecognizeExor( pObj, &pFanin0, &pFanin1 ) )
Alan Mishchenko committed
406 407
        {
            fprintf( pFile, "%s", (Level==0? "" : "(") );
Alan Mishchenko committed
408
            Hop_ObjPrintVerilog( pFile, Hop_NotCond(pFanin0, fCompl), vLevels, Level+1 );
Alan Mishchenko committed
409
            fprintf( pFile, " ^ " );
Alan Mishchenko committed
410
            Hop_ObjPrintVerilog( pFile, pFanin1, vLevels, Level+1 );
Alan Mishchenko committed
411 412 413 414
            fprintf( pFile, "%s", (Level==0? "" : ")") );
        }
        else 
        {
Alan Mishchenko committed
415
            pFaninC = Hop_ObjRecognizeMux( pObj, &pFanin1, &pFanin0 );
Alan Mishchenko committed
416
            fprintf( pFile, "%s", (Level==0? "" : "(") );
Alan Mishchenko committed
417
            Hop_ObjPrintVerilog( pFile, pFaninC, vLevels, Level+1 );
Alan Mishchenko committed
418
            fprintf( pFile, " ? " );
Alan Mishchenko committed
419
            Hop_ObjPrintVerilog( pFile, Hop_NotCond(pFanin1, fCompl), vLevels, Level+1 );
Alan Mishchenko committed
420
            fprintf( pFile, " : " );
Alan Mishchenko committed
421
            Hop_ObjPrintVerilog( pFile, Hop_NotCond(pFanin0, fCompl), vLevels, Level+1 );
Alan Mishchenko committed
422 423 424 425 426 427 428
            fprintf( pFile, "%s", (Level==0? "" : ")") );
        }
        return;
    }
    // AND case
    Vec_VecExpand( vLevels, Level );
    vSuper = Vec_VecEntry(vLevels, Level);
Alan Mishchenko committed
429
    Hop_ObjCollectMulti( pObj, vSuper );
Alan Mishchenko committed
430 431 432
    fprintf( pFile, "%s", (Level==0? "" : "(") );
    Vec_PtrForEachEntry( vSuper, pFanin, i )
    {
Alan Mishchenko committed
433
        Hop_ObjPrintVerilog( pFile, Hop_NotCond(pFanin, fCompl), vLevels, Level+1 );
Alan Mishchenko committed
434 435 436 437 438 439 440 441
        if ( i < Vec_PtrSize(vSuper) - 1 )
            fprintf( pFile, " %s ", fCompl? "|" : "&" );
    }
    fprintf( pFile, "%s", (Level==0? "" : ")") );
    return;
}


Alan Mishchenko committed
442 443 444 445 446 447 448 449 450 451 452
/**Function*************************************************************

  Synopsis    [Prints node in HAIG.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
453
void Hop_ObjPrintVerbose( Hop_Obj_t * pObj, int fHaig )
Alan Mishchenko committed
454
{
Alan Mishchenko committed
455
    assert( !Hop_IsComplement(pObj) );
Alan Mishchenko committed
456
    printf( "Node %p : ", pObj );
Alan Mishchenko committed
457
    if ( Hop_ObjIsConst1(pObj) )
Alan Mishchenko committed
458
        printf( "constant 1" );
Alan Mishchenko committed
459
    else if ( Hop_ObjIsPi(pObj) )
Alan Mishchenko committed
460 461 462
        printf( "PI" );
    else
        printf( "AND( %p%s, %p%s )", 
Alan Mishchenko committed
463 464 465
            Hop_ObjFanin0(pObj), (Hop_ObjFaninC0(pObj)? "\'" : " "), 
            Hop_ObjFanin1(pObj), (Hop_ObjFaninC1(pObj)? "\'" : " ") );
    printf( " (refs = %3d)", Hop_ObjRefs(pObj) );
Alan Mishchenko committed
466 467 468 469 470 471 472 473 474 475 476 477 478
}

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

  Synopsis    [Prints node in HAIG.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
479
void Hop_ManPrintVerbose( Hop_Man_t * p, int fHaig )
Alan Mishchenko committed
480 481
{
    Vec_Ptr_t * vNodes;
Alan Mishchenko committed
482
    Hop_Obj_t * pObj;
Alan Mishchenko committed
483 484
    int i;
    printf( "PIs: " );
Alan Mishchenko committed
485
    Hop_ManForEachPi( p, pObj, i )
Alan Mishchenko committed
486 487
        printf( " %p", pObj );
    printf( "\n" );
Alan Mishchenko committed
488
    vNodes = Hop_ManDfs( p );
Alan Mishchenko committed
489
    Vec_PtrForEachEntry( vNodes, pObj, i )
Alan Mishchenko committed
490
        Hop_ObjPrintVerbose( pObj, fHaig ), printf( "\n" );
Alan Mishchenko committed
491 492 493
    printf( "\n" );
}

Alan Mishchenko committed
494 495 496 497 498 499 500 501 502
/**Function*************************************************************

  Synopsis    [Writes the AIG into the BLIF file.]

  Description []
               
  SideEffects []

  SeeAlso     []
Alan Mishchenko committed
503

Alan Mishchenko committed
504
***********************************************************************/
Alan Mishchenko committed
505
void Hop_ManDumpBlif( Hop_Man_t * p, char * pFileName )
Alan Mishchenko committed
506 507 508
{
    FILE * pFile;
    Vec_Ptr_t * vNodes;
Alan Mishchenko committed
509
    Hop_Obj_t * pObj, * pConst1 = NULL;
Alan Mishchenko committed
510
    int i, nDigits, Counter = 0;
Alan Mishchenko committed
511
    if ( Hop_ManPoNum(p) == 0 )
Alan Mishchenko committed
512
    {
Alan Mishchenko committed
513
        printf( "Hop_ManDumpBlif(): AIG manager does not have POs.\n" );
Alan Mishchenko committed
514 515 516
        return;
    }
    // collect nodes in the DFS order
Alan Mishchenko committed
517
    vNodes = Hop_ManDfs( p );
Alan Mishchenko committed
518
    // assign IDs to objects
Alan Mishchenko committed
519 520
    Hop_ManConst1(p)->pData = (void *)Counter++;
    Hop_ManForEachPi( p, pObj, i )
Alan Mishchenko committed
521
        pObj->pData = (void *)Counter++;
Alan Mishchenko committed
522
    Hop_ManForEachPo( p, pObj, i )
Alan Mishchenko committed
523 524 525
        pObj->pData = (void *)Counter++;
    Vec_PtrForEachEntry( vNodes, pObj, i )
        pObj->pData = (void *)Counter++;
Alan Mishchenko committed
526
    nDigits = Hop_Base10Log( Counter );
Alan Mishchenko committed
527 528
    // write the file
    pFile = fopen( pFileName, "w" );
Alan Mishchenko committed
529
    fprintf( pFile, "# BLIF file written by procedure Hop_ManDumpBlif() in ABC\n" );
Alan Mishchenko committed
530 531 532 533
    fprintf( pFile, "# http://www.eecs.berkeley.edu/~alanmi/abc/\n" );
    fprintf( pFile, ".model test\n" );
    // write PIs
    fprintf( pFile, ".inputs" );
Alan Mishchenko committed
534
    Hop_ManForEachPi( p, pObj, i )
Alan Mishchenko committed
535 536 537 538
        fprintf( pFile, " n%0*d", nDigits, (int)pObj->pData );
    fprintf( pFile, "\n" );
    // write POs
    fprintf( pFile, ".outputs" );
Alan Mishchenko committed
539
    Hop_ManForEachPo( p, pObj, i )
Alan Mishchenko committed
540 541 542 543 544 545
        fprintf( pFile, " n%0*d", nDigits, (int)pObj->pData );
    fprintf( pFile, "\n" );
    // write nodes
    Vec_PtrForEachEntry( vNodes, pObj, i )
    {
        fprintf( pFile, ".names n%0*d n%0*d n%0*d\n", 
Alan Mishchenko committed
546 547
            nDigits, (int)Hop_ObjFanin0(pObj)->pData, 
            nDigits, (int)Hop_ObjFanin1(pObj)->pData, 
Alan Mishchenko committed
548
            nDigits, (int)pObj->pData );
Alan Mishchenko committed
549
        fprintf( pFile, "%d%d 1\n", !Hop_ObjFaninC0(pObj), !Hop_ObjFaninC1(pObj) );
Alan Mishchenko committed
550 551
    }
    // write POs
Alan Mishchenko committed
552
    Hop_ManForEachPo( p, pObj, i )
Alan Mishchenko committed
553 554
    {
        fprintf( pFile, ".names n%0*d n%0*d\n", 
Alan Mishchenko committed
555
            nDigits, (int)Hop_ObjFanin0(pObj)->pData, 
Alan Mishchenko committed
556
            nDigits, (int)pObj->pData );
Alan Mishchenko committed
557 558 559
        fprintf( pFile, "%d 1\n", !Hop_ObjFaninC0(pObj) );
        if ( Hop_ObjIsConst1(Hop_ObjFanin0(pObj)) )
            pConst1 = Hop_ManConst1(p);
Alan Mishchenko committed
560 561 562 563 564 565 566
    }
    if ( pConst1 )
        fprintf( pFile, ".names n%0*d\n 1\n", nDigits, (int)pConst1->pData );
    fprintf( pFile, ".end\n\n" );
    fclose( pFile );
    Vec_PtrFree( vNodes );
}
Alan Mishchenko committed
567

Alan Mishchenko committed
568 569 570 571 572
////////////////////////////////////////////////////////////////////////
///                       END OF FILE                                ///
////////////////////////////////////////////////////////////////////////