diff options
| -rw-r--r-- | abclib.dsp | 6 | ||||
| -rw-r--r-- | src/base/abc/abc.h | 5 | ||||
| -rw-r--r-- | src/base/abc/abcNtk.c | 2 | ||||
| -rw-r--r-- | src/base/abci/abcIf.c | 91 | ||||
| -rw-r--r-- | src/base/abci/abcPrint.c | 2 | ||||
| -rw-r--r-- | src/base/io/ioReadBlifMv.c | 1 | ||||
| -rw-r--r-- | src/map/if/if.h | 4 | ||||
| -rw-r--r-- | src/map/if/ifCut.c | 6 | ||||
| -rw-r--r-- | src/map/if/ifMap.c | 60 | ||||
| -rw-r--r-- | src/map/if/ifUtil.c | 1 | 
10 files changed, 170 insertions, 8 deletions
| @@ -2027,7 +2027,11 @@ SOURCE=.\src\map\if\ifCut.c  # End Source File  # Begin Source File -SOURCE=.\src\map\if\ifDec.c +SOURCE=.\src\map\if\ifDec07.c +# End Source File +# Begin Source File + +SOURCE=.\src\map\if\ifDec08.c  # End Source File  # Begin Source File diff --git a/src/base/abc/abc.h b/src/base/abc/abc.h index a7d7bd73..a7fa7d2d 100644 --- a/src/base/abc/abc.h +++ b/src/base/abc/abc.h @@ -179,9 +179,10 @@ struct Abc_Ntk_t_      Vec_Ptr_t *       vBoxes;        // the array of boxes      Vec_Ptr_t *       vLtlProperties;      // the number of living objects -    int               nConstrs;      // the number of constraints (model checking only) -    int               nObjs;         // the number of live objs      int nObjCounts[ABC_OBJ_NUMBER];  // the number of objects by type +    int               nObjs;         // the number of live objs +    int               nConstrs;      // the number of constraints +    int               nRealPos;      // the number of real POs      // the backup network and the step number      Abc_Ntk_t *       pNetBackup;    // the pointer to the previous backup network      int               iStep;         // the generation number for the given network diff --git a/src/base/abc/abcNtk.c b/src/base/abc/abcNtk.c index ef4c96e3..3ec71680 100644 --- a/src/base/abc/abcNtk.c +++ b/src/base/abc/abcNtk.c @@ -110,6 +110,7 @@ Abc_Ntk_t * Abc_NtkStartFrom( Abc_Ntk_t * pNtk, Abc_NtkType_t Type, Abc_NtkFunc_      // start the network      pNtkNew = Abc_NtkAlloc( Type, Func, 1 );      pNtkNew->nConstrs = pNtk->nConstrs; +    pNtkNew->nRealPos = pNtk->nRealPos;      // duplicate the name and the spec      pNtkNew->pName = Extra_UtilStrsav(pNtk->pName);      pNtkNew->pSpec = Extra_UtilStrsav(pNtk->pSpec); @@ -163,6 +164,7 @@ Abc_Ntk_t * Abc_NtkStartFromNoLatches( Abc_Ntk_t * pNtk, Abc_NtkType_t Type, Abc      // start the network      pNtkNew = Abc_NtkAlloc( Type, Func, 1 );      pNtkNew->nConstrs = pNtk->nConstrs; +    pNtkNew->nRealPos = pNtk->nRealPos;      // duplicate the name and the spec      pNtkNew->pName = Extra_UtilStrsav(pNtk->pName);      pNtkNew->pSpec = Extra_UtilStrsav(pNtk->pSpec); diff --git a/src/base/abci/abcIf.c b/src/base/abci/abcIf.c index 77f7805c..400e1193 100644 --- a/src/base/abci/abcIf.c +++ b/src/base/abci/abcIf.c @@ -38,6 +38,9 @@ static Vec_Ptr_t * Abc_NtkFindGoodOrder( Abc_Ntk_t * pNtk );  extern void Abc_NtkBddReorder( Abc_Ntk_t * pNtk, int fVerbose );  extern void Abc_NtkBidecResyn( Abc_Ntk_t * pNtk, int fVerbose ); + +extern void Abc_NtkCollectPoDrivers( If_Man_t * p, Abc_Ntk_t * pNtk ); +extern void Abc_NtkFreePoDrivers( If_Man_t * p );  ////////////////////////////////////////////////////////////////////////  ///                     FUNCTION DEFINITIONS                         /// @@ -126,17 +129,22 @@ Abc_Ntk_t * Abc_NtkIf( Abc_Ntk_t * pNtk, If_Par_t * pPars )              pPars->pTimesArr[c] = -ABC_INFINITY;      } -    // perform FPGA mapping +    // create FPGA mapper      pIfMan = Abc_NtkToIf( pNtk, pPars );          if ( pIfMan == NULL )          return NULL;      if ( pPars->fPower )          Abc_NtkIfComputeSwitching( pNtk, pIfMan ); + +    // perform FPGA mapping +//    Abc_NtkCollectPoDrivers( pIfMan, pNtk );      if ( !If_ManPerformMapping( pIfMan ) )      { +        Abc_NtkFreePoDrivers( pIfMan );          If_ManStop( pIfMan );          return NULL;      } +    Abc_NtkFreePoDrivers( pIfMan );      // transform the result of mapping into the new network      pNtkNew = Abc_NtkFromIf( pIfMan, pNtk ); @@ -691,6 +699,87 @@ Vec_Ptr_t * Abc_NtkFindGoodOrder( Abc_Ntk_t * pNtk )  } +/**Function************************************************************* + +  Synopsis    [Sets PO drivers.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Abc_NtkCollectPoDrivers( If_Man_t * p, Abc_Ntk_t * pNtk ) +{ +    // 1 a     2 b     3 c     4 a+b+c     5 ab+ac+bc +    Vec_Int_t * vTemp; +    Abc_Obj_t * pObj; +    If_Obj_t * pIfObj; +    int i, g, nGroups; +    if ( pNtk->nRealPos == 0 ) +    { +        printf( "PO drivers are not defined.\n" ); +        return; +    } +    if ( (Abc_NtkPoNum(pNtk) - pNtk->nRealPos) % 5 != 0 ) +    { +        printf( "PO drivers are not divisible by 5.\n" ); +        return; +    } +    nGroups = (Abc_NtkPoNum(pNtk) - pNtk->nRealPos) / 5; +    printf( "Processing %d groups of PO drivers.\n", nGroups ); +    // mark the drivers +    assert( p->pDriverCuts == NULL ); +    p->pDriverCuts = ABC_CALLOC( Vec_Int_t *, If_ManObjNum(p) ); +    for ( g = 0; g < nGroups; g++ ) +    { +        // collect inputs +        vTemp = Vec_IntAlloc( 3 ); +        for ( i = 0; i < 3; i++ ) +        { +            pObj   = Abc_NtkPo( pNtk, pNtk->nRealPos + g * 5 + i ); +            pIfObj = If_Regular( ((If_Obj_t *)pObj->pCopy)->pFanin0 ); +            Vec_IntPush( vTemp, pIfObj->Id ); +        } +        Vec_IntSort( vTemp, 0 ); +        // find output node +        pObj   = Abc_NtkPo( pNtk, pNtk->nRealPos + g * 5 + 3 ); +        pIfObj = If_Regular( ((If_Obj_t *)pObj->pCopy)->pFanin0 ); +        if ( !If_ObjIsConst1(pIfObj) && p->pDriverCuts[pIfObj->Id] == NULL ) +            p->pDriverCuts[pIfObj->Id] = Vec_IntDup( vTemp ); +        // find output node +        pObj   = Abc_NtkPo( pNtk, pNtk->nRealPos + g * 5 + 4 ); +        pIfObj = If_Regular( ((If_Obj_t *)pObj->pCopy)->pFanin0 ); +        if ( !If_ObjIsConst1(pIfObj) && p->pDriverCuts[pIfObj->Id] == NULL ) +        { +            p->pDriverCuts[pIfObj->Id] = Vec_IntDup( vTemp ); +            pIfObj->fDriver = 1; +        } +        Vec_IntFree( vTemp ); +    } +} + +/**Function************************************************************* + +  Synopsis    [Frees PO drivers.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Abc_NtkFreePoDrivers( If_Man_t * p ) +{ +    int i; +    if ( p->pDriverCuts == NULL ) +        return; +    for ( i = 0; i < If_ManObjNum(p); i++ ) +        Vec_IntFreeP( &p->pDriverCuts[i] ); +    ABC_FREE( p->pDriverCuts ); +}  ////////////////////////////////////////////////////////////////////////  ///                       END OF FILE                                /// diff --git a/src/base/abci/abcPrint.c b/src/base/abci/abcPrint.c index bdcd926e..352ddf52 100644 --- a/src/base/abci/abcPrint.c +++ b/src/base/abci/abcPrint.c @@ -212,6 +212,8 @@ void Abc_NtkPrintStats( Abc_Ntk_t * pNtk, int fFactored, int fSaveBest, int fDum      fprintf( pFile, " i/o =%5d/%5d", Abc_NtkPiNum(pNtk), Abc_NtkPoNum(pNtk) );      if ( Abc_NtkConstrNum(pNtk) )          fprintf( pFile, "(c=%d)", Abc_NtkConstrNum(pNtk) ); +    if ( pNtk->nRealPos ) +        fprintf( pFile, "(p=%d)", Abc_NtkPoNum(pNtk) - pNtk->nRealPos );      fprintf( pFile, "  lat =%5d", Abc_NtkLatchNum(pNtk) );      if ( Abc_NtkIsNetlist(pNtk) )      { diff --git a/src/base/io/ioReadBlifMv.c b/src/base/io/ioReadBlifMv.c index 1c28ac3d..e41b78b8 100644 --- a/src/base/io/ioReadBlifMv.c +++ b/src/base/io/ioReadBlifMv.c @@ -952,6 +952,7 @@ static int Io_MvParseLineOutputs( Io_MvMod_t * p, char * pLine )      Vec_Ptr_t * vTokens = p->pMan->vTokens;      char * pToken;      int i; +    p->pNtk->nRealPos = Abc_NtkPoNum(p->pNtk);      Io_MvSplitIntoTokens( vTokens, pLine, '\0' );      pToken = (char *)Vec_PtrEntry(vTokens, 0);      assert( !strcmp(pToken, "outputs") ); diff --git a/src/map/if/if.h b/src/map/if/if.h index 61944eaa..86d504bc 100644 --- a/src/map/if/if.h +++ b/src/map/if/if.h @@ -161,6 +161,7 @@ struct If_Man_t_      int                fNextRound;    // set to 1 after the first round      int                nChoices;      // the number of choice nodes      Vec_Int_t *        vSwitching;    // switching activity of each node +    Vec_Int_t **       pDriverCuts;   // temporary driver cuts      // sequential mapping      Vec_Ptr_t *        vLatchOrder;   // topological ordering of latches      Vec_Int_t *        vLags;         // sequentail lags of all nodes @@ -228,7 +229,8 @@ struct If_Obj_t_      unsigned           fMark   :  1;  // multipurpose mark      unsigned           fVisit  :  1;  // multipurpose mark      unsigned           fSpec   :  1;  // multipurpose mark -    unsigned           Level   : 21;  // logic level of the node +    unsigned           fDriver :  1;  // multipurpose mark +    unsigned           Level   : 20;  // logic level of the node      int                Id;            // integer ID      int                IdPio;         // integer ID of PIs/POs      int                nRefs;         // the number of references diff --git a/src/map/if/ifCut.c b/src/map/if/ifCut.c index f51807ee..59d4e8e3 100644 --- a/src/map/if/ifCut.c +++ b/src/map/if/ifCut.c @@ -881,7 +881,7 @@ float If_CutAreaFlow( If_Man_t * p, If_Cut_t * pCut )      Flow = If_CutLutArea(p, pCut);      If_CutForEachLeaf( p, pCut, pLeaf, i )      { -        if ( pLeaf->nRefs == 0 ) +        if ( pLeaf->nRefs == 0 || If_ObjIsConst1(pLeaf) )              Flow += If_ObjCutBest(pLeaf)->Area;          else if ( p->pPars->fSeqMap ) // seq              Flow += If_ObjCutBest(pLeaf)->Area / pLeaf->nRefs; @@ -914,7 +914,7 @@ float If_CutEdgeFlow( If_Man_t * p, If_Cut_t * pCut )      Flow = pCut->nLeaves;      If_CutForEachLeaf( p, pCut, pLeaf, i )      { -        if ( pLeaf->nRefs == 0 ) +        if ( pLeaf->nRefs == 0 || If_ObjIsConst1(pLeaf) )              Flow += If_ObjCutBest(pLeaf)->Edge;          else if ( p->pPars->fSeqMap ) // seq              Flow += If_ObjCutBest(pLeaf)->Edge / pLeaf->nRefs; @@ -948,7 +948,7 @@ float If_CutPowerFlow( If_Man_t * p, If_Cut_t * pCut, If_Obj_t * pRoot )      If_CutForEachLeaf( p, pCut, pLeaf, i )      {          Power += pSwitching[pLeaf->Id]; -        if ( pLeaf->nRefs == 0 ) +        if ( pLeaf->nRefs == 0 || If_ObjIsConst1(pLeaf) )              Power += If_ObjCutBest(pLeaf)->Power;          else if ( p->pPars->fSeqMap ) // seq              Power += If_ObjCutBest(pLeaf)->Power / pLeaf->nRefs; diff --git a/src/map/if/ifMap.c b/src/map/if/ifMap.c index b7b7c568..f2dbe3f7 100644 --- a/src/map/if/ifMap.c +++ b/src/map/if/ifMap.c @@ -53,6 +53,32 @@ static inline int If_WordCountOnes( unsigned uWord )  /**Function************************************************************* +  Synopsis    [Counts the number of 1s in the signature.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +float If_CutDelaySpecial( If_Man_t * p, If_Cut_t * pCut, int fCarry ) +{ +    static float Pin2Pin[2][3] = { {1.0, 1.0, 1.0}, {1.0, 1.0, 0.0} }; +    If_Obj_t * pLeaf; +    float DelayCur, Delay = -IF_FLOAT_LARGE; +    int i; +    assert( pCut->nLeaves <= 3 ); +    If_CutForEachLeaf( p, pCut, pLeaf, i ) +    { +        DelayCur = If_ObjCutBest(pLeaf)->Delay; +        Delay = IF_MAX( Delay, Pin2Pin[fCarry][i] + DelayCur ); +    } +    return Delay; + } + +/**Function************************************************************* +    Synopsis    [Finds the best cut for the given node.]    Description [Mapping modes: delay (0), area flow (1), area (2).] @@ -79,6 +105,40 @@ void If_ObjPerformMappingAnd( If_Man_t * p, If_Obj_t * pObj, int Mode, int fPrep          else if ( Mode == 1 )              pObj->EstRefs = (float)((2.0 * pObj->EstRefs + pObj->nRefs) / 3.0);      } + +    // process special cut +    if ( p->pDriverCuts && p->pDriverCuts[pObj->Id] ) +    { +        pCut = If_ObjCutBest(pObj); +        if ( pCut->nLeaves == 0 ) +        { +            pCut->nLeaves = Vec_IntSize( p->pDriverCuts[pObj->Id] ); +            Vec_IntForEachEntry( p->pDriverCuts[pObj->Id], k, i ) +                pCut->pLeaves[i] = k; +            assert( pCut->pLeaves[0] <= pCut->pLeaves[1] ); +//            if ( pObj->nRefs > 0 ) +//                If_CutAreaRef( p, pCut ); +        } +        pCut->Delay = If_CutDelaySpecial( p, pCut, pObj->fDriver ); +        pCut->Area  = (Mode == 2)? 1 : If_CutAreaFlow( p, pCut ); +        if ( p->pPars->fEdge ) +            pCut->Edge = (Mode == 2)? 3 : If_CutEdgeFlow( p, pCut ); +        if ( p->pPars->fPower ) +            pCut->Power  = (Mode == 2)? 0 : If_CutPowerFlow( p, pCut, pObj ); + +        // prepare the cutset +        pCutSet = If_ManSetupNodeCutSet( p, pObj ); +        // copy best cut +        If_CutCopy( p, pCutSet->ppCuts[pCutSet->nCuts++], If_ObjCutBest(pObj) ); +        // add the trivial cut to the set +        If_ManSetupCutTriv( p, pCutSet->ppCuts[pCutSet->nCuts++], pObj->Id ); +        // free the cuts +        If_ManDerefNodeCutSet( p, pObj ); +        assert( pCutSet->nCuts == 2 ); +        return; +    } + +    // deref the selected cut      if ( Mode && pObj->nRefs > 0 )          If_CutAreaDeref( p, If_ObjCutBest(pObj) ); diff --git a/src/map/if/ifUtil.c b/src/map/if/ifUtil.c index da3a4aa5..f752baef 100644 --- a/src/map/if/ifUtil.c +++ b/src/map/if/ifUtil.c @@ -769,6 +769,7 @@ int If_ManCountSpecialPos( If_Man_t * p )      return Counter;  } +  ////////////////////////////////////////////////////////////////////////  ///                       END OF FILE                                ///  //////////////////////////////////////////////////////////////////////// | 
