diff options
author | Alan Mishchenko <alanmi@berkeley.edu> | 2009-01-18 08:01:00 -0800 |
---|---|---|
committer | Alan Mishchenko <alanmi@berkeley.edu> | 2009-01-18 08:01:00 -0800 |
commit | f936cc0680c98ffe51b3a1716c996072d5dbf76c (patch) | |
tree | 784a2a809fb6b972ec6a8e2758ab758ca590d01a /src/aig/saig/saigStrSim.c | |
parent | c9ad5880cc61787dec6d018111b63023407ce0e6 (diff) | |
download | abc-f936cc0680c98ffe51b3a1716c996072d5dbf76c.tar.gz abc-f936cc0680c98ffe51b3a1716c996072d5dbf76c.tar.bz2 abc-f936cc0680c98ffe51b3a1716c996072d5dbf76c.zip |
Version abc90118
Diffstat (limited to 'src/aig/saig/saigStrSim.c')
-rw-r--r-- | src/aig/saig/saigStrSim.c | 971 |
1 files changed, 971 insertions, 0 deletions
diff --git a/src/aig/saig/saigStrSim.c b/src/aig/saig/saigStrSim.c new file mode 100644 index 00000000..ce4b8e05 --- /dev/null +++ b/src/aig/saig/saigStrSim.c @@ -0,0 +1,971 @@ +/**CFile**************************************************************** + + FileName [saigStrSim.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Sequential AIG package.] + + Synopsis [Structural matching using simulation.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: saigStrSim.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "saig.h" +#include "ssw.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +#define SAIG_WORDS 16 + +static inline Aig_Obj_t * Saig_ObjNext( Aig_Obj_t ** ppNexts, Aig_Obj_t * pObj ) { return ppNexts[pObj->Id]; } +static inline void Saig_ObjSetNext( Aig_Obj_t ** ppNexts, Aig_Obj_t * pObj, Aig_Obj_t * pNext ) { ppNexts[pObj->Id] = pNext; } + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Computes hash value of the node using its simulation info.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned Saig_StrSimHash( Aig_Obj_t * pObj ) +{ + static int s_SPrimes[128] = { + 1009, 1049, 1093, 1151, 1201, 1249, 1297, 1361, 1427, 1459, + 1499, 1559, 1607, 1657, 1709, 1759, 1823, 1877, 1933, 1997, + 2039, 2089, 2141, 2213, 2269, 2311, 2371, 2411, 2467, 2543, + 2609, 2663, 2699, 2741, 2797, 2851, 2909, 2969, 3037, 3089, + 3169, 3221, 3299, 3331, 3389, 3461, 3517, 3557, 3613, 3671, + 3719, 3779, 3847, 3907, 3943, 4013, 4073, 4129, 4201, 4243, + 4289, 4363, 4441, 4493, 4549, 4621, 4663, 4729, 4793, 4871, + 4933, 4973, 5021, 5087, 5153, 5227, 5281, 5351, 5417, 5471, + 5519, 5573, 5651, 5693, 5749, 5821, 5861, 5923, 6011, 6073, + 6131, 6199, 6257, 6301, 6353, 6397, 6481, 6563, 6619, 6689, + 6737, 6803, 6863, 6917, 6977, 7027, 7109, 7187, 7237, 7309, + 7393, 7477, 7523, 7561, 7607, 7681, 7727, 7817, 7877, 7933, + 8011, 8039, 8059, 8081, 8093, 8111, 8123, 8147 + }; + unsigned * pSims; + unsigned uHash = 0; + int i; + assert( SAIG_WORDS <= 128 ); + pSims = pObj->pData; + for ( i = 0; i < SAIG_WORDS; i++ ) + uHash ^= pSims[i] * s_SPrimes[i & 0x7F]; + return uHash; +} + +/**Function************************************************************* + + Synopsis [Computes hash value of the node using its simulation info.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Saig_StrSimIsEqual( Aig_Obj_t * pObj0, Aig_Obj_t * pObj1 ) +{ + unsigned * pSims0 = pObj0->pData; + unsigned * pSims1 = pObj1->pData; + int i; + for ( i = 0; i < SAIG_WORDS; i++ ) + if ( pSims0[i] != pSims1[i] ) + return 0; + return 1; +} + +/**Function************************************************************* + + Synopsis [Returns 1 if simulation info is zero.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Saig_StrSimIsZero( Aig_Obj_t * pObj ) +{ + unsigned * pSims = pObj->pData; + int i; + for ( i = 0; i < SAIG_WORDS; i++ ) + if ( pSims[i] != 0 ) + return 0; + return 1; +} + +/**Function************************************************************* + + Synopsis [Returns 1 if simulation info is one.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Saig_StrSimIsOne( Aig_Obj_t * pObj ) +{ + unsigned * pSims = pObj->pData; + int i; + for ( i = 0; i < SAIG_WORDS; i++ ) + if ( pSims[i] != ~0 ) + return 0; + return 1; +} + +/**Function************************************************************* + + Synopsis [Assigns random simulation info.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_StrSimAssignRandom( Aig_Obj_t * pObj ) +{ + unsigned * pSims = pObj->pData; + int i; + for ( i = 0; i < SAIG_WORDS; i++ ) + pSims[i] = Aig_ManRandom(0); +} + +/**Function************************************************************* + + Synopsis [Assigns constant 0 simulation info.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_StrSimAssignOne( Aig_Obj_t * pObj ) +{ + unsigned * pSims = pObj->pData; + int i; + for ( i = 0; i < SAIG_WORDS; i++ ) + pSims[i] = ~0; +} + +/**Function************************************************************* + + Synopsis [Assigns constant 0 simulation info.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_StrSimAssignZeroInit( Aig_Obj_t * pObj ) +{ + unsigned * pSims = pObj->pData; + pSims[0] = 0; +} + +/**Function************************************************************* + + Synopsis [Simulated one node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_StrSimulateNode( Aig_Obj_t * pObj, int i ) +{ + unsigned * pSims = pObj->pData; + unsigned * pSims0 = Aig_ObjFanin0(pObj)->pData; + unsigned * pSims1 = Aig_ObjFanin1(pObj)->pData; + if ( Aig_ObjFaninC0(pObj) && Aig_ObjFaninC1(pObj) ) + pSims[i] = ~(pSims0[i] | pSims1[i]); + else if ( Aig_ObjFaninC0(pObj) && !Aig_ObjFaninC1(pObj) ) + pSims[i] = (~pSims0[i] & pSims1[i]); + else if ( !Aig_ObjFaninC0(pObj) && Aig_ObjFaninC1(pObj) ) + pSims[i] = (pSims0[i] & ~pSims1[i]); + else // if ( !Aig_ObjFaninC0(pObj) && !Aig_ObjFaninC1(pObj) ) + pSims[i] = (pSims0[i] & pSims1[i]); +} + +/**Function************************************************************* + + Synopsis [Saves output of one node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_StrSimSaveOutput( Aig_Obj_t * pObj, int i ) +{ + unsigned * pSims = pObj->pData; + unsigned * pSims0 = Aig_ObjFanin0(pObj)->pData; + if ( Aig_ObjFaninC0(pObj) ) + pSims[i] = ~pSims0[i]; + else + pSims[i] = pSims0[i]; +} + +/**Function************************************************************* + + Synopsis [Transfers simulation output to another node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_StrSimTransfer( Aig_Obj_t * pObj0, Aig_Obj_t * pObj1 ) +{ + unsigned * pSims0 = pObj0->pData; + unsigned * pSims1 = pObj1->pData; + int i; + for ( i = 0; i < SAIG_WORDS; i++ ) + pSims1[i] = pSims0[i]; +} + +/**Function************************************************************* + + Synopsis [Transfers simulation output to another node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_StrSimTransferNext( Aig_Obj_t * pObj0, Aig_Obj_t * pObj1, int i ) +{ + unsigned * pSims0 = pObj0->pData; + unsigned * pSims1 = pObj1->pData; + assert( i < SAIG_WORDS - 1 ); + pSims1[i+1] = pSims0[i]; +} + +/**Function************************************************************* + + Synopsis [Perform one round of simulation.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_StrSimulateRound( Aig_Man_t * p0, Aig_Man_t * p1 ) +{ + Aig_Obj_t * pObj0, * pObj1; + int f, i; + // simulate the nodes + Aig_ManForEachObj( p0, pObj0, i ) + { + if ( !Aig_ObjIsPi(pObj0) && !Aig_ObjIsNode(pObj0) ) + continue; + pObj1 = Aig_ObjRepr(p0, pObj0); + if ( pObj1 == NULL ) + continue; + assert( Aig_ObjRepr(p1, pObj1) == pObj0 ); + Saig_StrSimAssignRandom( pObj0 ); + Saig_StrSimTransfer( pObj0, pObj1 ); + } + // simulate the timeframes + for ( f = 0; f < SAIG_WORDS; f++ ) + { + // simulate the first AIG + Aig_ManForEachNode( p0, pObj0, i ) + if ( Aig_ObjRepr(p0, pObj0) == NULL ) + Saig_StrSimulateNode( pObj0, f ); + Saig_ManForEachLi( p0, pObj0, i ) + Saig_StrSimSaveOutput( pObj0, f ); + if ( f < SAIG_WORDS - 1 ) + Saig_ManForEachLiLo( p0, pObj0, pObj1, i ) + Saig_StrSimTransferNext( pObj0, pObj1, f ); + // simulate the second AIG + Aig_ManForEachNode( p1, pObj1, i ) + if ( Aig_ObjRepr(p1, pObj1) == NULL ) + Saig_StrSimulateNode( pObj1, f ); + Saig_ManForEachLi( p1, pObj1, i ) + Saig_StrSimSaveOutput( pObj1, f ); + if ( f < SAIG_WORDS - 1 ) + Saig_ManForEachLiLo( p1, pObj1, pObj0, i ) + Saig_StrSimTransferNext( pObj1, pObj0, f ); + } +} + +/**Function************************************************************* + + Synopsis [Checks if the entry exists in the table.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Obj_t * Saig_StrSimTableLookup( Aig_Obj_t ** ppTable, Aig_Obj_t ** ppNexts, int nTableSize, Aig_Obj_t * pObj ) +{ + Aig_Obj_t * pEntry; + int iEntry; + // find the hash entry + iEntry = Saig_StrSimHash( pObj ) % nTableSize; + // check if there are nodes with this signatures + for ( pEntry = ppTable[iEntry]; pEntry; pEntry = Saig_ObjNext(ppNexts,pEntry) ) + if ( Saig_StrSimIsEqual( pEntry, pObj ) ) + return pEntry; + return NULL; +} + +/**Function************************************************************* + + Synopsis [Inserts the entry into the table.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_StrSimTableInsert( Aig_Obj_t ** ppTable, Aig_Obj_t ** ppNexts, int nTableSize, Aig_Obj_t * pObj ) +{ + // find the hash entry + int iEntry = Saig_StrSimHash( pObj ) % nTableSize; + // check if there are nodes with this signatures + if ( ppTable[iEntry] == NULL ) + ppTable[iEntry] = pObj; + else + { + Saig_ObjSetNext( ppNexts, pObj, Saig_ObjNext(ppNexts, ppTable[iEntry]) ); + Saig_ObjSetNext( ppNexts, ppTable[iEntry], pObj ); + } +} + +/**Function************************************************************* + + Synopsis [Perform one round of matching.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Saig_StrSimDetectUnique( Aig_Man_t * p0, Aig_Man_t * p1 ) +{ + Aig_Obj_t ** ppTable, ** ppNexts, ** ppCands; + Aig_Obj_t * pObj, * pEntry; + int i, nTableSize, Counter; + + // allocate the hash table hashing simulation info into nodes + nTableSize = Aig_PrimeCudd( Aig_ManObjNum(p0)/2 ); + ppTable = CALLOC( Aig_Obj_t *, nTableSize ); + ppNexts = CALLOC( Aig_Obj_t *, Aig_ManObjNumMax(p0) ); + ppCands = CALLOC( Aig_Obj_t *, Aig_ManObjNumMax(p0) ); + + // hash nodes of the first AIG + Aig_ManForEachObj( p0, pObj, i ) + { + if ( !Aig_ObjIsPi(pObj) && !Aig_ObjIsNode(pObj) ) + continue; + if ( Aig_ObjRepr(p0, pObj) ) + continue; + if ( Saig_StrSimIsZero(pObj) || Saig_StrSimIsOne(pObj) ) + continue; + // check if the entry exists + pEntry = Saig_StrSimTableLookup( ppTable, ppNexts, nTableSize, pObj ); + if ( pEntry == NULL ) // insert + Saig_StrSimTableInsert( ppTable, ppNexts, nTableSize, pObj ); + else // mark the entry as not unique + pEntry->fMarkA = 1; + } + + // hash nodes from the second AIG + Aig_ManForEachObj( p1, pObj, i ) + { + if ( !Aig_ObjIsPi(pObj) && !Aig_ObjIsNode(pObj) ) + continue; + if ( Aig_ObjRepr(p1, pObj) ) + continue; + if ( Saig_StrSimIsZero(pObj) || Saig_StrSimIsOne(pObj) ) + continue; + // check if the entry exists + pEntry = Saig_StrSimTableLookup( ppTable, ppNexts, nTableSize, pObj ); + if ( pEntry == NULL ) // skip + continue; + // if there is no candidate, label it + if ( Saig_ObjNext( ppCands, pEntry ) == NULL ) + Saig_ObjSetNext( ppCands, pEntry, pObj ); + else // mark the entry as not unique + pEntry->fMarkA = 1; + } + + // create representatives for the unique entries + Counter = 0; + for ( i = 0; i < nTableSize; i++ ) + for ( pEntry = ppTable[i]; pEntry; pEntry = Saig_ObjNext(ppNexts,pEntry) ) + if ( !pEntry->fMarkA && (pObj = Saig_ObjNext( ppCands, pEntry )) ) + { +// assert( Aig_ObjIsNode(pEntry) == Aig_ObjIsNode(pObj) ); + if ( Aig_ObjType(pEntry) != Aig_ObjType(pObj) ) + continue; + Aig_ObjSetRepr( p0, pEntry, pObj ); + Aig_ObjSetRepr( p1, pObj, pEntry ); + Counter++; + } + + // cleanup + Aig_ManCleanMarkA( p0 ); + free( ppTable ); + free( ppNexts ); + free( ppCands ); + return Counter; +} + +/**Function************************************************************* + + Synopsis [Counts the number of matched flops.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Saig_StrSimCountMatchedFlops( Aig_Man_t * p ) +{ + Aig_Obj_t * pObj; + int i, Counter = 0; + Saig_ManForEachLo( p, pObj, i ) + if ( Aig_ObjRepr(p, pObj) ) + Counter++; + return Counter; +} + +/**Function************************************************************* + + Synopsis [Counts the number of matched nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Saig_StrSimCountMatchedNodes( Aig_Man_t * p ) +{ + Aig_Obj_t * pObj; + int i, Counter = 0; + Aig_ManForEachNode( p, pObj, i ) + if ( Aig_ObjRepr(p, pObj) ) + Counter++; + return Counter; +} + +/**Function************************************************************* + + Synopsis [Performs structural matching of two AIGs using simulation.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_StrSimPrepareAig( Aig_Man_t * p ) +{ + Aig_Obj_t * pObj; + int i; + Aig_ManReprStart( p, Aig_ManObjNumMax(p) ); + // allocate simulation info + p->pData2 = Vec_PtrAllocSimInfo( Aig_ManObjNumMax(p), SAIG_WORDS ); + Aig_ManForEachObj( p, pObj, i ) + pObj->pData = Vec_PtrEntry( p->pData2, i ); + // set simulation info for constant1 and register outputs + Saig_StrSimAssignOne( Aig_ManConst1(p) ); + Saig_ManForEachLo( p, pObj, i ) + Saig_StrSimAssignZeroInit( pObj ); +} + +/**Function************************************************************* + + Synopsis [Performs structural matching of two AIGs using simulation.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_StrSimSetInitMatching( Aig_Man_t * p0, Aig_Man_t * p1 ) +{ + Aig_Obj_t * pObj0, * pObj1; + int i; + pObj0 = Aig_ManConst1( p0 ); + pObj1 = Aig_ManConst1( p1 ); + Aig_ObjSetRepr( p0, pObj0, pObj1 ); + Aig_ObjSetRepr( p1, pObj1, pObj0 ); + Saig_ManForEachPi( p0, pObj0, i ) + { + pObj1 = Aig_ManPi( p1, i ); + Aig_ObjSetRepr( p0, pObj0, pObj1 ); + Aig_ObjSetRepr( p1, pObj1, pObj0 ); + } +} + +/**Function************************************************************* + + Synopsis [Performs structural matching of two AIGs using simulation.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_StrSimSetFinalMatching( Aig_Man_t * p0, Aig_Man_t * p1 ) +{ + Aig_Obj_t * pObj0, * pObj1; + Aig_Obj_t * pFanin00, * pFanin01; + Aig_Obj_t * pFanin10, * pFanin11; + int i, CountAll = 0, CountNot = 0; + Aig_ManIncrementTravId( p0 ); + Aig_ManForEachObj( p0, pObj0, i ) + { + pObj1 = Aig_ObjRepr( p0, pObj0 ); + if ( pObj1 == NULL ) + continue; + CountAll++; + assert( pObj0 == Aig_ObjRepr( p1, pObj1 ) ); + if ( Aig_ObjIsNode(pObj0) ) + { + assert( Aig_ObjIsNode(pObj1) ); + pFanin00 = Aig_ObjFanin0(pObj0); + pFanin01 = Aig_ObjFanin1(pObj0); + pFanin10 = Aig_ObjFanin0(pObj1); + pFanin11 = Aig_ObjFanin1(pObj1); + if ( Aig_ObjRepr(p0, pFanin00) != pFanin10 || + Aig_ObjRepr(p0, pFanin01) != pFanin11 ) + { + Aig_ObjSetTravIdCurrent(p0, pObj0); + CountNot++; + } + } + else if ( Saig_ObjIsLo(p0, pObj0) ) + { + assert( Saig_ObjIsLo(p1, pObj1) ); + pFanin00 = Aig_ObjFanin0( Saig_ObjLoToLi(p0, pObj0) ); + pFanin10 = Aig_ObjFanin0( Saig_ObjLoToLi(p1, pObj1) ); + if ( Aig_ObjRepr(p0, pFanin00) != pFanin10 ) + { + Aig_ObjSetTravIdCurrent(p0, pObj0); + CountNot++; + } + } + } + // remove irrelevant matches + Aig_ManForEachObj( p0, pObj0, i ) + { + pObj1 = Aig_ObjRepr( p0, pObj0 ); + if ( pObj1 == NULL ) + continue; + assert( pObj0 == Aig_ObjRepr( p1, pObj1 ) ); + if ( Aig_ObjIsTravIdCurrent( p0, pObj0 ) ) + { + Aig_ObjSetRepr( p0, pObj0, NULL ); + Aig_ObjSetRepr( p1, pObj1, NULL ); + } + } + printf( "Total matches = %6d. Wrong matches = %6d. Ratio = %5.2f %%\n", + CountAll, CountNot, 100.0*CountNot/CountAll ); +} + +/**Function************************************************************* + + Synopsis [Returns the number of dangling nodes removed.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_StrSimSetContiguousMatching_rec( Aig_Man_t * p, Aig_Obj_t * pObj ) +{ + Aig_Obj_t * pFanout; + int i, iFanout = -1; + if ( Aig_ObjIsTravIdCurrent(p, pObj) ) + return; + Aig_ObjSetTravIdCurrent(p, pObj); + if ( Saig_ObjIsPo( p, pObj ) ) + return; + if ( Saig_ObjIsLi( p, pObj ) ) + { + Saig_StrSimSetContiguousMatching_rec( p, Saig_ObjLiToLo(p, pObj) ); + return; + } + assert( Aig_ObjIsPi(pObj) || Aig_ObjIsNode(pObj) ); + if ( Aig_ObjRepr(p, pObj) == NULL ) + return; + // go through the fanouts + Aig_ObjForEachFanout( p, pObj, pFanout, iFanout, i ) + Saig_StrSimSetContiguousMatching_rec( p, pFanout ); + // go through the fanins + if ( !Aig_ObjIsPi( pObj ) ) + { + Saig_StrSimSetContiguousMatching_rec( p, Aig_ObjFanin0(pObj) ); + Saig_StrSimSetContiguousMatching_rec( p, Aig_ObjFanin1(pObj) ); + } +} + +/**Function************************************************************* + + Synopsis [Performs structural matching of two AIGs using simulation.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_StrSimSetContiguousMatching( Aig_Man_t * p0, Aig_Man_t * p1 ) +{ + Aig_Obj_t * pObj0, * pObj1; + int i, CountAll = 0, CountNot = 0; + // mark nodes reachable through the PIs + Aig_ManIncrementTravId( p0 ); + Aig_ObjSetTravIdCurrent( p0, Aig_ManConst1(p0) ); + Saig_ManForEachPi( p0, pObj0, i ) + Saig_StrSimSetContiguousMatching_rec( p0, pObj0 ); + // remove irrelevant matches + Aig_ManForEachObj( p0, pObj0, i ) + { + pObj1 = Aig_ObjRepr( p0, pObj0 ); + if ( pObj1 == NULL ) + continue; + CountAll++; + assert( pObj0 == Aig_ObjRepr( p1, pObj1 ) ); + if ( !Aig_ObjIsTravIdCurrent( p0, pObj0 ) ) + { + Aig_ObjSetRepr( p0, pObj0, NULL ); + Aig_ObjSetRepr( p1, pObj1, NULL ); + CountNot++; + } + } + printf( "Total matches = %6d. Wrong matches = %6d. Ratio = %5.2f %%\n", + CountAll, CountNot, 100.0*CountNot/CountAll ); +} + + + +/**Function************************************************************* + + Synopsis [Establishes relationship between nodes using pairing.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ssw_StrSimMatchingExtendOne( Aig_Man_t * p, Vec_Ptr_t * vNodes ) +{ + Aig_Obj_t * pNext, * pObj; + int i, k, iFan; + Vec_PtrClear( vNodes ); + Aig_ManIncrementTravId( p ); + Aig_ManForEachObj( p, pObj, i ) + { + if ( !Aig_ObjIsNode(pObj) && !Aig_ObjIsPi(pObj) ) + continue; + if ( Aig_ObjRepr( p, pObj ) != NULL ) + continue; + if ( Saig_ObjIsLo(p, pObj) ) + { + pNext = Saig_ObjLoToLi(p, pObj); + pNext = Aig_ObjFanin0(pNext); + if ( Aig_ObjRepr( p, pNext ) && !Aig_ObjIsTravIdCurrent(p, pNext) && !Aig_ObjIsConst1(pNext) ) + { + Aig_ObjSetTravIdCurrent(p, pNext); + Vec_PtrPush( vNodes, pNext ); + } + } + if ( Aig_ObjIsNode(pObj) ) + { + pNext = Aig_ObjFanin0(pObj); + if ( Aig_ObjRepr( p, pNext )&& !Aig_ObjIsTravIdCurrent(p, pNext) ) + { + Aig_ObjSetTravIdCurrent(p, pNext); + Vec_PtrPush( vNodes, pNext ); + } + pNext = Aig_ObjFanin1(pObj); + if ( Aig_ObjRepr( p, pNext ) && !Aig_ObjIsTravIdCurrent(p, pNext) ) + { + Aig_ObjSetTravIdCurrent(p, pNext); + Vec_PtrPush( vNodes, pNext ); + } + } + Aig_ObjForEachFanout( p, pObj, pNext, iFan, k ) + { + if ( Saig_ObjIsPo(p, pNext) ) + continue; + if ( Saig_ObjIsLi(p, pNext) ) + pNext = Saig_ObjLiToLo(p, pNext); + if ( Aig_ObjRepr( p, pNext ) && !Aig_ObjIsTravIdCurrent(p, pNext) ) + { + Aig_ObjSetTravIdCurrent(p, pNext); + Vec_PtrPush( vNodes, pNext ); + } + } + } +} + +/**Function************************************************************* + + Synopsis [Establishes relationship between nodes using pairing.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Ssw_StrSimMatchingCountUnmached( Aig_Man_t * p ) +{ + Aig_Obj_t * pObj; + int i, Counter = 0; + Aig_ManForEachObj( p, pObj, i ) + { + if ( !Aig_ObjIsNode(pObj) && !Aig_ObjIsPi(pObj) ) + continue; + if ( Aig_ObjRepr( p, pObj ) != NULL ) + continue; + Counter++; + } + return Counter; +} + +/**Function************************************************************* + + Synopsis [Establishes relationship between nodes using pairing.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ssw_StrSimMatchingExtend( Aig_Man_t * p0, Aig_Man_t * p1, int nDist, int fVerbose ) +{ + Vec_Ptr_t * vNodes0, * vNodes1; + Aig_Obj_t * pNext0, * pNext1; + int d, k; + vNodes0 = Vec_PtrAlloc( 1000 ); + vNodes1 = Vec_PtrAlloc( 1000 ); + if ( fVerbose ) + { + int nUnmached = Ssw_StrSimMatchingCountUnmached(p0); + printf( "Extending islands by %d steps:\n", nDist ); + printf( "%2d : Total = %6d. Unmatched = %6d. Ratio = %6.2f %%\n", + 0, Aig_ManPiNum(p0) + Aig_ManNodeNum(p0), + nUnmached, 100.0 * nUnmached/(Aig_ManPiNum(p0) + Aig_ManNodeNum(p0)) ); + } + for ( d = 0; d < nDist; d++ ) + { + Ssw_StrSimMatchingExtendOne( p0, vNodes0 ); + Ssw_StrSimMatchingExtendOne( p1, vNodes1 ); + Vec_PtrForEachEntry( vNodes0, pNext0, k ) + { + pNext1 = Aig_ObjRepr( p0, pNext0 ); + if ( pNext1 == NULL ) + continue; + assert( pNext0 == Aig_ObjRepr( p1, pNext1 ) ); + if ( Saig_ObjIsPi(p1, pNext1) ) + continue; + Aig_ObjSetRepr( p0, pNext0, NULL ); + Aig_ObjSetRepr( p1, pNext1, NULL ); + } + Vec_PtrForEachEntry( vNodes1, pNext1, k ) + { + pNext0 = Aig_ObjRepr( p1, pNext1 ); + if ( pNext0 == NULL ) + continue; + assert( pNext1 == Aig_ObjRepr( p0, pNext0 ) ); + if ( Saig_ObjIsPi(p0, pNext0) ) + continue; + Aig_ObjSetRepr( p0, pNext0, NULL ); + Aig_ObjSetRepr( p1, pNext1, NULL ); + } + if ( fVerbose ) + { + int nUnmached = Ssw_StrSimMatchingCountUnmached(p0); + printf( "%2d : Total = %6d. Unmatched = %6d. Ratio = %6.2f %%\n", + d+1, Aig_ManPiNum(p0) + Aig_ManNodeNum(p0), + nUnmached, 100.0 * nUnmached/(Aig_ManPiNum(p0) + Aig_ManNodeNum(p0)) ); + } + } + Vec_PtrFree( vNodes0 ); + Vec_PtrFree( vNodes1 ); +} + + +/**Function************************************************************* + + Synopsis [Performs structural matching of two AIGs using simulation.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Saig_StrSimPerformMatching( Aig_Man_t * p0, Aig_Man_t * p1, int nDist, int fVerbose, Aig_Man_t ** ppMiter ) +{ + extern Aig_Man_t * Saig_ManWindowExtractMiter( Aig_Man_t * p0, Aig_Man_t * p1 ); + + Vec_Int_t * vPairs; + Aig_Man_t * pPart0, * pPart1; + Aig_Obj_t * pObj0, * pObj1; + int i, nMatches, clk, clkTotal = clock(); + Aig_ManRandom( 1 ); + // consider the case when a miter is given + if ( p1 == NULL ) + { + if ( fVerbose ) + { + Aig_ManPrintStats( p0 ); + } + // demiter the miter + if ( !Saig_ManDemiterSimpleDiff( p0, &pPart0, &pPart1 ) ) + { + printf( "Demitering has failed.\n" ); + return NULL; + } + } + else + { + pPart0 = Aig_ManDupSimple( p0 ); + pPart1 = Aig_ManDupSimple( p1 ); + } + if ( fVerbose ) + { + Aig_ManPrintStats( pPart0 ); + Aig_ManPrintStats( pPart1 ); + } + // start simulation + Saig_StrSimPrepareAig( pPart0 ); + Saig_StrSimPrepareAig( pPart1 ); + Saig_StrSimSetInitMatching( pPart0, pPart1 ); + if ( fVerbose ) + { + printf( "Allocated %6.2f Mb to simulate the first AIG.\n", + 1.0 * Aig_ManObjNumMax(pPart0) * SAIG_WORDS * sizeof(unsigned) / (1<<20) ); + printf( "Allocated %6.2f Mb to simulate the second AIG.\n", + 1.0 * Aig_ManObjNumMax(pPart1) * SAIG_WORDS * sizeof(unsigned) / (1<<20) ); + } + // iterate matching + nMatches = 1; + for ( i = 0; nMatches > 0; i++ ) + { + clk = clock(); + Saig_StrSimulateRound( pPart0, pPart1 ); + nMatches = Saig_StrSimDetectUnique( pPart0, pPart1 ); + if ( fVerbose ) + { + int nFlops = Saig_StrSimCountMatchedFlops(pPart0); + int nNodes = Saig_StrSimCountMatchedNodes(pPart0); + printf( "%3d : Match =%6d. FF =%6d. (%6.2f %%) Node =%6d. (%6.2f %%) ", + i, nMatches, + nFlops, 100.0*nFlops/Aig_ManRegNum(pPart0), + nNodes, 100.0*nNodes/Aig_ManNodeNum(pPart0) ); + PRT( "Time", clock() - clk ); + } + if ( i == 20 ) + break; + } + // cleanup + Vec_PtrFree( pPart0->pData2 ); pPart0->pData2 = NULL; + Vec_PtrFree( pPart1->pData2 ); pPart1->pData2 = NULL; + // extend the islands + Aig_ManFanoutStart( pPart0 ); + Aig_ManFanoutStart( pPart1 ); + if ( nDist ) + Ssw_StrSimMatchingExtend( pPart0, pPart1, nDist, fVerbose ); + Saig_StrSimSetFinalMatching( pPart0, pPart1 ); +// Saig_StrSimSetContiguousMatching( pPart0, pPart1 ); + // copy the results into array + vPairs = Vec_IntAlloc( 2*Aig_ManObjNumMax(pPart0) ); + Aig_ManForEachObj( pPart0, pObj0, i ) + { + pObj1 = Aig_ObjRepr(pPart0, pObj0); + if ( pObj1 == NULL ) + continue; + assert( pObj0 == Aig_ObjRepr(pPart1, pObj1) ); + Vec_IntPush( vPairs, pObj0->Id ); + Vec_IntPush( vPairs, pObj1->Id ); + } + // this procedure adds matching of PO and LI + if ( ppMiter ) + *ppMiter = Saig_ManWindowExtractMiter( pPart0, pPart1 ); + Aig_ManFanoutStop( pPart0 ); + Aig_ManFanoutStop( pPart1 ); + Aig_ManStop( pPart0 ); + Aig_ManStop( pPart1 ); + PRT( "Total runtime", clock() - clkTotal ); + return vPairs; +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + |