abcRewrite.c 12.4 KB
Newer Older
Alan Mishchenko committed
1 2
/**CFile****************************************************************

Alan Mishchenko committed
3
  FileName    [abcRewrite.c]
Alan Mishchenko committed
4 5 6 7 8

  SystemName  [ABC: Logic synthesis and verification system.]

  PackageName [Network and node package.]

Alan Mishchenko committed
9
  Synopsis    [Technology-independent resynthesis of the AIG based on DAG aware rewriting.]
Alan Mishchenko committed
10 11 12 13 14 15 16

  Author      [Alan Mishchenko]
  
  Affiliation [UC Berkeley]

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

Alan Mishchenko committed
17
  Revision    [$Id: abcRewrite.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
Alan Mishchenko committed
18 19 20 21

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

#include "abc.h"
22
#include "extra.h"
Alan Mishchenko committed
23
#include "rwr.h"
Alan Mishchenko committed
24
#include "dec.h"
Alan Mishchenko committed
25

26 27 28
ABC_NAMESPACE_IMPL_START


Alan Mishchenko committed
29 30 31 32 33 34
/*
    The ideas realized in this package are inspired by the paper:
    Per Bjesse, Arne Boralv, "DAG-aware circuit compression for 
    formal verification", Proc. ICCAD 2004, pp. 42-49.
*/

Alan Mishchenko committed
35 36 37 38
////////////////////////////////////////////////////////////////////////
///                        DECLARATIONS                              ///
////////////////////////////////////////////////////////////////////////

Alan Mishchenko committed
39
static Cut_Man_t * Abc_NtkStartCutManForRewrite( Abc_Ntk_t * pNtk );
Alan Mishchenko committed
40
static void        Abc_NodePrintCuts( Abc_Obj_t * pNode );
Alan Mishchenko committed
41 42 43 44 45
static void        Abc_ManShowCutCone( Abc_Obj_t * pNode, Vec_Ptr_t * vLeaves );

extern void  Abc_PlaceBegin( Abc_Ntk_t * pNtk );
extern void  Abc_PlaceEnd( Abc_Ntk_t * pNtk );
extern void  Abc_PlaceUpdate( Vec_Ptr_t * vAddedCells, Vec_Ptr_t * vUpdatedNets );
Alan Mishchenko committed
46

Alan Mishchenko committed
47
////////////////////////////////////////////////////////////////////////
Alan Mishchenko committed
48
///                     FUNCTION DEFINITIONS                         ///
Alan Mishchenko committed
49 50 51 52
////////////////////////////////////////////////////////////////////////

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

Alan Mishchenko committed
53
  Synopsis    [Performs incremental rewriting of the AIG.]
Alan Mishchenko committed
54

Alan Mishchenko committed
55
  Description []
Alan Mishchenko committed
56 57 58 59 60 61
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
62
int Abc_NtkRewrite( Abc_Ntk_t * pNtk, int fUpdateLevel, int fUseZeros, int fVerbose, int fVeryVerbose, int fPlaceEnable )
Alan Mishchenko committed
63
{
64
    extern void           Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain );
Alan Mishchenko committed
65
    ProgressBar * pProgress;
Alan Mishchenko committed
66 67
    Cut_Man_t * pManCut;
    Rwr_Man_t * pManRwr;
Alan Mishchenko committed
68
    Abc_Obj_t * pNode;
Alan Mishchenko committed
69
//    Vec_Ptr_t * vAddedCells = NULL, * vUpdatedNets = NULL;
Alan Mishchenko committed
70 71
    Dec_Graph_t * pGraph;
    int i, nNodes, nGain, fCompl;
Alan Mishchenko committed
72
    int clk, clkStart = clock();
Alan Mishchenko committed
73

Alan Mishchenko committed
74
    assert( Abc_NtkIsStrash(pNtk) );
Alan Mishchenko committed
75
    // cleanup the AIG
76
    Abc_AigCleanup((Abc_Aig_t *)pNtk->pManFunc);
Alan Mishchenko committed
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
/*
    {
        Vec_Vec_t * vParts;
        vParts = Abc_NtkPartitionSmart( pNtk, 50, 1 );
        Vec_VecFree( vParts );
    }
*/

    // start placement package
//    if ( fPlaceEnable )
//    {
//        Abc_PlaceBegin( pNtk );
//        vAddedCells = Abc_AigUpdateStart( pNtk->pManFunc, &vUpdatedNets );
//    }

Alan Mishchenko committed
92
    // start the rewriting manager
Alan Mishchenko committed
93 94
    pManRwr = Rwr_ManStart( 0 );
    if ( pManRwr == NULL )
Alan Mishchenko committed
95
        return 0;
Alan Mishchenko committed
96 97 98
    // compute the reverse levels if level update is requested
    if ( fUpdateLevel )
        Abc_NtkStartReverseLevels( pNtk, 0 );
Alan Mishchenko committed
99 100
    // start the cut manager
clk = clock();
Alan Mishchenko committed
101
    pManCut = Abc_NtkStartCutManForRewrite( pNtk );
Alan Mishchenko committed
102 103
Rwr_ManAddTimeCuts( pManRwr, clock() - clk );
    pNtk->pManCut = pManCut;
Alan Mishchenko committed
104

Alan Mishchenko committed
105 106 107
    if ( fVeryVerbose )
        Rwr_ScoresClean( pManRwr );

Alan Mishchenko committed
108
    // resynthesize each node once
Alan Mishchenko committed
109
    pManRwr->nNodesBeg = Abc_NtkNodeNum(pNtk);
Alan Mishchenko committed
110 111
    nNodes = Abc_NtkObjNumMax(pNtk);
    pProgress = Extra_ProgressBarStart( stdout, nNodes );
Alan Mishchenko committed
112 113
    Abc_NtkForEachNode( pNtk, pNode, i )
    {
Alan Mishchenko committed
114 115 116 117
        Extra_ProgressBarUpdate( pProgress, i, NULL );
        // stop if all nodes have been tried once
        if ( i >= nNodes )
            break;
Alan Mishchenko committed
118 119
        // skip persistant nodes
        if ( Abc_NodeIsPersistant(pNode) )
Alan Mishchenko committed
120
            continue;
Alan Mishchenko committed
121 122 123
        // skip the nodes with many fanouts
        if ( Abc_ObjFanoutNum(pNode) > 1000 )
            continue;
Alan Mishchenko committed
124

Alan Mishchenko committed
125
        // for each cut, try to resynthesize it
Alan Mishchenko committed
126
        nGain = Rwr_NodeRewrite( pManRwr, pManCut, pNode, fUpdateLevel, fUseZeros, fPlaceEnable );
Alan Mishchenko committed
127
        if ( !(nGain > 0 || (nGain == 0 && fUseZeros)) )
Alan Mishchenko committed
128 129 130 131
            continue;
        // if we end up here, a rewriting step is accepted

        // get hold of the new subgraph to be added to the AIG
132
        pGraph = (Dec_Graph_t *)Rwr_ManReadDecs(pManRwr);
Alan Mishchenko committed
133 134 135 136
        fCompl = Rwr_ManReadCompl(pManRwr);

        // reset the array of the changed nodes
        if ( fPlaceEnable )
137
            Abc_AigUpdateReset( (Abc_Aig_t *)pNtk->pManFunc );
Alan Mishchenko committed
138 139 140 141 142 143 144 145 146 147 148

        // complement the FF if needed
        if ( fCompl ) Dec_GraphComplement( pGraph );
clk = clock();
        Dec_GraphUpdateNetwork( pNode, pGraph, fUpdateLevel, nGain );
Rwr_ManAddTimeUpdate( pManRwr, clock() - clk );
        if ( fCompl ) Dec_GraphComplement( pGraph );

        // use the array of changed nodes to update placement
//        if ( fPlaceEnable )
//            Abc_PlaceUpdate( vAddedCells, vUpdatedNets );
Alan Mishchenko committed
149 150
    }
    Extra_ProgressBarStop( pProgress );
Alan Mishchenko committed
151 152
Rwr_ManAddTimeTotal( pManRwr, clock() - clkStart );
    // print stats
Alan Mishchenko committed
153
    pManRwr->nNodesEnd = Abc_NtkNodeNum(pNtk);
Alan Mishchenko committed
154 155
    if ( fVerbose )
        Rwr_ManPrintStats( pManRwr );
Alan Mishchenko committed
156 157 158
//        Rwr_ManPrintStatsFile( pManRwr );
    if ( fVeryVerbose )
        Rwr_ScoresReport( pManRwr );
Alan Mishchenko committed
159 160 161 162
    // delete the managers
    Rwr_ManStop( pManRwr );
    Cut_ManStop( pManCut );
    pNtk->pManCut = NULL;
Alan Mishchenko committed
163 164 165 166 167 168 169 170 171 172 173 174

    // start placement package
//    if ( fPlaceEnable )
//    {
//        Abc_PlaceEnd( pNtk );
//        Abc_AigUpdateStop( pNtk->pManFunc );
//    }

    // put the nodes into the DFS order and reassign their IDs
    {
//        int clk = clock();
    Abc_NtkReassignIds( pNtk );
Alan Mishchenko committed
175
//        ABC_PRT( "time", clock() - clk );
Alan Mishchenko committed
176 177 178 179 180 181 182
    }
//    Abc_AigCheckFaninOrder( pNtk->pManFunc );
    // fix the levels
    if ( fUpdateLevel )
        Abc_NtkStopReverseLevels( pNtk );
    else
        Abc_NtkLevel( pNtk );
Alan Mishchenko committed
183
    // check
Alan Mishchenko committed
184
    if ( !Abc_NtkCheck( pNtk ) )
Alan Mishchenko committed
185
    {
Alan Mishchenko committed
186
        printf( "Abc_NtkRewrite: The network check has failed.\n" );
Alan Mishchenko committed
187 188 189 190 191 192
        return 0;
    }
    return 1;
}


Alan Mishchenko committed
193 194 195 196 197 198 199 200 201 202 203
/**Function*************************************************************

  Synopsis    [Starts the cut manager for rewriting.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
204
Cut_Man_t * Abc_NtkStartCutManForRewrite( Abc_Ntk_t * pNtk )
Alan Mishchenko committed
205 206 207 208 209 210 211 212 213 214
{
    static Cut_Params_t Params, * pParams = &Params;
    Cut_Man_t * pManCut;
    Abc_Obj_t * pObj;
    int i;
    // start the cut manager
    memset( pParams, 0, sizeof(Cut_Params_t) );
    pParams->nVarsMax  = 4;     // the max cut size ("k" of the k-feasible cuts)
    pParams->nKeepMax  = 250;   // the max number of cuts kept at a node
    pParams->fTruth    = 1;     // compute truth tables
Alan Mishchenko committed
215
    pParams->fFilter   = 1;     // filter dominated cuts
Alan Mishchenko committed
216
    pParams->fSeq      = 0;     // compute sequential cuts
Alan Mishchenko committed
217
    pParams->fDrop     = 0;     // drop cuts on the fly
Alan Mishchenko committed
218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242
    pParams->fVerbose  = 0;     // the verbosiness flag
    pParams->nIdsMax   = Abc_NtkObjNumMax( pNtk );
    pManCut = Cut_ManStart( pParams );
    if ( pParams->fDrop )
        Cut_ManSetFanoutCounts( pManCut, Abc_NtkFanoutCounts(pNtk) );
    // set cuts for PIs
    Abc_NtkForEachCi( pNtk, pObj, i )
        if ( Abc_ObjFanoutNum(pObj) > 0 )
            Cut_NodeSetTriv( pManCut, pObj->Id );
    return pManCut;
}

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

  Synopsis    [Prints the cuts at the nodes.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Abc_NodePrintCuts( Abc_Obj_t * pNode )
{
Alan Mishchenko committed
243
    Vec_Ptr_t * vCuts;
Alan Mishchenko committed
244
    Cut_Cut_t * pCut;
Alan Mishchenko committed
245 246
    int k;

Alan Mishchenko committed
247
    printf( "\nNode %s\n", Abc_ObjName(pNode) );
Alan Mishchenko committed
248
    vCuts = (Vec_Ptr_t *)pNode->pCopy;
249
    Vec_PtrForEachEntry( Cut_Cut_t *, vCuts, pCut, k )
Alan Mishchenko committed
250
    {
Alan Mishchenko committed
251
        Extra_PrintBinary( stdout, (unsigned *)&pCut->uSign, 16 ); 
Alan Mishchenko committed
252
        printf( "   " );
Alan Mishchenko committed
253
        Cut_CutPrint( pCut, 0 );   
Alan Mishchenko committed
254 255 256 257
        printf( "\n" );
    }
}

Alan Mishchenko committed
258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273

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

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Abc_ManRewritePrintDivs( Vec_Ptr_t * vDivs, int nLeaves )
{
    Abc_Obj_t * pFanin, * pNode, * pRoot;
    int i, k;
274
    pRoot = (Abc_Obj_t *)Vec_PtrEntryLast(vDivs);
Alan Mishchenko committed
275
    // print the nodes
276
    Vec_PtrForEachEntry( Abc_Obj_t *, vDivs, pNode, i )
Alan Mishchenko committed
277 278 279 280 281 282 283 284
    {
        if ( i < nLeaves )
        {
            printf( "%6d : %c\n", pNode->Id, 'a'+i );
            continue;
        }
        printf( "%6d : %2d = ", pNode->Id, i );
        // find the first fanin
285
        Vec_PtrForEachEntry( Abc_Obj_t *, vDivs, pFanin, k )
Alan Mishchenko committed
286 287 288 289 290 291 292 293
            if ( Abc_ObjFanin0(pNode) == pFanin )
                break;
        if ( k < nLeaves )
            printf( "%c", 'a' + k );
        else
            printf( "%d", k );
        printf( "%s ", Abc_ObjFaninC0(pNode)? "\'" : "" );
        // find the second fanin
294
        Vec_PtrForEachEntry( Abc_Obj_t *, vDivs, pFanin, k )
Alan Mishchenko committed
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
            if ( Abc_ObjFanin1(pNode) == pFanin )
                break;
        if ( k < nLeaves )
            printf( "%c", 'a' + k );
        else
            printf( "%d", k );
        printf( "%s ", Abc_ObjFaninC1(pNode)? "\'" : "" );
        if ( pNode == pRoot )
            printf( " root" );
        printf( "\n" );
    }
    printf( "\n" );
}

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

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Abc_ManShowCutCone_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vDivs )
{
    if ( Abc_NodeIsTravIdCurrent(pNode) )
        return;
    Abc_NodeSetTravIdCurrent(pNode);
    Abc_ManShowCutCone_rec( Abc_ObjFanin0(pNode), vDivs );
    Abc_ManShowCutCone_rec( Abc_ObjFanin1(pNode), vDivs );
    Vec_PtrPush( vDivs, pNode );
}

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

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Abc_ManShowCutCone( Abc_Obj_t * pNode, Vec_Ptr_t * vLeaves )
{
    Abc_Ntk_t * pNtk = pNode->pNtk;
    Abc_Obj_t * pObj;
    Vec_Ptr_t * vDivs;
    int i;
    vDivs = Vec_PtrAlloc( 100 );
    Abc_NtkIncrementTravId( pNtk );
349
    Vec_PtrForEachEntry( Abc_Obj_t *, vLeaves, pObj, i )
Alan Mishchenko committed
350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 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
    {
        Abc_NodeSetTravIdCurrent( Abc_ObjRegular(pObj) );
        Vec_PtrPush( vDivs, Abc_ObjRegular(pObj) );
    }
    Abc_ManShowCutCone_rec( pNode, vDivs );
    Abc_ManRewritePrintDivs( vDivs, Vec_PtrSize(vLeaves) );
    Vec_PtrFree( vDivs );
}


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

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Abc_RwrExpWithCut_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vLeaves, int fUseA )
{
    if ( Vec_PtrFind(vLeaves, pNode) >= 0 || Vec_PtrFind(vLeaves, Abc_ObjNot(pNode)) >= 0 )
    {
        if ( fUseA )
            Abc_ObjRegular(pNode)->fMarkA = 1;
        else
            Abc_ObjRegular(pNode)->fMarkB = 1;
        return;
    }
    assert( Abc_ObjIsNode(pNode) );
    Abc_RwrExpWithCut_rec( Abc_ObjFanin0(pNode), vLeaves, fUseA );
    Abc_RwrExpWithCut_rec( Abc_ObjFanin1(pNode), vLeaves, fUseA );
}

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

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Abc_RwrExpWithCut( Abc_Obj_t * pNode, Vec_Ptr_t * vLeaves )
{
    Abc_Obj_t * pObj;
    int i, CountA, CountB;
    Abc_RwrExpWithCut_rec( Abc_ObjFanin0(pNode), vLeaves, 1 );
    Abc_RwrExpWithCut_rec( Abc_ObjFanin1(pNode), vLeaves, 0 );
    CountA = CountB = 0;
404
    Vec_PtrForEachEntry( Abc_Obj_t *, vLeaves, pObj, i )
Alan Mishchenko committed
405 406 407 408 409 410 411 412 413 414
    {
        CountA += Abc_ObjRegular(pObj)->fMarkA;
        CountB += Abc_ObjRegular(pObj)->fMarkB;
        Abc_ObjRegular(pObj)->fMarkA = 0;
        Abc_ObjRegular(pObj)->fMarkB = 0;
    }
    printf( "(%d,%d:%d) ", CountA, CountB, CountA+CountB-Vec_PtrSize(vLeaves) );
}


Alan Mishchenko committed
415 416 417 418 419
////////////////////////////////////////////////////////////////////////
///                       END OF FILE                                ///
////////////////////////////////////////////////////////////////////////


420 421
ABC_NAMESPACE_IMPL_END