nwkMap.c 13 KB
Newer Older
Alan Mishchenko committed
1 2
/**CFile****************************************************************

Alan Mishchenko committed
3
  FileName    [nwkMap.c]
Alan Mishchenko committed
4 5 6

  SystemName  [ABC: Logic synthesis and verification system.]

Alan Mishchenko committed
7
  PackageName [Logic network representation.]
Alan Mishchenko committed
8 9 10 11 12 13 14 15 16

  Synopsis    [Interface to technology mapping.]

  Author      [Alan Mishchenko]
  
  Affiliation [UC Berkeley]

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

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

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

Alan Mishchenko committed
21
#include "nwk.h"
22
#include "map/if/if.h"
Alan Mishchenko committed
23

24 25 26
ABC_NAMESPACE_IMPL_START


Alan Mishchenko committed
27 28 29 30 31 32 33 34 35 36
////////////////////////////////////////////////////////////////////////
///                        DECLARATIONS                              ///
////////////////////////////////////////////////////////////////////////

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

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

Alan Mishchenko committed
37 38 39 40 41 42 43 44 45
  Synopsis    [Load the network into FPGA manager.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
46
void Nwk_ManSetIfParsDefault( If_Par_t * pPars )
Alan Mishchenko committed
47 48 49 50 51 52 53 54 55 56 57
{
//    extern void * Abc_FrameReadLibLut();
    // set defaults
    memset( pPars, 0, sizeof(If_Par_t) );
    // user-controlable paramters
//    pPars->nLutSize    = -1;
    pPars->nLutSize    =  6;
    pPars->nCutsMax    =  8;
    pPars->nFlowIters  =  1;
    pPars->nAreaIters  =  2;
    pPars->DelayTarget = -1;
Alan Mishchenko committed
58
    pPars->Epsilon     =  (float)0.005;
Alan Mishchenko committed
59 60 61
    pPars->fPreprocess =  1;
    pPars->fArea       =  0;
    pPars->fFancy      =  0;
Alan Mishchenko committed
62
    pPars->fExpRed     =  1; ////
Alan Mishchenko committed
63 64
    pPars->fLatchPaths =  0;
    pPars->fEdge       =  1;
Alan Mishchenko committed
65
    pPars->fPower      =  0;
Alan Mishchenko committed
66 67
    pPars->fCutMin     =  0;
    pPars->fVerbose    =  0;
Alan Mishchenko committed
68 69
    // internal parameters
    pPars->fTruth      =  0;
70 71
    pPars->nLatchesCi  =  0;
    pPars->nLatchesCo  =  0;
Alan Mishchenko committed
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
    pPars->fLiftLeaves =  0;
//    pPars->pLutLib     =  Abc_FrameReadLibLut();
    pPars->pLutLib     =  NULL;
    pPars->pTimesArr   =  NULL; 
    pPars->pTimesArr   =  NULL;   
    pPars->pFuncCost   =  NULL;   
/*
    if ( pPars->nLutSize == -1 )
    {
        if ( pPars->pLutLib == NULL )
        {
            printf( "The LUT library is not given.\n" );
            return;
        }
        // get LUT size from the library
        pPars->nLutSize = pPars->pLutLib->LutMax;
    }
*/
}

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

  Synopsis    [Load the network into FPGA manager.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
103
If_Man_t * Nwk_ManToIf( Aig_Man_t * p, If_Par_t * pPars, Vec_Ptr_t * vAigToIf )
Alan Mishchenko committed
104
{
Alan Mishchenko committed
105 106
    extern Vec_Int_t * Saig_ManComputeSwitchProbs( Aig_Man_t * p, int nFrames, int nPref, int fProbOne );
    Vec_Int_t * vSwitching = NULL, * vSwitching2 = NULL;
107
    float * pSwitching = NULL, * pSwitching2 = NULL;
Alan Mishchenko committed
108
    If_Man_t * pIfMan;
Alan Mishchenko committed
109 110
    If_Obj_t * pIfObj;
    Aig_Obj_t * pNode, * pFanin, * pPrev;
111
    int i;
112
    abctime clk = Abc_Clock();
Alan Mishchenko committed
113 114 115 116 117 118 119
    // set the number of registers (switch activity will be combinational)
    Aig_ManSetRegNum( p, 0 );
    if ( pPars->fPower )
    {
        vSwitching  = Saig_ManComputeSwitchProbs( p, 48, 16, 0 );
        if ( pPars->fVerbose )
        {
120
            ABC_PRT( "Computing switching activity", Abc_Clock() - clk );
Alan Mishchenko committed
121 122 123 124 125
        }
        pSwitching  = (float *)vSwitching->pArray;
        vSwitching2 = Vec_IntStart( Aig_ManObjNumMax(p) );
        pSwitching2 = (float *)vSwitching2->pArray;
    }
Alan Mishchenko committed
126 127
    // start the mapping manager and set its parameters
    pIfMan = If_ManStart( pPars );
Alan Mishchenko committed
128
    pIfMan->vSwitching = vSwitching2;
Alan Mishchenko committed
129 130 131 132
    // load the AIG into the mapper
    Aig_ManForEachObj( p, pNode, i )
    {
        if ( Aig_ObjIsAnd(pNode) )
133
        {
Alan Mishchenko committed
134
            pIfObj = If_ManCreateAnd( pIfMan, 
135 136 137 138
                If_NotCond( (If_Obj_t *)Aig_ObjFanin0(pNode)->pData, Aig_ObjFaninC0(pNode) ), 
                If_NotCond( (If_Obj_t *)Aig_ObjFanin1(pNode)->pData, Aig_ObjFaninC1(pNode) ) );
//            printf( "no%d=%d\n ", If_ObjId(pIfObj), If_ObjLevel(pIfObj) );
        }
139
        else if ( Aig_ObjIsCi(pNode) )
Alan Mishchenko committed
140
        {
Alan Mishchenko committed
141 142
            pIfObj = If_ManCreateCi( pIfMan );
            If_ObjSetLevel( pIfObj, Aig_ObjLevel(pNode) );
143
//            printf( "pi%d=%d\n ", If_ObjId(pIfObj), If_ObjLevel(pIfObj) );
Alan Mishchenko committed
144 145
            if ( pIfMan->nLevelMax < (int)pIfObj->Level )
                pIfMan->nLevelMax = (int)pIfObj->Level;
Alan Mishchenko committed
146
        }
147
        else if ( Aig_ObjIsCo(pNode) )
Alan Mishchenko committed
148
        {
149 150
            pIfObj = If_ManCreateCo( pIfMan, If_NotCond( (If_Obj_t *)Aig_ObjFanin0(pNode)->pData, Aig_ObjFaninC0(pNode) ) );
//            printf( "po%d=%d\n ", If_ObjId(pIfObj), If_ObjLevel(pIfObj) );
Alan Mishchenko committed
151
        }
Alan Mishchenko committed
152
        else if ( Aig_ObjIsConst1(pNode) )
Alan Mishchenko committed
153
            pIfObj = If_ManConst1( pIfMan );
Alan Mishchenko committed
154 155
        else // add the node to the mapper
            assert( 0 );
Alan Mishchenko committed
156 157 158 159
        // save the result
        assert( Vec_PtrEntry(vAigToIf, i) == NULL );
        Vec_PtrWriteEntry( vAigToIf, i, pIfObj );
        pNode->pData = pIfObj;
Alan Mishchenko committed
160 161
        if ( vSwitching2 )
            pSwitching2[pIfObj->Id] = pSwitching[pNode->Id];            
Alan Mishchenko committed
162
        // set up the choice node
Alan Mishchenko committed
163
        if ( Aig_ObjIsChoice( p, pNode ) )
Alan Mishchenko committed
164
        {
Alan Mishchenko committed
165
            for ( pPrev = pNode, pFanin = Aig_ObjEquiv(p, pNode); pFanin; pPrev = pFanin, pFanin = Aig_ObjEquiv(p, pFanin) )
166 167
                If_ObjSetChoice( (If_Obj_t *)pPrev->pData, (If_Obj_t *)pFanin->pData );
            If_ManCreateChoice( pIfMan, (If_Obj_t *)pNode->pData );
Alan Mishchenko committed
168
        }
Alan Mishchenko committed
169
//        assert( If_ObjLevel(pIfObj) == Aig_ObjLevel(pNode) );
Alan Mishchenko committed
170
    }
Alan Mishchenko committed
171 172
    if ( vSwitching )
        Vec_IntFree( vSwitching );
Alan Mishchenko committed
173 174 175 176 177 178
    return pIfMan;
}


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

Alan Mishchenko committed
179
  Synopsis    [Recursively derives the local AIG for the cut.]
Alan Mishchenko committed
180 181 182 183 184 185 186 187

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
188
Hop_Obj_t * Nwk_NodeIfToHop2_rec( Hop_Man_t * pHopMan, If_Man_t * pIfMan, If_Obj_t * pIfObj, Vec_Ptr_t * vVisited )
Alan Mishchenko committed
189 190 191 192 193 194 195 196
{
    If_Cut_t * pCut;
    If_Obj_t * pTemp;
    Hop_Obj_t * gFunc, * gFunc0, * gFunc1;
    // get the best cut
    pCut = If_ObjCutBest(pIfObj);
    // if the cut is visited, return the result
    if ( If_CutData(pCut) )
197
        return (Hop_Obj_t *)If_CutData(pCut);
Alan Mishchenko committed
198 199 200 201 202 203
    // mark the node as visited
    Vec_PtrPush( vVisited, pCut );
    // insert the worst case
    If_CutSetData( pCut, (void *)1 );
    // skip in case of primary input
    if ( If_ObjIsCi(pIfObj) )
204
        return (Hop_Obj_t *)If_CutData(pCut);
Alan Mishchenko committed
205 206 207
    // compute the functions of the children
    for ( pTemp = pIfObj; pTemp; pTemp = pTemp->pEquiv )
    {
Alan Mishchenko committed
208
        gFunc0 = Nwk_NodeIfToHop2_rec( pHopMan, pIfMan, pTemp->pFanin0, vVisited );
Alan Mishchenko committed
209 210
        if ( gFunc0 == (void *)1 )
            continue;
Alan Mishchenko committed
211
        gFunc1 = Nwk_NodeIfToHop2_rec( pHopMan, pIfMan, pTemp->pFanin1, vVisited );
Alan Mishchenko committed
212 213 214 215 216 217 218 219 220
        if ( gFunc1 == (void *)1 )
            continue;
        // both branches are solved
        gFunc = Hop_And( pHopMan, Hop_NotCond(gFunc0, pTemp->fCompl0), Hop_NotCond(gFunc1, pTemp->fCompl1) ); 
        if ( pTemp->fPhase != pIfObj->fPhase )
            gFunc = Hop_Not(gFunc);
        If_CutSetData( pCut, gFunc );
        break;
    }
221
    return (Hop_Obj_t *)If_CutData(pCut);
Alan Mishchenko committed
222 223 224 225
}

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

Alan Mishchenko committed
226
  Synopsis    [Derives the local AIG for the cut.]
Alan Mishchenko committed
227 228 229 230 231 232 233 234

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
235
Hop_Obj_t * Nwk_NodeIfToHop( Hop_Man_t * pHopMan, If_Man_t * pIfMan, If_Obj_t * pIfObj )
Alan Mishchenko committed
236 237 238 239 240 241 242 243 244 245 246 247 248
{
    If_Cut_t * pCut;
    Hop_Obj_t * gFunc;
    If_Obj_t * pLeaf;
    int i;
    // get the best cut
    pCut = If_ObjCutBest(pIfObj);
    assert( pCut->nLeaves > 1 );
    // set the leaf variables
    If_CutForEachLeaf( pIfMan, pCut, pLeaf, i )
        If_CutSetData( If_ObjCutBest(pLeaf), Hop_IthVar(pHopMan, i) );
    // recursively compute the function while collecting visited cuts
    Vec_PtrClear( pIfMan->vTemp );
Alan Mishchenko committed
249
    gFunc = Nwk_NodeIfToHop2_rec( pHopMan, pIfMan, pIfObj, pIfMan->vTemp ); 
Alan Mishchenko committed
250 251
    if ( gFunc == (void *)1 )
    {
Alan Mishchenko committed
252
        printf( "Nwk_NodeIfToHop(): Computing local AIG has failed.\n" );
Alan Mishchenko committed
253 254 255 256 257 258
        return NULL;
    }
//    printf( "%d ", Vec_PtrSize(p->vTemp) );
    // clean the cuts
    If_CutForEachLeaf( pIfMan, pCut, pLeaf, i )
        If_CutSetData( If_ObjCutBest(pLeaf), NULL );
259
    Vec_PtrForEachEntry( If_Cut_t *, pIfMan->vTemp, pCut, i )
Alan Mishchenko committed
260 261 262 263 264 265
        If_CutSetData( pCut, NULL );
    return gFunc;
}

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

Alan Mishchenko committed
266 267 268 269 270 271 272 273 274
  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
275
Nwk_Man_t * Nwk_ManFromIf( If_Man_t * pIfMan, Aig_Man_t * p, Vec_Ptr_t * vAigToIf )
Alan Mishchenko committed
276
{
Alan Mishchenko committed
277
    Vec_Ptr_t * vIfToAig;
Alan Mishchenko committed
278 279
    Nwk_Man_t * pNtk;
    Nwk_Obj_t * pObjNew;
Alan Mishchenko committed
280
    Aig_Obj_t * pObj, * pObjRepr;
Alan Mishchenko committed
281 282 283
    If_Obj_t * pIfObj;
    If_Cut_t * pCutBest;
    int i, k, nLeaves, * ppLeaves;
284 285
    assert( Aig_ManCiNum(p) == If_ManCiNum(pIfMan) );
    assert( Aig_ManCoNum(p) == If_ManCoNum(pIfMan) );
Alan Mishchenko committed
286
    assert( Aig_ManNodeNum(p) == If_ManAndNum(pIfMan) );
Alan Mishchenko committed
287
    Aig_ManCleanData( p );
Alan Mishchenko committed
288
    If_ManCleanCutData( pIfMan );
Alan Mishchenko committed
289 290 291 292
    // create mapping of IF to AIG
    vIfToAig = Vec_PtrStart( If_ManObjNum(pIfMan) );
    Aig_ManForEachObj( p, pObj, i )
    {
293
        pIfObj = (If_Obj_t *)Vec_PtrEntry( vAigToIf, i );
Alan Mishchenko committed
294 295
        Vec_PtrWriteEntry( vIfToAig, pIfObj->Id, pObj );
    }
Alan Mishchenko committed
296
    // construct the network
Alan Mishchenko committed
297
    pNtk = Nwk_ManAlloc();
298 299
    pNtk->pName = Abc_UtilStrsav( p->pName );
    pNtk->pSpec = Abc_UtilStrsav( p->pSpec );
Alan Mishchenko committed
300 301 302
//    pNtk->nLatches = Aig_ManRegNum(p);
//    pNtk->nTruePis = Nwk_ManCiNum(pNtk) - pNtk->nLatches;
//    pNtk->nTruePos = Nwk_ManCoNum(pNtk) - pNtk->nLatches;
Alan Mishchenko committed
303 304
    Aig_ManForEachObj( p, pObj, i )
    {
305
        pIfObj = (If_Obj_t *)Vec_PtrEntry( vAigToIf, i );
Alan Mishchenko committed
306 307 308 309 310 311 312 313
        if ( pIfObj->nRefs == 0 && !If_ObjIsTerm(pIfObj) )
            continue;
        if ( Aig_ObjIsNode(pObj) )
        {
            pCutBest = If_ObjCutBest( pIfObj );
            nLeaves  = If_CutLeaveNum( pCutBest ); 
            ppLeaves = If_CutLeaves( pCutBest );
            // create node
Alan Mishchenko committed
314
            pObjNew = Nwk_ManCreateNode( pNtk, nLeaves, pIfObj->nRefs );
Alan Mishchenko committed
315
            for ( k = 0; k < nLeaves; k++ )
Alan Mishchenko committed
316
            {
317 318
                pObjRepr = (Aig_Obj_t *)Vec_PtrEntry( vIfToAig, ppLeaves[k] );
                Nwk_ObjAddFanin( pObjNew, (Nwk_Obj_t *)pObjRepr->pData );
Alan Mishchenko committed
319
            }
Alan Mishchenko committed
320
            // get the functionality
Alan Mishchenko committed
321
            pObjNew->pFunc = Nwk_NodeIfToHop( pNtk->pManHop, pIfMan, pIfObj );
Alan Mishchenko committed
322
        }
323
        else if ( Aig_ObjIsCi(pObj) )
Alan Mishchenko committed
324
            pObjNew = Nwk_ManCreateCi( pNtk, pIfObj->nRefs );
325
        else if ( Aig_ObjIsCo(pObj) )
Alan Mishchenko committed
326
        {
Alan Mishchenko committed
327
            pObjNew = Nwk_ManCreateCo( pNtk );
Alan Mishchenko committed
328
            pObjNew->fInvert = Aig_ObjFaninC0(pObj);
329
            Nwk_ObjAddFanin( pObjNew, (Nwk_Obj_t *)Aig_ObjFanin0(pObj)->pData );
Alan Mishchenko committed
330
//printf( "%d ", pObjNew->Id );
Alan Mishchenko committed
331 332 333
        }
        else if ( Aig_ObjIsConst1(pObj) )
        {
Alan Mishchenko committed
334
            pObjNew = Nwk_ManCreateNode( pNtk, 0, pIfObj->nRefs );
Alan Mishchenko committed
335 336 337 338 339 340
            pObjNew->pFunc = Hop_ManConst1( pNtk->pManHop );
        }
        else
            assert( 0 );
        pObj->pData = pObjNew;
    }
Alan Mishchenko committed
341
//printf( "\n" );
Alan Mishchenko committed
342
    Vec_PtrFree( vIfToAig );
Alan Mishchenko committed
343
    pNtk->pManTime = Tim_ManDup( pIfMan->pManTim, 0 );
Alan Mishchenko committed
344
    Nwk_ManMinimumBase( pNtk, 0 );
Alan Mishchenko committed
345
    assert( Nwk_ManCheck( pNtk ) );
Alan Mishchenko committed
346 347 348 349 350 351 352 353 354 355 356 357 358 359
    return pNtk;
}

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

  Synopsis    [Interface with the FPGA mapping package.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
360
Nwk_Man_t * Nwk_MappingIf( Aig_Man_t * p, Tim_Man_t * pManTime, If_Par_t * pPars )
Alan Mishchenko committed
361
{
Alan Mishchenko committed
362
    Nwk_Man_t * pNtk;
Alan Mishchenko committed
363
    If_Man_t * pIfMan;
Alan Mishchenko committed
364
    Vec_Ptr_t * vAigToIf;
Alan Mishchenko committed
365
    // set the arrival times
366 367
    pPars->pTimesArr = ABC_ALLOC( float, Aig_ManCiNum(p) );
    memset( pPars->pTimesArr, 0, sizeof(float) * Aig_ManCiNum(p) );
Alan Mishchenko committed
368
    // translate into the mapper
Alan Mishchenko committed
369 370
    vAigToIf = Vec_PtrStart( Aig_ManObjNumMax(p) );
    pIfMan = Nwk_ManToIf( p, pPars, vAigToIf );    
Alan Mishchenko committed
371 372 373
    if ( pIfMan == NULL )
        return NULL;
    pIfMan->pManTim = Tim_ManDup( pManTime, 0 );
374
    pIfMan->pPars->fCutMin = 0; // is not compatible with deriving result
Alan Mishchenko committed
375 376 377 378 379 380
    if ( !If_ManPerformMapping( pIfMan ) )
    {
        If_ManStop( pIfMan );
        return NULL;
    }
    // transform the result of mapping into the new network
Alan Mishchenko committed
381
    pNtk = Nwk_ManFromIf( pIfMan, p, vAigToIf );
Alan Mishchenko committed
382 383
    if ( pPars->fBidec && pPars->nLutSize <= 8 )
        Nwk_ManBidecResyn( pNtk, 0 );
Alan Mishchenko committed
384
    If_ManStop( pIfMan );
Alan Mishchenko committed
385
    Vec_PtrFree( vAigToIf );
Alan Mishchenko committed
386 387 388
    return pNtk;
}

Alan Mishchenko committed
389 390 391 392 393 394

////////////////////////////////////////////////////////////////////////
///                       END OF FILE                                ///
////////////////////////////////////////////////////////////////////////


395 396
ABC_NAMESPACE_IMPL_END