mpmGates.c 9.49 KB
Newer Older
Alan Mishchenko committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
/**CFile****************************************************************

  FileName    [mpmGates.c]

  SystemName  [ABC: Logic synthesis and verification system.]

  PackageName [Configurable technology mapper.]

  Synopsis    [Standard-cell mapping.]

  Author      [Alan Mishchenko]
  
  Affiliation [UC Berkeley]

  Date        [Ver. 1.0. Started - June 1, 2013.]

  Revision    [$Id: mpmGates.c,v 1.00 2013/06/01 00:00:00 alanmi Exp $]

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

#include "mpmInt.h"
#include "misc/st/st.h"
#include "map/mio/mio.h"
24 25
#include "map/scl/sclSize.h"
#include "map/scl/sclTime.h"
Alan Mishchenko committed
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48

ABC_NAMESPACE_IMPL_START


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

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

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

  Synopsis    [Finds matches fore each DSD class.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
49
Vec_Wec_t * Mpm_ManFindDsdMatches( Mpm_Man_t * p, void * pScl )
Alan Mishchenko committed
50 51 52
{
    int fVerbose = p->pPars->fVeryVerbose;
    SC_Lib * pLib = (SC_Lib *)pScl;
Alan Mishchenko committed
53 54
    Vec_Wec_t * vClasses;
    Vec_Int_t * vClass;
Alan Mishchenko committed
55 56 57
    SC_Cell * pRepr;
    int i, Config, iClass;
    word Truth;
Alan Mishchenko committed
58
    vClasses = Vec_WecStart( 600 );
Alan Mishchenko committed
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
    SC_LibForEachCellClass( pLib, pRepr, i )
    {
        if ( pRepr->n_inputs > 6 || pRepr->n_outputs > 1 )
        {
            if ( fVerbose )
            printf( "Skipping cell %s with %d inputs and %d outputs\n", pRepr->pName, pRepr->n_inputs, pRepr->n_outputs );
            continue;
        }
        Truth = *Vec_WrdArray( SC_CellPin(pRepr, pRepr->n_inputs)->vFunc );
        Config = Mpm_CutCheckDsd6( p, Truth );
        if ( Config == -1 )
        {
            if ( fVerbose )
            printf( "Skipping cell %s with non-DSD function\n", pRepr->pName );
            continue;
        }
        iClass = Config >> 17;
        Config = (pRepr->Id << 17) | (Config & 0x1FFFF);
        // write gate and NPN config for this DSD class
Alan Mishchenko committed
78 79
        vClass = Vec_WecEntry( vClasses, iClass );
        Vec_IntPush( vClass, Config );
Alan Mishchenko committed
80 81 82 83 84 85
        if ( !fVerbose )
            continue;

        printf( "Gate %5d  %-30s : ", pRepr->Id, pRepr->pName );
        printf( "Class %3d  ", iClass );
        printf( "Area %10.3f  ", pRepr->area );
Alan Mishchenko committed
86
        Extra_PrintBinary( stdout, (unsigned *)&Config, 17 );
Alan Mishchenko committed
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
        printf( "   " );
        Kit_DsdPrintFromTruth( (unsigned *)&Truth, pRepr->n_inputs ); printf( "\n" );
    }
    return vClasses;
}

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

  Synopsis    [Find mapping of DSD classes into Genlib library cells.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
104
Vec_Ptr_t * Mpm_ManFindCells( Mio_Library_t * pMio, SC_Lib * pScl, Vec_Wec_t * vNpnConfigs )
Alan Mishchenko committed
105 106
{
    Vec_Ptr_t * vNpnGatesMio;
Alan Mishchenko committed
107
    Vec_Int_t * vClass;
Alan Mishchenko committed
108 109
    Mio_Gate_t * pMioGate;
    SC_Cell * pCell;
Alan Mishchenko committed
110
    int Config, iClass;
Alan Mishchenko committed
111 112
    vNpnGatesMio = Vec_PtrStart( Vec_WecSize(vNpnConfigs) );
    Vec_WecForEachLevel( vNpnConfigs, vClass, iClass )
Alan Mishchenko committed
113
    {
Alan Mishchenko committed
114
        if ( Vec_IntSize(vClass) == 0 )
Alan Mishchenko committed
115
            continue;
Alan Mishchenko committed
116
        Config = Vec_IntEntry(vClass, 0);
Alan Mishchenko committed
117
        pCell = SC_LibCell( pScl, (Config >> 17) );
Alan Mishchenko committed
118
        pMioGate = Mio_LibraryReadGateByName( pMio, pCell->pName, NULL );
Alan Mishchenko committed
119 120 121 122 123
        if ( pMioGate == NULL )
        {
            Vec_PtrFree( vNpnGatesMio );
            return NULL;
        }
Alan Mishchenko committed
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
        assert( pMioGate != NULL );
        Vec_PtrWriteEntry( vNpnGatesMio, iClass, pMioGate );
    }
    return vNpnGatesMio;
}

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

  Synopsis    [Derive mapped network as an ABC network.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Vec_Int_t * Mpm_ManFindMappedNodes( Mpm_Man_t * p )
{
    Vec_Int_t * vNodes;
    Mig_Obj_t * pObj;
    vNodes = Vec_IntAlloc( 1000 );
    Mig_ManForEachObj( p->pMig, pObj )
        if ( Mig_ObjIsNode(pObj) && Mpm_ObjMapRef(p, pObj) )
            Vec_IntPush( vNodes, Mig_ObjId(pObj) );
    return vNodes;
}
Abc_Obj_t * Mpm_ManGetAbcNode( Abc_Ntk_t * pNtk, Vec_Int_t * vCopy, int iMigLit )
{
    Abc_Obj_t * pObj;
    int iObjId = Vec_IntEntry( vCopy, iMigLit );
    if ( iObjId >= 0 )
        return Abc_NtkObj( pNtk, iObjId );
    iObjId = Vec_IntEntry( vCopy, Abc_LitNot(iMigLit) );
    assert( iObjId >= 0 );
    pObj = Abc_NtkCreateNodeInv( pNtk, Abc_NtkObj(pNtk, iObjId) );
    Vec_IntWriteEntry( vCopy, iMigLit, Abc_ObjId(pObj) );
    return pObj;
}
Abc_Ntk_t * Mpm_ManDeriveMappedAbcNtk( Mpm_Man_t * p, Mio_Library_t * pMio )
{
    Abc_Ntk_t * pNtk;
    Vec_Ptr_t * vNpnGatesMio;
Alan Mishchenko committed
167
    Vec_Int_t * vNodes, * vCopy, * vClass;
Alan Mishchenko committed
168 169 170
    Abc_Obj_t * pObj, * pFanin;
    Mig_Obj_t * pNode;
    Mpm_Cut_t * pCutBest;
Alan Mishchenko committed
171
    int i, k, iNode, iMigLit, fCompl, Config;
Alan Mishchenko committed
172 173

    // find mapping of SCL cells into MIO cells
Alan Mishchenko committed
174 175 176 177 178 179
    vNpnGatesMio = Mpm_ManFindCells( pMio, (SC_Lib *)p->pPars->pScl, p->vNpnConfigs );
    if ( vNpnGatesMio == NULL )
    {
        printf( "Genlib library does not match SCL library.\n" );
        return NULL;
    }
Alan Mishchenko committed
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200

    // create mapping for each phase of each node
    vCopy = Vec_IntStartFull( 2 * Mig_ManObjNum(p->pMig) );

    // get internal nodes
    vNodes = Mpm_ManFindMappedNodes( p );

    // start the network
    pNtk = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_MAP, 1 );
    pNtk->pName = Extra_UtilStrsav( p->pMig->pName );
    pNtk->pManFunc = pMio;

    // create primary inputs
    Mig_ManForEachCi( p->pMig, pNode, i )
    {
        pObj = Abc_NtkCreatePi(pNtk);
        Vec_IntWriteEntry( vCopy, Abc_Var2Lit( Mig_ObjId(pNode), 0 ), Abc_ObjId(pObj) );
    }
    Abc_NtkAddDummyPiNames( pNtk );

    // create constant nodes
Alan Mishchenko committed
201 202 203 204 205 206 207 208 209 210 211 212 213 214
    Mig_ManForEachCo( p->pMig, pNode, i )
        if ( Mig_ObjFaninLit(pNode, 0) == 0 )
        {
            pObj = Abc_NtkCreateNodeConst0(pNtk);
            Vec_IntWriteEntry( vCopy, Abc_Var2Lit( 0, 0 ), Abc_ObjId(pObj) );
            break;
        }
    Mig_ManForEachCo( p->pMig, pNode, i )
        if ( Mig_ObjFaninLit(pNode, 0) == 1 )
        {
            pObj = Abc_NtkCreateNodeConst1(pNtk);
            Vec_IntWriteEntry( vCopy, Abc_Var2Lit( 0, 1 ), Abc_ObjId(pObj) );
            break;
        }
Alan Mishchenko committed
215 216 217 218

    // create internal nodes
    Vec_IntForEachEntry( vNodes, iNode, i )
    {
Alan Mishchenko committed
219
        pCutBest = Mpm_ObjCutBestP( p, Mig_ManObj(p->pMig, iNode) );
Alan Mishchenko committed
220 221
        vClass = Vec_WecEntry( p->vNpnConfigs, Abc_Lit2Var(pCutBest->iFunc) );
        Config = Vec_IntEntry( vClass, 0 );
Alan Mishchenko committed
222 223
        pObj = Abc_NtkCreateNode( pNtk );
        pObj->pData = Vec_PtrEntry( vNpnGatesMio, Abc_Lit2Var(pCutBest->iFunc) );
Alan Mishchenko committed
224
        assert( pObj->pData != NULL );
225
        fCompl = pCutBest->fCompl ^ Abc_LitIsCompl(pCutBest->iFunc) ^ ((Config >> 16) & 1);
Alan Mishchenko committed
226 227
        Config &= 0xFFFF;
        for ( k = 0; k < (int)pCutBest->nLeaves; k++ )
Alan Mishchenko committed
228
        {
Alan Mishchenko committed
229 230 231
            assert( (Config >> 6) < 720 );
            iMigLit = pCutBest->pLeaves[ (int)(p->Perm6[Config >> 6][k]) ];
            pFanin = Mpm_ManGetAbcNode( pNtk, vCopy, Abc_LitNotCond(iMigLit, (Config >> k) & 1) );
Alan Mishchenko committed
232 233
            Abc_ObjAddFanin( pObj, pFanin );
        }
Alan Mishchenko committed
234
        Vec_IntWriteEntry( vCopy, Abc_Var2Lit(iNode, fCompl), Abc_ObjId(pObj) );
Alan Mishchenko committed
235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271
    }

    // create primary outputs
    Mig_ManForEachCo( p->pMig, pNode, i )
    {
        pObj = Abc_NtkCreatePo(pNtk);
        pFanin = Mpm_ManGetAbcNode( pNtk, vCopy, Mig_ObjFaninLit(pNode, 0) );
        Abc_ObjAddFanin( pObj, pFanin );
    }
    Abc_NtkAddDummyPoNames( pNtk );

    // clean up
    Vec_PtrFree( vNpnGatesMio );
    Vec_IntFree( vNodes );
    Vec_IntFree( vCopy );
    return pNtk;
}

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

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Abc_Ntk_t * Mpm_ManPerformCellMapping( Mig_Man_t * pMig, Mpm_Par_t * pPars, Mio_Library_t * pMio )
{
    Abc_Ntk_t * pNew;
    Mpm_Man_t * p;
    assert( pPars->fMap4Gates );
    p = Mpm_ManStart( pMig, pPars );
    if ( p->pPars->fVerbose ) 
        Mpm_ManPrintStatsInit( p );
Alan Mishchenko committed
272
    p->vNpnConfigs = Mpm_ManFindDsdMatches( p, p->pPars->pScl );
Alan Mishchenko committed
273 274 275 276 277 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
    Mpm_ManPrepare( p );
    Mpm_ManPerform( p );
    if ( p->pPars->fVerbose ) 
        Mpm_ManPrintStats( p );
    pNew = Mpm_ManDeriveMappedAbcNtk( p, pMio );
    Mpm_ManStop( p );
    return pNew;
}
Abc_Ntk_t * Mpm_ManCellMapping( Gia_Man_t * pGia, Mpm_Par_t * pPars, void * pMio )
{
    Mig_Man_t * p;
    Abc_Ntk_t * pNew;
    assert( pMio != NULL );
    assert( pPars->pLib->LutMax <= MPM_VAR_MAX );
    assert( pPars->nNumCuts <= MPM_CUT_MAX );
    if ( pPars->fUseGates )
    {
        pGia = Gia_ManDupMuxes( pGia );
        p = Mig_ManCreate( pGia );
        Gia_ManStop( pGia );
    }
    else
        p = Mig_ManCreate( pGia );
    pNew = Mpm_ManPerformCellMapping( p, pPars, (Mio_Library_t *)pMio );
    Mig_ManStop( p );
    return pNew;
}

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


ABC_NAMESPACE_IMPL_END