seqMapCore.c 23.8 KB
Newer Older
Alan Mishchenko committed
1 2 3 4 5 6 7 8
/**CFile****************************************************************

  FileName    [seqMapCore.c]

  SystemName  [ABC: Logic synthesis and verification system.]

  PackageName [Construction and manipulation of sequential AIGs.]

Alan Mishchenko committed
9
  Synopsis    [The core of SC mapping/retiming package.]
Alan Mishchenko committed
10 11 12 13 14 15 16 17 18 19 20 21

  Author      [Alan Mishchenko]
  
  Affiliation [UC Berkeley]

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

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

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

#include "seqInt.h"
Alan Mishchenko committed
22 23 24
#include "main.h"
#include "mio.h"
#include "mapper.h"
Alan Mishchenko committed
25 26 27 28 29

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

Alan Mishchenko committed
30 31 32 33 34 35
extern Abc_Ntk_t *  Seq_NtkMapDup( Abc_Ntk_t * pNtk );
extern int          Seq_NtkMapInitCompatible( Abc_Ntk_t * pNtk, int fVerbose );
extern Abc_Ntk_t *  Seq_NtkSeqMapMapped( Abc_Ntk_t * pNtk );

static int          Seq_MapMappingCount( Abc_Ntk_t * pNtk );
static int          Seq_MapMappingCount_rec( Abc_Ntk_t * pNtk, unsigned SeqEdge, Vec_Ptr_t * vLeaves );
Alan Mishchenko committed
36
static Abc_Obj_t *  Seq_MapMappingBuild_rec( Abc_Ntk_t * pNtkNew, Abc_Ntk_t * pNtk, unsigned SeqEdge, int fTop, int fCompl, int LagCut, Vec_Ptr_t * vLeaves, unsigned uPhase );
Alan Mishchenko committed
37 38 39 40 41
static DdNode *     Seq_MapMappingBdd_rec( DdManager * dd, Abc_Ntk_t * pNtk, unsigned SeqEdge, Vec_Ptr_t * vLeaves );
static void         Seq_MapMappingEdges_rec( Abc_Ntk_t * pNtk, unsigned SeqEdge, Abc_Obj_t * pPrev, Vec_Ptr_t * vLeaves, Vec_Vec_t * vMapEdges );
static void         Seq_MapMappingConnect_rec( Abc_Ntk_t * pNtk, unsigned SeqEdge, Abc_Obj_t * pPrev, int Edge, Abc_Obj_t * pRoot, Vec_Ptr_t * vLeaves );
static DdNode *     Seq_MapMappingConnectBdd_rec( Abc_Ntk_t * pNtk, unsigned SeqEdge, Abc_Obj_t * pPrev, int Edge, Abc_Obj_t * pRoot, Vec_Ptr_t * vLeaves );

Alan Mishchenko committed
42 43 44 45 46 47
////////////////////////////////////////////////////////////////////////
///                     FUNCTION DEFINITIONS                         ///
////////////////////////////////////////////////////////////////////////

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

Alan Mishchenko committed
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
  Synopsis    [Performs Map mapping and retiming.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Abc_Ntk_t * Seq_MapRetime( Abc_Ntk_t * pNtk, int nMaxIters, int fVerbose )
{
    Abc_Seq_t * p = pNtk->pManFunc;
    Abc_Ntk_t * pNtkNew;
    Abc_Ntk_t * pNtkMap;
    int RetValue;

    // derive the supergate library
    if ( Abc_FrameReadLibSuper() == NULL && Abc_FrameReadLibGen() )
    {
        printf( "A simple supergate library is derived from gate library \"%s\".\n", 
            Mio_LibraryReadName(Abc_FrameReadLibGen()) );
        Map_SuperLibDeriveFromGenlib( Abc_FrameReadLibGen() );
    }
    p->pSuperLib   = Abc_FrameReadLibSuper();
    p->nVarsMax    = Map_SuperLibReadVarsMax(p->pSuperLib);
    p->nMaxIters   = nMaxIters;
    p->fStandCells = 1;

    // find the best mapping and retiming for all nodes (p->vLValues, p->vBestCuts, p->vLags)
Alan Mishchenko committed
77 78
    if ( !Seq_MapRetimeDelayLags( pNtk, fVerbose ) )
        return NULL;
Alan Mishchenko committed
79 80
    if ( RetValue = Abc_NtkGetChoiceNum(pNtk) )
    {
Alan Mishchenko committed
81 82
        printf( "The network has %d choices. The resulting network is not derived (this is temporary).\n", RetValue );
        printf( "The mininum clock period computed is %5.2f.\n", p->FiBestFloat );
Alan Mishchenko committed
83 84
        return NULL;
    }
Alan Mishchenko committed
85
    printf( "The mininum clock period computed is %5.2f.\n", p->FiBestFloat );
Alan Mishchenko committed
86
    printf( "The resulting network is derived as BDD logic network (this is temporary).\n" );
Alan Mishchenko committed
87 88 89 90 91 92 93 94 95 96 97 98

    // duplicate the nodes contained in multiple cuts
    pNtkNew = Seq_NtkMapDup( pNtk );
    
    // implement the retiming
    RetValue = Seq_NtkImplementRetiming( pNtkNew, ((Abc_Seq_t *)pNtkNew->pManFunc)->vLags, fVerbose );
    if ( RetValue == 0 )
        printf( "Retiming completed but initial state computation has failed.\n" );

    // check the compatibility of initial states computed
    if ( RetValue = Seq_NtkMapInitCompatible( pNtkNew, fVerbose ) )
        printf( "The number of LUTs with incompatible edges = %d.\n", RetValue );
Alan Mishchenko committed
99
//    return pNtkNew;
Alan Mishchenko committed
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123

    // create the final mapped network
    pNtkMap = Seq_NtkSeqMapMapped( pNtkNew );
    Abc_NtkDelete( pNtkNew );
    return pNtkMap;
}

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

  Synopsis    [Derives the network by duplicating some of the nodes.]

  Description [Information about mapping is given as mapping nodes (p->vMapAnds)
  and best cuts for each node (p->vMapCuts).]
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Abc_Ntk_t * Seq_NtkMapDup( Abc_Ntk_t * pNtk )
{
    Abc_Seq_t * pNew, * p = pNtk->pManFunc;
    Seq_Match_t * pMatch;
    Abc_Ntk_t * pNtkNew; 
Alan Mishchenko committed
124
    Abc_Obj_t * pObj, * pFanin, * pFaninNew, * pLeaf;
Alan Mishchenko committed
125 126 127 128 129 130 131 132
    Vec_Ptr_t * vLeaves;
    unsigned SeqEdge;
    int i, k, nObjsNew, Lag;
    
    assert( Abc_NtkIsSeq(pNtk) );

    // start the expanded network
    pNtkNew = Abc_NtkStartFrom( pNtk, pNtk->ntkType, pNtk->ntkFunc );
Alan Mishchenko committed
133
    Abc_NtkCleanNext(pNtk);
Alan Mishchenko committed
134 135 136 137 138 139 140

    // start the new sequential AIG manager
    nObjsNew = 1 + Abc_NtkPiNum(pNtk) + Abc_NtkPoNum(pNtk) + Seq_MapMappingCount(pNtk);
    Seq_Resize( pNtkNew->pManFunc, nObjsNew );

    // duplicate the nodes in the mapping
    Vec_PtrForEachEntry( p->vMapAnds, pMatch, i )
Alan Mishchenko committed
141 142 143
    {
//        Abc_NtkDupObj( pNtkNew, pMatch->pAnd );
        if ( !pMatch->fCompl )
Alan Mishchenko committed
144
            pMatch->pAnd->pCopy = Abc_NtkCreateNode( pNtkNew );
Alan Mishchenko committed
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
        else
            pMatch->pAnd->pNext = Abc_NtkCreateNode( pNtkNew );
    }

    // compute the real phase assignment
    Vec_PtrForEachEntry( p->vMapAnds, pMatch, i )
    {
        pMatch->uPhaseR = 0;
        // get the leaves of the cut
        vLeaves = Vec_VecEntry( p->vMapCuts, i );
        // convert the leaf nodes
        Vec_PtrForEachEntry( vLeaves, pLeaf, k )
        {
            SeqEdge = (unsigned)pLeaf;
            pLeaf = Abc_NtkObj( pNtk, SeqEdge >> 8 );

            // set the phase
            if ( pMatch->uPhase & (1 << k) ) // neg is required
            {
                if ( pLeaf->pNext ) // neg is available
                    pMatch->uPhaseR |= (1 << k); // neg is used
//                else
//                    Seq_NodeSetLag( pLeaf, Seq_NodeGetLagN(pLeaf) );
            }
            else // pos is required
            {
                if ( pLeaf->pCopy == NULL ) // pos is not available
                    pMatch->uPhaseR |= (1 << k); // neg is used
//                else
//                    Seq_NodeSetLagN( pLeaf, Seq_NodeGetLag(pLeaf) );
            }
        }
    }

Alan Mishchenko committed
179 180

    // recursively construct the internals of each node
Alan Mishchenko committed
181
    Vec_PtrForEachEntry( p->vMapAnds, pMatch, i )
Alan Mishchenko committed
182
    {
Alan Mishchenko committed
183 184 185 186
//        if ( pMatch->pSuper == NULL )
//        {
//            int x = 0;
//        }
Alan Mishchenko committed
187
        vLeaves = Vec_VecEntry( p->vMapCuts, i );
Alan Mishchenko committed
188 189 190 191
        if ( !pMatch->fCompl )
            Seq_MapMappingBuild_rec( pNtkNew, pNtk, pMatch->pAnd->Id << 8, 1, pMatch->fCompl, Seq_NodeGetLag(pMatch->pAnd), vLeaves, pMatch->uPhaseR );
        else
            Seq_MapMappingBuild_rec( pNtkNew, pNtk, pMatch->pAnd->Id << 8, 1, pMatch->fCompl, Seq_NodeGetLagN(pMatch->pAnd), vLeaves, pMatch->uPhaseR );
Alan Mishchenko committed
192 193 194 195
    }
    assert( nObjsNew == pNtkNew->nObjs );

    // set the POs
Alan Mishchenko committed
196 197
//    Abc_NtkFinalize( pNtk, pNtkNew );
    Abc_NtkForEachPo( pNtk, pObj, i )
Alan Mishchenko committed
198
    {
Alan Mishchenko committed
199 200 201 202 203 204 205
        pFanin = Abc_ObjFanin0(pObj);
        if ( Abc_ObjFaninC0(pObj) )
            pFaninNew = pFanin->pNext ? pFanin->pNext : pFanin->pCopy;
        else
            pFaninNew = pFanin->pCopy ? pFanin->pCopy : pFanin->pNext;
        pFaninNew = Abc_ObjNotCond( pFaninNew, Abc_ObjFaninC0(pObj) );
        Abc_ObjAddFanin( pObj->pCopy, pFaninNew );
Alan Mishchenko committed
206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221
    }

    // duplicate the latches on the PO edges
    Abc_NtkForEachPo( pNtk, pObj, i )
        Seq_NodeDupLats( pObj->pCopy, pObj, 0 );

    // transfer the mapping info to the new manager
    Vec_PtrForEachEntry( p->vMapAnds, pMatch, i )
    {
        // get the leaves of the cut
        vLeaves = Vec_VecEntry( p->vMapCuts, i );
        // convert the leaf nodes
        Vec_PtrForEachEntry( vLeaves, pLeaf, k )
        {
            SeqEdge = (unsigned)pLeaf;
            pLeaf = Abc_NtkObj( pNtk, SeqEdge >> 8 );
Alan Mishchenko committed
222 223 224 225 226 227

//            Lag = (SeqEdge & 255) + Seq_NodeGetLag(pMatch->pAnd) - Seq_NodeGetLag(pLeaf);
            Lag = (SeqEdge & 255) + 
                (pMatch->fCompl?                     Seq_NodeGetLagN(pMatch->pAnd) : Seq_NodeGetLag(pMatch->pAnd)) - 
                (((pMatch->uPhaseR & (1 << k)) > 0)? Seq_NodeGetLagN(pLeaf)        : Seq_NodeGetLag(pLeaf)       );

Alan Mishchenko committed
228
            assert( Lag >= 0 );
Alan Mishchenko committed
229 230 231 232 233 234 235

            // translate the old leaf into the leaf in the new network
//            if ( pMatch->uPhase & (1 << k) ) // negative phase is required
//                pFaninNew = pLeaf->pNext? pLeaf->pNext : pLeaf->pCopy;
//            else // positive phase is required
//                pFaninNew = pLeaf->pCopy? pLeaf->pCopy : pLeaf->pNext;

Alan Mishchenko committed
236
            // translate the old leaf into the leaf in the new network
Alan Mishchenko committed
237 238 239 240 241 242
            if ( pMatch->uPhaseR & (1 << k) ) // negative phase is required
                pFaninNew = pLeaf->pNext;
            else // positive phase is required
                pFaninNew = pLeaf->pCopy;

            Vec_PtrWriteEntry( vLeaves, k, (void *)((pFaninNew->Id << 8) | Lag) );
Alan Mishchenko committed
243
//            printf( "%d -> %d\n", pLeaf->Id, pLeaf->pCopy->Id );
Alan Mishchenko committed
244 245

            // UPDATE PHASE!!!   leaving only those bits that require inverters
Alan Mishchenko committed
246
        }
Alan Mishchenko committed
247 248 249
        // convert the root node
//        Vec_PtrWriteEntry( p->vMapAnds, i, pObj->pCopy );
        pMatch->pAnd = pMatch->fCompl? pMatch->pAnd->pNext : pMatch->pAnd->pCopy;
Alan Mishchenko committed
250 251
    }
    pNew = pNtkNew->pManFunc;
Alan Mishchenko committed
252 253 254 255
    pNew->nVarsMax    = p->nVarsMax;
    pNew->vMapAnds    = p->vMapAnds;     p->vMapAnds    = NULL;
    pNew->vMapCuts    = p->vMapCuts;     p->vMapCuts    = NULL;
    pNew->fStandCells = p->fStandCells;  p->fStandCells = 0;
Alan Mishchenko committed
256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277

    if ( !Abc_NtkCheck( pNtkNew ) )
        fprintf( stdout, "Seq_NtkMapDup(): Network check has failed.\n" );
    return pNtkNew;
}

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

  Synopsis    [Checks if the initial states are compatible.]

  Description [Checks of all the initial states on the fanins edges
  of the cut have compatible number of latches and initial states.
  If this is not true, then the mapped network with the does not have initial 
  state. Returns the number of LUTs with incompatible edges.]
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Seq_NtkMapInitCompatible( Abc_Ntk_t * pNtk, int fVerbose )
{
Alan Mishchenko committed
278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 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
    Abc_Seq_t * p = pNtk->pManFunc;
    Seq_Match_t * pMatch;
    Abc_Obj_t * pAnd, * pLeaf, * pFanout0, * pFanout1;
    Vec_Vec_t * vTotalEdges;
    Vec_Ptr_t * vLeaves, * vEdges;
    int i, k, m, Edge0, Edge1, nLatchAfter, nLatches1, nLatches2;
    unsigned SeqEdge;
    int CountBad = 0, CountAll = 0;

    vTotalEdges = Vec_VecStart( p->nVarsMax );
    // go through all the nodes (cuts) used in the mapping
    Vec_PtrForEachEntry( p->vMapAnds, pMatch, i )
    {
        pAnd = pMatch->pAnd;
//        printf( "*** Node %d.\n", pAnd->Id );

        // get the cut of this gate
        vLeaves = Vec_VecEntry( p->vMapCuts, i );

        // get the edges pointing to the leaves
        Vec_VecClear( vTotalEdges );
        Seq_MapMappingEdges_rec( pNtk, pAnd->Id << 8, NULL, vLeaves, vTotalEdges );

        // for each leaf, consider its edges
        Vec_PtrForEachEntry( vLeaves, pLeaf, k )
        {
            SeqEdge = (unsigned)pLeaf;
            pLeaf = Abc_NtkObj( pNtk, SeqEdge >> 8 );
            nLatchAfter = SeqEdge & 255;
            if ( nLatchAfter == 0 )
                continue;

            // go through the edges
            vEdges = Vec_VecEntry( vTotalEdges, k );
            pFanout0 = NULL;
            Vec_PtrForEachEntry( vEdges, pFanout1, m )
            {
                Edge1    = Abc_ObjIsComplement(pFanout1);
                pFanout1 = Abc_ObjRegular(pFanout1);
//printf( "Fanin = %d. Fanout = %d.\n", pLeaf->Id, pFanout1->Id );

                // make sure this is the same fanin
                if ( Edge1 )
                    assert( pLeaf == Abc_ObjFanin1(pFanout1) );
                else
                    assert( pLeaf == Abc_ObjFanin0(pFanout1) );

                // save the first one
                if ( pFanout0 == NULL )
                {
                    pFanout0 = pFanout1;
                    Edge0    = Edge1;
                    continue;
                }
                // compare the rings
                // if they have different number of latches, this is the bug
                nLatches1 = Seq_NodeCountLats(pFanout0, Edge0);
                nLatches2 = Seq_NodeCountLats(pFanout1, Edge1);
                assert( nLatches1 == nLatches2 );
                assert( nLatches1 == nLatchAfter );
                assert( nLatches1 > 0 );

                // if they have different initial states, this is the problem
                if ( !Seq_NodeCompareLats(pFanout0, Edge0, pFanout1, Edge1) )
                {
                    CountBad++;
                    break;
                }
                CountAll++;
            }
        }
    }
    if ( fVerbose )
        printf( "The number of pairs of edges checked = %d.\n", CountAll );
    Vec_VecFree( vTotalEdges );
    return CountBad;
Alan Mishchenko committed
354 355 356 357 358 359 360 361 362 363 364 365 366 367 368
}

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

  Synopsis    [Derives the final mapped network.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Abc_Ntk_t * Seq_NtkSeqMapMapped( Abc_Ntk_t * pNtk )
{
Alan Mishchenko committed
369 370 371 372
    Abc_Seq_t * p = pNtk->pManFunc;
    Seq_Match_t * pMatch;
    Abc_Ntk_t * pNtkMap; 
    Vec_Ptr_t * vLeaves;
Alan Mishchenko committed
373
    Abc_Obj_t * pObj, * pFaninNew;
Alan Mishchenko committed
374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414
    Seq_Lat_t * pRing;
    int i;

    assert( Abc_NtkIsSeq(pNtk) );

    // start the network
    pNtkMap = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_BDD );

    // duplicate the nodes used in the mapping
    Vec_PtrForEachEntry( p->vMapAnds, pMatch, i )
        pMatch->pAnd->pCopy = Abc_NtkCreateNode( pNtkMap );

    // create and share the latches
    Seq_NtkShareLatchesMapping( pNtkMap, pNtk, p->vMapAnds, 0 );

    // connect the nodes
    Vec_PtrForEachEntry( p->vMapAnds, pMatch, i )
    {
        pObj = pMatch->pAnd;
        // get the leaves of this gate
        vLeaves = Vec_VecEntry( p->vMapCuts, i );
        // get the BDD of the node
        pObj->pCopy->pData = Seq_MapMappingConnectBdd_rec( pNtk, pObj->Id << 8, NULL, -1, pObj, vLeaves );
        Cudd_Ref( pObj->pCopy->pData );
        // complement the BDD of the cut if it came from the opposite polarity choice cut
//        if ( Vec_StrEntry(p->vPhase, i) )
//            pObj->pCopy->pData = Cudd_Not( pObj->pCopy->pData );
    }

    // set the POs
    Abc_NtkForEachPo( pNtk, pObj, i )
    {
        if ( pRing = Seq_NodeGetRing(pObj,0) )
            pFaninNew = pRing->pLatch;
        else
            pFaninNew = Abc_ObjFanin0(pObj)->pCopy;
        pFaninNew = Abc_ObjNotCond( pFaninNew, Abc_ObjFaninC0(pObj) );
        Abc_ObjAddFanin( pObj->pCopy, pFaninNew );
    }

    // add the latches and their names
Alan Mishchenko committed
415
    Abc_NtkAddDummyBoxNames( pNtkMap );
Alan Mishchenko committed
416
    Abc_NtkOrderCisCos( pNtkMap );
Alan Mishchenko committed
417 418 419 420 421 422 423
    // fix the problem with complemented and duplicated CO edges
    Abc_NtkLogicMakeSimpleCos( pNtkMap, 1 );
    // make the network minimum base
    Abc_NtkMinimumBase( pNtkMap );
    if ( !Abc_NtkCheck( pNtkMap ) )
        fprintf( stdout, "Seq_NtkSeqFpgaMapped(): Network check has failed.\n" );
    return pNtkMap;
Alan Mishchenko committed
424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442
}



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

  Synopsis    [Counts the number of nodes in the bag.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Seq_MapMappingCount( Abc_Ntk_t * pNtk )
{
    Abc_Seq_t * p = pNtk->pManFunc;
    Vec_Ptr_t * vLeaves;
Alan Mishchenko committed
443
    Seq_Match_t * pMatch;
Alan Mishchenko committed
444
    int i, Counter = 0;
Alan Mishchenko committed
445
    Vec_PtrForEachEntry( p->vMapAnds, pMatch, i )
Alan Mishchenko committed
446 447
    {
        vLeaves = Vec_VecEntry( p->vMapCuts, i );
Alan Mishchenko committed
448
        Counter += Seq_MapMappingCount_rec( pNtk, pMatch->pAnd->Id << 8, vLeaves );
Alan Mishchenko committed
449 450 451 452 453 454 455
    }
    return Counter;
}

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

  Synopsis    [Counts the number of nodes in the bag.]
Alan Mishchenko committed
456 457 458 459 460 461 462 463

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
464 465 466 467 468 469 470 471 472 473 474 475 476
int Seq_MapMappingCount_rec( Abc_Ntk_t * pNtk, unsigned SeqEdge, Vec_Ptr_t * vLeaves )
{
    Abc_Obj_t * pObj, * pLeaf;
    unsigned SeqEdge0, SeqEdge1;
    int Lag, i;
    // get the object and the lag
    pObj = Abc_NtkObj( pNtk, SeqEdge >> 8 );
    Lag  = SeqEdge & 255;
    // if the node is the fanin of the cut, return
    Vec_PtrForEachEntry( vLeaves, pLeaf, i )
        if ( SeqEdge == (unsigned)pLeaf )
            return 0;
    // continue unfolding
Alan Mishchenko committed
477
    assert( Abc_AigNodeIsAnd(pObj) );
Alan Mishchenko committed
478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498
    // get new sequential edges
    assert( Lag + Seq_ObjFaninL0(pObj) < 255 );
    assert( Lag + Seq_ObjFaninL1(pObj) < 255 );
    SeqEdge0 = (Abc_ObjFanin0(pObj)->Id << 8) + Lag + Seq_ObjFaninL0(pObj);
    SeqEdge1 = (Abc_ObjFanin1(pObj)->Id << 8) + Lag + Seq_ObjFaninL1(pObj);
    // call for the children
    return 1 + Seq_MapMappingCount_rec( pNtk, SeqEdge0, vLeaves ) + 
        Seq_MapMappingCount_rec( pNtk, SeqEdge1, vLeaves );
}

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

  Synopsis    [Collects the edges pointing to the leaves of the cut.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
499
Abc_Obj_t * Seq_MapMappingBuild_rec( Abc_Ntk_t * pNtkNew, Abc_Ntk_t * pNtk, unsigned SeqEdge, int fTop, int fCompl, int LagCut, Vec_Ptr_t * vLeaves, unsigned uPhase )
Alan Mishchenko committed
500 501 502 503 504 505 506 507 508 509
{
    Abc_Obj_t * pObj, * pObjNew, * pLeaf, * pFaninNew0, * pFaninNew1;
    unsigned SeqEdge0, SeqEdge1;
    int Lag, i;
    // get the object and the lag
    pObj = Abc_NtkObj( pNtk, SeqEdge >> 8 );
    Lag  = SeqEdge & 255;
    // if the node is the fanin of the cut, return
    Vec_PtrForEachEntry( vLeaves, pLeaf, i )
        if ( SeqEdge == (unsigned)pLeaf )
Alan Mishchenko committed
510 511 512 513 514 515 516 517 518 519 520
        {
//            if ( uPhase & (1 << i) ) // negative phase is required
//                return pObj->pNext? pObj->pNext : pObj->pCopy;
//            else // positive phase is required
//                return pObj->pCopy? pObj->pCopy : pObj->pNext;

            if ( uPhase & (1 << i) ) // negative phase is required
                return pObj->pNext;
            else // positive phase is required
                return pObj->pCopy;
        }
Alan Mishchenko committed
521
    // continue unfolding
Alan Mishchenko committed
522
    assert( Abc_AigNodeIsAnd(pObj) );
Alan Mishchenko committed
523 524 525 526 527 528
    // get new sequential edges
    assert( Lag + Seq_ObjFaninL0(pObj) < 255 );
    assert( Lag + Seq_ObjFaninL1(pObj) < 255 );
    SeqEdge0 = (Abc_ObjFanin0(pObj)->Id << 8) + Lag + Seq_ObjFaninL0(pObj);
    SeqEdge1 = (Abc_ObjFanin1(pObj)->Id << 8) + Lag + Seq_ObjFaninL1(pObj);
    // call for the children    
Alan Mishchenko committed
529
    pObjNew = fTop? (fCompl? pObj->pNext : pObj->pCopy) : Abc_NtkCreateNode( pNtkNew );
Alan Mishchenko committed
530
    // solve subproblems
Alan Mishchenko committed
531 532
    pFaninNew0 = Seq_MapMappingBuild_rec( pNtkNew, pNtk, SeqEdge0, 0, fCompl, LagCut, vLeaves, uPhase );
    pFaninNew1 = Seq_MapMappingBuild_rec( pNtkNew, pNtk, SeqEdge1, 0, fCompl, LagCut, vLeaves, uPhase );
Alan Mishchenko committed
533 534 535 536 537 538 539 540 541 542 543
    // add the fanins to the node
    Abc_ObjAddFanin( pObjNew, Abc_ObjNotCond( pFaninNew0, Abc_ObjFaninC0(pObj) ) );
    Abc_ObjAddFanin( pObjNew, Abc_ObjNotCond( pFaninNew1, Abc_ObjFaninC1(pObj) ) );
    Seq_NodeDupLats( pObjNew, pObj, 0 );
    Seq_NodeDupLats( pObjNew, pObj, 1 );
    // set the lag of the new node equal to the internal lag plus mapping/retiming lag
    Seq_NodeSetLag( pObjNew, (char)(Lag + LagCut) );
//    Seq_NodeSetLag( pObjNew, (char)(Lag) );
    return pObjNew;
}

Alan Mishchenko committed
544

Alan Mishchenko committed
545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574
/**Function*************************************************************

  Synopsis    [Collects the edges pointing to the leaves of the cut.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Seq_MapMappingEdges_rec( Abc_Ntk_t * pNtk, unsigned SeqEdge, Abc_Obj_t * pPrev, Vec_Ptr_t * vLeaves, Vec_Vec_t * vMapEdges )
{
    Abc_Obj_t * pObj, * pLeaf;
    unsigned SeqEdge0, SeqEdge1;
    int Lag, i;
    // get the object and the lag
    pObj = Abc_NtkObj( pNtk, SeqEdge >> 8 );
    Lag  = SeqEdge & 255;
    // if the node is the fanin of the cut, return
    Vec_PtrForEachEntry( vLeaves, pLeaf, i )
    {
        if ( SeqEdge == (unsigned)pLeaf )
        {
            assert( pPrev != NULL );
            Vec_VecPush( vMapEdges, i, pPrev );
            return;
        }
    }
    // continue unfolding
Alan Mishchenko committed
575
    assert( Abc_AigNodeIsAnd(pObj) );
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 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627
    // get new sequential edges
    assert( Lag + Seq_ObjFaninL0(pObj) < 255 );
    assert( Lag + Seq_ObjFaninL1(pObj) < 255 );
    SeqEdge0 = (Abc_ObjFanin0(pObj)->Id << 8) + Lag + Seq_ObjFaninL0(pObj);
    SeqEdge1 = (Abc_ObjFanin1(pObj)->Id << 8) + Lag + Seq_ObjFaninL1(pObj);
    // call for the children    
    Seq_MapMappingEdges_rec( pNtk, SeqEdge0, pObj            , vLeaves, vMapEdges );
    Seq_MapMappingEdges_rec( pNtk, SeqEdge1, Abc_ObjNot(pObj), vLeaves, vMapEdges );
}

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

  Synopsis    [Collects the edges pointing to the leaves of the cut.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
DdNode * Seq_MapMappingConnectBdd_rec( Abc_Ntk_t * pNtk, unsigned SeqEdge, Abc_Obj_t * pPrev, int Edge, Abc_Obj_t * pRoot, Vec_Ptr_t * vLeaves )
{
    Seq_Lat_t * pRing;
    Abc_Obj_t * pObj, * pLeaf, * pFanin, * pFaninNew;
    unsigned SeqEdge0, SeqEdge1;
    DdManager * dd = pRoot->pCopy->pNtk->pManFunc;
    DdNode * bFunc, * bFunc0, * bFunc1;
    int Lag, i, k;
    // get the object and the lag
    pObj = Abc_NtkObj( pNtk, SeqEdge >> 8 );
    Lag  = SeqEdge & 255;
    // if the node is the fanin of the cut, add the connection and return
    Vec_PtrForEachEntry( vLeaves, pLeaf, i )
    {
        if ( SeqEdge == (unsigned)pLeaf )
        {
            assert( pPrev != NULL );
            if ( pRing = Seq_NodeGetRing(pPrev,Edge) )
                pFaninNew = pRing->pLatch;
            else
                pFaninNew = Abc_ObjFanin(pPrev,Edge)->pCopy;

            // check if the root already has this fanin
            Abc_ObjForEachFanin( pRoot->pCopy, pFanin, k )
                if ( pFanin == pFaninNew )
                    return Cudd_bddIthVar( dd, k );
            Abc_ObjAddFanin( pRoot->pCopy, pFaninNew );
            return Cudd_bddIthVar( dd, k );
        }
    }
    // continue unfolding
Alan Mishchenko committed
628
    assert( Abc_AigNodeIsAnd(pObj) );
Alan Mishchenko committed
629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647
    // get new sequential edges
    assert( Lag + Seq_ObjFaninL0(pObj) < 255 );
    assert( Lag + Seq_ObjFaninL1(pObj) < 255 );
    SeqEdge0 = (Abc_ObjFanin0(pObj)->Id << 8) + Lag + Seq_ObjFaninL0(pObj);
    SeqEdge1 = (Abc_ObjFanin1(pObj)->Id << 8) + Lag + Seq_ObjFaninL1(pObj);
    // call for the children    
    bFunc0 = Seq_MapMappingConnectBdd_rec( pNtk, SeqEdge0, pObj, 0, pRoot, vLeaves );    Cudd_Ref( bFunc0 );
    bFunc1 = Seq_MapMappingConnectBdd_rec( pNtk, SeqEdge1, pObj, 1, pRoot, vLeaves );    Cudd_Ref( bFunc1 );
    bFunc0 = Cudd_NotCond( bFunc0, Abc_ObjFaninC0(pObj) );
    bFunc1 = Cudd_NotCond( bFunc1, Abc_ObjFaninC1(pObj) );
    // get the BDD of the node
    bFunc  = Cudd_bddAnd( dd, bFunc0, bFunc1 );  Cudd_Ref( bFunc );
    Cudd_RecursiveDeref( dd, bFunc0 );
    Cudd_RecursiveDeref( dd, bFunc1 );
    // return the BDD
    Cudd_Deref( bFunc );
    return bFunc;
}

Alan Mishchenko committed
648 649 650 651 652
////////////////////////////////////////////////////////////////////////
///                       END OF FILE                                ///
////////////////////////////////////////////////////////////////////////