mirror of https://github.com/YosysHQ/abc.git
308 lines
9.5 KiB
C
308 lines
9.5 KiB
C
/**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 );
|
|
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
|
|
|