abcMap.c 35.4 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
/**CFile****************************************************************

  FileName    [abcMap.c]

  SystemName  [ABC: Logic synthesis and verification system.]

  PackageName [Network and node package.]

  Synopsis    [Interface with the SC mapping package.]

  Author      [Alan Mishchenko]
  
  Affiliation [UC Berkeley]

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

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

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

21 22 23 24
#include "base/abc/abc.h"
#include "base/main/main.h"
#include "map/mio/mio.h"
#include "map/mapper/mapper.h"
25 26
#include "misc/util/utilNam.h"
#include "map/scl/sclCon.h"
Alan Mishchenko committed
27

28 29 30
ABC_NAMESPACE_IMPL_START


Alan Mishchenko committed
31 32 33 34
////////////////////////////////////////////////////////////////////////
///                        DECLARATIONS                              ///
////////////////////////////////////////////////////////////////////////

Alan Mishchenko committed
35
static Map_Man_t *  Abc_NtkToMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, float * pSwitching, int fVerbose );
Alan Mishchenko committed
36 37 38
static Abc_Ntk_t *  Abc_NtkFromMap( Map_Man_t * pMan, Abc_Ntk_t * pNtk );
static Abc_Obj_t *  Abc_NodeFromMap_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, int fPhase );
static Abc_Obj_t *  Abc_NodeFromMapPhase_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, int fPhase );
Alan Mishchenko committed
39 40 41 42 43 44

static Abc_Ntk_t *  Abc_NtkFromMapSuperChoice( Map_Man_t * pMan, Abc_Ntk_t * pNtk );
static void         Abc_NodeSuperChoice( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode );
static void         Abc_NodeFromMapCutPhase( Abc_Ntk_t * pNtkNew, Map_Cut_t * pCut, int fPhase );
static Abc_Obj_t *  Abc_NodeFromMapSuperChoice_rec( Abc_Ntk_t * pNtkNew, Map_Super_t * pSuper, Abc_Obj_t * pNodePis[], int nNodePis );

Alan Mishchenko committed
45 46
 
////////////////////////////////////////////////////////////////////////
Alan Mishchenko committed
47
///                     FUNCTION DEFINITIONS                         ///
Alan Mishchenko committed
48 49 50 51 52 53 54 55 56 57 58 59 60
////////////////////////////////////////////////////////////////////////

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

  Synopsis    [Interface with the mapping package.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
61
Abc_Ntk_t * Abc_NtkMap( Abc_Ntk_t * pNtk, double DelayTarget, double AreaMulti, double DelayMulti, float LogFan, float Slew, float Gain, int nGatesMin, int fRecovery, int fSwitching, int fSkipFanout, int fUseProfile, int fVerbose )
Alan Mishchenko committed
62
{
63
    static int fUseMulti = 0;
Alan Mishchenko committed
64
    int fShowSwitching = 1;
Alan Mishchenko committed
65 66
    Abc_Ntk_t * pNtkNew;
    Map_Man_t * pMan;
Alan Mishchenko committed
67
    Vec_Int_t * vSwitching = NULL;
Alan Mishchenko committed
68
    float * pSwitching = NULL;
69
    abctime clk, clkTotal = Abc_Clock();
70 71
    Mio_Library_t * pLib = (Mio_Library_t *)Abc_FrameReadLibGen();

Alan Mishchenko committed
72
    assert( Abc_NtkIsStrash(pNtk) );
73
    // derive library from SCL
74
    // if the library is created here, it will be deleted when pSuperLib is deleted in Map_SuperLibFree()
75
    if ( Abc_FrameReadLibScl() && Abc_SclHasDelayInfo( Abc_FrameReadLibScl() ) )
76
    {
77 78 79 80
        if ( pLib && Mio_LibraryHasProfile(pLib) )
            pLib = Abc_SclDeriveGenlib( Abc_FrameReadLibScl(), pLib, Slew, Gain, nGatesMin, fVerbose );
        else
            pLib = Abc_SclDeriveGenlib( Abc_FrameReadLibScl(), NULL, Slew, Gain, nGatesMin, fVerbose );
81
        if ( Abc_FrameReadLibGen() )
82
        {
83
            Mio_LibraryTransferDelays( (Mio_Library_t *)Abc_FrameReadLibGen(), pLib );
84 85
            Mio_LibraryTransferProfile( pLib, (Mio_Library_t *)Abc_FrameReadLibGen() );
        }
86 87 88
        // remove supergate library
        Map_SuperLibFree( (Map_SuperLib_t *)Abc_FrameReadLibSuper() );
        Abc_FrameSetLibSuper( NULL );
89
    }
90
    // quit if there is no library
91
    if ( pLib == NULL )
Alan Mishchenko committed
92 93 94 95
    {
        printf( "The current library is not available.\n" );
        return 0;
    }
96 97 98 99 100
    if ( AreaMulti != 0.0 )
        fUseMulti = 1, printf( "The cell areas are multiplied by the factor: <num_fanins> ^ (%.2f).\n", AreaMulti );
    if ( DelayMulti != 0.0 )
        fUseMulti = 1, printf( "The cell delays are multiplied by the factor: <num_fanins> ^ (%.2f).\n", DelayMulti );

101
    // penalize large gates by increasing their area
102 103 104 105
    if ( AreaMulti != 0.0 )
        Mio_LibraryMultiArea( pLib, AreaMulti );
    if ( DelayMulti != 0.0 )
        Mio_LibraryMultiDelay( pLib, DelayMulti );
106

Alan Mishchenko committed
107
    // derive the supergate library
108
    if ( fUseMulti || Abc_FrameReadLibSuper() == NULL )
Alan Mishchenko committed
109
    {
110 111 112
        if ( fVerbose )
            printf( "Converting \"%s\" into supergate library \"%s\".\n", 
                Mio_LibraryReadName(pLib), Extra_FileNameGenericAppend(Mio_LibraryReadName(pLib), ".super") );
113
        // compute supergate library to be used for mapping
114 115
        if ( Mio_LibraryHasProfile(pLib) )
            printf( "Abc_NtkMap(): Genlib library has profile.\n" );
116
        Map_SuperLibDeriveFromGenlib( pLib, fVerbose );
Alan Mishchenko committed
117 118
    }

119 120
    // return the library to normal
    if ( AreaMulti != 0.0 )
121
        Mio_LibraryMultiArea( (Mio_Library_t *)Abc_FrameReadLibGen(), -AreaMulti );
122
    if ( DelayMulti != 0.0 )
123
        Mio_LibraryMultiDelay( (Mio_Library_t *)Abc_FrameReadLibGen(), -DelayMulti );
124

Alan Mishchenko committed
125
    // print a warning about choice nodes
126
    if ( fVerbose && Abc_NtkGetChoiceNum( pNtk ) )
Alan Mishchenko committed
127 128
        printf( "Performing mapping with choices.\n" );

Alan Mishchenko committed
129 130 131 132 133 134 135 136 137
    // compute switching activity
    fShowSwitching |= fSwitching;
    if ( fShowSwitching )
    {
        extern Vec_Int_t * Sim_NtkComputeSwitching( Abc_Ntk_t * pNtk, int nPatterns );
        vSwitching = Sim_NtkComputeSwitching( pNtk, 4096 );
        pSwitching = (float *)vSwitching->pArray;
    }

Alan Mishchenko committed
138
    // perform the mapping
Alan Mishchenko committed
139 140
    pMan = Abc_NtkToMap( pNtk, DelayTarget, fRecovery, pSwitching, fVerbose );
    if ( pSwitching ) Vec_IntFree( vSwitching );
Alan Mishchenko committed
141 142
    if ( pMan == NULL )
        return NULL;
143
clk = Abc_Clock();
Alan Mishchenko committed
144
    Map_ManSetSwitching( pMan, fSwitching );
145
    Map_ManSetSkipFanout( pMan, fSkipFanout );
146 147
    if ( fUseProfile )
        Map_ManSetUseProfile( pMan );
148 149
    if ( LogFan != 0 )
        Map_ManCreateNodeDelays( pMan, LogFan );
Alan Mishchenko committed
150 151 152 153 154
    if ( !Map_Mapping( pMan ) )
    {
        Map_ManFree( pMan );
        return NULL;
    }
155
//    Map_ManPrintStatsToFile( pNtk->pSpec, Map_ManReadAreaFinal(pMan), Map_ManReadRequiredGlo(pMan), Abc_Clock()-clk );
Alan Mishchenko committed
156 157 158

    // reconstruct the network after mapping
    pNtkNew = Abc_NtkFromMap( pMan, pNtk );
159 160
    if ( Mio_LibraryHasProfile(pLib) )
        Mio_LibraryTransferProfile2( (Mio_Library_t *)Abc_FrameReadLibGen(), pLib );
Alan Mishchenko committed
161
    Map_ManFree( pMan );
Alan Mishchenko committed
162 163 164
    if ( pNtkNew == NULL )
        return NULL;

Alan Mishchenko committed
165 166
    if ( pNtk->pExdc )
        pNtkNew->pExdc = Abc_NtkDup( pNtk->pExdc );
Alan Mishchenko committed
167 168
if ( fVerbose )
{
169
ABC_PRT( "Total runtime", Abc_Clock() - clkTotal );
Alan Mishchenko committed
170
}
Alan Mishchenko committed
171

Alan Mishchenko committed
172
    // make sure that everything is okay
Alan Mishchenko committed
173
    if ( !Abc_NtkCheck( pNtkNew ) )
Alan Mishchenko committed
174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
    {
        printf( "Abc_NtkMap: The network check has failed.\n" );
        Abc_NtkDelete( pNtkNew );
        return NULL;
    }
    return pNtkNew;
}

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

  Synopsis    [Load the network into manager.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
193 194 195 196 197 198 199
Map_Time_t * Abc_NtkMapCopyCiArrival( Abc_Ntk_t * pNtk, Abc_Time_t * ppTimes )
{
    Map_Time_t * p;
    int i;
    p = ABC_CALLOC( Map_Time_t, Abc_NtkCiNum(pNtk) );
    for ( i = 0; i < Abc_NtkCiNum(pNtk); i++ )
    {
200 201 202
        p[i].Fall = ppTimes[i].Fall;
        p[i].Rise = ppTimes[i].Rise;
        p[i].Worst = Abc_MaxFloat( p[i].Fall, p[i].Rise );
203 204 205 206 207 208 209 210 211 212 213
    }
    ABC_FREE( ppTimes );
    return p;
}
Map_Time_t * Abc_NtkMapCopyCoRequired( Abc_Ntk_t * pNtk, Abc_Time_t * ppTimes )
{
    Map_Time_t * p;
    int i;
    p = ABC_CALLOC( Map_Time_t, Abc_NtkCoNum(pNtk) );
    for ( i = 0; i < Abc_NtkCoNum(pNtk); i++ )
    {
214 215 216
        p[i].Fall = ppTimes[i].Fall;
        p[i].Rise = ppTimes[i].Rise;
        p[i].Worst = Abc_MaxFloat( p[i].Fall, p[i].Rise );
217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232
    }
    ABC_FREE( ppTimes );
    return p;
}

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

  Synopsis    [Load the network into manager.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
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
Map_Time_t * Abc_NtkMapCopyCiArrivalCon( Abc_Ntk_t * pNtk )
{
    Map_Time_t * p; int i;
    p = ABC_CALLOC( Map_Time_t, Abc_NtkCiNum(pNtk) );
    for ( i = 0; i < Abc_NtkCiNum(pNtk); i++ )
        p[i].Fall = p[i].Rise = p[i].Worst = Scl_Int2Flt( Scl_ConGetInArr(i) );
    return p;
}
Map_Time_t * Abc_NtkMapCopyCoRequiredCon( Abc_Ntk_t * pNtk )
{
    Map_Time_t * p; int i;
    p = ABC_CALLOC( Map_Time_t, Abc_NtkCoNum(pNtk) );
    for ( i = 0; i < Abc_NtkCoNum(pNtk); i++ )
        p[i].Fall = p[i].Rise = p[i].Worst = Scl_Int2Flt( Scl_ConGetOutReq(i) );
    return p;
}

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

  Synopsis    [Load the network into manager.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
261
Map_Man_t * Abc_NtkToMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, float * pSwitching, int fVerbose )
Alan Mishchenko committed
262 263 264 265 266 267 268
{
    Map_Man_t * pMan;
    Map_Node_t * pNodeMap;
    Vec_Ptr_t * vNodes;
    Abc_Obj_t * pNode, * pFanin, * pPrev;
    int i;

Alan Mishchenko committed
269
    assert( Abc_NtkIsStrash(pNtk) );
Alan Mishchenko committed
270 271

    // start the mapping manager and set its parameters
272
    pMan = Map_ManCreate( Abc_NtkPiNum(pNtk) + Abc_NtkLatchNum(pNtk) - pNtk->nBarBufs, Abc_NtkPoNum(pNtk) + Abc_NtkLatchNum(pNtk) - pNtk->nBarBufs, fVerbose );
Alan Mishchenko committed
273 274 275
    if ( pMan == NULL )
        return NULL;
    Map_ManSetAreaRecovery( pMan, fRecovery );
Alan Mishchenko committed
276
    Map_ManSetOutputNames( pMan, Abc_NtkCollectCioNames(pNtk, 1) );
Alan Mishchenko committed
277
    Map_ManSetDelayTarget( pMan, (float)DelayTarget );
278 279 280 281 282 283 284 285 286 287

    // set arrival and requireds
    if ( Scl_ConIsRunning() && Scl_ConHasInArrs() )
        Map_ManSetInputArrivals( pMan, Abc_NtkMapCopyCiArrivalCon(pNtk) );
    else
        Map_ManSetInputArrivals( pMan, Abc_NtkMapCopyCiArrival(pNtk, Abc_NtkGetCiArrivalTimes(pNtk)) );
    if ( Scl_ConIsRunning() && Scl_ConHasOutReqs() )
        Map_ManSetOutputRequireds( pMan, Abc_NtkMapCopyCoRequiredCon(pNtk) );
    else
        Map_ManSetOutputRequireds( pMan, Abc_NtkMapCopyCoRequired(pNtk, Abc_NtkGetCoRequiredTimes(pNtk)) );
Alan Mishchenko committed
288 289 290

    // create PIs and remember them in the old nodes
    Abc_NtkCleanCopy( pNtk );
Alan Mishchenko committed
291
    Abc_AigConst1(pNtk)->pCopy = (Abc_Obj_t *)Map_ManReadConst1(pMan);
Alan Mishchenko committed
292
    Abc_NtkForEachCi( pNtk, pNode, i )
Alan Mishchenko committed
293
    {
294 295
        if ( i == Abc_NtkCiNum(pNtk) - pNtk->nBarBufs )
            break;
Alan Mishchenko committed
296 297 298 299 300
        pNodeMap = Map_ManReadInputs(pMan)[i];
        pNode->pCopy = (Abc_Obj_t *)pNodeMap;
        if ( pSwitching )
            Map_NodeSetSwitching( pNodeMap, pSwitching[pNode->Id] );
    }
Alan Mishchenko committed
301 302

    // load the AIG into the mapper
303
    vNodes = Abc_AigDfsMap( pNtk );
304
    Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNode, i )
Alan Mishchenko committed
305
    {
306 307 308 309 310 311 312 313
        if ( Abc_ObjIsLatch(pNode) )
        {
            pFanin = Abc_ObjFanin0(pNode);
            pNodeMap = Map_NodeBuf( pMan, Map_NotCond( Abc_ObjFanin0(pFanin)->pCopy, (int)Abc_ObjFaninC0(pFanin) ) );
            Abc_ObjFanout0(pNode)->pCopy = (Abc_Obj_t *)pNodeMap;
            continue;
        }
        assert( Abc_ObjIsNode(pNode) );
Alan Mishchenko committed
314 315
        // add the node to the mapper
        pNodeMap = Map_NodeAnd( pMan, 
316 317
            Map_NotCond( Abc_ObjFanin0(pNode)->pCopy, (int)Abc_ObjFaninC0(pNode) ),
            Map_NotCond( Abc_ObjFanin1(pNode)->pCopy, (int)Abc_ObjFaninC1(pNode) ) );
Alan Mishchenko committed
318 319 320
        assert( pNode->pCopy == NULL );
        // remember the node
        pNode->pCopy = (Abc_Obj_t *)pNodeMap;
Alan Mishchenko committed
321 322
        if ( pSwitching )
            Map_NodeSetSwitching( pNodeMap, pSwitching[pNode->Id] );
Alan Mishchenko committed
323
        // set up the choice node
Alan Mishchenko committed
324
        if ( Abc_AigNodeIsChoice( pNode ) )
325
            for ( pPrev = pNode, pFanin = (Abc_Obj_t *)pNode->pData; pFanin; pPrev = pFanin, pFanin = (Abc_Obj_t *)pFanin->pData )
Alan Mishchenko committed
326 327 328 329 330
            {
                Map_NodeSetNextE( (Map_Node_t *)pPrev->pCopy, (Map_Node_t *)pFanin->pCopy );
                Map_NodeSetRepr( (Map_Node_t *)pFanin->pCopy, (Map_Node_t *)pNode->pCopy );
            }
    }
331
    assert( Map_ManReadBufNum(pMan) == pNtk->nBarBufs );
Alan Mishchenko committed
332 333 334 335
    Vec_PtrFree( vNodes );

    // set the primary outputs in the required phase
    Abc_NtkForEachCo( pNtk, pNode, i )
336 337 338
    {
        if ( i == Abc_NtkCoNum(pNtk) - pNtk->nBarBufs )
            break;
339
        Map_ManReadOutputs(pMan)[i] = Map_NotCond( (Map_Node_t *)Abc_ObjFanin0(pNode)->pCopy, (int)Abc_ObjFaninC0(pNode) );
340
    }
Alan Mishchenko committed
341 342 343 344 345 346 347 348 349 350 351 352 353 354
    return pMan;
}

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

  Synopsis    [Creates the mapped network.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
355
Abc_Obj_t * Abc_NodeFromMapSuper_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, Map_Super_t * pSuper, Abc_Obj_t * pNodePis[], int nNodePis )
Alan Mishchenko committed
356
{
357 358 359 360 361 362 363 364 365
    Mio_Library_t * pLib = (Mio_Library_t *)Abc_FrameReadLibGen();
    Mio_Gate_t * pRoot;
    Map_Super_t ** ppFanins;
    Abc_Obj_t * pNodeNew, * pNodeFanin;
    int nFanins, Number, i;

    // get the parameters of the supergate
    pRoot = Map_SuperReadRoot(pSuper);
    if ( pRoot == NULL )
Alan Mishchenko committed
366
    {
367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382
        Number = Map_SuperReadNum(pSuper);
        if ( Number < nNodePis )  
        {
            return pNodePis[Number];
        }
        else
        {  
//            assert( 0 );
            /* It might happen that a super gate with 5 inputs is constructed that
             * actually depends only on the first four variables; i.e the fifth is a
             * don't care -- in that case we connect constant node for the fifth
             * (since the cut only has 4 variables). An interesting question is what
             * if the first variable (and not the fifth one is the redundant one;
             * can that happen?) */
            return Abc_NtkCreateNodeConst0(pNtkNew);
        }
Alan Mishchenko committed
383
    }
384
    pRoot = Mio_LibraryReadGateByName( pLib, Mio_GateReadName(pRoot), NULL );
Alan Mishchenko committed
385

386 387 388 389 390 391
    // get information about the fanins of the supergate
    nFanins  = Map_SuperReadFaninNum( pSuper );
    ppFanins = Map_SuperReadFanins( pSuper );
    // create a new node with these fanins
    pNodeNew = Abc_NtkCreateNode( pNtkNew );
    for ( i = 0; i < nFanins; i++ )
Alan Mishchenko committed
392
    {
393 394
        pNodeFanin = Abc_NodeFromMapSuper_rec( pNtkNew, pNodeMap, ppFanins[i], pNodePis, nNodePis );
        Abc_ObjAddFanin( pNodeNew, pNodeFanin );
Alan Mishchenko committed
395
    }
396 397
    pNodeNew->pData = pRoot;
    return pNodeNew;
Alan Mishchenko committed
398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435
}
Abc_Obj_t * Abc_NodeFromMapPhase_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, int fPhase )
{
    Abc_Obj_t * pNodePIs[10];
    Abc_Obj_t * pNodeNew;
    Map_Node_t ** ppLeaves;
    Map_Cut_t * pCutBest;
    Map_Super_t * pSuperBest;
    unsigned uPhaseBest;
    int i, fInvPin, nLeaves;

    // make sure the node can be implemented in this phase
    assert( Map_NodeReadCutBest(pNodeMap, fPhase) != NULL || Map_NodeIsConst(pNodeMap) );
    // check if the phase is already implemented
    pNodeNew = (Abc_Obj_t *)Map_NodeReadData( pNodeMap, fPhase );
    if ( pNodeNew )
        return pNodeNew;

    // get the information about the best cut 
    pCutBest   = Map_NodeReadCutBest( pNodeMap, fPhase );
    pSuperBest = Map_CutReadSuperBest( pCutBest, fPhase );
    uPhaseBest = Map_CutReadPhaseBest( pCutBest, fPhase );
    nLeaves    = Map_CutReadLeavesNum( pCutBest );
    ppLeaves   = Map_CutReadLeaves( pCutBest );

    // collect the PI nodes
    for ( i = 0; i < nLeaves; i++ )
    {
        fInvPin = ((uPhaseBest & (1 << i)) > 0);
        pNodePIs[i] = Abc_NodeFromMap_rec( pNtkNew, ppLeaves[i], !fInvPin );
        assert( pNodePIs[i] != NULL );
    }

    // implement the supergate
    pNodeNew = Abc_NodeFromMapSuper_rec( pNtkNew, pNodeMap, pSuperBest, pNodePIs, nLeaves );
    Map_NodeSetData( pNodeMap, fPhase, (char *)pNodeNew );
    return pNodeNew;
}
436 437 438
Abc_Obj_t * Abc_NodeFromMap_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, int fPhase )
{
    Abc_Obj_t * pNodeNew, * pNodeInv;
Alan Mishchenko committed
439

440 441 442 443 444 445 446 447
    // check the case of constant node
    if ( Map_NodeIsConst(pNodeMap) )
    {
        pNodeNew = fPhase? Abc_NtkCreateNodeConst1(pNtkNew) : Abc_NtkCreateNodeConst0(pNtkNew);
        if ( pNodeNew->pData == NULL )
            printf( "Error creating mapped network: Library does not have a constant %d gate.\n", fPhase );
        return pNodeNew;
    }
Alan Mishchenko committed
448

449 450 451 452
    // check if the phase is already implemented
    pNodeNew = (Abc_Obj_t *)Map_NodeReadData( pNodeMap, fPhase );
    if ( pNodeNew )
        return pNodeNew;
Alan Mishchenko committed
453

454 455 456
    // implement the node if the best cut is assigned
    if ( Map_NodeReadCutBest(pNodeMap, fPhase) != NULL )
        return Abc_NodeFromMapPhase_rec( pNtkNew, pNodeMap, fPhase );
Alan Mishchenko committed
457

458 459 460
    // if the cut is not assigned, implement the node
    assert( Map_NodeReadCutBest(pNodeMap, !fPhase) != NULL || Map_NodeIsConst(pNodeMap) );
    pNodeNew = Abc_NodeFromMapPhase_rec( pNtkNew, pNodeMap, !fPhase );
Alan Mishchenko committed
461

462 463 464
    // add the inverter
    pNodeInv = Abc_NtkCreateNode( pNtkNew );
    Abc_ObjAddFanin( pNodeInv, pNodeNew );
465
    pNodeInv->pData = Mio_LibraryReadInv((Mio_Library_t *)Abc_FrameReadLibGen());
Alan Mishchenko committed
466

467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482
    // set the inverter
    Map_NodeSetData( pNodeMap, fPhase, (char *)pNodeInv );
    return pNodeInv;
}
Abc_Ntk_t * Abc_NtkFromMap( Map_Man_t * pMan, Abc_Ntk_t * pNtk )
{
    Abc_Ntk_t * pNtkNew;
    Map_Node_t * pNodeMap;
    Abc_Obj_t * pNode, * pNodeNew;
    int i, nDupGates;
    assert( Map_ManReadBufNum(pMan) == pNtk->nBarBufs );
    // create the new network
    pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_MAP );
    // make the mapper point to the new network
    Map_ManCleanData( pMan );
    Abc_NtkForEachCi( pNtk, pNode, i )
Alan Mishchenko committed
483
    {
484 485 486
        if ( i >= Abc_NtkCiNum(pNtk) - pNtk->nBarBufs )
            break;
        Map_NodeSetData( Map_ManReadInputs(pMan)[i], 1, (char *)pNode->pCopy );
Alan Mishchenko committed
487
    }
488
    Abc_NtkForEachCi( pNtk, pNode, i )
Alan Mishchenko committed
489
    {
490 491 492
        if ( i < Abc_NtkCiNum(pNtk) - pNtk->nBarBufs )
            continue;
        Map_NodeSetData( Map_ManReadBufs(pMan)[i - (Abc_NtkCiNum(pNtk) - pNtk->nBarBufs)], 1, (char *)pNode->pCopy );
Alan Mishchenko committed
493
    }
494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517
    // assign the mapping of the required phase to the POs
    Abc_NtkForEachCo( pNtk, pNode, i )
    {
        if ( i < Abc_NtkCoNum(pNtk) - pNtk->nBarBufs )
            continue;
        pNodeMap = Map_ManReadBufDriver( pMan, i - (Abc_NtkCoNum(pNtk) - pNtk->nBarBufs) );
        pNodeNew = Abc_NodeFromMap_rec( pNtkNew, Map_Regular(pNodeMap), !Map_IsComplement(pNodeMap) );
        assert( !Abc_ObjIsComplement(pNodeNew) );
        Abc_ObjAddFanin( pNode->pCopy, pNodeNew );
    }
    Abc_NtkForEachCo( pNtk, pNode, i )
    {
        if ( i >= Abc_NtkCoNum(pNtk) - pNtk->nBarBufs )
            break;
        pNodeMap = Map_ManReadOutputs(pMan)[i];
        pNodeNew = Abc_NodeFromMap_rec( pNtkNew, Map_Regular(pNodeMap), !Map_IsComplement(pNodeMap) );
        assert( !Abc_ObjIsComplement(pNodeNew) );
        Abc_ObjAddFanin( pNode->pCopy, pNodeNew );
    }
    // decouple the PO driver nodes to reduce the number of levels
    nDupGates = Abc_NtkLogicMakeSimpleCos( pNtkNew, 1 );
//    if ( nDupGates && Map_ManReadVerbose(pMan) )
//        printf( "Duplicated %d gates to decouple the CO drivers.\n", nDupGates );
    return pNtkNew;
Alan Mishchenko committed
518 519
}

Alan Mishchenko committed
520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536
/**Function*************************************************************

  Synopsis    [Interface with the mapping package.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Abc_Ntk_t * Abc_NtkSuperChoice( Abc_Ntk_t * pNtk )
{
    Abc_Ntk_t * pNtkNew;

    Map_Man_t * pMan;

Alan Mishchenko committed
537
    assert( Abc_NtkIsStrash(pNtk) );
Alan Mishchenko committed
538 539

    // check that the library is available
Alan Mishchenko committed
540
    if ( Abc_FrameReadLibGen() == NULL )
Alan Mishchenko committed
541 542 543 544 545 546
    {
        printf( "The current library is not available.\n" );
        return 0;
    }

    // derive the supergate library
Alan Mishchenko committed
547
    if ( Abc_FrameReadLibSuper() == NULL && Abc_FrameReadLibGen() )
Alan Mishchenko committed
548
    {
549 550
//        printf( "A simple supergate library is derived from gate library \"%s\".\n", 
//            Mio_LibraryReadName((Mio_Library_t *)Abc_FrameReadLibGen()) );
551
        Map_SuperLibDeriveFromGenlib( (Mio_Library_t *)Abc_FrameReadLibGen(), 0 );
Alan Mishchenko committed
552 553 554
    }

    // print a warning about choice nodes
Alan Mishchenko committed
555
    if ( Abc_NtkGetChoiceNum( pNtk ) )
Alan Mishchenko committed
556 557 558
        printf( "Performing mapping with choices.\n" );

    // perform the mapping
Alan Mishchenko committed
559
    pMan = Abc_NtkToMap( pNtk, -1, 1, NULL, 0 );
Alan Mishchenko committed
560 561 562 563 564 565 566 567 568 569 570 571 572 573 574
    if ( pMan == NULL )
        return NULL;
    if ( !Map_Mapping( pMan ) )
    {
        Map_ManFree( pMan );
        return NULL;
    }

    // reconstruct the network after mapping
    pNtkNew = Abc_NtkFromMapSuperChoice( pMan, pNtk );
    if ( pNtkNew == NULL )
        return NULL;
    Map_ManFree( pMan );

    // make sure that everything is okay
Alan Mishchenko committed
575
    if ( !Abc_NtkCheck( pNtkNew ) )
Alan Mishchenko committed
576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597
    {
        printf( "Abc_NtkMap: The network check has failed.\n" );
        Abc_NtkDelete( pNtkNew );
        return NULL;
    }
    return pNtkNew;
}


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

  Synopsis    [Creates the mapped network.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Abc_Ntk_t * Abc_NtkFromMapSuperChoice( Map_Man_t * pMan, Abc_Ntk_t * pNtk )
{
Alan Mishchenko committed
598
    extern Abc_Ntk_t * Abc_NtkMulti( Abc_Ntk_t * pNtk, int nThresh, int nFaninMax, int fCnf, int fMulti, int fSimple, int fFactor );
Alan Mishchenko committed
599 600 601 602 603 604 605 606 607 608 609 610 611 612 613
    ProgressBar * pProgress;
    Abc_Ntk_t * pNtkNew, * pNtkNew2;
    Abc_Obj_t * pNode;
    int i;

    // save the pointer to the mapped nodes
    Abc_NtkForEachCi( pNtk, pNode, i )
        pNode->pNext = pNode->pCopy;
    Abc_NtkForEachPo( pNtk, pNode, i )
        pNode->pNext = pNode->pCopy;
    Abc_NtkForEachNode( pNtk, pNode, i )
        pNode->pNext = pNode->pCopy;

    // duplicate the network
    pNtkNew2 = Abc_NtkDup( pNtk );
Alan Mishchenko committed
614
    pNtkNew  = Abc_NtkMulti( pNtkNew2, 0, 20, 0, 0, 1, 0 );
615
    if ( !Abc_NtkBddToSop( pNtkNew, -1, ABC_INFINITY ) )
Alan Mishchenko committed
616 617 618 619
    {
        printf( "Abc_NtkFromMapSuperChoice(): Converting to SOPs has failed.\n" );
        return NULL;
    }
Alan Mishchenko committed
620 621 622 623 624 625 626 627 628 629 630 631 632

    // set the old network to point to the new network
    Abc_NtkForEachCi( pNtk, pNode, i )
        pNode->pCopy = pNode->pCopy->pCopy;
    Abc_NtkForEachPo( pNtk, pNode, i )
        pNode->pCopy = pNode->pCopy->pCopy;
    Abc_NtkForEachNode( pNtk, pNode, i )
        pNode->pCopy = pNode->pCopy->pCopy;
    Abc_NtkDelete( pNtkNew2 );

    // set the pointers from the mapper to the new nodes
    Abc_NtkForEachCi( pNtk, pNode, i )
    {
Alan Mishchenko committed
633
        Map_NodeSetData( Map_ManReadInputs(pMan)[i], 0, (char *)Abc_NtkCreateNodeInv(pNtkNew,pNode->pCopy) );
Alan Mishchenko committed
634 635 636 637
        Map_NodeSetData( Map_ManReadInputs(pMan)[i], 1, (char *)pNode->pCopy );
    }
    Abc_NtkForEachNode( pNtk, pNode, i )
    {
Alan Mishchenko committed
638 639 640
//        if ( Abc_NodeIsConst(pNode) )
//            continue;
        Map_NodeSetData( (Map_Node_t *)pNode->pNext, 0, (char *)Abc_NtkCreateNodeInv(pNtkNew,pNode->pCopy) );
Alan Mishchenko committed
641 642 643 644
        Map_NodeSetData( (Map_Node_t *)pNode->pNext, 1, (char *)pNode->pCopy );
    }

    // assign the mapping of the required phase to the POs
Alan Mishchenko committed
645
    pProgress = Extra_ProgressBarStart( stdout, Abc_NtkObjNumMax(pNtk) );
Alan Mishchenko committed
646 647 648
    Abc_NtkForEachNode( pNtk, pNode, i )
    {
        Extra_ProgressBarUpdate( pProgress, i, NULL );
Alan Mishchenko committed
649 650
//        if ( Abc_NodeIsConst(pNode) )
//            continue;
Alan Mishchenko committed
651 652 653 654 655 656 657 658 659 660 661 662 663 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 692 693 694 695 696 697 698 699 700 701 702 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
        Abc_NodeSuperChoice( pNtkNew, pNode );
    }
    Extra_ProgressBarStop( pProgress );
    return pNtkNew;
}


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

  Synopsis    [Creates the mapped network.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Abc_NodeSuperChoice( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode )
{
    Map_Node_t * pMapNode = (Map_Node_t *)pNode->pNext;
    Map_Cut_t * pCuts, * pTemp;

    pCuts = Map_NodeReadCuts(pMapNode);
    for ( pTemp = Map_CutReadNext(pCuts); pTemp; pTemp = Map_CutReadNext(pTemp) )
    {
        Abc_NodeFromMapCutPhase( pNtkNew, pTemp, 0 );
        Abc_NodeFromMapCutPhase( pNtkNew, pTemp, 1 );
    }
}


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

  Synopsis    [Constructs the nodes corrresponding to one node.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Abc_NodeFromMapCutPhase( Abc_Ntk_t * pNtkNew, Map_Cut_t * pCut, int fPhase )
{
    Abc_Obj_t * pNodePIs[10];
    Map_Node_t ** ppLeaves;
    Map_Super_t * pSuperBest;
    unsigned uPhaseBest;
    int i, fInvPin, nLeaves;

    pSuperBest = Map_CutReadSuperBest( pCut, fPhase );
    if ( pSuperBest == NULL )
        return;

    // get the information about the best cut 
    uPhaseBest = Map_CutReadPhaseBest( pCut, fPhase );
    nLeaves    = Map_CutReadLeavesNum( pCut );
    ppLeaves   = Map_CutReadLeaves( pCut );

    // collect the PI nodes
    for ( i = 0; i < nLeaves; i++ )
    {
        fInvPin = ((uPhaseBest & (1 << i)) > 0);
        pNodePIs[i] = (Abc_Obj_t *)Map_NodeReadData( ppLeaves[i], !fInvPin );
        assert( pNodePIs[i] != NULL );
    }

    // implement the supergate
    Abc_NodeFromMapSuperChoice_rec( pNtkNew, pSuperBest, pNodePIs, nLeaves );
}


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

  Synopsis    [Constructs the nodes corrresponding to one supergate.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Abc_Obj_t * Abc_NodeFromMapSuperChoice_rec( Abc_Ntk_t * pNtkNew, Map_Super_t * pSuper, Abc_Obj_t * pNodePis[], int nNodePis )
{
737
    Mio_Library_t * pLib = (Mio_Library_t *)Abc_FrameReadLibGen();
Alan Mishchenko committed
738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760
    Mio_Gate_t * pRoot;
    Map_Super_t ** ppFanins;
    Abc_Obj_t * pNodeNew, * pNodeFanin;
    int nFanins, Number, i;

    // get the parameters of the supergate
    pRoot = Map_SuperReadRoot(pSuper);
    if ( pRoot == NULL )
    {
        Number = Map_SuperReadNum(pSuper);
        if ( Number < nNodePis )  
        {
            return pNodePis[Number];
        }
        else
        {  
//            assert( 0 );
            /* It might happen that a super gate with 5 inputs is constructed that
             * actually depends only on the first four variables; i.e the fifth is a
             * don't care -- in that case we connect constant node for the fifth
             * (since the cut only has 4 variables). An interesting question is what
             * if the first variable (and not the fifth one is the redundant one;
             * can that happen?) */
Alan Mishchenko committed
761
            return Abc_NtkCreateNodeConst0(pNtkNew);
Alan Mishchenko committed
762 763
        }
    }
764
    pRoot = Mio_LibraryReadGateByName( pLib, Mio_GateReadName(pRoot), NULL );
Alan Mishchenko committed
765 766 767 768 769 770 771 772 773 774 775

    // get information about the fanins of the supergate
    nFanins  = Map_SuperReadFaninNum( pSuper );
    ppFanins = Map_SuperReadFanins( pSuper );
    // create a new node with these fanins
    pNodeNew = Abc_NtkCreateNode( pNtkNew );
    for ( i = 0; i < nFanins; i++ )
    {
        pNodeFanin = Abc_NodeFromMapSuperChoice_rec( pNtkNew, ppFanins[i], pNodePis, nNodePis );
        Abc_ObjAddFanin( pNodeNew, pNodeFanin );
    }
776
    pNodeNew->pData = Abc_SopRegister( (Mem_Flex_t *)pNtkNew->pManFunc, Mio_GateReadSop(pRoot) );
Alan Mishchenko committed
777 778 779
    return pNodeNew;
}

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
/**Function*************************************************************

  Synopsis    [Returns the twin node if it exists.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Abc_Obj_t * Abc_NtkFetchTwinNode( Abc_Obj_t * pNode )
{
    Abc_Obj_t * pNode2;
    Mio_Gate_t * pGate = (Mio_Gate_t *)pNode->pData;
    assert( Abc_NtkHasMapping(pNode->pNtk) );
    if ( pGate == NULL || Mio_GateReadTwin(pGate) == NULL )
        return NULL;
    // assuming the twin node is following next
    if ( (int)Abc_ObjId(pNode) == Abc_NtkObjNumMax(pNode->pNtk) - 1 )
        return NULL;
    pNode2 = Abc_NtkObj( pNode->pNtk, Abc_ObjId(pNode) + 1 );
    if ( pNode2 == NULL || !Abc_ObjIsNode(pNode2) || Abc_ObjFaninNum(pNode) != Abc_ObjFaninNum(pNode2) )
        return NULL;
    if ( Mio_GateReadTwin(pGate) != (Mio_Gate_t *)pNode2->pData )
        return NULL;
    return pNode2;
}

Alan Mishchenko committed
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
/**Function*************************************************************

  Synopsis    [Dumps mapped network in the mini-mapped format.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Vec_Int_t * Abc_NtkWriteMiniMapping( Abc_Ntk_t * pNtk )
{
    Vec_Ptr_t * vNodes;
    Vec_Int_t * vMapping;
    Vec_Str_t * vGates;
    Abc_Obj_t * pObj, * pFanin;
    int i, k, nNodes, nFanins, nExtra, * pArray;
    assert( Abc_NtkHasMapping(pNtk) );
    // collect nodes in the DFS order
    vNodes = Abc_NtkDfs( pNtk, 0 );
    // assign unique numbers
    nNodes = nFanins = 0;
    Abc_NtkForEachCi( pNtk, pObj, i )
        pObj->iTemp = nNodes++;
    Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
        pObj->iTemp = nNodes++, nFanins += Abc_ObjFaninNum(pObj);
837 838
    // allocate attay to store mapping (4 counters + fanins for each node + PO drivers + gate names)
    vMapping = Vec_IntAlloc( 4 + Abc_NtkNodeNum(pNtk) + nFanins + Abc_NtkCoNum(pNtk) + 10000 );
839 840 841 842 843 844 845 846 847 848 849 850
    // write the numbers of CI/CO/Node/FF
    Vec_IntPush( vMapping, Abc_NtkCiNum(pNtk) );
    Vec_IntPush( vMapping, Abc_NtkCoNum(pNtk) );
    Vec_IntPush( vMapping, Abc_NtkNodeNum(pNtk) );
    Vec_IntPush( vMapping, Abc_NtkLatchNum(pNtk) );
    // write the nodes
    vGates = Vec_StrAlloc( 10000 );
    Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
    {
        Vec_IntPush( vMapping, Abc_ObjFaninNum(pObj) );
        Abc_ObjForEachFanin( pObj, pFanin, k )
            Vec_IntPush( vMapping, pFanin->iTemp );
851
        // remember this gate (to be added to the mapping later)
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
        Vec_StrPrintStr( vGates, Mio_GateReadName((Mio_Gate_t *)pObj->pData) );
        Vec_StrPush( vGates, '\0' );
    }
    // write the COs literals
    Abc_NtkForEachCo( pNtk, pObj, i )
        Vec_IntPush( vMapping, Abc_ObjFanin0(pObj)->iTemp );
    // finish off the array
    nExtra = 4 - Vec_StrSize(vGates) % 4;
    for ( i = 0; i < nExtra; i++ )
        Vec_StrPush( vGates, '\0' );
    // add gates to the array
    assert( Vec_StrSize(vGates) % 4 == 0 );
    nExtra = Vec_StrSize(vGates) / 4;
    pArray = (int *)Vec_StrArray(vGates);
    for ( i = 0; i < nExtra; i++ )
        Vec_IntPush( vMapping, pArray[i] );
    // cleanup and return
    Vec_PtrFree( vNodes );
    Vec_StrFree( vGates );
    return vMapping;
}

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

  Synopsis    [Prints mapped network represented in mini-mapped format.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Abc_NtkPrintMiniMapping( int * pArray )
{
    int nCis, nCos, nNodes, nFlops;
    int i, k, nLeaves, Pos = 4;
    char * pBuffer, * pName;
    nCis = pArray[0];
    nCos = pArray[1];
    nNodes = pArray[2];
    nFlops = pArray[3];
    printf( "Mapped network has %d CIs, %d COs, %d gates, and %d flops.\n", nCis, nCos, nNodes, nFlops );
    printf( "The first %d object IDs (from 0 to %d) are reserved for the CIs.\n", nCis, nCis - 1 );
    for ( i = 0; i < nNodes; i++ )
    {
        printf( "Node %d has fanins {", nCis + i );
        nLeaves = pArray[Pos++];
        for ( k = 0; k < nLeaves; k++ )
            printf( " %d", pArray[Pos++] );
        printf( " }\n" );
    }
    for ( i = 0; i < nCos; i++ )
        printf( "CO %d is driven by node %d\n", i, pArray[Pos++] );
    pBuffer = (char *)(pArray + Pos);
    for ( i = 0; i < nNodes; i++ )
    {
        pName = pBuffer;
        pBuffer += strlen(pName) + 1;
        printf( "Node %d has gate \"%s\"\n", nCis + i, pName );
    }
}

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

  Synopsis    [This procedure outputs an array representing mini-mapped network.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
926
int * Abc_NtkOutputMiniMapping( Abc_Frame_t * pAbc )
927
{
928
    //Abc_Frame_t * pAbc = (Abc_Frame_t *)pAbc0;
929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950
    Abc_Ntk_t * pNtk;
    Vec_Int_t * vMapping;
    int * pArray;
    if ( pAbc == NULL )
        printf( "ABC framework is not initialized by calling Abc_Start()\n" );
    pNtk = Abc_FrameReadNtk( pAbc );
    if ( pNtk == NULL )
        printf( "Current network in ABC framework is not defined.\n" );
    if ( !Abc_NtkHasMapping(pNtk) )
        printf( "Current network in ABC framework is not mapped.\n" );
    // derive mini-mapping
    vMapping = Abc_NtkWriteMiniMapping( pNtk );
    pArray = Vec_IntArray( vMapping );
    ABC_FREE( vMapping );
    // print mini-mapping (optional)
//    Abc_NtkPrintMiniMapping( pArray );
    // return the array representation of mini-mapping
    return pArray;
}

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

951
  Synopsis    [Test for mini-mapped format.]
952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Abc_NtkTestMiniMapping( Abc_Ntk_t * p )
{
    Vec_Int_t * vMapping;
    vMapping = Abc_NtkWriteMiniMapping( p );
    Abc_NtkPrintMiniMapping( Vec_IntArray(vMapping) );
    printf( "Array has size %d ints.\n", Vec_IntSize(vMapping) );
    Vec_IntFree( vMapping );
}

969 970
/**Function*************************************************************

971
  Synopsis    [These APIs set arrival/required times of CIs/COs.]
972 973 974 975 976 977 978 979

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
980
void Abc_NtkSetCiArrivalTime( Abc_Frame_t * pAbc, int iCi, float Rise, float Fall )
981
{
982
    //Abc_Frame_t * pAbc = (Abc_Frame_t *)pAbc0;
983 984 985
    Abc_Ntk_t * pNtk;
    Abc_Obj_t * pNode;
    if ( pAbc == NULL )
986
    {
987
        printf( "ABC framework is not initialized by calling Abc_Start()\n" );
988 989
        return;
    }
990 991
    pNtk = Abc_FrameReadNtk( pAbc );
    if ( pNtk == NULL )
992
    {
993
        printf( "Current network in ABC framework is not defined.\n" );
994 995
        return;
    }
996
    if ( iCi < 0 || iCi >= Abc_NtkCiNum(pNtk) )
997
    {
998
        printf( "CI index is not valid.\n" );
999 1000
        return;
    }
1001 1002 1003
    pNode = Abc_NtkCi( pNtk, iCi );
    Abc_NtkTimeSetArrival( pNtk, Abc_ObjId(pNode), Rise, Fall );
}
1004
void Abc_NtkSetCoRequiredTime( Abc_Frame_t * pAbc, int iCo, float Rise, float Fall )
1005
{
1006
    //Abc_Frame_t * pAbc = (Abc_Frame_t *)pAbc0;
1007 1008
    Abc_Ntk_t * pNtk;
    Abc_Obj_t * pNode;
1009 1010
    if ( pAbc == NULL )\
    {
1011
        printf( "ABC framework is not initialized by calling Abc_Start()\n" );
1012 1013
        return;
    }
1014 1015
    pNtk = Abc_FrameReadNtk( pAbc );
    if ( pNtk == NULL )
1016
    {
1017
        printf( "Current network in ABC framework is not defined.\n" );
1018 1019
        return;
    }
1020
    if ( iCo < 0 || iCo >= Abc_NtkCoNum(pNtk) )
1021
    {
1022
        printf( "CO index is not valid.\n" );
1023 1024
        return;
    }
1025 1026 1027
    pNode = Abc_NtkCo( pNtk, iCo );
    Abc_NtkTimeSetRequired( pNtk, Abc_ObjId(pNode), Rise, Fall );
}
1028

1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039
/**Function*************************************************************

  Synopsis    [This APIs set AND gate delay.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
1040
void Abc_NtkSetAndGateDelay( Abc_Frame_t * pAbc, float Delay )
1041
{
1042
    //Abc_Frame_t * pAbc = (Abc_Frame_t *)pAbc0;
1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057
    Abc_Ntk_t * pNtk;
    if ( pAbc == NULL )
    {
        printf( "ABC framework is not initialized by calling Abc_Start()\n" );
        return;
    }
    pNtk = Abc_FrameReadNtk( pAbc );
    if ( pNtk == NULL )
    {
        printf( "Current network in ABC framework is not defined.\n" );
        return;
    }
    pNtk->AndGateDelay = Delay;
}

Alan Mishchenko committed
1058 1059 1060 1061 1062
////////////////////////////////////////////////////////////////////////
///                       END OF FILE                                ///
////////////////////////////////////////////////////////////////////////


1063 1064
ABC_NAMESPACE_IMPL_END