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


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

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

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
189
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
190 191 192 193 194 195 196 197
{
    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) )
198
        return (Hop_Obj_t *)If_CutData(pCut);
Alan Mishchenko committed
199 200 201 202 203 204
    // 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) )
205
        return (Hop_Obj_t *)If_CutData(pCut);
Alan Mishchenko committed
206 207 208
    // compute the functions of the children
    for ( pTemp = pIfObj; pTemp; pTemp = pTemp->pEquiv )
    {
Alan Mishchenko committed
209
        gFunc0 = Nwk_NodeIfToHop2_rec( pHopMan, pIfMan, pTemp->pFanin0, vVisited );
Alan Mishchenko committed
210 211
        if ( gFunc0 == (void *)1 )
            continue;
Alan Mishchenko committed
212
        gFunc1 = Nwk_NodeIfToHop2_rec( pHopMan, pIfMan, pTemp->pFanin1, vVisited );
Alan Mishchenko committed
213 214 215 216 217 218 219 220 221
        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;
    }
222
    return (Hop_Obj_t *)If_CutData(pCut);
Alan Mishchenko committed
223 224 225 226
}

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

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

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
236
Hop_Obj_t * Nwk_NodeIfToHop( Hop_Man_t * pHopMan, If_Man_t * pIfMan, If_Obj_t * pIfObj )
Alan Mishchenko committed
237 238 239 240 241 242 243 244 245 246 247 248 249
{
    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
250
    gFunc = Nwk_NodeIfToHop2_rec( pHopMan, pIfMan, pIfObj, pIfMan->vTemp ); 
Alan Mishchenko committed
251 252
    if ( gFunc == (void *)1 )
    {
Alan Mishchenko committed
253
        printf( "Nwk_NodeIfToHop(): Computing local AIG has failed.\n" );
Alan Mishchenko committed
254 255 256 257 258 259
        return NULL;
    }
//    printf( "%d ", Vec_PtrSize(p->vTemp) );
    // clean the cuts
    If_CutForEachLeaf( pIfMan, pCut, pLeaf, i )
        If_CutSetData( If_ObjCutBest(pLeaf), NULL );
260
    Vec_PtrForEachEntry( If_Cut_t *, pIfMan->vTemp, pCut, i )
Alan Mishchenko committed
261 262 263 264 265 266
        If_CutSetData( pCut, NULL );
    return gFunc;
}

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

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

  Description []
               
  SideEffects []

  SeeAlso     []

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

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

  Synopsis    [Interface with the FPGA mapping package.]

  Description []
               
  SideEffects []

  SeeAlso     []

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

Alan Mishchenko committed
390 391 392 393 394 395

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


396 397
ABC_NAMESPACE_IMPL_END