giaTim.c 21.9 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 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
/**CFile****************************************************************

  FileName    [giaTim.c]

  SystemName  [ABC: Logic synthesis and verification system.]

  PackageName [Scalable AIG package.]

  Synopsis    [Procedures with hierarchy/timing manager.]

  Author      [Alan Mishchenko]
  
  Affiliation [UC Berkeley]

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

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

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

#include "gia.h"
#include "misc/tim/tim.h"
#include "proof/cec/cec.h"

ABC_NAMESPACE_IMPL_START


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

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

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

  Synopsis    [Duplicates AIG in the DFS order while putting CIs first.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Gia_Man_t * Gia_ManDupNormalize( Gia_Man_t * p )
{
    Gia_Man_t * pNew;
    Gia_Obj_t * pObj;
    int i;
    Gia_ManFillValue( p );
    pNew = Gia_ManStart( Gia_ManObjNum(p) );
    pNew->pName = Abc_UtilStrsav( p->pName );
    pNew->pSpec = Abc_UtilStrsav( p->pSpec );
    Gia_ManConst0(p)->Value = 0;
    Gia_ManForEachCi( p, pObj, i )
        pObj->Value = Gia_ManAppendCi(pNew);
    Gia_ManForEachAnd( p, pObj, i )
        pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
    Gia_ManForEachCo( p, pObj, i )
        pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
    Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
64
    pNew->nConstrs = p->nConstrs;
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
    assert( Gia_ManIsNormalized(pNew) );
    Gia_ManDupRemapEquiv( pNew, p );
    return pNew;
}

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

  Synopsis    [Find the ordering of AIG objects.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
81
int Gia_ManOrderWithBoxes_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vNodes )
82 83
{
    if ( Gia_ObjIsTravIdCurrent(p, pObj) )
84
        return 0;
85
    Gia_ObjSetTravIdCurrent(p, pObj);
86 87
    if ( Gia_ObjIsCi(pObj) )
    {
88
        p->iData2 = Gia_ObjCioId(pObj);
89 90
        return 1;
    }
91
    assert( Gia_ObjIsAnd(pObj) );
92
    if ( Gia_ObjSibl(p, Gia_ObjId(p, pObj)) )
93
        if ( Gia_ManOrderWithBoxes_rec( p, Gia_ObjSiblObj(p, Gia_ObjId(p, pObj)), vNodes ) )
94
            return 1;
95
    if ( Gia_ManOrderWithBoxes_rec( p, Gia_ObjFanin0(pObj), vNodes ) )
96
        return 1;
97
    if ( Gia_ManOrderWithBoxes_rec( p, Gia_ObjFanin1(pObj), vNodes ) )
98
        return 1;
99
    Vec_IntPush( vNodes, Gia_ObjId(p, pObj) );
100
    return 0;
101
}
102
Vec_Int_t * Gia_ManOrderWithBoxes( Gia_Man_t * p )
103
{
Alan Mishchenko committed
104
    Tim_Man_t * pManTime = (Tim_Man_t *)p->pManTime;
105 106 107
    Vec_Int_t * vNodes;
    Gia_Obj_t * pObj;
    int i, k, curCi, curCo;
Alan Mishchenko committed
108
    assert( pManTime != NULL );
109
    assert( Gia_ManIsNormalized( p ) );
110 111 112 113 114 115 116 117
    // start trav IDs
    Gia_ManIncrementTravId( p );
    // start the array
    vNodes = Vec_IntAlloc( Gia_ManObjNum(p) );
    // include constant
    Vec_IntPush( vNodes, 0 );
    Gia_ObjSetTravIdCurrent( p, Gia_ManConst0(p) );
    // include primary inputs
Alan Mishchenko committed
118
    for ( i = 0; i < Tim_ManPiNum(pManTime); i++ )
119 120 121 122 123 124 125
    {
        pObj = Gia_ManPi( p, i );
        Vec_IntPush( vNodes, Gia_ObjId(p, pObj) );
        Gia_ObjSetTravIdCurrent( p, pObj );
        assert( Gia_ObjId(p, pObj) == i+1 );
    }
    // for each box, include box nodes
Alan Mishchenko committed
126
    curCi = Tim_ManPiNum(pManTime);
127
    curCo = 0;
Alan Mishchenko committed
128
    for ( i = 0; i < Tim_ManBoxNum(pManTime); i++ )
129 130
    {
        // add internal nodes
Alan Mishchenko committed
131
        for ( k = 0; k < Tim_ManBoxInputNum(pManTime, i); k++ )
132 133
        {
            pObj = Gia_ManPo( p, curCo + k );
134
            if ( Gia_ManOrderWithBoxes_rec( p, Gia_ObjFanin0(pObj), vNodes ) )
135
            {
136
                int iCiNum  = p->iData2;
Alan Mishchenko committed
137
                int iBoxNum = Tim_ManBoxFindFromCiNum( pManTime, iCiNum );
138
                printf( "The command has to terminate. Boxes are not in a topological order.\n" );
139 140
                printf( "The following information may help debugging (numbers are 0-based):\n" );
                printf( "Input %d of BoxA %d (1stCI = %d; 1stCO = %d) has TFI with CI %d,\n", 
Alan Mishchenko committed
141
                    k, i, Tim_ManBoxOutputFirst(pManTime, i), Tim_ManBoxInputFirst(pManTime, i), iCiNum );
142
                printf( "which corresponds to output %d of BoxB %d (1stCI = %d; 1stCO = %d).\n", 
Alan Mishchenko committed
143 144
                    iCiNum - Tim_ManBoxOutputFirst(pManTime, iBoxNum), iBoxNum, 
                    Tim_ManBoxOutputFirst(pManTime, iBoxNum), Tim_ManBoxInputFirst(pManTime, iBoxNum) );
145
                printf( "In a correct topological order, BoxB should precede BoxA.\n" );
146
                Vec_IntFree( vNodes );
147
                p->iData2 = 0;
148 149
                return NULL;
            }
150 151
        }
        // add POs corresponding to box inputs
Alan Mishchenko committed
152
        for ( k = 0; k < Tim_ManBoxInputNum(pManTime, i); k++ )
153 154 155 156
        {
            pObj = Gia_ManPo( p, curCo + k );
            Vec_IntPush( vNodes, Gia_ObjId(p, pObj) );
        }
Alan Mishchenko committed
157
        curCo += Tim_ManBoxInputNum(pManTime, i);
158
        // add PIs corresponding to box outputs
Alan Mishchenko committed
159
        for ( k = 0; k < Tim_ManBoxOutputNum(pManTime, i); k++ )
160 161 162 163 164
        {
            pObj = Gia_ManPi( p, curCi + k );
            Vec_IntPush( vNodes, Gia_ObjId(p, pObj) );
            Gia_ObjSetTravIdCurrent( p, pObj );
        }
Alan Mishchenko committed
165
        curCi += Tim_ManBoxOutputNum(pManTime, i);
166 167
    }
    // add remaining nodes
Alan Mishchenko committed
168
    for ( i = Tim_ManCoNum(pManTime) - Tim_ManPoNum(pManTime); i < Tim_ManCoNum(pManTime); i++ )
169 170
    {
        pObj = Gia_ManPo( p, i );
171
        Gia_ManOrderWithBoxes_rec( p, Gia_ObjFanin0(pObj), vNodes );
172 173
    }
    // add POs
Alan Mishchenko committed
174
    for ( i = Tim_ManCoNum(pManTime) - Tim_ManPoNum(pManTime); i < Tim_ManCoNum(pManTime); i++ )
175 176 177 178
    {
        pObj = Gia_ManPo( p, i );
        Vec_IntPush( vNodes, Gia_ObjId(p, pObj) );
    }
Alan Mishchenko committed
179
    curCo += Tim_ManPoNum(pManTime);
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197
    // verify counts
    assert( curCi == Gia_ManPiNum(p) );
    assert( curCo == Gia_ManPoNum(p) );
    assert( Vec_IntSize(vNodes) == Gia_ManObjNum(p) );
    return vNodes;
}

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

  Synopsis    [Duplicates AIG according to the timing manager.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
198
Gia_Man_t * Gia_ManDupUnnormalize( Gia_Man_t * p )
199 200 201 202 203
{
    Vec_Int_t * vNodes;
    Gia_Man_t * pNew;
    Gia_Obj_t * pObj;
    int i;
204
    vNodes = Gia_ManOrderWithBoxes( p );
205 206
    if ( vNodes == NULL )
        return NULL;
207 208 209 210
    Gia_ManFillValue( p );
    pNew = Gia_ManStart( Gia_ManObjNum(p) );
    pNew->pName = Abc_UtilStrsav( p->pName );
    pNew->pSpec = Abc_UtilStrsav( p->pSpec );
211 212
    if ( p->pSibls )
        pNew->pSibls = ABC_CALLOC( int, Gia_ManObjNum(p) );
213 214 215
    Gia_ManForEachObjVec( vNodes, p, pObj, i )
    {
        if ( Gia_ObjIsAnd(pObj) )
216
        {
217
            pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
218 219 220
            if ( Gia_ObjSibl(p, Gia_ObjId(p, pObj)) )
                pNew->pSibls[Abc_Lit2Var(pObj->Value)] = Abc_Lit2Var(Gia_ObjSiblObj(p, Gia_ObjId(p, pObj))->Value);        
        }
221 222 223 224 225 226 227 228 229
        else if ( Gia_ObjIsCi(pObj) )
            pObj->Value = Gia_ManAppendCi( pNew );
        else if ( Gia_ObjIsCo(pObj) )
            pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
        else if ( Gia_ObjIsConst0(pObj) )
            pObj->Value = 0;
        else assert( 0 );
    }
    Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
230
    Vec_IntFree( vNodes );
231 232 233 234 235 236
    return pNew;
}


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

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 263 264
  Synopsis    [Remaps the AIG from the old manager into the new manager.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Gia_ManCleanupRemap( Gia_Man_t * p, Gia_Man_t * pGia )
{
    Gia_Obj_t * pObj, * pObjGia;
    int i, iPrev;
    Gia_ManForEachObj1( p, pObj, i )
    {
        iPrev = Gia_ObjValue(pObj);
        if ( iPrev == ~0 )
            continue;
        pObjGia = Gia_ManObj( pGia, Abc_Lit2Var(iPrev) );
        if ( pObjGia->Value == ~0 )
            Gia_ObjSetValue( pObj, pObjGia->Value ); 
        else
            Gia_ObjSetValue( pObj, Abc_LitNotCond(pObjGia->Value, Abc_LitIsCompl(iPrev)) );
    }
}

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

265
  Synopsis    [Computes AIG with boxes.]
266 267 268 269 270 271 272 273

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
274
void Gia_ManDupCollapse_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Gia_Man_t * pNew )
275 276 277 278 279
{
    if ( Gia_ObjIsTravIdCurrent(p, pObj) )
        return;
    Gia_ObjSetTravIdCurrent(p, pObj);
    assert( Gia_ObjIsAnd(pObj) );
280
    if ( Gia_ObjSibl(p, Gia_ObjId(p, pObj)) )
281 282 283
        Gia_ManDupCollapse_rec( p, Gia_ObjSiblObj(p, Gia_ObjId(p, pObj)), pNew );
    Gia_ManDupCollapse_rec( p, Gia_ObjFanin0(pObj), pNew );
    Gia_ManDupCollapse_rec( p, Gia_ObjFanin1(pObj), pNew );
284 285
//    assert( !~pObj->Value );
    pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
286 287
    if ( Gia_ObjSibl(p, Gia_ObjId(p, pObj)) )
        pNew->pSibls[Abc_Lit2Var(pObj->Value)] = Abc_Lit2Var(Gia_ObjSiblObj(p, Gia_ObjId(p, pObj))->Value);        
288
}
289
Gia_Man_t * Gia_ManDupCollapse( Gia_Man_t * p, Gia_Man_t * pBoxes, Vec_Int_t * vBoxPres )
290
{
Alan Mishchenko committed
291
    Tim_Man_t * pManTime = (Tim_Man_t *)p->pManTime;
292 293 294 295
    Gia_Man_t * pNew, * pTemp;
    Gia_Obj_t * pObj, * pObjBox;
    int i, k, curCi, curCo;
    assert( Gia_ManRegNum(p) == 0 );
Alan Mishchenko committed
296
    assert( Gia_ManPiNum(p) == Tim_ManPiNum(pManTime) + Gia_ManPoNum(pBoxes) );
297 298 299
    pNew = Gia_ManStart( Gia_ManObjNum(p) );
    pNew->pName = Abc_UtilStrsav( p->pName );
    pNew->pSpec = Abc_UtilStrsav( p->pSpec );
300 301
    if ( p->pSibls )
        pNew->pSibls = ABC_CALLOC( int, Gia_ManObjNum(p) );
302 303 304 305 306 307
    Gia_ManHashAlloc( pNew );
    // copy const and real PIs
    Gia_ManFillValue( p );
    Gia_ManConst0(p)->Value = 0;
    Gia_ManIncrementTravId( p );
    Gia_ObjSetTravIdCurrent( p, Gia_ManConst0(p) );
Alan Mishchenko committed
308
    for ( i = 0; i < Tim_ManPiNum(pManTime); i++ )
309 310 311 312 313 314
    {
        pObj = Gia_ManPi( p, i );
        pObj->Value = Gia_ManAppendCi(pNew);
        Gia_ObjSetTravIdCurrent( p, pObj );
    }
    // create logic for each box
Alan Mishchenko committed
315
    curCi = Tim_ManPiNum(pManTime);
316
    curCo = 0;
Alan Mishchenko committed
317
    for ( i = 0; i < Tim_ManBoxNum(pManTime); i++ )
318 319 320 321 322 323
    {
        // clean boxes
        Gia_ManIncrementTravId( pBoxes );
        Gia_ObjSetTravIdCurrent( pBoxes, Gia_ManConst0(pBoxes) );
        Gia_ManConst0(pBoxes)->Value = 0;
        // add internal nodes
Alan Mishchenko committed
324
        if ( Tim_ManBoxIsBlack(pManTime, i) )
325
        {
326
            int fSkip = (vBoxPres != NULL && !Vec_IntEntry(vBoxPres, i));
Alan Mishchenko committed
327
            for ( k = 0; k < Tim_ManBoxInputNum(pManTime, i); k++ )
328 329 330 331 332
            {
                pObj = Gia_ManPo( p, curCo + k );
                Gia_ManDupCollapse_rec( p, Gia_ObjFanin0(pObj), pNew );
                pObj->Value = fSkip ? -1 : Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
            }
Alan Mishchenko committed
333
            for ( k = 0; k < Tim_ManBoxOutputNum(pManTime, i); k++ )
334 335 336 337 338
            {
                pObj = Gia_ManPi( p, curCi + k );
                pObj->Value = fSkip ? 0 : Gia_ManAppendCi(pNew);
                Gia_ObjSetTravIdCurrent( p, pObj );
            }
339
        }
340
        else
341
        {
Alan Mishchenko committed
342
            for ( k = 0; k < Tim_ManBoxInputNum(pManTime, i); k++ )
343 344 345 346 347 348 349 350 351
            {
                // build logic
                pObj = Gia_ManPo( p, curCo + k );
                Gia_ManDupCollapse_rec( p, Gia_ObjFanin0(pObj), pNew );
                // transfer to the PI
                pObjBox = Gia_ManPi( pBoxes, k );
                pObjBox->Value = Gia_ObjFanin0Copy(pObj);
                Gia_ObjSetTravIdCurrent( pBoxes, pObjBox );
            }
Alan Mishchenko committed
352
            for ( k = 0; k < Tim_ManBoxOutputNum(pManTime, i); k++ )
353 354
            {
                // build logic
Alan Mishchenko committed
355
                pObjBox = Gia_ManPo( pBoxes, curCi - Tim_ManPiNum(pManTime) + k );
356 357 358 359 360 361
                Gia_ManDupCollapse_rec( pBoxes, Gia_ObjFanin0(pObjBox), pNew );
                // transfer to the PI
                pObj = Gia_ManPi( p, curCi + k );
                pObj->Value = Gia_ObjFanin0Copy(pObjBox);
                Gia_ObjSetTravIdCurrent( p, pObj );
            }
362
        }
Alan Mishchenko committed
363 364
        curCo += Tim_ManBoxInputNum(pManTime, i);
        curCi += Tim_ManBoxOutputNum(pManTime, i);
365 366
    }
    // add remaining nodes
Alan Mishchenko committed
367
    for ( i = Tim_ManCoNum(pManTime) - Tim_ManPoNum(pManTime); i < Tim_ManCoNum(pManTime); i++ )
368 369
    {
        pObj = Gia_ManPo( p, i );
370
        Gia_ManDupCollapse_rec( p, Gia_ObjFanin0(pObj), pNew );
371 372
        pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
    }
Alan Mishchenko committed
373
    curCo += Tim_ManPoNum(pManTime);
374 375 376 377 378 379
    // verify counts
    assert( curCi == Gia_ManPiNum(p) );
    assert( curCo == Gia_ManPoNum(p) );
    Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
    Gia_ManHashStop( pNew );
    pNew = Gia_ManCleanup( pTemp = pNew );
380
    Gia_ManCleanupRemap( p, pTemp );
381
    Gia_ManStop( pTemp );
Alan Mishchenko committed
382 383
    assert( Tim_ManPoNum(pManTime) == Gia_ManPoNum(pNew) );
    assert( Tim_ManPiNum(pManTime) == Gia_ManPiNum(pNew) );
384 385 386 387 388
    return pNew;
}

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

389
  Synopsis    [Computes level with boxes.]
390 391 392 393 394 395 396 397

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
398
int Gia_ManLevelWithBoxes_rec( Gia_Man_t * p, Gia_Obj_t * pObj )
399 400
{
    if ( Gia_ObjIsTravIdCurrent(p, pObj) )
401
        return 0;
402
    Gia_ObjSetTravIdCurrent(p, pObj);
403 404
    if ( Gia_ObjIsCi(pObj) )
        return 1;
405
    assert( Gia_ObjIsAnd(pObj) );
406 407
    if ( Gia_ObjSibl(p, Gia_ObjId(p, pObj)) )
        Gia_ManLevelWithBoxes_rec( p, Gia_ObjSiblObj(p, Gia_ObjId(p, pObj)) );
408 409 410 411
    if ( Gia_ManLevelWithBoxes_rec( p, Gia_ObjFanin0(pObj) ) )
        return 1;
    if ( Gia_ManLevelWithBoxes_rec( p, Gia_ObjFanin1(pObj) ) )
        return 1;
412
    Gia_ObjSetAndLevel( p, pObj );
413
    return 0;
414 415 416
}
int Gia_ManLevelWithBoxes( Gia_Man_t * p )
{
417
    int nAnd2Delay = p->nAnd2Delay ? p->nAnd2Delay : 1;
Alan Mishchenko committed
418
    Tim_Man_t * pManTime = (Tim_Man_t *)p->pManTime;
419 420
    Gia_Obj_t * pObj, * pObjIn;
    int i, k, j, curCi, curCo, LevelMax;
421 422 423 424 425 426
    assert( Gia_ManRegNum(p) == 0 );
    // copy const and real PIs
    Gia_ManCleanLevels( p, Gia_ManObjNum(p) );
    Gia_ObjSetLevel( p, Gia_ManConst0(p), 0 );
    Gia_ManIncrementTravId( p );
    Gia_ObjSetTravIdCurrent( p, Gia_ManConst0(p) );
Alan Mishchenko committed
427
    for ( i = 0; i < Tim_ManPiNum(pManTime); i++ )
428 429
    {
        pObj = Gia_ManPi( p, i );
Alan Mishchenko committed
430
        Gia_ObjSetLevel( p, pObj, Tim_ManGetCiArrival(pManTime, i) / nAnd2Delay );
431 432 433
        Gia_ObjSetTravIdCurrent( p, pObj );
    }
    // create logic for each box
Alan Mishchenko committed
434
    curCi = Tim_ManPiNum(pManTime);
435
    curCo = 0;
Alan Mishchenko committed
436
    for ( i = 0; i < Tim_ManBoxNum(pManTime); i++ )
437
    {
Alan Mishchenko committed
438 439 440
        int nBoxInputs  = Tim_ManBoxInputNum( pManTime, i );
        int nBoxOutputs = Tim_ManBoxOutputNum( pManTime, i );
        float * pDelayTable = Tim_ManBoxDelayTable( pManTime, i );
441 442
        // compute level for TFI of box inputs
        for ( k = 0; k < nBoxInputs; k++ )
443 444
        {
            pObj = Gia_ManPo( p, curCo + k );
445 446 447 448 449
            if ( Gia_ManLevelWithBoxes_rec( p, Gia_ObjFanin0(pObj) ) )
            {
                printf( "Boxes are not in a topological order. Switching to level computation without boxes.\n" );
                return Gia_ManLevelNum( p );
            }
450
            // set box input level
451 452
            Gia_ObjSetCoLevel( p, pObj );
        }
453 454
        // compute level for box outputs
        for ( k = 0; k < nBoxOutputs; k++ )
455 456 457
        {
            pObj = Gia_ManPi( p, curCi + k );
            Gia_ObjSetTravIdCurrent( p, pObj );
458 459 460 461 462 463 464 465
            // evaluate delay of this output
            LevelMax = 0;
            assert( nBoxInputs == (int)pDelayTable[1] );
            for ( j = 0; j < nBoxInputs && (pObjIn = Gia_ManPo(p, curCo + j)); j++ )
                if ( (int)pDelayTable[3+k*nBoxInputs+j] != -ABC_INFINITY )
                    LevelMax = Abc_MaxInt( LevelMax, Gia_ObjLevel(p, pObjIn) + ((int)pDelayTable[3+k*nBoxInputs+j] / nAnd2Delay) );
            // set box output level
            Gia_ObjSetLevel( p, pObj, LevelMax );
466
        }
467 468
        curCo += nBoxInputs;
        curCi += nBoxOutputs;
469 470 471
    }
    // add remaining nodes
    p->nLevels = 0;
Alan Mishchenko committed
472
    for ( i = Tim_ManCoNum(pManTime) - Tim_ManPoNum(pManTime); i < Tim_ManCoNum(pManTime); i++ )
473 474 475 476 477 478
    {
        pObj = Gia_ManPo( p, i );
        Gia_ManLevelWithBoxes_rec( p, Gia_ObjFanin0(pObj) );
        Gia_ObjSetCoLevel( p, pObj );
        p->nLevels = Abc_MaxInt( p->nLevels, Gia_ObjLevel(p, pObj) );
    }
Alan Mishchenko committed
479
    curCo += Tim_ManPoNum(pManTime);
480 481 482 483 484 485 486 487 488
    // verify counts
    assert( curCi == Gia_ManPiNum(p) );
    assert( curCo == Gia_ManPoNum(p) );
//    printf( "Max level is %d.\n", p->nLevels );
    return p->nLevels;
}

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

489
  Synopsis    [Verify XAIG against its spec.]
490 491 492 493 494 495 496 497 498 499 500 501 502

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Gia_ManVerifyWithBoxes( Gia_Man_t * pGia, void * pParsInit )
{
    int fVerbose =  1;
    int Status   = -1;
    Gia_Man_t * pSpec, * pGia0, * pGia1, * pMiter;
503
    Vec_Int_t * vBoxPres = NULL;
504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530
    if ( pGia->pSpec == NULL )
    {
        printf( "Spec file is not given. Use standard flow.\n" );
        return Status;
    }
    if ( pGia->pManTime == NULL )
    {
        printf( "Design has no tim manager. Use standard flow.\n" );
        return Status;
    }
    if ( pGia->pAigExtra == NULL )
    {
        printf( "Design has no box logic. Use standard flow.\n" );
        return Status;
    }
    // read original AIG
    pSpec = Gia_AigerRead( pGia->pSpec, 0, 0 );
    if ( pSpec->pManTime == NULL )
    {
        printf( "Spec has no tim manager. Use standard flow.\n" );
        return Status;
    }
    if ( pSpec->pAigExtra == NULL )
    {
        printf( "Spec has no box logic. Use standard flow.\n" );
        return Status;
    }
531 532
    // if timing managers have different number of black boxes,
    // it is possible that some of the boxes are swept away
533
    if ( Tim_ManBlackBoxNum( (Tim_Man_t *)pSpec->pManTime ) > 0 )
534
    {
535 536
        // specification cannot have fewer boxes than implementation
        if ( Tim_ManBoxNum( (Tim_Man_t *)pSpec->pManTime ) < Tim_ManBoxNum( (Tim_Man_t *)pGia->pManTime ) )
537
        {
538
            printf( "Spec has more boxes than the design. Cannot proceed.\n" );
539 540
            return Status;
        }
541 542 543 544 545 546 547 548 549 550
        // to align the boxes, find what boxes of pSpec are dropped in pGia
        if ( Tim_ManBoxNum( (Tim_Man_t *)pSpec->pManTime ) != Tim_ManBoxNum( (Tim_Man_t *)pGia->pManTime ) )
        {
            vBoxPres = Tim_ManAlignTwo( (Tim_Man_t *)pSpec->pManTime, (Tim_Man_t *)pGia->pManTime );
            if ( vBoxPres == NULL )
            {
                printf( "Boxes of spec and design cannot be aligned. Cannot proceed.\n" );
                return Status;
            }
        }
551 552 553 554 555
    }
    // collapse two designs
    pGia0 = Gia_ManDupCollapse( pSpec, pSpec->pAigExtra, vBoxPres );
    pGia1 = Gia_ManDupCollapse( pGia,  pGia->pAigExtra,  NULL  );
    Vec_IntFreeP( &vBoxPres );
556
    // compute the miter
557
    pMiter = Gia_ManMiter( pGia0, pGia1, 0, 1, 0, 0, fVerbose );
558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575
    if ( pMiter )
    {
        Cec_ParCec_t ParsCec, * pPars = &ParsCec;
        Cec_ManCecSetDefaultParams( pPars );
        pPars->fVerbose = fVerbose;
        if ( pParsInit )
            memcpy( pPars, pParsInit, sizeof(Cec_ParCec_t) );
        Status = Cec_ManVerify( pMiter, pPars );
        Gia_ManStop( pMiter );
        if ( pPars->iOutFail >= 0 )
            Abc_Print( 1, "Verification failed for at least one output (%d).\n", pPars->iOutFail );
    }
    Gia_ManStop( pGia0 );
    Gia_ManStop( pGia1 );
    Gia_ManStop( pSpec );
    return Status;
}

576 577
/**Function*************************************************************

578
  Synopsis    [Update hierarchy/timing manager.]
579 580 581 582 583 584 585 586 587 588

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void * Gia_ManUpdateTimMan( Gia_Man_t * p, Vec_Int_t * vBoxPres )
{
Alan Mishchenko committed
589 590 591 592
    Tim_Man_t * pManTime = (Tim_Man_t *)p->pManTime;
    assert( pManTime != NULL );
    assert( Tim_ManBoxNum(pManTime) == Vec_IntSize(vBoxPres) );
    return Tim_ManTrim( pManTime, vBoxPres );
593 594
}

595 596
/**Function*************************************************************

597
  Synopsis    [Update AIG of the holes.]
598 599 600 601 602 603 604 605

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
606
Gia_Man_t * Gia_ManUpdateExtraAig( void * pTime, Gia_Man_t * p, Vec_Int_t * vBoxPres )
607
{
608
    Gia_Man_t * pNew = NULL;
609
    Tim_Man_t * pManTime = (Tim_Man_t *)pTime;
610
    Vec_Int_t * vOutPres = Vec_IntAlloc( 100 );
611
    int i, k, curPo = 0;
612
    assert( Vec_IntSize(vBoxPres) == Tim_ManBoxNum(pManTime) );
613
    assert( Gia_ManPoNum(p) == Tim_ManCiNum(pManTime) - Tim_ManPiNum(pManTime) );
614 615 616 617 618 619
    for ( i = 0; i < Tim_ManBoxNum(pManTime); i++ )
    {
        for ( k = 0; k < Tim_ManBoxOutputNum(pManTime, i); k++ )
            Vec_IntPush( vOutPres, Vec_IntEntry(vBoxPres, i) );
        curPo += Tim_ManBoxOutputNum(pManTime, i);
    }
620 621 622
    assert( curPo == Gia_ManPoNum(p) );
//    if ( Vec_IntSize(vOutPres) > 0 )
        pNew = Gia_ManDupOutputVec( p, vOutPres );
623 624 625 626
    Vec_IntFree( vOutPres );
    return pNew;
}

627 628 629 630 631 632 633
////////////////////////////////////////////////////////////////////////
///                       END OF FILE                                ///
////////////////////////////////////////////////////////////////////////


ABC_NAMESPACE_IMPL_END