diff options
Diffstat (limited to 'src/temp/player')
-rw-r--r-- | src/temp/player/module.make | 4 | ||||
-rw-r--r-- | src/temp/player/player.h | 113 | ||||
-rw-r--r-- | src/temp/player/playerAbc.c | 228 | ||||
-rw-r--r-- | src/temp/player/playerBuild.c | 283 | ||||
-rw-r--r-- | src/temp/player/playerCore.c | 376 | ||||
-rw-r--r-- | src/temp/player/playerMan.c | 125 | ||||
-rw-r--r-- | src/temp/player/playerToAbc.c | 523 | ||||
-rw-r--r-- | src/temp/player/playerUtil.c | 353 |
8 files changed, 2005 insertions, 0 deletions
diff --git a/src/temp/player/module.make b/src/temp/player/module.make new file mode 100644 index 00000000..5185f56e --- /dev/null +++ b/src/temp/player/module.make @@ -0,0 +1,4 @@ +SRC += src/temp/player/playerToAbc.c \ + src/temp/player/playerCore.c \ + src/temp/player/playerMan.c \ + src/temp/player/playerUtil.c diff --git a/src/temp/player/player.h b/src/temp/player/player.h new file mode 100644 index 00000000..a4ee5650 --- /dev/null +++ b/src/temp/player/player.h @@ -0,0 +1,113 @@ +/**CFile**************************************************************** + + FileName [player.h] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [PLA decomposition package.] + + Synopsis [External declarations.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: player.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#ifndef __XYZ_H__ +#define __XYZ_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "ivy.h" +#include "esop.h" +#include "vec.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Pla_Man_t_ Pla_Man_t; +typedef struct Pla_Obj_t_ Pla_Obj_t; + +// storage for node information +struct Pla_Obj_t_ +{ + unsigned fFixed : 1; // fixed node + unsigned Depth : 31; // the depth in terms of LUTs/PLAs + int nRefs; // the number of references + Vec_Int_t vSupp[2]; // supports in two frames + Esop_Cube_t * pCover[2]; // esops in two frames +}; + +// storage for additional information +struct Pla_Man_t_ +{ + // general characteristics + int nLutMax; // the number of vars + int nPlaMax; // the number of vars + int nCubesMax; // the limit on the number of cubes in the intermediate covers + Ivy_Man_t * pManAig; // the AIG manager + Pla_Obj_t * pPlaStrs; // memory for structures + Esop_Man_t * pManMin; // the cube manager + // arrays to map local variables + Vec_Int_t * vComTo0; // mapping of common variables into first fanin + Vec_Int_t * vComTo1; // mapping of common variables into second fanin + Vec_Int_t * vPairs0; // the first var in each pair of common vars + Vec_Int_t * vPairs1; // the second var in each pair of common vars + Vec_Int_t * vTriv0; // trival support of the first node + Vec_Int_t * vTriv1; // trival support of the second node + // statistics + int nNodes; // the number of nodes processed + int nNodesLut; // the number of nodes processed + int nNodesPla; // the number of nodes processed + int nNodesBoth; // the number of nodes processed + int nNodesDeref; // the number of nodes processed +}; + +#define PLAYER_FANIN_LIMIT 128 + +#define PLA_MIN(a,b) (((a) < (b))? (a) : (b)) +#define PLA_MAX(a,b) (((a) > (b))? (a) : (b)) + +#define PLA_EMPTY ((Esop_Cube_t *)1) + +static inline Pla_Man_t * Ivy_ObjPlaMan( Ivy_Man_t * p, Ivy_Obj_t * pObj ) { return (Pla_Man_t *)p->pData; } +static inline Pla_Obj_t * Ivy_ObjPlaStr( Ivy_Man_t * p, Ivy_Obj_t * pObj ) { return ((Pla_Man_t *)p->pData)->pPlaStrs + pObj->Id; } + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/*=== playerToAbc.c ==============================================================*/ +extern void * Abc_NtkPlayer( void * pNtk, int nLutMax, int nPlaMax, int RankCost, int fFastMode, int fRewriting, int fSynthesis, int fVerbose ); +/*=== playerCore.c =============================================================*/ +extern Pla_Man_t * Pla_ManDecompose( Ivy_Man_t * p, int nLutMax, int nPlaMax, int fVerbose ); +/*=== playerMan.c ==============================================================*/ +extern Pla_Man_t * Pla_ManAlloc( Ivy_Man_t * p, int nLutMax, int nPlaMax ); +extern void Pla_ManFree( Pla_Man_t * p ); +extern void Pla_ManFreeStr( Pla_Man_t * p, Pla_Obj_t * pStr ); +/*=== playerUtil.c =============================================================*/ +extern int Pla_ManMergeTwoSupports( Pla_Man_t * p, Vec_Int_t * vSupp0, Vec_Int_t * vSupp1, Vec_Int_t * vSupp ); +extern Esop_Cube_t * Pla_ManAndTwoCovers( Pla_Man_t * p, Esop_Cube_t * pCover0, Esop_Cube_t * pCover1, int nSupp, int fStopAtLimit ); +extern Esop_Cube_t * Pla_ManExorTwoCovers( Pla_Man_t * p, Esop_Cube_t * pCover0, Esop_Cube_t * pCover1, int nSupp, int fStopAtLimit ); +extern void Pla_ManComputeStats( Ivy_Man_t * pAig, Vec_Int_t * vNodes ); + +#ifdef __cplusplus +} +#endif + +#endif + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + + diff --git a/src/temp/player/playerAbc.c b/src/temp/player/playerAbc.c new file mode 100644 index 00000000..dcbca462 --- /dev/null +++ b/src/temp/player/playerAbc.c @@ -0,0 +1,228 @@ +/**CFile**************************************************************** + + FileName [playerAbc.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: playerAbc.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 * pNtkOld, Ivy_Man_t * p ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +#if 0 + +/**Function************************************************************* + + Synopsis [Gives the current ABC network to PLAyer for processing.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void * Abc_NtkPlayer( void * pNtk, int nLutMax, int nPlaMax, int RankCost, int fFastMode, int fVerbose ) +{ + int fUseRewriting = 1; + Ivy_Man_t * pMan, * pManExt; + Abc_Ntk_t * pNtkAig; + + 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 ( fUseRewriting ) + { + // simplify + pMan = Ivy_ManResyn( pManExt = pMan, 1, 0 ); + Ivy_ManStop( pManExt ); + if ( fVerbose ) + Ivy_ManPrintStats( pMan ); + } + // perform decomposition/mapping into PLAs/LUTs + pManExt = Pla_ManDecompose( pMan, nLutMax, nPlaMax, fVerbose ); + Ivy_ManStop( pMan ); + pMan = pManExt; + if ( fVerbose ) + Ivy_ManPrintStats( pMan ); + // convert from the extended AIG manager into an SOP network + pNtkAig = Ivy_ManToAbc( pNtk, pMan ); + Ivy_ManStop( pMan ); + // chech the resulting network + if ( !Abc_NtkCheck( pNtkAig ) ) + { + printf( "Abc_NtkPlayer: The network check has failed.\n" ); + Abc_NtkDelete( pNtkAig ); + return NULL; + } + return pNtkAig; +} + +/**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( Abc_NtkCiNum(pNtk), Abc_NtkCoNum(pNtk), Abc_NtkNodeNum(pNtk) + 10 ); + // create the PIs + Abc_AigConst1(pNtk)->pCopy = (Abc_Obj_t *)Ivy_ManConst1(pMan); + Abc_NtkForEachCi( pNtk, pObj, i ) + pObj->pCopy = (Abc_Obj_t *)Ivy_ManPi(pMan, i); + // perform the conversion of the internal nodes + Abc_AigForEachAnd( pNtk, pObj, i ) + pObj->pCopy = (Abc_Obj_t *)Ivy_And( (Ivy_Obj_t *)Abc_ObjChild0Copy(pObj), (Ivy_Obj_t *)Abc_ObjChild1Copy(pObj) ); + // create the POs + Abc_NtkForEachCo( pNtk, pObj, i ) + Ivy_ObjConnect( Ivy_ManPo(pMan, i), (Ivy_Obj_t *)Abc_ObjChild0Copy(pObj) ); + Ivy_ManCleanup( pMan ); + return pMan; +} + +/**Function************************************************************* + + Synopsis [Converts AIG manager after PLA/LUT mapping into a logic ABC network.] + + Description [The AIG manager contains nodes with extended functionality. + Node types are in pObj->Type. Node fanins are in pObj->vFanins. Functions + of LUT nodes are in pMan->vTruths.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Ivy_ManToAbc( Abc_Ntk_t * pNtkOld, Ivy_Man_t * pMan ) +{ + Abc_Ntk_t * pNtkNew; + Vec_Int_t * vIvyNodes, * vIvyFanins, * vTruths = pMan->vTruths; + Abc_Obj_t * pObj, * pObjNew, * pFaninNew; + Ivy_Obj_t * pIvyNode, * pIvyFanin; + int pCompls[PLAYER_FANIN_LIMIT]; + int i, k, Fanin, nFanins; + // start the new ABC network + pNtkNew = Abc_NtkStartFrom( pNtkOld, ABC_NTK_LOGIC, ABC_FUNC_SOP ); + // transfer the pointers to the basic nodes + Ivy_ManCleanTravId(pMan); + Ivy_ManConst1(pMan)->TravId = Abc_AigConst1(pNtkNew)->Id; + Abc_NtkForEachCi( pNtkNew, pObjNew, i ) + Ivy_ManPi(pMan, i)->TravId = pObjNew->Id; + // construct the logic network isomorphic to logic network in the AIG manager + vIvyNodes = Ivy_ManDfsExt( pMan ); + Ivy_ManForEachNodeVec( pMan, vIvyNodes, pIvyNode, i ) + { + // get fanins of the old node + vIvyFanins = Ivy_ObjGetFanins( pIvyNode ); + nFanins = Vec_IntSize(vIvyFanins); + // create the new node + pObjNew = Abc_NtkCreateNode( pNtkNew ); + Vec_IntForEachEntry( vIvyFanins, Fanin, k ) + { + pIvyFanin = Ivy_ObjObj( pIvyNode, Ivy_EdgeId(Fanin) ); + pFaninNew = Abc_NtkObj( pNtkNew, pIvyFanin->TravId ); + Abc_ObjAddFanin( pObjNew, pFaninNew ); + pCompls[k] = Ivy_EdgeIsComplement(Fanin); + assert( Ivy_ObjIsAndMulti(pIvyNode) || nFanins == 1 || pCompls[k] == 0 ); // EXOR/LUT cannot have complemented fanins + } + assert( k <= PLAYER_FANIN_LIMIT ); + // create logic function of the node + if ( Ivy_ObjIsAndMulti(pIvyNode) ) + pObjNew->pData = Abc_SopCreateAnd( pNtkNew->pManFunc, nFanins, pCompls ); + else if ( Ivy_ObjIsExorMulti(pIvyNode) ) + pObjNew->pData = Abc_SopCreateXorSpecial( pNtkNew->pManFunc, nFanins ); + else if ( Ivy_ObjIsLut(pIvyNode) ) + pObjNew->pData = Abc_SopCreateFromTruth( pNtkNew->pManFunc, nFanins, Ivy_ObjGetTruth(pIvyNode) ); + else assert( 0 ); + assert( Abc_SopGetVarNum(pObjNew->pData) == nFanins ); + pIvyNode->TravId = pObjNew->Id; + } +//Pla_ManComputeStats( pMan, vIvyNodes ); + Vec_IntFree( vIvyNodes ); + // connect the PO nodes + Abc_NtkForEachCo( pNtkOld, pObj, i ) + { + // get the old fanin of the PO node + vIvyFanins = Ivy_ObjGetFanins( Ivy_ManPo(pMan, i) ); + Fanin = Vec_IntEntry( vIvyFanins, 0 ); + pIvyFanin = Ivy_ManObj( pMan, Ivy_EdgeId(Fanin) ); + // get the new ABC node corresponding to the old fanin + pFaninNew = Abc_NtkObj( pNtkNew, pIvyFanin->TravId ); + if ( Ivy_EdgeIsComplement(Fanin) ) // complement + { +// pFaninNew = Abc_NtkCreateNodeInv(pNtkNew, pFaninNew); + if ( Abc_ObjIsCi(pFaninNew) ) + pFaninNew = Abc_NtkCreateNodeInv(pNtkNew, pFaninNew); + else + { + // clone the node + pObjNew = Abc_NtkCloneObj( pFaninNew ); + // set complemented functions + pObjNew->pData = Abc_SopRegister( pNtkNew->pManFunc, pFaninNew->pData ); + Abc_SopComplement(pObjNew->pData); + // return the new node + pFaninNew = pObjNew; + } + assert( Abc_SopGetVarNum(pFaninNew->pData) == Abc_ObjFaninNum(pFaninNew) ); + } + Abc_ObjAddFanin( pObj->pCopy, pFaninNew ); + } + // remove dangling nodes + Abc_NtkForEachNode(pNtkNew, pObj, i) + if ( Abc_ObjFanoutNum(pObj) == 0 ) + Abc_NtkDeleteObj(pObj); + // fix CIs feeding directly into COs + Abc_NtkLogicMakeSimpleCos( pNtkNew, 0 ); + return pNtkNew; +} + +#endif + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/temp/player/playerBuild.c b/src/temp/player/playerBuild.c new file mode 100644 index 00000000..e878f19c --- /dev/null +++ b/src/temp/player/playerBuild.c @@ -0,0 +1,283 @@ +/**CFile**************************************************************** + + FileName [playerBuild.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [PLA decomposition package.] + + Synopsis [] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - May 11, 2006.] + + Revision [$Id: playerBuild.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "player.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static Ivy_Obj_t * Pla_ManToAig_rec( Ivy_Man_t * pNew, Ivy_Obj_t * pObjOld ); +static Ivy_Obj_t * Ivy_ManToAigCube( Ivy_Man_t * pNew, Ivy_Obj_t * pObj, Esop_Cube_t * pCube, Vec_Int_t * vSupp ); +static Ivy_Obj_t * Ivy_ManToAigConst( Ivy_Man_t * pNew, int fConst1 ); +static int Pla_ManToAigLutFuncs( Ivy_Man_t * pNew, Ivy_Man_t * pOld ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +#if 0 + +/**Function************************************************************* + + Synopsis [Constructs the AIG manager (IVY) for the network after mapping.] + + Description [Uses extended node types (multi-input AND, multi-input EXOR, LUT).] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Ivy_Man_t * Pla_ManToAig( Ivy_Man_t * pOld ) +{ + Ivy_Man_t * pNew; + Ivy_Obj_t * pObjOld, * pObjNew; + int i; + // start the new manager + pNew = Ivy_ManStart( Ivy_ManPiNum(pOld), Ivy_ManPoNum(pOld), 2*Ivy_ManNodeNum(pOld) + 10 ); + pNew->fExtended = 1; + // transfer the const/PI numbers + Ivy_ManCleanTravId(pOld); + Ivy_ManConst1(pOld)->TravId = Ivy_ManConst1(pNew)->Id; + Ivy_ManForEachPi( pOld, pObjOld, i ) + pObjOld->TravId = Ivy_ManPi(pNew, i)->Id; + // recursively construct the network + Ivy_ManForEachPo( pOld, pObjOld, i ) + { + pObjNew = Pla_ManToAig_rec( pNew, Ivy_ObjFanin0(pObjOld) ); + Ivy_ObjStartFanins( Ivy_ManPo(pNew, i), 1 ); + Ivy_ObjAddFanin( Ivy_ManPo(pNew, i), Ivy_EdgeCreate(pObjNew->Id, Ivy_ObjFaninC0(pObjOld)) ); + } + // compute the LUT functions + Pla_ManToAigLutFuncs( pNew, pOld ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Recursively construct the new node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Ivy_Obj_t * Pla_ManToAig_rec( Ivy_Man_t * pNew, Ivy_Obj_t * pObjOld ) +{ + Pla_Man_t * p = Ivy_ObjMan(pObjOld)->pData; + Vec_Int_t * vSupp; + Esop_Cube_t * pCover, * pCube; + Ivy_Obj_t * pFaninOld, * pFaninNew, * pObjNew; + Pla_Obj_t * pStr; + int Entry, nCubes, ObjNewId, i; + // skip the node if it is a constant or already processed + if ( Ivy_ObjIsConst1(pObjOld) || pObjOld->TravId ) + return Ivy_ManObj( pNew, pObjOld->TravId ); + assert( Ivy_ObjIsAnd(pObjOld) || Ivy_ObjIsExor(pObjOld) ); + // get the support and the cover + pStr = Ivy_ObjPlaStr( pNew, pObjOld ); + 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 ); + } + // process the fanins + Vec_IntForEachEntry( vSupp, Entry, i ) + Pla_ManToAig_rec( pNew, Ivy_ObjObj(pObjOld, Entry) ); + // consider the case of a LUT + if ( pCover == PLA_EMPTY ) + { + pObjNew = Ivy_ObjCreateExt( pNew, IVY_LUT ); + Ivy_ObjStartFanins( pObjNew, p->nLutMax ); + // remember new object ID in case it changes + ObjNewId = pObjNew->Id; + Vec_IntForEachEntry( vSupp, Entry, i ) + { + pFaninOld = Ivy_ObjObj( pObjOld, Entry ); + Ivy_ObjAddFanin( Ivy_ManObj(pNew, ObjNewId), Ivy_EdgeCreate(pFaninOld->TravId, 0) ); + } + // get the new object + pObjNew = Ivy_ManObj(pNew, ObjNewId); + } + else + { + // for each cube, construct the node + nCubes = Esop_CoverCountCubes( pCover ); + if ( nCubes == 0 ) + pObjNew = Ivy_ManToAigConst( pNew, 0 ); + else if ( nCubes == 1 ) + pObjNew = Ivy_ManToAigCube( pNew, pObjOld, pCover, vSupp ); + else + { + pObjNew = Ivy_ObjCreateExt( pNew, IVY_EXORM ); + Ivy_ObjStartFanins( pObjNew, p->nLutMax ); + // remember new object ID in case it changes + ObjNewId = pObjNew->Id; + Esop_CoverForEachCube( pCover, pCube ) + { + pFaninNew = Ivy_ManToAigCube( pNew, pObjOld, pCube, vSupp ); + Ivy_ObjAddFanin( Ivy_ManObj(pNew, ObjNewId), Ivy_EdgeCreate(pFaninNew->Id, 0) ); + } + // get the new object + pObjNew = Ivy_ManObj(pNew, ObjNewId); + } + } + pObjOld->TravId = pObjNew->Id; + pObjNew->TravId = pObjOld->Id; + return pObjNew; +} + + +/**Function************************************************************* + + Synopsis [Returns constant 1 node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Ivy_Obj_t * Ivy_ManToAigConst( Ivy_Man_t * pNew, int fConst1 ) +{ + Ivy_Obj_t * pObjNew; + pObjNew = Ivy_ObjCreateExt( pNew, IVY_ANDM ); + Ivy_ObjStartFanins( pObjNew, 1 ); + Ivy_ObjAddFanin( pObjNew, Ivy_EdgeCreate(0, !fConst1) ); + return pObjNew; +} + +/**Function************************************************************* + + Synopsis [Derives the decomposed network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Ivy_Obj_t * Ivy_ManToAigCube( Ivy_Man_t * pNew, Ivy_Obj_t * pObjOld, Esop_Cube_t * pCube, Vec_Int_t * vSupp ) +{ + Ivy_Obj_t * pObjNew, * pFaninOld; + int i, Value; + // if tautology cube, create constant 1 node + if ( pCube->nLits == 0 ) + return Ivy_ManToAigConst( pNew, 1 ); + // create AND node + pObjNew = Ivy_ObjCreateExt( pNew, IVY_ANDM ); + Ivy_ObjStartFanins( pObjNew, pCube->nLits ); + // add fanins + for ( i = 0; i < (int)pCube->nVars; i++ ) + { + Value = Esop_CubeGetVar( pCube, i ); + assert( Value != 0 ); + if ( Value == 3 ) + continue; + pFaninOld = Ivy_ObjObj( pObjOld, Vec_IntEntry(vSupp, i) ); + Ivy_ObjAddFanin( pObjNew, Ivy_EdgeCreate( pFaninOld->TravId, Value==1 ) ); + } + assert( Ivy_ObjFaninNum(pObjNew) == (int)pCube->nLits ); + return pObjNew; +} + + +/**Function************************************************************* + + Synopsis [Recursively construct the new node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Pla_ManToAigLutFuncs( Ivy_Man_t * pNew, Ivy_Man_t * pOld ) +{ + Vec_Int_t * vSupp, * vFanins, * vNodes, * vTemp; + Ivy_Obj_t * pObjOld, * pObjNew; + unsigned * pComputed, * pTruth; + int i, k, Counter = 0; + // create mapping from the LUT nodes into truth table indices + assert( pNew->vTruths == NULL ); + vNodes = Vec_IntAlloc( 100 ); + vTemp = Vec_IntAlloc( 100 ); + pNew->vTruths = Vec_IntStart( Ivy_ManObjIdNext(pNew) ); + Ivy_ManForEachObj( pNew, pObjNew, i ) + { + if ( Ivy_ObjIsLut(pObjNew) ) + Vec_IntWriteEntry( pNew->vTruths, i, 8 * Counter++ ); + else + Vec_IntWriteEntry( pNew->vTruths, i, -1 ); + } + // allocate memory + pNew->pMemory = ALLOC( unsigned, 8 * Counter ); + memset( pNew->pMemory, 0, sizeof(unsigned) * 8 * Counter ); + // derive truth tables + Ivy_ManForEachObj( pNew, pObjNew, i ) + { + if ( !Ivy_ObjIsLut(pObjNew) ) + continue; + pObjOld = Ivy_ManObj( pOld, pObjNew->TravId ); + vSupp = Ivy_ObjPlaStr(pNew, pObjOld)->vSupp; + assert( Vec_IntSize(vSupp) <= 8 ); + pTruth = Ivy_ObjGetTruth( pObjNew ); + pComputed = Ivy_ManCutTruth( pNew, pObjOld, vSupp, vNodes, vTemp ); + // check if the truth table is constant 0 + for ( k = 0; k < 8; k++ ) + if ( pComputed[k] ) + break; + if ( k == 8 ) + { + // create inverter + for ( k = 0; k < 8; k++ ) + pComputed[k] = 0x55555555; + // point it to the constant 1 node + vFanins = Ivy_ObjGetFanins( pObjNew ); + Vec_IntClear( vFanins ); + Vec_IntPush( vFanins, Ivy_EdgeCreate(0, 1) ); + } + memcpy( pTruth, pComputed, sizeof(unsigned) * 8 ); +// Extra_PrintBinary( stdout, pTruth, 16 ); printf( "\n" ); + } + Vec_IntFree( vTemp ); + Vec_IntFree( vNodes ); + return Counter; +} + +#endif + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/temp/player/playerCore.c b/src/temp/player/playerCore.c new file mode 100644 index 00000000..b87f39d4 --- /dev/null +++ b/src/temp/player/playerCore.c @@ -0,0 +1,376 @@ +/**CFile**************************************************************** + + FileName [playerCore.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [PLA decomposition package.] + + Synopsis [] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - May 11, 2006.] + + Revision [$Id: playerCore.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "player.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static int Pla_ManDecomposeInt( Pla_Man_t * p ); +static int Pla_ManDecomposeNode( Pla_Man_t * p, Ivy_Obj_t * pObj ); +static void Pla_NodeGetSuppsAndCovers( Pla_Man_t * p, Ivy_Obj_t * pObj, int Level, + Vec_Int_t ** pvSuppA, Vec_Int_t ** pvSuppB, Esop_Cube_t ** pvCovA, Esop_Cube_t ** pvCovB ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Performs decomposition/mapping into PLAs and K-LUTs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Pla_Man_t * Pla_ManDecompose( Ivy_Man_t * pAig, int nLutMax, int nPlaMax, int fVerbose ) +{ + Pla_Man_t * p; + p = Pla_ManAlloc( pAig, nLutMax, nPlaMax ); + if ( !Pla_ManDecomposeInt( p ) ) + { + printf( "Decomposition/mapping failed.\n" ); + Pla_ManFree( p ); + return NULL; + } + return p; +} + +/**Function************************************************************* + + Synopsis [Performs decomposition/mapping into PLAs and K-LUTs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Pla_ManDecomposeInt( Pla_Man_t * p ) +{ + Ivy_Man_t * pAig = p->pManAig; + Ivy_Obj_t * pObj; + Pla_Obj_t * pStr; + int i; + + // prepare the PI structures + Ivy_ManForEachPi( pAig, pObj, i ) + { + pStr = Ivy_ObjPlaStr( pAig, pObj ); + pStr->fFixed = 1; + pStr->Depth = 0; + pStr->nRefs = (unsigned)pObj->nRefs; + pStr->pCover[0] = PLA_EMPTY; + pStr->pCover[1] = PLA_EMPTY; + } + + // assuming DFS ordering of nodes in the manager + Ivy_ManForEachNode( pAig, pObj, i ) + if ( !Pla_ManDecomposeNode(p, pObj) ) + return 0; + return 1; +} + +/**Function************************************************************* + + Synopsis [Records decomposition statistics for one node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Pla_ManCountDecNodes( Pla_Man_t * p, Pla_Obj_t * pStr ) +{ + if ( Vec_IntSize(pStr->vSupp) <= p->nLutMax && pStr->pCover[1] != PLA_EMPTY ) + p->nNodesBoth++; + else if ( Vec_IntSize(pStr->vSupp) <= p->nLutMax ) + p->nNodesLut++; + else if ( pStr->pCover[1] != PLA_EMPTY ) + p->nNodesPla++; +} + +/**Function************************************************************* + + Synopsis [Performs decomposition/mapping for one node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Pla_ManDecomposeNode( Pla_Man_t * p, Ivy_Obj_t * pObj ) +{ + Pla_Obj_t * pStr, * pStr0, * pStr1; + Vec_Int_t * vSuppA, * vSuppB, * vSupp0, * vSupp1; + Esop_Cube_t * pCovA, * pCovB; + int nSuppSize1, nSuppSize2; + + assert( pObj->nRefs > 0 ); + p->nNodes++; + + // get the structures + pStr = Ivy_ObjPlaStr( p->pManAig, pObj ); + pStr0 = Ivy_ObjPlaStr( p->pManAig, Ivy_ObjFanin0( pObj ) ); + pStr1 = Ivy_ObjPlaStr( p->pManAig, Ivy_ObjFanin1( pObj ) ); + vSupp0 = &pStr->vSupp[0]; + vSupp1 = &pStr->vSupp[1]; + pStr->pCover[0] = PLA_EMPTY; + pStr->pCover[1] = PLA_EMPTY; + + // process level 1 + Pla_NodeGetSuppsAndCovers( p, pObj, 1, &vSuppA, &vSuppB, &pCovA, &pCovB ); + nSuppSize1 = Pla_ManMergeTwoSupports( p, vSuppA, vSuppB, vSupp0 ); + if ( nSuppSize1 > p->nPlaMax || pCovA == PLA_EMPTY || pCovB == PLA_EMPTY ) + pStr->pCover[0] = PLA_EMPTY; + else if ( Ivy_ObjIsAnd(pObj) ) + pStr->pCover[0] = Pla_ManAndTwoCovers( p, pCovA, pCovB, nSuppSize1, 1 ); + else + pStr->pCover[0] = Pla_ManExorTwoCovers( p, pCovA, pCovB, nSuppSize1, 1 ); + + // process level 2 + if ( PLA_MAX(pStr0->Depth, pStr1->Depth) > 1 ) + { + Pla_NodeGetSuppsAndCovers( p, pObj, 2, &vSuppA, &vSuppB, &pCovA, &pCovB ); + nSuppSize2 = Pla_ManMergeTwoSupports( p, vSuppA, vSuppB, vSupp1 ); + if ( nSuppSize2 > p->nPlaMax || pCovA == PLA_EMPTY || pCovB == PLA_EMPTY ) + pStr->pCover[1] = PLA_EMPTY; + else if ( Ivy_ObjIsAnd(pObj) ) + pStr->pCover[1] = Pla_ManAndTwoCovers( p, pCovA, pCovB, nSuppSize2, 1 ); + else + pStr->pCover[1] = Pla_ManExorTwoCovers( p, pCovA, pCovB, nSuppSize2, 1 ); + } + + // determine the level of this node + pStr->nRefs = (unsigned)pObj->nRefs; + pStr->Depth = PLA_MAX( pStr0->Depth, pStr1->Depth ); + pStr->Depth = pStr->Depth? pStr->Depth : 1; + if ( nSuppSize1 > p->nLutMax && pStr->pCover[1] == PLA_EMPTY ) + { + pStr->Depth++; + // free second level + if ( pStr->pCover[1] != PLA_EMPTY ) + Esop_CoverRecycle( p->pManMin, pStr->pCover[1] ); + vSupp1->nCap = 0; + vSupp1->nSize = 0; + FREE( vSupp1->pArray ); + pStr->pCover[1] = PLA_EMPTY; + // move first to second + pStr->vSupp[1] = pStr->vSupp[0]; + pStr->pCover[1] = pStr->pCover[0]; + vSupp0->nCap = 0; + vSupp0->nSize = 0; + vSupp0->pArray = NULL; + pStr->pCover[0] = PLA_EMPTY; + // get zero level + Pla_NodeGetSuppsAndCovers( p, pObj, 0, &vSuppA, &vSuppB, &pCovA, &pCovB ); + nSuppSize2 = Pla_ManMergeTwoSupports( p, vSuppA, vSuppB, vSupp0 ); + assert( nSuppSize2 == 2 ); + if ( pCovA == PLA_EMPTY || pCovB == PLA_EMPTY ) + pStr->pCover[0] = PLA_EMPTY; + else if ( Ivy_ObjIsAnd(pObj) ) + pStr->pCover[0] = Pla_ManAndTwoCovers( p, pCovA, pCovB, nSuppSize2, 0 ); + else + pStr->pCover[0] = Pla_ManExorTwoCovers( p, pCovA, pCovB, nSuppSize2, 0 ); + // count stats + if ( pStr0->fFixed == 0 ) Pla_ManCountDecNodes( p, pStr0 ); + if ( pStr1->fFixed == 0 ) Pla_ManCountDecNodes( p, pStr1 ); + // mark the nodes + pStr0->fFixed = 1; + pStr1->fFixed = 1; + } + else if ( pStr0->Depth < pStr1->Depth ) + { + if ( pStr0->fFixed == 0 ) Pla_ManCountDecNodes( p, pStr0 ); + pStr0->fFixed = 1; + } + else // if ( pStr0->Depth > pStr1->Depth ) + { + if ( pStr1->fFixed == 0 ) Pla_ManCountDecNodes( p, pStr1 ); + pStr1->fFixed = 1; + } + assert( pStr->Depth ); + + // free some of the covers to save memory + assert( pStr0->nRefs > 0 ); + assert( pStr1->nRefs > 0 ); + pStr0->nRefs--; + pStr1->nRefs--; + + if ( pStr0->nRefs == 0 && !pStr0->fFixed ) + Pla_ManFreeStr( p, pStr0 ), p->nNodesDeref++; + if ( pStr1->nRefs == 0 && !pStr1->fFixed ) + Pla_ManFreeStr( p, pStr1 ), p->nNodesDeref++; + + return 1; +} + +/**Function************************************************************* + + Synopsis [Returns pointers to the support arrays on the given level.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Pla_NodeGetSuppsAndCovers( Pla_Man_t * p, Ivy_Obj_t * pObj, int Level, + Vec_Int_t ** pvSuppA, Vec_Int_t ** pvSuppB, Esop_Cube_t ** pvCovA, Esop_Cube_t ** pvCovB ) +{ + Ivy_Obj_t * pFan0, * pFan1; + Pla_Obj_t * pStr, * pStr0, * pStr1; + Esop_Cube_t * pCovA, * pCovB; + int fCompl0, fCompl1; + assert( Level >= 0 && Level <= 2 ); + // get the complemented attributes + fCompl0 = Ivy_ObjFaninC0( pObj ); + fCompl1 = Ivy_ObjFaninC1( pObj ); + // get the fanins + pFan0 = Ivy_ObjFanin0( pObj ); + pFan1 = Ivy_ObjFanin1( pObj ); + // get the structures + pStr = Ivy_ObjPlaStr( p->pManAig, pObj ); + pStr0 = Ivy_ObjPlaStr( p->pManAig, pFan0 ); + pStr1 = Ivy_ObjPlaStr( p->pManAig, pFan1 ); + // make sure the fanins are processed + assert( Ivy_ObjIsPi(pFan0) || pStr0->Depth > 0 ); + assert( Ivy_ObjIsPi(pFan1) || pStr1->Depth > 0 ); + // prepare the return values depending on the level + Vec_IntWriteEntry( p->vTriv0, 0, pFan0->Id ); + Vec_IntWriteEntry( p->vTriv1, 0, pFan1->Id ); + *pvSuppA = p->vTriv0; + *pvSuppB = p->vTriv1; + pCovA = p->pManMin->pTriv0; + pCovB = p->pManMin->pTriv1; + if ( Level == 1 ) + { + if ( pStr0->Depth == pStr1->Depth ) + { + if ( pStr0->Depth > 0 ) + { + *pvSuppA = &pStr0->vSupp[0]; + *pvSuppB = &pStr1->vSupp[0]; + pCovA = pStr0->pCover[0]; + pCovB = pStr1->pCover[0]; + } + } + else if ( pStr0->Depth < pStr1->Depth ) + { + *pvSuppB = &pStr1->vSupp[0]; + pCovB = pStr1->pCover[0]; + } + else // if ( pStr0->Depth > pStr1->Depth ) + { + *pvSuppA = &pStr0->vSupp[0]; + pCovA = pStr0->pCover[0]; + } + } + else if ( Level == 2 ) + { + if ( pStr0->Depth == pStr1->Depth ) + { + *pvSuppA = &pStr0->vSupp[1]; + *pvSuppB = &pStr1->vSupp[1]; + pCovA = pStr0->pCover[1]; + pCovB = pStr1->pCover[1]; + } + else if ( pStr0->Depth + 1 == pStr1->Depth ) + { + *pvSuppA = &pStr0->vSupp[0]; + *pvSuppB = &pStr1->vSupp[1]; + pCovA = pStr0->pCover[0]; + pCovB = pStr1->pCover[1]; + } + else if ( pStr0->Depth == pStr1->Depth + 1 ) + { + *pvSuppA = &pStr0->vSupp[1]; + *pvSuppB = &pStr1->vSupp[0]; + pCovA = pStr0->pCover[1]; + pCovB = pStr1->pCover[0]; + } + else if ( pStr0->Depth < pStr1->Depth ) + { + *pvSuppB = &pStr1->vSupp[1]; + pCovB = pStr1->pCover[1]; + } + else // if ( pStr0->Depth > pStr1->Depth ) + { + *pvSuppA = &pStr0->vSupp[1]; + pCovA = pStr0->pCover[1]; + } + } + // complement the first if needed + if ( pCovA == PLA_EMPTY || !fCompl0 ) + *pvCovA = pCovA; + else if ( pCovA && pCovA->nLits == 0 ) // topmost one is the tautology cube + *pvCovA = pCovA->pNext; + else + *pvCovA = p->pManMin->pOne0, p->pManMin->pOne0->pNext = pCovA; + // complement the second if needed + if ( pCovB == PLA_EMPTY || !fCompl1 ) + *pvCovB = pCovB; + else if ( pCovB && pCovB->nLits == 0 ) // topmost one is the tautology cube + *pvCovB = pCovB->pNext; + else + *pvCovB = p->pManMin->pOne1, p->pManMin->pOne1->pNext = pCovB; +} + + +/* + if ( pObj->Id == 1371 ) + { + int k; + printf( "Zero : " ); + for ( k = 0; k < vSuppA->nSize; k++ ) + printf( "%d ", vSuppA->pArray[k] ); + printf( "\n" ); + printf( "One : " ); + for ( k = 0; k < vSuppB->nSize; k++ ) + printf( "%d ", vSuppB->pArray[k] ); + printf( "\n" ); + printf( "Node : " ); + for ( k = 0; k < vSupp0->nSize; k++ ) + printf( "%d ", vSupp0->pArray[k] ); + printf( "\n" ); + printf( "\n" ); + printf( "\n" ); + Esop_CoverWrite( stdout, pCovA ); + printf( "\n" ); + Esop_CoverWrite( stdout, pCovB ); + printf( "\n" ); + } +*/ + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/temp/player/playerMan.c b/src/temp/player/playerMan.c new file mode 100644 index 00000000..32eacc9b --- /dev/null +++ b/src/temp/player/playerMan.c @@ -0,0 +1,125 @@ +/**CFile**************************************************************** + + FileName [playerMan.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [PLA decomposition package.] + + Synopsis [] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - May 11, 2006.] + + Revision [$Id: playerMan.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "player.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Allocates the PLA/LUT mapping manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Pla_Man_t * Pla_ManAlloc( Ivy_Man_t * pAig, int nLutMax, int nPlaMax ) +{ + Pla_Man_t * pMan; + assert( !(nLutMax < 2 || nLutMax > 8 || nPlaMax < 8 || nPlaMax > 128) ); + // start the manager + pMan = ALLOC( Pla_Man_t, 1 ); + memset( pMan, 0, sizeof(Pla_Man_t) ); + pMan->nLutMax = nLutMax; + pMan->nPlaMax = nPlaMax; + pMan->nCubesMax = 2 * nPlaMax; // higher limit, later reduced + pMan->pManAig = pAig; + // set up the temporaries + pMan->vComTo0 = Vec_IntAlloc( 2 * nPlaMax ); + pMan->vComTo1 = Vec_IntAlloc( 2 * nPlaMax ); + pMan->vPairs0 = Vec_IntAlloc( nPlaMax ); + pMan->vPairs1 = Vec_IntAlloc( nPlaMax ); + pMan->vTriv0 = Vec_IntAlloc( 1 ); Vec_IntPush( pMan->vTriv0, -1 ); + pMan->vTriv1 = Vec_IntAlloc( 1 ); Vec_IntPush( pMan->vTriv1, -1 ); + // allocate memory for object structures + pMan->pPlaStrs = ALLOC( Pla_Obj_t, Ivy_ManObjIdMax(pAig)+1 ); + memset( pMan->pPlaStrs, 0, sizeof(Pla_Obj_t) * (Ivy_ManObjIdMax(pAig)+1) ); + // create the cube manager + pMan->pManMin = Esop_ManAlloc( nPlaMax ); + // save the resulting manager + assert( pAig->pData == NULL ); + pAig->pData = pMan; + return pMan; +} + +/**Function************************************************************* + + Synopsis [Frees the PLA/LUT mapping manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Pla_ManFree( Pla_Man_t * p ) +{ + Pla_Obj_t * pStr; + int i; + Esop_ManFree( p->pManMin ); + Vec_IntFree( p->vTriv0 ); + Vec_IntFree( p->vTriv1 ); + Vec_IntFree( p->vComTo0 ); + Vec_IntFree( p->vComTo1 ); + Vec_IntFree( p->vPairs0 ); + Vec_IntFree( p->vPairs1 ); + for ( i = 0, pStr = p->pPlaStrs; i <= Ivy_ManObjIdMax(p->pManAig); i++, pStr++ ) + FREE( pStr->vSupp[0].pArray ), FREE( pStr->vSupp[1].pArray ); + free( p->pPlaStrs ); + free( p ); +} + +/**Function************************************************************* + + Synopsis [Cleans the PLA/LUT structure of the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Pla_ManFreeStr( Pla_Man_t * p, Pla_Obj_t * pStr ) +{ + if ( pStr->pCover[0] != PLA_EMPTY ) Esop_CoverRecycle( p->pManMin, pStr->pCover[0] ); + if ( pStr->pCover[1] != PLA_EMPTY ) Esop_CoverRecycle( p->pManMin, pStr->pCover[1] ); + if ( pStr->vSupp[0].pArray ) free( pStr->vSupp[0].pArray ); + if ( pStr->vSupp[1].pArray ) free( pStr->vSupp[1].pArray ); + memset( pStr, 0, sizeof(Pla_Obj_t) ); + pStr->pCover[0] = PLA_EMPTY; + pStr->pCover[1] = PLA_EMPTY; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + 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 /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/temp/player/playerUtil.c b/src/temp/player/playerUtil.c new file mode 100644 index 00000000..1c8aeec2 --- /dev/null +++ b/src/temp/player/playerUtil.c @@ -0,0 +1,353 @@ +/**CFile**************************************************************** + + FileName [playerUtil.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [PLA decomposition package.] + + Synopsis [] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - May 11, 2006.] + + Revision [$Id: playerUtil.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "player.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Merges two supports.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Pla_ManMergeTwoSupports( Pla_Man_t * p, Vec_Int_t * vSupp0, Vec_Int_t * vSupp1, Vec_Int_t * vSupp ) +{ + int k0, k1; + + assert( vSupp0->nSize && vSupp1->nSize ); + + Vec_IntFill( p->vComTo0, vSupp0->nSize + vSupp1->nSize, -1 ); + Vec_IntFill( p->vComTo1, vSupp0->nSize + vSupp1->nSize, -1 ); + Vec_IntClear( p->vPairs0 ); + Vec_IntClear( p->vPairs1 ); + + vSupp->nSize = 0; + vSupp->nCap = vSupp0->nSize + vSupp1->nSize; + vSupp->pArray = ALLOC( int, vSupp->nCap ); + + for ( k0 = k1 = 0; k0 < vSupp0->nSize && k1 < vSupp1->nSize; ) + { + if ( vSupp0->pArray[k0] == vSupp1->pArray[k1] ) + { + Vec_IntWriteEntry( p->vComTo0, vSupp->nSize, k0 ); + Vec_IntWriteEntry( p->vComTo1, vSupp->nSize, k1 ); + Vec_IntPush( p->vPairs0, k0 ); + Vec_IntPush( p->vPairs1, k1 ); + Vec_IntPush( vSupp, vSupp0->pArray[k0] ); + k0++; k1++; + } + else if ( vSupp0->pArray[k0] < vSupp1->pArray[k1] ) + { + Vec_IntWriteEntry( p->vComTo0, vSupp->nSize, k0 ); + Vec_IntPush( vSupp, vSupp0->pArray[k0] ); + k0++; + } + else + { + Vec_IntWriteEntry( p->vComTo1, vSupp->nSize, k1 ); + Vec_IntPush( vSupp, vSupp1->pArray[k1] ); + k1++; + } + } + for ( ; k0 < vSupp0->nSize; k0++ ) + { + Vec_IntWriteEntry( p->vComTo0, vSupp->nSize, k0 ); + Vec_IntPush( vSupp, vSupp0->pArray[k0] ); + } + for ( ; k1 < vSupp1->nSize; k1++ ) + { + Vec_IntWriteEntry( p->vComTo1, vSupp->nSize, k1 ); + Vec_IntPush( vSupp, vSupp1->pArray[k1] ); + } +/* + printf( "Zero : " ); + for ( k = 0; k < vSupp0->nSize; k++ ) + printf( "%d ", vSupp0->pArray[k] ); + printf( "\n" ); + + printf( "One : " ); + for ( k = 0; k < vSupp1->nSize; k++ ) + printf( "%d ", vSupp1->pArray[k] ); + printf( "\n" ); + + printf( "Sum : " ); + for ( k = 0; k < vSupp->nSize; k++ ) + printf( "%d ", vSupp->pArray[k] ); + printf( "\n" ); + printf( "\n" ); +*/ + return Vec_IntSize(vSupp); +} + + +/**Function************************************************************* + + Synopsis [Computes the produce of two covers.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Esop_Cube_t * Pla_ManAndTwoCovers( Pla_Man_t * p, Esop_Cube_t * pCover0, Esop_Cube_t * pCover1, int nSupp, int fStopAtLimit ) +{ + Esop_Cube_t * pCube, * pCube0, * pCube1; + Esop_Cube_t * pCover; + int i, Val0, Val1; + assert( pCover0 != PLA_EMPTY && pCover1 != PLA_EMPTY ); + + // clean storage + assert( nSupp <= p->nPlaMax ); + Esop_ManClean( p->pManMin, nSupp ); + // go through the cube pairs + Esop_CoverForEachCube( pCover0, pCube0 ) + Esop_CoverForEachCube( pCover1, pCube1 ) + { + // go through the support variables of the cubes + for ( i = 0; i < p->vPairs0->nSize; i++ ) + { + Val0 = Esop_CubeGetVar( pCube0, p->vPairs0->pArray[i] ); + Val1 = Esop_CubeGetVar( pCube1, p->vPairs1->pArray[i] ); + if ( (Val0 & Val1) == 0 ) + break; + } + // check disjointness + if ( i < p->vPairs0->nSize ) + continue; + + if ( fStopAtLimit && p->pManMin->nCubes > p->nCubesMax ) + { + pCover = Esop_CoverCollect( p->pManMin, nSupp ); +//Esop_CoverWriteFile( pCover, "large", 1 ); + Esop_CoverRecycle( p->pManMin, pCover ); + return PLA_EMPTY; + } + + // create the product cube + pCube = Esop_CubeAlloc( p->pManMin ); + + // add the literals + pCube->nLits = 0; + for ( i = 0; i < nSupp; i++ ) + { + if ( p->vComTo0->pArray[i] == -1 ) + Val0 = 3; + else + Val0 = Esop_CubeGetVar( pCube0, p->vComTo0->pArray[i] ); + + if ( p->vComTo1->pArray[i] == -1 ) + Val1 = 3; + else + Val1 = Esop_CubeGetVar( pCube1, p->vComTo1->pArray[i] ); + + if ( (Val0 & Val1) == 3 ) + continue; + + Esop_CubeXorVar( pCube, i, (Val0 & Val1) ^ 3 ); + pCube->nLits++; + } + // add the cube to storage + Esop_EsopAddCube( p->pManMin, pCube ); + } + + // minimize the cover + Esop_EsopMinimize( p->pManMin ); + pCover = Esop_CoverCollect( p->pManMin, nSupp ); + + // quit if the cover is too large + if ( fStopAtLimit && Esop_CoverCountCubes(pCover) > p->nPlaMax ) + { + Esop_CoverRecycle( p->pManMin, pCover ); + return PLA_EMPTY; + } +// if ( pCover && pCover->nWords > 4 ) +// printf( "%d", pCover->nWords ); +// else +// printf( "." ); + return pCover; +} + +/**Function************************************************************* + + Synopsis [Computes the EXOR of two covers.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Esop_Cube_t * Pla_ManExorTwoCovers( Pla_Man_t * p, Esop_Cube_t * pCover0, Esop_Cube_t * pCover1, int nSupp, int fStopAtLimit ) +{ + Esop_Cube_t * pCube, * pCube0, * pCube1; + Esop_Cube_t * pCover; + int i, Val0, Val1; + assert( pCover0 != PLA_EMPTY && pCover1 != PLA_EMPTY ); + + // clean storage + assert( nSupp <= p->nPlaMax ); + Esop_ManClean( p->pManMin, nSupp ); + Esop_CoverForEachCube( pCover0, pCube0 ) + { + // create the cube + pCube = Esop_CubeAlloc( p->pManMin ); + pCube->nLits = 0; + for ( i = 0; i < p->vComTo0->nSize; i++ ) + { + if ( p->vComTo0->pArray[i] == -1 ) + continue; + Val0 = Esop_CubeGetVar( pCube0, p->vComTo0->pArray[i] ); + if ( Val0 == 3 ) + continue; + Esop_CubeXorVar( pCube, i, Val0 ^ 3 ); + pCube->nLits++; + } + if ( fStopAtLimit && p->pManMin->nCubes > p->nCubesMax ) + { + pCover = Esop_CoverCollect( p->pManMin, nSupp ); + Esop_CoverRecycle( p->pManMin, pCover ); + return PLA_EMPTY; + } + // add the cube to storage + Esop_EsopAddCube( p->pManMin, pCube ); + } + Esop_CoverForEachCube( pCover1, pCube1 ) + { + // create the cube + pCube = Esop_CubeAlloc( p->pManMin ); + pCube->nLits = 0; + for ( i = 0; i < p->vComTo1->nSize; i++ ) + { + if ( p->vComTo1->pArray[i] == -1 ) + continue; + Val1 = Esop_CubeGetVar( pCube1, p->vComTo1->pArray[i] ); + if ( Val1 == 3 ) + continue; + Esop_CubeXorVar( pCube, i, Val1 ^ 3 ); + pCube->nLits++; + } + if ( fStopAtLimit && p->pManMin->nCubes > p->nCubesMax ) + { + pCover = Esop_CoverCollect( p->pManMin, nSupp ); + Esop_CoverRecycle( p->pManMin, pCover ); + return PLA_EMPTY; + } + // add the cube to storage + Esop_EsopAddCube( p->pManMin, pCube ); + } + + // minimize the cover + Esop_EsopMinimize( p->pManMin ); + pCover = Esop_CoverCollect( p->pManMin, nSupp ); + + // quit if the cover is too large + if ( fStopAtLimit && Esop_CoverCountCubes(pCover) > p->nPlaMax ) + { + Esop_CoverRecycle( p->pManMin, pCover ); + return PLA_EMPTY; + } + return pCover; +} + +#if 0 + +/**Function************************************************************* + + Synopsis [Computes area/delay of the mapping.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Pla_ManComputeStats( Ivy_Man_t * p, Vec_Int_t * vNodes ) +{ + Ivy_Obj_t * pObj, * pFanin; + Vec_Int_t * vFanins; + int Area, Delay, Fanin, nFanins, i, k; + + Delay = Area = 0; + // compute levels and area + Ivy_ManForEachPi( p, pObj, i ) + pObj->Level = 0; + Ivy_ManForEachNodeVec( p, vNodes, pObj, i ) + { + // compute level of the node + pObj->Level = 0; + vFanins = Ivy_ObjGetFanins( pObj ); + Vec_IntForEachEntry( vFanins, Fanin, k ) + { + pFanin = Ivy_ManObj(p, Ivy_EdgeId(Fanin)); + pObj->Level = IVY_MAX( pObj->Level, pFanin->Level ); + } + pObj->Level += 1; + // compute area of the node + nFanins = Ivy_ObjFaninNum( pObj ); + if ( nFanins <= 4 ) + Area += 1; + else if ( nFanins <= 6 ) + Area += 2; + else if ( nFanins <= 8 ) + Area += 4; + else if ( nFanins <= 16 ) + Area += 8; + else if ( nFanins <= 32 ) + Area += 16; + else if ( nFanins <= 64 ) + Area += 32; + else if ( nFanins <= 128 ) + Area += 64; + else + assert( 0 ); + } + Ivy_ManForEachPo( p, pObj, i ) + { + Fanin = Ivy_ObjReadFanin(pObj, 0); + pFanin = Ivy_ManObj( p, Ivy_EdgeId(Fanin) ); + pObj->Level = pFanin->Level; + Delay = IVY_MAX( Delay, (int)pObj->Level ); + } + printf( "Area = %d. Delay = %d.\n", Area, Delay ); +} + +#endif + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + |