blob: 1b8f318072c91db33926cdc8a925f0e513fe6ce7 [file] [log] [blame]
/**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