diff options
Diffstat (limited to 'src/temp/player/playerToAbc.c')
-rw-r--r-- | src/temp/player/playerToAbc.c | 523 |
1 files changed, 523 insertions, 0 deletions
diff --git a/src/temp/player/playerToAbc.c b/src/temp/player/playerToAbc.c new file mode 100644 index 00000000..81032826 --- /dev/null +++ b/src/temp/player/playerToAbc.c @@ -0,0 +1,523 @@ +/**CFile**************************************************************** + + FileName [playerToAbc.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [PLAyer decomposition package.] + + Synopsis [Bridge between ABC and PLAyer.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - May 20, 2006.] + + Revision [$Id: playerToAbc.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "player.h" +#include "abc.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static Ivy_Man_t * Ivy_ManFromAbc( Abc_Ntk_t * p ); +static Abc_Ntk_t * Ivy_ManToAbc( Abc_Ntk_t * pNtk, Ivy_Man_t * pMan, Pla_Man_t * p, int fFastMode ); +static Abc_Obj_t * Ivy_ManToAbc_rec( Abc_Ntk_t * pNtkNew, Ivy_Man_t * pMan, Pla_Man_t * p, Ivy_Obj_t * pObjIvy, Vec_Int_t * vNodes, Vec_Int_t * vTemp ); +static Abc_Obj_t * Ivy_ManToAbcFast_rec( Abc_Ntk_t * pNtkNew, Ivy_Man_t * pMan, Ivy_Obj_t * pObjIvy, Vec_Int_t * vNodes, Vec_Int_t * vTemp ); +static Abc_Obj_t * Ivy_ManToAigCube( Abc_Ntk_t * pNtkNew, Ivy_Man_t * pMan, Ivy_Obj_t * pObjIvy, Esop_Cube_t * pCube, Vec_Int_t * vSupp ); +static int Abc_NtkPlayerCost( Abc_Ntk_t * pNtk, int RankCost, int fVerbose ); + +static inline void Abc_ObjSetIvy2Abc( Ivy_Man_t * p, int IvyId, Abc_Obj_t * pObjAbc ) { assert(Vec_PtrEntry(p->pCopy, IvyId) == NULL); assert(!Abc_ObjIsComplement(pObjAbc)); Vec_PtrWriteEntry( p->pCopy, IvyId, pObjAbc ); } +static inline Abc_Obj_t * Abc_ObjGetIvy2Abc( Ivy_Man_t * p, int IvyId ) { return Vec_PtrEntry( p->pCopy, IvyId ); } + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Applies PLA/LUT mapping to the ABC network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void * Abc_NtkPlayer( void * pNtk, int nLutMax, int nPlaMax, int RankCost, int fFastMode, int fRewriting, int fSynthesis, int fVerbose ) +{ + Pla_Man_t * p; + Ivy_Man_t * pMan, * pManExt; + Abc_Ntk_t * pNtkNew; + if ( !Abc_NtkIsStrash(pNtk) ) + return NULL; + // convert to the new AIG manager + pMan = Ivy_ManFromAbc( pNtk ); + // check the correctness of conversion + if ( !Ivy_ManCheck( pMan ) ) + { + printf( "Abc_NtkPlayer: Internal AIG check has failed.\n" ); + Ivy_ManStop( pMan ); + return NULL; + } + if ( fVerbose ) + Ivy_ManPrintStats( pMan ); + if ( fRewriting ) + { + // simplify + pMan = Ivy_ManResyn0( pManExt = pMan, 1, 0 ); + Ivy_ManStop( pManExt ); + if ( fVerbose ) + Ivy_ManPrintStats( pMan ); + } + if ( fSynthesis ) + { + // simplify + pMan = Ivy_ManResyn( pManExt = pMan, 1, 0 ); + Ivy_ManStop( pManExt ); + if ( fVerbose ) + Ivy_ManPrintStats( pMan ); + } + // perform decomposition + if ( fFastMode ) + { + // perform mapping into LUTs + Ivy_FastMapPerform( pMan, nLutMax, 1, fVerbose ); + // convert from the extended AIG manager into an SOP network + pNtkNew = Ivy_ManToAbc( pNtk, pMan, NULL, fFastMode ); +// pNtkNew = NULL; + Ivy_FastMapStop( pMan ); + } + else + { + assert( nLutMax >= 2 && nLutMax <= 8 ); + // perform decomposition/mapping into PLAs/LUTs + p = Pla_ManDecompose( pMan, nLutMax, nPlaMax, fVerbose ); + // convert from the extended AIG manager into an SOP network + pNtkNew = Ivy_ManToAbc( pNtk, pMan, p, fFastMode ); + Pla_ManFree( p ); + } + Ivy_ManStop( pMan ); + // chech the resulting network + if ( pNtkNew && !Abc_NtkCheck( pNtkNew ) ) + { + printf( "Abc_NtkPlayer: The network check has failed.\n" ); + Abc_NtkDelete( pNtkNew ); + return NULL; + } +// Abc_NtkPlayerCost( pNtkNew, RankCost, fVerbose ); + return pNtkNew; +} + +/**Function************************************************************* + + Synopsis [Converts from strashed AIG in ABC into strash AIG in IVY.] + + Description [Assumes DFS ordering of nodes in the AIG of ABC.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Ivy_Man_t * Ivy_ManFromAbc( Abc_Ntk_t * pNtk ) +{ + Ivy_Man_t * pMan; + Abc_Obj_t * pObj; + int i; + // create the manager + pMan = Ivy_ManStart(); + // create the PIs + Abc_AigConst1(pNtk)->pCopy = (Abc_Obj_t *)Ivy_ManConst1(pMan); + Abc_NtkForEachCi( pNtk, pObj, i ) + pObj->pCopy = (Abc_Obj_t *)Ivy_ObjCreatePi(pMan); + // perform the conversion of the internal nodes + Abc_AigForEachAnd( pNtk, pObj, i ) + pObj->pCopy = (Abc_Obj_t *)Ivy_And( pMan, (Ivy_Obj_t *)Abc_ObjChild0Copy(pObj), (Ivy_Obj_t *)Abc_ObjChild1Copy(pObj) ); + // create the POs + Abc_NtkForEachCo( pNtk, pObj, i ) + Ivy_ObjCreatePo( pMan, (Ivy_Obj_t *)Abc_ObjChild0Copy(pObj) ); + Ivy_ManCleanup( pMan ); + return pMan; +} + +/**Function************************************************************* + + Synopsis [Constructs the ABC network after mapping.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Ivy_ManToAbc( Abc_Ntk_t * pNtk, Ivy_Man_t * pMan, Pla_Man_t * p, int fFastMode ) +{ + Abc_Ntk_t * pNtkNew; + Abc_Obj_t * pObjAbc, * pObj; + Ivy_Obj_t * pObjIvy; + Vec_Int_t * vNodes, * vTemp; + int i; + // start mapping from Ivy into Abc + pMan->pCopy = Vec_PtrStart( Ivy_ManObjIdMax(pMan) + 1 ); + // start the new ABC network + pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP ); + // transfer the pointers to the basic nodes + Abc_ObjSetIvy2Abc( pMan, Ivy_ManConst1(pMan)->Id, Abc_NtkCreateNodeConst1(pNtkNew) ); + Abc_NtkForEachCi( pNtkNew, pObjAbc, i ) + Abc_ObjSetIvy2Abc( pMan, Ivy_ManPi(pMan, i)->Id, pObjAbc ); + // recursively construct the network + vNodes = Vec_IntAlloc( 100 ); + vTemp = Vec_IntAlloc( 100 ); + Ivy_ManForEachPo( pMan, pObjIvy, i ) + { + // get the new ABC node corresponding to the old fanin of the PO in IVY + if ( fFastMode ) + pObjAbc = Ivy_ManToAbcFast_rec( pNtkNew, pMan, Ivy_ObjFanin0(pObjIvy), vNodes, vTemp ); + else + pObjAbc = Ivy_ManToAbc_rec( pNtkNew, pMan, p, Ivy_ObjFanin0(pObjIvy), vNodes, vTemp ); + // consider the case of complemented fanin of the PO + if ( Ivy_ObjFaninC0(pObjIvy) ) // complement + { + if ( Abc_ObjIsCi(pObjAbc) ) + pObjAbc = Abc_NtkCreateNodeInv( pNtkNew, pObjAbc ); + else + { + // clone the node + pObj = Abc_NtkCloneObj( pObjAbc ); + // set complemented functions + pObj->pData = Abc_SopRegister( pNtkNew->pManFunc, pObjAbc->pData ); + Abc_SopComplement(pObj->pData); + // return the new node + pObjAbc = pObj; + } + assert( Abc_SopGetVarNum(pObjAbc->pData) == Abc_ObjFaninNum(pObjAbc) ); + } + Abc_ObjAddFanin( Abc_NtkCo(pNtkNew, i), pObjAbc ); + } + Vec_IntFree( vTemp ); + Vec_IntFree( vNodes ); + Vec_PtrFree( pMan->pCopy ); + pMan->pCopy = NULL; + // remove dangling nodes +// Abc_NtkForEachNode( pNtkNew, pObjAbc, i ) +// if ( Abc_ObjFanoutNum(pObjAbc) == 0 ) +// Abc_NtkDeleteObj(pObjAbc); + Abc_NtkCleanup( pNtkNew, 0 ); + // fix CIs feeding directly into COs + Abc_NtkLogicMakeSimpleCos( pNtkNew, 0 ); + return pNtkNew; +} + +/**Function************************************************************* + + Synopsis [Recursively construct the new node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Ivy_ManToAbc_rec( Abc_Ntk_t * pNtkNew, Ivy_Man_t * pMan, Pla_Man_t * p, Ivy_Obj_t * pObjIvy, Vec_Int_t * vNodes, Vec_Int_t * vTemp ) +{ + Vec_Int_t * vSupp; + Esop_Cube_t * pCover, * pCube; + Abc_Obj_t * pObjAbc, * pFaninAbc; + Pla_Obj_t * pStr; + int Entry, nCubes, i; + unsigned * puTruth; + // skip the node if it is a constant or already processed + pObjAbc = Abc_ObjGetIvy2Abc( pMan, pObjIvy->Id ); + if ( pObjAbc ) + return pObjAbc; + assert( Ivy_ObjIsAnd(pObjIvy) || Ivy_ObjIsExor(pObjIvy) ); + // get the support and the cover + pStr = Ivy_ObjPlaStr( pMan, pObjIvy ); + if ( Vec_IntSize( &pStr->vSupp[0] ) <= p->nLutMax ) + { + vSupp = &pStr->vSupp[0]; + pCover = PLA_EMPTY; + } + else + { + vSupp = &pStr->vSupp[1]; + pCover = pStr->pCover[1]; + assert( pCover != PLA_EMPTY ); + } + // create new node and its fanins + Vec_IntForEachEntry( vSupp, Entry, i ) + Ivy_ManToAbc_rec( pNtkNew, pMan, p, Ivy_ManObj(pMan, Entry), vNodes, vTemp ); + // consider the case of a LUT + if ( pCover == PLA_EMPTY ) + { + pObjAbc = Abc_NtkCreateNode( pNtkNew ); + Vec_IntForEachEntry( vSupp, Entry, i ) + Abc_ObjAddFanin( pObjAbc, Abc_ObjGetIvy2Abc(pMan, Entry) ); + // check if the truth table is constant 0 + puTruth = Ivy_ManCutTruth( pMan, pObjIvy, vSupp, vNodes, vTemp ); + // if the function is constant 0, create constant 0 node + if ( Extra_TruthIsConst0(puTruth, 8) ) + { + pObjAbc->pData = Abc_SopCreateAnd( pNtkNew->pManFunc, Vec_IntSize(vSupp), NULL ); + pObjAbc = Abc_NtkCreateNodeConst0( pNtkNew ); + } + else if ( Extra_TruthIsConst1(puTruth, 8) ) + { + pObjAbc->pData = Abc_SopCreateAnd( pNtkNew->pManFunc, Vec_IntSize(vSupp), NULL ); + pObjAbc = Abc_NtkCreateNodeConst1( pNtkNew ); + } + else + { + int fCompl = Ivy_TruthIsop( puTruth, Vec_IntSize(vSupp), vNodes, 1 ); + if ( vNodes->nSize == -1 ) + printf( "Ivy_ManToAbc_rec(): Internal error.\n" ); + pObjAbc->pData = Abc_SopCreateFromIsop( pNtkNew->pManFunc, Vec_IntSize(vSupp), vNodes ); + if ( fCompl ) Abc_SopComplement(pObjAbc->pData); +// printf( "Cover contains %d cubes.\n", Vec_IntSize(vNodes) ); +// pObjAbc->pData = Abc_SopCreateFromTruth( pNtkNew->pManFunc, Vec_IntSize(vSupp), puTruth ); + } + } + else + { + // for each cube, construct the node + nCubes = Esop_CoverCountCubes( pCover ); + if ( nCubes == 0 ) + pObjAbc = Abc_NtkCreateNodeConst0( pNtkNew ); + else if ( nCubes == 1 ) + pObjAbc = Ivy_ManToAigCube( pNtkNew, pMan, pObjIvy, pCover, vSupp ); + else + { + pObjAbc = Abc_NtkCreateNode( pNtkNew ); + Esop_CoverForEachCube( pCover, pCube ) + { + pFaninAbc = Ivy_ManToAigCube( pNtkNew, pMan, pObjIvy, pCube, vSupp ); + Abc_ObjAddFanin( pObjAbc, pFaninAbc ); + } + pObjAbc->pData = Abc_SopCreateXorSpecial( pNtkNew->pManFunc, Abc_ObjFaninNum(pObjAbc) ); + } + } + Abc_ObjSetIvy2Abc( pMan, pObjIvy->Id, pObjAbc ); + return pObjAbc; +} + +/**Function************************************************************* + + Synopsis [Derives the decomposed network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Ivy_ManToAigCube( Abc_Ntk_t * pNtkNew, Ivy_Man_t * pMan, Ivy_Obj_t * pObjIvy, Esop_Cube_t * pCube, Vec_Int_t * vSupp ) +{ + int pCompls[PLAYER_FANIN_LIMIT]; + Abc_Obj_t * pObjAbc, * pFaninAbc; + int i, k, Value; + // if tautology cube, create constant 1 node + if ( pCube->nLits == 0 ) + return Abc_NtkCreateNodeConst1(pNtkNew); + // create AND node + pObjAbc = Abc_NtkCreateNode( pNtkNew ); + for ( i = k = 0; i < (int)pCube->nVars; i++ ) + { + Value = Esop_CubeGetVar( pCube, i ); + assert( Value != 0 ); + if ( Value == 3 ) + continue; + pFaninAbc = Abc_ObjGetIvy2Abc( pMan, Vec_IntEntry(vSupp, i) ); + pFaninAbc = Abc_ObjNotCond( pFaninAbc, Value==1 ); + Abc_ObjAddFanin( pObjAbc, Abc_ObjRegular(pFaninAbc) ); + pCompls[k++] = Abc_ObjIsComplement(pFaninAbc); + } + pObjAbc->pData = Abc_SopCreateAnd( pNtkNew->pManFunc, Abc_ObjFaninNum(pObjAbc), pCompls ); + assert( Abc_ObjFaninNum(pObjAbc) == (int)pCube->nLits ); + return pObjAbc; +} + + + + +/**Function************************************************************* + + Synopsis [Recursively construct the new node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Ivy_ManToAbcFast_rec( Abc_Ntk_t * pNtkNew, Ivy_Man_t * pMan, Ivy_Obj_t * pObjIvy, Vec_Int_t * vNodes, Vec_Int_t * vTemp ) +{ + Vec_Int_t Supp, * vSupp = &Supp; + Abc_Obj_t * pObjAbc, * pFaninAbc; + int i, Entry; + unsigned * puTruth; + // skip the node if it is a constant or already processed + pObjAbc = Abc_ObjGetIvy2Abc( pMan, pObjIvy->Id ); + if ( pObjAbc ) + return pObjAbc; + assert( Ivy_ObjIsAnd(pObjIvy) || Ivy_ObjIsExor(pObjIvy) ); + // get the support of K-LUT + Ivy_FastMapReadSupp( pMan, pObjIvy, vSupp ); + // create new ABC node and its fanins + pObjAbc = Abc_NtkCreateNode( pNtkNew ); + Vec_IntForEachEntry( vSupp, Entry, i ) + { + pFaninAbc = Ivy_ManToAbcFast_rec( pNtkNew, pMan, Ivy_ManObj(pMan, Entry), vNodes, vTemp ); + Abc_ObjAddFanin( pObjAbc, pFaninAbc ); + } + // check if the truth table is constant 0 + puTruth = Ivy_ManCutTruth( pMan, pObjIvy, vSupp, vNodes, vTemp ); + // if the function is constant 0, create constant 0 node + if ( Extra_TruthIsConst0(puTruth, 8) ) + { + pObjAbc->pData = Abc_SopCreateAnd( pNtkNew->pManFunc, Vec_IntSize(vSupp), NULL ); + pObjAbc = Abc_NtkCreateNodeConst0( pNtkNew ); + } + else if ( Extra_TruthIsConst1(puTruth, 8) ) + { + pObjAbc->pData = Abc_SopCreateAnd( pNtkNew->pManFunc, Vec_IntSize(vSupp), NULL ); + pObjAbc = Abc_NtkCreateNodeConst1( pNtkNew ); + } + else + { + int fCompl = Ivy_TruthIsop( puTruth, Vec_IntSize(vSupp), vNodes, 1 ); + if ( vNodes->nSize == -1 ) + printf( "Ivy_ManToAbcFast_rec(): Internal error.\n" ); + pObjAbc->pData = Abc_SopCreateFromIsop( pNtkNew->pManFunc, Vec_IntSize(vSupp), vNodes ); + if ( fCompl ) Abc_SopComplement(pObjAbc->pData); + } + Abc_ObjSetIvy2Abc( pMan, pObjIvy->Id, pObjAbc ); + return pObjAbc; +} + + +/**Function************************************************************* + + Synopsis [Computes cost of the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Abc_NodePlayerCost( int nFanins ) +{ + if ( nFanins <= 4 ) + return 1; + if ( nFanins <= 6 ) + return 2; + if ( nFanins <= 8 ) + return 4; + if ( nFanins <= 16 ) + return 8; + if ( nFanins <= 32 ) + return 16; + if ( nFanins <= 64 ) + return 32; + if ( nFanins <= 128 ) + return 64; + assert( 0 ); + return 0; +} + +/**Function************************************************************* + + Synopsis [Computes the number of ranks needed for one level.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Abc_NtkPlayerCostOneLevel( int nCost, int RankCost ) +{ + return (nCost / RankCost) + ((nCost % RankCost) > 0); +} + +/**Function************************************************************* + + Synopsis [Computes the cost function for the network (number of ranks).] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NtkPlayerCost( Abc_Ntk_t * pNtk, int RankCost, int fVerbose ) +{ + Abc_Obj_t * pObj; + int * pLevelCosts, * pLevelCostsR; + int Cost, CostTotal, CostTotalR, nRanksTotal, nRanksTotalR; + int nFanins, nLevels, LevelR, i; + // compute the reverse levels + Abc_NtkStartReverseLevels( pNtk ); + // compute the costs for each level + nLevels = Abc_NtkGetLevelNum( pNtk ); + pLevelCosts = ALLOC( int, nLevels + 1 ); + pLevelCostsR = ALLOC( int, nLevels + 1 ); + memset( pLevelCosts, 0, sizeof(int) * (nLevels + 1) ); + memset( pLevelCostsR, 0, sizeof(int) * (nLevels + 1) ); + Abc_NtkForEachNode( pNtk, pObj, i ) + { + nFanins = Abc_ObjFaninNum(pObj); + if ( nFanins == 0 ) + continue; + Cost = Abc_NodePlayerCost( nFanins ); + LevelR = Vec_IntEntry( pNtk->vLevelsR, pObj->Id ); + pLevelCosts[ pObj->Level ] += Cost; + pLevelCostsR[ LevelR ] += Cost; + } + // compute the total cost + CostTotal = CostTotalR = nRanksTotal = nRanksTotalR = 0; + for ( i = 0; i <= nLevels; i++ ) + { + CostTotal += pLevelCosts[i]; + CostTotalR += pLevelCostsR[i]; + nRanksTotal += Abc_NtkPlayerCostOneLevel( pLevelCosts[i], RankCost ); + nRanksTotalR += Abc_NtkPlayerCostOneLevel( pLevelCostsR[i], RankCost ); + } + assert( CostTotal == CostTotalR ); + // print out statistics + if ( fVerbose ) + { + for ( i = 1; i <= nLevels; i++ ) + { + printf( "Level %2d : Cost = %7d. Ranks = %6.3f. Cost = %7d. Ranks = %6.3f.\n", i, + pLevelCosts[i], ((double)pLevelCosts[i])/RankCost, + pLevelCostsR[nLevels+1-i], ((double)pLevelCostsR[nLevels+1-i])/RankCost ); + } + printf( "TOTAL : Cost = %7d. Ranks = %6d. RanksR = %5d. RanksBest = %5d.\n", + CostTotal, nRanksTotal, nRanksTotalR, nLevels ); + } + free( pLevelCosts ); + free( pLevelCostsR ); + return nRanksTotal; +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + |