/**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" #include "map/scl/sclSize.h" #include "map/scl/sclTime.h" ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Finds matches fore each DSD class.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Vec_Wec_t * Mpm_ManFindDsdMatches( Mpm_Man_t * p, void * pScl ) { int fVerbose = p->pPars->fVeryVerbose; SC_Lib * pLib = (SC_Lib *)pScl; Vec_Wec_t * vClasses; Vec_Int_t * vClass; SC_Cell * pRepr; int i, Config, iClass; word Truth; vClasses = Vec_WecStart( 600 ); 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 vClass = Vec_WecEntry( vClasses, iClass ); Vec_IntPush( vClass, Config ); if ( !fVerbose ) continue; printf( "Gate %5d %-30s : ", pRepr->Id, pRepr->pName ); printf( "Class %3d ", iClass ); printf( "Area %10.3f ", pRepr->area ); Extra_PrintBinary( stdout, (unsigned *)&Config, 17 ); 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 [] ***********************************************************************/ Vec_Ptr_t * Mpm_ManFindCells( Mio_Library_t * pMio, SC_Lib * pScl, Vec_Wec_t * vNpnConfigs ) { Vec_Ptr_t * vNpnGatesMio; Vec_Int_t * vClass; Mio_Gate_t * pMioGate; SC_Cell * pCell; int Config, iClass; vNpnGatesMio = Vec_PtrStart( Vec_WecSize(vNpnConfigs) ); Vec_WecForEachLevel( vNpnConfigs, vClass, iClass ) { if ( Vec_IntSize(vClass) == 0 ) continue; Config = Vec_IntEntry(vClass, 0); pCell = SC_LibCell( pScl, (Config >> 17) ); pMioGate = Mio_LibraryReadGateByName( pMio, pCell->pName, NULL ); if ( pMioGate == NULL ) { Vec_PtrFree( vNpnGatesMio ); return NULL; } 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; Vec_Int_t * vNodes, * vCopy, * vClass; Abc_Obj_t * pObj, * pFanin; Mig_Obj_t * pNode; Mpm_Cut_t * pCutBest; int i, k, iNode, iMigLit, fCompl, Config; // find mapping of SCL cells into MIO cells 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; } // 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 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; } // create internal nodes Vec_IntForEachEntry( vNodes, iNode, i ) { pCutBest = Mpm_ObjCutBestP( p, Mig_ManObj(p->pMig, iNode) ); vClass = Vec_WecEntry( p->vNpnConfigs, Abc_Lit2Var(pCutBest->iFunc) ); Config = Vec_IntEntry( vClass, 0 ); pObj = Abc_NtkCreateNode( pNtk ); pObj->pData = Vec_PtrEntry( vNpnGatesMio, Abc_Lit2Var(pCutBest->iFunc) ); assert( pObj->pData != NULL ); fCompl = pCutBest->fCompl ^ Abc_LitIsCompl(pCutBest->iFunc) ^ ((Config >> 16) & 1); Config &= 0xFFFF; for ( k = 0; k < (int)pCutBest->nLeaves; k++ ) { assert( (Config >> 6) < 720 ); iMigLit = pCutBest->pLeaves[ (int)(p->Perm6[Config >> 6][k]) ]; pFanin = Mpm_ManGetAbcNode( pNtk, vCopy, Abc_LitNotCond(iMigLit, (Config >> k) & 1) ); Abc_ObjAddFanin( pObj, pFanin ); } Vec_IntWriteEntry( vCopy, Abc_Var2Lit(iNode, fCompl), Abc_ObjId(pObj) ); } // 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 ); p->vNpnConfigs = Mpm_ManFindDsdMatches( p, p->pPars->pScl ); 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, 2 ); 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