diff options
author | Alan Mishchenko <alanmi@berkeley.edu> | 2010-11-01 01:35:04 -0700 |
---|---|---|
committer | Alan Mishchenko <alanmi@berkeley.edu> | 2010-11-01 01:35:04 -0700 |
commit | 6130e39b18b5f53902e4eab14f6d5cdde5219563 (patch) | |
tree | 0db0628479a1b750e9af1f66cb8379ebd0913d31 /src/base/abci/abcDress2.c | |
parent | f0e77f6797c0504b0da25a56152b707d3357f386 (diff) | |
download | abc-6130e39b18b5f53902e4eab14f6d5cdde5219563.tar.gz abc-6130e39b18b5f53902e4eab14f6d5cdde5219563.tar.bz2 abc-6130e39b18b5f53902e4eab14f6d5cdde5219563.zip |
initial commit of public abc
Diffstat (limited to 'src/base/abci/abcDress2.c')
-rw-r--r-- | src/base/abci/abcDress2.c | 435 |
1 files changed, 435 insertions, 0 deletions
diff --git a/src/base/abci/abcDress2.c b/src/base/abci/abcDress2.c new file mode 100644 index 00000000..039a4fed --- /dev/null +++ b/src/base/abci/abcDress2.c @@ -0,0 +1,435 @@ +/**CFile**************************************************************** + + FileName [abcDressw.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Network and node package.] + + Synopsis [Transfers names from one netlist to the other.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: abcDressw.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abc.h" +#include "aig.h" +#include "dch.h" + +ABC_NAMESPACE_IMPL_START + + +/* + Procedure Abc_NtkDressComputeEquivs() implemented in this file computes + equivalence classes of objects of the two networks (pNtk1 and pNtk2). + + It is possible that pNtk1 is the network before synthesis and pNtk2 is the + network after synthesis. The equiv classes of nodes from these networks + can be used to transfer the names from pNtk1 to pNtk2, or vice versa. + + The above procedure returns the array (Vec_Ptr_t) of integer arrays (Vec_Int_t). + Each of the integer arrays contains entries of one equivalence class. + Each entry (EquivId) contains the following information: + (1) object ID, which is a number 'num', such that 0 <= 'num' < MaxId + where MaxId is the largest ID of nodes in a network + (2) the polarity of the node, which is a binary number, 0 or 1, giving + the node's value when pattern (000...0) is applied to the inputs + (3) the number of the network, 0 or 1, which stands for pNtk1 and pNtk2, respectively + The first array in the array of arrays is empty, or contains nodes that + are equivalent to a constant (if such nodes appear in the network). + + Given EquivID defined above, use the APIs below to get its components. +*/ + +// declarations to be added to the application code +extern int Abc_ObjEquivId2ObjId( int EquivId ); +extern int Abc_ObjEquivId2Polar( int EquivId ); +extern int Abc_ObjEquivId2NtkId( int EquivId ); + +// definition that may remain in this file +int Abc_ObjEquivId2ObjId( int EquivId ) { return EquivId >> 2; } +int Abc_ObjEquivId2Polar( int EquivId ) { return (EquivId >> 1) & 1; } +int Abc_ObjEquivId2NtkId( int EquivId ) { return EquivId & 1; } + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +extern Aig_Man_t * Abc_NtkToDar( Abc_Ntk_t * pNtk, int fExors, int fRegisters ); +extern void Dch_ComputeEquivalences( Aig_Man_t * pAig, Dch_Pars_t * pPars ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Creates the dual output miter.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Man_t * Aig_ManCreateDualOutputMiter( Aig_Man_t * p1, Aig_Man_t * p2 ) +{ + Aig_Man_t * pNew; + Aig_Obj_t * pObj; + int i; + assert( Aig_ManPiNum(p1) == Aig_ManPiNum(p2) ); + assert( Aig_ManPoNum(p1) == Aig_ManPoNum(p2) ); + pNew = Aig_ManStart( Aig_ManObjNumMax(p1) + Aig_ManObjNumMax(p2) ); + // add first AIG + Aig_ManConst1(p1)->pData = Aig_ManConst1(pNew); + Aig_ManForEachPi( p1, pObj, i ) + pObj->pData = Aig_ObjCreatePi( pNew ); + Aig_ManForEachNode( p1, pObj, i ) + pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); + // add second AIG + Aig_ManConst1(p2)->pData = Aig_ManConst1(pNew); + Aig_ManForEachPi( p2, pObj, i ) + pObj->pData = Aig_ManPi( pNew, i ); + Aig_ManForEachNode( p2, pObj, i ) + pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); + // add the outputs + for ( i = 0; i < Aig_ManPoNum(p1); i++ ) + { + Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(Aig_ManPo(p1, i)) ); + Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(Aig_ManPo(p2, i)) ); + } + Aig_ManCleanup( pNew ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Sets polarity attribute of each object in the network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkDressMapSetPolarity( Abc_Ntk_t * pNtk ) +{ + Abc_Obj_t * pObj, * pAnd; + int i; + // each node refers to the the strash copy whose polarity is set + Abc_NtkForEachObj( pNtk, pObj, i ) + { + if ( (pAnd = Abc_ObjRegular(pObj->pCopy)) && Abc_ObjType(pAnd) != ABC_OBJ_NONE ) // strashed object is present and legal + pObj->fPhase = pAnd->fPhase ^ Abc_ObjIsComplement(pObj->pCopy); + } +} + +/**Function************************************************************* + + Synopsis [Create mapping of node IDs of pNtk into equiv classes of pMiter.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Abc_NtkDressMapClasses( Aig_Man_t * pMiter, Abc_Ntk_t * pNtk ) +{ + Vec_Int_t * vId2Lit; + Abc_Obj_t * pObj, * pAnd; + Aig_Obj_t * pObjMan, * pObjMiter, * pObjRepr; + int i; + vId2Lit = Vec_IntAlloc( 0 ); + Vec_IntFill( vId2Lit, Abc_NtkObjNumMax(pNtk), -1 ); + Abc_NtkForEachNode( pNtk, pObj, i ) + { + // get the pointer to the miter node corresponding to pObj + if ( (pAnd = Abc_ObjRegular(pObj->pCopy)) && Abc_ObjType(pAnd) != ABC_OBJ_NONE && // strashed node is present and legal + (pObjMan = Aig_Regular((Aig_Obj_t *)pAnd->pCopy)) && Aig_ObjType(pObjMan) != AIG_OBJ_NONE && // AIG node is present and legal + (pObjMiter = Aig_Regular((Aig_Obj_t *)pObjMan->pData)) && Aig_ObjType(pObjMiter) != AIG_OBJ_NONE ) // miter node is present and legal + { + // get the representative of the miter node + pObjRepr = Aig_ObjRepr( pMiter, pObjMiter ); + pObjRepr = pObjRepr? pObjRepr : pObjMiter; + // map pObj (whose ID is i) into the repr node ID (i.e. equiv class) + Vec_IntWriteEntry( vId2Lit, i, Aig_ObjId(pObjRepr) ); + } + } + return vId2Lit; +} + +/**Function************************************************************* + + Synopsis [Returns the vector of given equivalence class of objects.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Abc_ObjDressClass( Vec_Ptr_t * vRes, Vec_Int_t * vClass2Num, int Class ) +{ + int ClassNumber; + assert( Class > 0 ); + ClassNumber = Vec_IntEntry( vClass2Num, Class ); + assert( ClassNumber != 0 ); + if ( ClassNumber > 0 ) + return (Vec_Int_t *)Vec_PtrEntry( vRes, ClassNumber ); // previous class + // create new class + Vec_IntWriteEntry( vClass2Num, Class, Vec_PtrSize(vRes) ); + Vec_PtrPush( vRes, Vec_IntAlloc(4) ); + return (Vec_Int_t *)Vec_PtrEntryLast( vRes ); +} + +/**Function************************************************************* + + Synopsis [Returns the ID of a node in an equivalence class.] + + Description [The ID is composed of three parts: object ID, followed + by one bit telling the phase of this node, followed by one bit + telling the network to which this node belongs.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_ObjDressMakeId( Abc_Ntk_t * pNtk, int ObjId, int iNtk ) +{ + return (ObjId << 2) | (Abc_NtkObj(pNtk,ObjId)->fPhase << 1) | iNtk; +} + +/**Function************************************************************* + + Synopsis [Computes equivalence classes of objects in pNtk1 and pNtk2.] + + Description [Internal procedure.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Abc_NtkDressMapIds( Aig_Man_t * pMiter, Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2 ) +{ + Vec_Ptr_t * vRes; + Vec_Int_t * vId2Lit1, * vId2Lit2, * vCounts0, * vCounts1, * vClassC, * vClass2Num; + int i, Class; + // start the classes + vRes = Vec_PtrAlloc( 1000 ); + // set polarity of the nodes + Abc_NtkDressMapSetPolarity( pNtk1 ); + Abc_NtkDressMapSetPolarity( pNtk2 ); + // create mapping of node IDs of pNtk1/pNtk2 into the IDs of equiv classes of pMiter + vId2Lit1 = Abc_NtkDressMapClasses( pMiter, pNtk1 ); + vId2Lit2 = Abc_NtkDressMapClasses( pMiter, pNtk2 ); + // count the number of nodes in each equivalence class + vCounts0 = Vec_IntStart( Aig_ManObjNumMax(pMiter) ); + Vec_IntForEachEntry( vId2Lit1, Class, i ) + if ( Class >= 0 ) + Vec_IntAddToEntry( vCounts0, Class, 1 ); + vCounts1 = Vec_IntStart( Aig_ManObjNumMax(pMiter) ); + Vec_IntForEachEntry( vId2Lit2, Class, i ) + if ( Class >= 0 ) + Vec_IntAddToEntry( vCounts1, Class, 1 ); + // get the costant class + vClassC = Vec_IntAlloc( 100 ); + Vec_IntForEachEntry( vId2Lit1, Class, i ) + if ( Class == 0 ) + Vec_IntPush( vClassC, Abc_ObjDressMakeId(pNtk1, i, 0) ); + Vec_IntForEachEntry( vId2Lit2, Class, i ) + if ( Class == 0 ) + Vec_IntPush( vClassC, Abc_ObjDressMakeId(pNtk2, i, 1) ); + Vec_PtrPush( vRes, vClassC ); + // map repr node IDs into class numbers + vClass2Num = Vec_IntAlloc( 0 ); + Vec_IntFill( vClass2Num, Aig_ManObjNumMax(pMiter), -1 ); + // keep classes having at least one element from pNtk1 and one from pNtk2 + Vec_IntForEachEntry( vId2Lit1, Class, i ) + if ( Class > 0 && Vec_IntEntry(vCounts0, Class) && Vec_IntEntry(vCounts1, Class) ) + Vec_IntPush( Abc_ObjDressClass(vRes, vClass2Num, Class), Abc_ObjDressMakeId(pNtk1, i, 0) ); + Vec_IntForEachEntry( vId2Lit2, Class, i ) + if ( Class > 0 && Vec_IntEntry(vCounts0, Class) && Vec_IntEntry(vCounts1, Class) ) + Vec_IntPush( Abc_ObjDressClass(vRes, vClass2Num, Class), Abc_ObjDressMakeId(pNtk2, i, 1) ); + // package them accordingly + Vec_IntFree( vClass2Num ); + Vec_IntFree( vCounts0 ); + Vec_IntFree( vCounts1 ); + Vec_IntFree( vId2Lit1 ); + Vec_IntFree( vId2Lit2 ); + return vRes; +} + +/**Function************************************************************* + + Synopsis [Computes equivalence classes of objects in pNtk1 and pNtk2.] + + Description [Returns the array (Vec_Ptr_t) of integer arrays (Vec_Int_t). + Each of the integer arrays contains entries of one equivalence class. + Each entry contains the following information: the network number (0/1), + the polarity (0/1) and the object ID in the the network (0 <= num < MaxId) + where MaxId is the largest number of an ID of an object in that network.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Abc_NtkDressComputeEquivs( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nConflictLimit, int fVerbose ) +{ + Dch_Pars_t Pars, * pPars = &Pars; + Abc_Ntk_t * pAig1, * pAig2; + Aig_Man_t * pMan1, * pMan2, * pMiter; + Vec_Ptr_t * vRes; + assert( !Abc_NtkIsStrash(pNtk1) ); + assert( !Abc_NtkIsStrash(pNtk2) ); + // convert network into AIG + pAig1 = Abc_NtkStrash( pNtk1, 1, 1, 0 ); + pAig2 = Abc_NtkStrash( pNtk2, 1, 1, 0 ); + pMan1 = Abc_NtkToDar( pAig1, 0, 0 ); + pMan2 = Abc_NtkToDar( pAig2, 0, 0 ); + // derive the miter + pMiter = Aig_ManCreateDualOutputMiter( pMan1, pMan2 ); + // set up parameters for SAT sweeping + Dch_ManSetDefaultParams( pPars ); + pPars->nBTLimit = nConflictLimit; + pPars->fVerbose = fVerbose; + // perform SAT sweeping + Dch_ComputeEquivalences( pMiter, pPars ); + // now, pMiter is annotated with the equivl class info + // convert this info into the resulting array + vRes = Abc_NtkDressMapIds( pMiter, pNtk1, pNtk2 ); + Aig_ManStop( pMiter ); + Aig_ManStop( pMan1 ); + Aig_ManStop( pMan2 ); + Abc_NtkDelete( pAig1 ); + Abc_NtkDelete( pAig2 ); + return vRes; +} + +/**Function************************************************************* + + Synopsis [Prints information about node equivalences.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkDressPrintEquivs( Vec_Ptr_t * vRes ) +{ + Vec_Int_t * vClass; + int i, k, Entry; + Vec_PtrForEachEntry( Vec_Int_t *, vRes, vClass, i ) + { + printf( "Class %5d : ", i ); + printf( "Num =%5d ", Vec_IntSize(vClass) ); + Vec_IntForEachEntry( vClass, Entry, k ) + printf( "%5d%c%d ", + Abc_ObjEquivId2ObjId(Entry), + Abc_ObjEquivId2Polar(Entry)? '-':'+', + Abc_ObjEquivId2NtkId(Entry) ); + printf( "\n" ); + } +} + +/**Function************************************************************* + + Synopsis [Prints information about node equivalences.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkDressPrintStats( Vec_Ptr_t * vRes, int nNodes0, int nNodes1, int Time ) +{ + Vec_Int_t * vClass; + int i, k, Entry; + int NegAll[2] = {0}, PosAll[2] = {0}, PairsAll = 0, PairsOne = 0; + int Pos[2], Neg[2]; + // count the number of equivalences in each class + Vec_PtrForEachEntry( Vec_Int_t *, vRes, vClass, i ) + { + Pos[0] = Pos[1] = 0; + Neg[0] = Neg[1] = 0; + Vec_IntForEachEntry( vClass, Entry, k ) + { + if ( Abc_ObjEquivId2NtkId(Entry) ) + { + if ( Abc_ObjEquivId2Polar(Entry) ) + Neg[1]++; // negative polarity in network 1 + else + Pos[1]++; // positive polarity in network 1 + } + else + { + if ( Abc_ObjEquivId2Polar(Entry) ) + Neg[0]++; // negative polarity in network 0 + else + Pos[0]++; // positive polarity in network 0 + } + } + PosAll[0] += Pos[0]; // total positive polarity in network 0 + PosAll[1] += Pos[1]; // total positive polarity in network 1 + NegAll[0] += Neg[0]; // total negative polarity in network 0 + NegAll[1] += Neg[1]; // total negative polarity in network 1 + + // assuming that the name can be transferred to only one node + PairsAll += ABC_MIN(Neg[0] + Pos[0], Neg[1] + Pos[1]); + PairsOne += ABC_MIN(Neg[0], Neg[1]) + ABC_MIN(Pos[0], Pos[1]); + } + printf( "Total number of equiv classes = %7d.\n", Vec_PtrSize(vRes) ); + printf( "Participating nodes from both networks = %7d.\n", NegAll[0]+PosAll[0]+NegAll[1]+PosAll[1] ); + printf( "Participating nodes from the first network = %7d. (%7.2f %% of nodes)\n", NegAll[0]+PosAll[0], 100.0*(NegAll[0]+PosAll[0])/(nNodes0+1) ); + printf( "Participating nodes from the second network = %7d. (%7.2f %% of nodes)\n", NegAll[1]+PosAll[1], 100.0*(NegAll[1]+PosAll[1])/(nNodes1+1) ); + printf( "Node pairs (any polarity) = %7d. (%7.2f %% of names can be moved)\n", PairsAll, 100.0*PairsAll/(nNodes0+1) ); + printf( "Node pairs (same polarity) = %7d. (%7.2f %% of names can be moved)\n", PairsOne, 100.0*PairsOne/(nNodes0+1) ); + ABC_PRT( "Total runtime", Time ); +} + +/**Function************************************************************* + + Synopsis [Transfers names from pNtk1 to pNtk2.] + + Description [Internally calls new procedure for mapping node IDs of + both networks into the shared equivalence classes.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkDress2( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nConflictLimit, int fVerbose ) +{ + Vec_Ptr_t * vRes; + int clk = clock(); + vRes = Abc_NtkDressComputeEquivs( pNtk1, pNtk2, nConflictLimit, fVerbose ); +// Abc_NtkDressPrintEquivs( vRes ); + Abc_NtkDressPrintStats( vRes, Abc_NtkNodeNum(pNtk1), Abc_NtkNodeNum(pNtk1), clock() - clk ); + Vec_VecFree( (Vec_Vec_t *)vRes ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + |