blob: 80bb0d838da7aea2f9e7b76cfe7105076fa96f01 [file] [log] [blame]
/**CFile****************************************************************
FileName [bm.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Boolean Matching package.]
Synopsis [Check P-equivalence and PP-equivalence of two circuits.]
Author [Hadi Katebi]
Affiliation [University of Michigan]
Date [Ver. 1.0. Started - January, 2009.]
Revision [No revisions so far]
Comments [This is the cleaned up version of the code I used for DATE 2010 publication.]
[If you have any question or if you find a bug, contact me at hadik@umich.edu.]
[I don't guarantee that I can fix all the bugs, but I can definitely point you to
the right direction so you can fix the bugs yourself].
Debugging [There are some part of the code that are commented out. Those parts mostly print
the contents of the data structures to the standard output. Un-comment them if you
find them useful for debugging.]
***********************************************************************/
#include "base/abc/abc.h"
#include "opt/sim/sim.h"
#include "sat/bsat/satSolver.h"
//#include "bdd/extrab/extraBdd.h"
ABC_NAMESPACE_IMPL_START
#define FALSE 0
#define TRUE 1
int match1by1(Abc_Ntk_t * pNtk1, Vec_Ptr_t ** nodesInLevel1, Vec_Int_t ** iMatch1, Vec_Int_t ** iDep1, Vec_Int_t * matchedInputs1, int * iGroup1, Vec_Int_t ** oMatch1, int * oGroup1,
Abc_Ntk_t * pNtk2, Vec_Ptr_t ** nodesInLevel2, Vec_Int_t ** iMatch2, Vec_Int_t ** iDep2, Vec_Int_t * matchedInputs2, int * iGroup2, Vec_Int_t ** oMatch2, int * oGroup2,
Vec_Int_t * matchedOutputs1, Vec_Int_t * matchedOutputs2, Vec_Int_t * oMatchedGroups, Vec_Int_t * iNonSingleton, int ii, int idx);
int Abc_NtkBmSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, Vec_Ptr_t * iMatchPairs, Vec_Ptr_t * oMatchPairs, Vec_Int_t * mismatch, int mode);
void getDependencies(Abc_Ntk_t *pNtk, Vec_Int_t** iDep, Vec_Int_t** oDep)
{
Vec_Ptr_t * vSuppFun;
int i, j;
vSuppFun = Sim_ComputeFunSupp(pNtk, 0);
for(i = 0; i < Abc_NtkPoNum(pNtk); i++) {
char * seg = (char *)vSuppFun->pArray[i];
for(j = 0; j < Abc_NtkPiNum(pNtk); j+=8) {
if(((*seg) & 0x01) == 0x01)
Vec_IntPushOrder(oDep[i], j);
if(((*seg) & 0x02) == 0x02)
Vec_IntPushOrder(oDep[i], j+1);
if(((*seg) & 0x04) == 0x04)
Vec_IntPushOrder(oDep[i], j+2);
if(((*seg) & 0x08) == 0x08)
Vec_IntPushOrder(oDep[i], j+3);
if(((*seg) & 0x10) == 0x10)
Vec_IntPushOrder(oDep[i], j+4);
if(((*seg) & 0x20) == 0x20)
Vec_IntPushOrder(oDep[i], j+5);
if(((*seg) & 0x40) == 0x40)
Vec_IntPushOrder(oDep[i], j+6);
if(((*seg) & 0x80) == 0x80)
Vec_IntPushOrder(oDep[i], j+7);
seg++;
}
}
for(i = 0; i < Abc_NtkPoNum(pNtk); i++)
for(j = 0; j < Vec_IntSize(oDep[i]); j++)
Vec_IntPush(iDep[Vec_IntEntry(oDep[i], j)], i);
/*for(i = 0; i < Abc_NtkPoNum(pNtk); i++)
{
printf("Output %d: ", i);
for(j = 0; j < Vec_IntSize(oDep[i]); j++)
printf("%d ", Vec_IntEntry(oDep[i], j));
printf("\n");
}
printf("\n");
for(i = 0; i < Abc_NtkPiNum(pNtk); i++)
{
printf("Input %d: ", i);
for(j = 0; j < Vec_IntSize(iDep[i]); j++)
printf("%d ", Vec_IntEntry(iDep[i], j));
printf("\n");
}
printf("\n"); */
}
void initMatchList(Abc_Ntk_t *pNtk, Vec_Int_t** iDep, Vec_Int_t** oDep, Vec_Int_t** iMatch, int* iLastItem, Vec_Int_t** oMatch, int* oLastItem, int* iGroup, int* oGroup, int p_equivalence)
{
int i, j, curr;
Vec_Int_t** temp;
if(!p_equivalence) {
temp = ABC_ALLOC( Vec_Int_t*, Abc_NtkPiNum(pNtk)+1);
for(i = 0; i < Abc_NtkPiNum(pNtk)+1; i++)
temp[i] = Vec_IntAlloc( 0 );
for(i = 0; i < Abc_NtkPoNum(pNtk); i++)
Vec_IntPush(temp[Vec_IntSize(oDep[i])], i);
curr = 0;
for(i = 0; i < Abc_NtkPiNum(pNtk)+1; i++)
{
if(Vec_IntSize(temp[i]) == 0)
Vec_IntFree( temp[i] );
else
{
oMatch[curr] = temp[i];
for(j = 0; j < Vec_IntSize(temp[i]); j++)
oGroup[Vec_IntEntry(oMatch[curr], j)] = curr;
curr++;
}
}
*oLastItem = curr;
ABC_FREE( temp );
}
else {
// the else part fixes the outputs for P-equivalence checking
for(i = 0; i < Abc_NtkPoNum(pNtk); i++)
{
Vec_IntPush(oMatch[i], i);
oGroup[i] = i;
(*oLastItem) = Abc_NtkPoNum(pNtk);
}
}
/*for(j = 0; j < *oLastItem; j++)
{
printf("oMatch %d: ", j);
for(i = 0; i < Vec_IntSize(oMatch[j]); i++)
printf("%d ", Vec_IntEntry(oMatch[j], i));
printf("\n");
}
for(i = 0; i < Abc_NtkPoNum(pNtk); i++)
printf("%d: %d ", i, oGroup[i]);*/
//////////////////////////////////////////////////////////////////////////////
temp = ABC_ALLOC( Vec_Int_t*, Abc_NtkPoNum(pNtk)+1 );
for(i = 0; i < Abc_NtkPoNum(pNtk)+1; i++)
temp[i] = Vec_IntAlloc( 0 );
for(i = 0; i < Abc_NtkPiNum(pNtk); i++)
Vec_IntPush(temp[Vec_IntSize(iDep[i])], i);
curr = 0;
for(i = 0; i < Abc_NtkPoNum(pNtk)+1; i++)
{
if(Vec_IntSize(temp[i]) == 0)
Vec_IntFree( temp[i] );
else
{
iMatch[curr] = temp[i];
for(j = 0; j < Vec_IntSize(iMatch[curr]); j++)
iGroup[Vec_IntEntry(iMatch[curr], j)] = curr;
curr++;
}
}
*iLastItem = curr;
ABC_FREE( temp );
/*printf("\n");
for(j = 0; j < *iLastItem; j++)
{
printf("iMatch %d: ", j);
for(i = 0; i < Vec_IntSize(iMatch[j]); i++)
printf("%d ", Vec_IntEntry(iMatch[j], i));
printf("\n");
}
for(i = 0; i < Abc_NtkPiNum(pNtk); i++)
printf("%d: %d ", i, iGroup[i]);
printf("\n");*/
}
void iSortDependencies(Abc_Ntk_t *pNtk, Vec_Int_t** iDep, int* oGroup)
{
int i, j, k;
Vec_Int_t * temp;
Vec_Int_t * oGroupList;
oGroupList = Vec_IntAlloc( 10 );
for(i = 0; i < Abc_NtkPiNum(pNtk); i++)
{
if(Vec_IntSize(iDep[i]) == 1)
continue;
temp = Vec_IntAlloc( Vec_IntSize(iDep[i]) );
for(j = 0; j < Vec_IntSize(iDep[i]); j++)
Vec_IntPushUniqueOrder(oGroupList, oGroup[Vec_IntEntry(iDep[i], j)]);
for(j = 0; j < Vec_IntSize(oGroupList); j++)
{
for(k = 0; k < Vec_IntSize(iDep[i]); k++)
if(oGroup[Vec_IntEntry(iDep[i], k)] == Vec_IntEntry(oGroupList, j))
{
Vec_IntPush( temp, Vec_IntEntry(iDep[i], k) );
Vec_IntRemove( iDep[i], Vec_IntEntry(iDep[i], k) );
k--;
}
}
Vec_IntFree( iDep[i] );
iDep[i] = temp;
Vec_IntClear( oGroupList );
/*printf("Input %d: ", i);
for(j = 0; j < Vec_IntSize(iDep[i]); j++)
printf("%d ", Vec_IntEntry(iDep[i], j));
printf("\n");*/
}
Vec_IntFree( oGroupList );
}
void oSortDependencies(Abc_Ntk_t *pNtk, Vec_Int_t** oDep, int* iGroup)
{
int i, j, k;
Vec_Int_t * temp;
Vec_Int_t * iGroupList;
iGroupList = Vec_IntAlloc( 10 );
for(i = 0; i < Abc_NtkPoNum(pNtk); i++)
{
if(Vec_IntSize(oDep[i]) == 1)
continue;
temp = Vec_IntAlloc( Vec_IntSize(oDep[i]) );
for(j = 0; j < Vec_IntSize(oDep[i]); j++)
Vec_IntPushUniqueOrder(iGroupList, iGroup[Vec_IntEntry(oDep[i], j)]);
for(j = 0; j < Vec_IntSize(iGroupList); j++)
{
for(k = 0; k < Vec_IntSize(oDep[i]); k++)
if(iGroup[Vec_IntEntry(oDep[i], k)] == Vec_IntEntry(iGroupList, j))
{
Vec_IntPush( temp, Vec_IntEntry(oDep[i], k) );
Vec_IntRemove( oDep[i], Vec_IntEntry(oDep[i], k) );
k--;
}
}
Vec_IntFree( oDep[i] );
oDep[i] = temp;
Vec_IntClear( iGroupList );
/*printf("Output %d: ", i);
for(j = 0; j < Vec_IntSize(oDep[i]); j++)
printf("%d ", Vec_IntEntry(oDep[i], j));
printf("\n");*/
}
Vec_IntFree( iGroupList );
}
int oSplitByDep(Abc_Ntk_t *pNtk, Vec_Int_t** oDep, Vec_Int_t** oMatch, int* oGroup, int* oLastItem, int* iGroup)
{
int i, j, k;
int numOfItemsAdded;
Vec_Int_t * array, * sortedArray;
numOfItemsAdded = 0;
for(i = 0; i < *oLastItem; i++)
{
if(Vec_IntSize(oMatch[i]) == 1)
continue;
array = Vec_IntAlloc( Vec_IntSize(oMatch[i]) );
sortedArray = Vec_IntAlloc( Vec_IntSize(oMatch[i]) );
for(j = 0; j < Vec_IntSize(oMatch[i]); j++)
{
int factor, encode;
encode = 0;
factor = 1;
for(k = 0; k < Vec_IntSize(oDep[Vec_IntEntry(oMatch[i], j)]); k++)
encode += iGroup[Vec_IntEntry(oDep[Vec_IntEntry(oMatch[i], j)], k)] * factor;
Vec_IntPush(array, encode);
Vec_IntPushUniqueOrder(sortedArray, encode);
if( encode < 0)
printf("WARNING! Integer overflow!");
//printf("%d ", Vec_IntEntry(array, j));
}
while( Vec_IntSize(sortedArray) > 1 )
{
for(k = 0; k < Vec_IntSize(oMatch[i]); k++)
{
if(Vec_IntEntry(array, k) == Vec_IntEntryLast(sortedArray))
{
Vec_IntPush(oMatch[*oLastItem+numOfItemsAdded], Vec_IntEntry(oMatch[i], k));
oGroup[Vec_IntEntry(oMatch[i], k)] = *oLastItem+numOfItemsAdded;
Vec_IntRemove( oMatch[i], Vec_IntEntry(oMatch[i], k) );
Vec_IntRemove( array, Vec_IntEntry(array, k) );
k--;
}
}
numOfItemsAdded++;
Vec_IntPop(sortedArray);
}
Vec_IntFree( array );
Vec_IntFree( sortedArray );
//printf("\n");
}
*oLastItem += numOfItemsAdded;
/*printf("\n");
for(j = 0; j < *oLastItem ; j++)
{
printf("oMatch %d: ", j);
for(i = 0; i < Vec_IntSize(oMatch[j]); i++)
printf("%d ", Vec_IntEntry(oMatch[j], i));
printf("\n");
}*/
return numOfItemsAdded;
}
int iSplitByDep(Abc_Ntk_t *pNtk, Vec_Int_t** iDep, Vec_Int_t** iMatch, int* iGroup, int* iLastItem, int* oGroup)
{
int i, j, k;
int numOfItemsAdded = 0;
Vec_Int_t * array, * sortedArray;
for(i = 0; i < *iLastItem; i++)
{
if(Vec_IntSize(iMatch[i]) == 1)
continue;
array = Vec_IntAlloc( Vec_IntSize(iMatch[i]) );
sortedArray = Vec_IntAlloc( Vec_IntSize(iMatch[i]) );
for(j = 0; j < Vec_IntSize(iMatch[i]); j++)
{
int factor, encode;
encode = 0;
factor = 1;
for(k = 0; k < Vec_IntSize(iDep[Vec_IntEntry(iMatch[i], j)]); k++)
encode += oGroup[Vec_IntEntry(iDep[Vec_IntEntry(iMatch[i], j)], k)] * factor;
Vec_IntPush(array, encode);
Vec_IntPushUniqueOrder(sortedArray, encode);
//printf("%d ", Vec_IntEntry(array, j));
}
while( Vec_IntSize(sortedArray) > 1 )
{
for(k = 0; k < Vec_IntSize(iMatch[i]); k++)
{
if(Vec_IntEntry(array, k) == Vec_IntEntryLast(sortedArray))
{
Vec_IntPush(iMatch[*iLastItem+numOfItemsAdded], Vec_IntEntry(iMatch[i], k));
iGroup[Vec_IntEntry(iMatch[i], k)] = *iLastItem+numOfItemsAdded;
Vec_IntRemove( iMatch[i], Vec_IntEntry(iMatch[i], k) );
Vec_IntRemove( array, Vec_IntEntry(array, k) );
k--;
}
}
numOfItemsAdded++;
Vec_IntPop(sortedArray);
}
Vec_IntFree( array );
Vec_IntFree( sortedArray );
//printf("\n");
}
*iLastItem += numOfItemsAdded;
/*printf("\n");
for(j = 0; j < *iLastItem ; j++)
{
printf("iMatch %d: ", j);
for(i = 0; i < Vec_IntSize(iMatch[j]); i++)
printf("%d ", Vec_IntEntry(iMatch[j], i));
printf("\n");
}*/
return numOfItemsAdded;
}
Vec_Ptr_t ** findTopologicalOrder( Abc_Ntk_t * pNtk )
{
Vec_Ptr_t ** vNodes;
Abc_Obj_t * pObj, * pFanout;
int i, k;
extern void Abc_NtkDfsReverse_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes );
// start the array of nodes
vNodes = ABC_ALLOC(Vec_Ptr_t *, Abc_NtkPiNum(pNtk));
for(i = 0; i < Abc_NtkPiNum(pNtk); i++)
vNodes[i] = Vec_PtrAlloc(50);
Abc_NtkForEachCi( pNtk, pObj, i )
{
// set the traversal ID
Abc_NtkIncrementTravId( pNtk );
Abc_NodeSetTravIdCurrent( pObj );
pObj = Abc_ObjFanout0Ntk(pObj);
Abc_ObjForEachFanout( pObj, pFanout, k )
Abc_NtkDfsReverse_rec( pFanout, vNodes[i] );
}
return vNodes;
}
int * Abc_NtkSimulateOneNode( Abc_Ntk_t * pNtk, int * pModel, int input, Vec_Ptr_t ** topOrder )
{
Abc_Obj_t * pNode;
Vec_Ptr_t * vNodes;
int * pValues, Value0, Value1, i;
vNodes = Vec_PtrAlloc( 50 );
/*
printf( "Counter example: " );
Abc_NtkForEachCi( pNtk, pNode, i )
printf( " %d", pModel[i] );
printf( "\n" );
*/
// increment the trav ID
Abc_NtkIncrementTravId( pNtk );
// set the CI values
Abc_AigConst1(pNtk)->pCopy = (Abc_Obj_t *)1;
pNode = Abc_NtkCi(pNtk, input);
pNode->iTemp = pModel[input];
// simulate in the topological order
for(i = Vec_PtrSize(topOrder[input])-1; i >= 0; i--)
{
pNode = (Abc_Obj_t *)Vec_PtrEntry(topOrder[input], i);
Value0 = ((int)(ABC_PTRUINT_T)Abc_ObjFanin0(pNode)->pCopy) ^ Abc_ObjFaninC0(pNode);
Value1 = ((int)(ABC_PTRUINT_T)Abc_ObjFanin1(pNode)->pCopy) ^ Abc_ObjFaninC1(pNode);
if( pNode->iTemp != (Value0 & Value1))
{
pNode->iTemp = (Value0 & Value1);
Vec_PtrPush(vNodes, pNode);
}
}
// fill the output values
pValues = ABC_ALLOC( int, Abc_NtkCoNum(pNtk) );
Abc_NtkForEachCo( pNtk, pNode, i )
pValues[i] = ((int)(ABC_PTRUINT_T)Abc_ObjFanin0(pNode)->pCopy) ^ Abc_ObjFaninC0(pNode);
pNode = Abc_NtkCi(pNtk, input);
if(pNode->pCopy == (Abc_Obj_t *)1)
pNode->pCopy = (Abc_Obj_t *)0;
else
pNode->pCopy = (Abc_Obj_t *)1;
for(i = 0; i < Vec_PtrSize(vNodes); i++)
{
pNode = (Abc_Obj_t *)Vec_PtrEntry(vNodes, i);
if(pNode->pCopy == (Abc_Obj_t *)1)
pNode->pCopy = (Abc_Obj_t *)0;
else
pNode->pCopy = (Abc_Obj_t *)1;
}
Vec_PtrFree( vNodes );
return pValues;
}
int refineIOBySimulation(Abc_Ntk_t *pNtk, Vec_Int_t** iMatch, int* iLastItem, int * iGroup, Vec_Int_t** iDep, Vec_Int_t** oMatch, int* oLastItem, int * oGroup, Vec_Int_t** oDep, char * vPiValues, int * observability, Vec_Ptr_t ** topOrder)
{
Abc_Obj_t * pObj;
int * pModel;//, ** pModel2;
int * output, * output2;
int lastItem;
int i, j, k;
Vec_Int_t * iComputedNum, * iComputedNumSorted;
Vec_Int_t * oComputedNum; // encoding the number of flips
int factor;
int isRefined = FALSE;
pModel = ABC_ALLOC( int, Abc_NtkCiNum(pNtk) );
Abc_NtkForEachPi( pNtk, pObj, i )
pModel[i] = vPiValues[i] - '0';
Abc_NtkForEachLatch( pNtk, pObj, i )
pModel[Abc_NtkPiNum(pNtk)+i] = pObj->iData - 1;
output = Abc_NtkVerifySimulatePattern( pNtk, pModel );
oComputedNum = Vec_IntAlloc( Abc_NtkPoNum(pNtk) );
for(i = 0; i < Abc_NtkPoNum(pNtk); i++)
Vec_IntPush(oComputedNum, 0);
/****************************************************************************************/
/********** group outputs that produce 1 and outputs that produce 0 together ************/
lastItem = *oLastItem;
for(i = 0; i < lastItem && (*oLastItem) != Abc_NtkPoNum(pNtk); i++)
{
int flag = FALSE;
if(Vec_IntSize(oMatch[i]) == 1)
continue;
for(j = 1; j < Vec_IntSize(oMatch[i]); j++)
if(output[Vec_IntEntry(oMatch[i], 0)] != output[Vec_IntEntry(oMatch[i], j)])
{
flag = TRUE;
break;
}
if(flag)
{
for(j = 0; j < Vec_IntSize(oMatch[i]); j++)
if(output[Vec_IntEntry(oMatch[i], j)])
{
Vec_IntPush(oMatch[*oLastItem], Vec_IntEntry(oMatch[i], j));
oGroup[Vec_IntEntry(oMatch[i], j)] = *oLastItem;
Vec_IntRemove(oMatch[i], Vec_IntEntry(oMatch[i], j));
j--;
}
(*oLastItem)++;
}
}
if( (*oLastItem) > lastItem )
{
isRefined = TRUE;
iSortDependencies(pNtk, iDep, oGroup);
}
/****************************************************************************************/
/************* group inputs that make the same number of flips in outpus ****************/
lastItem = *iLastItem;
for(i = 0; i < lastItem && (*iLastItem) != Abc_NtkPiNum(pNtk); i++)
{
int num;
if(Vec_IntSize(iMatch[i]) == 1)
continue;
iComputedNum = Vec_IntAlloc( Vec_IntSize(iMatch[i]) );
iComputedNumSorted = Vec_IntAlloc( Vec_IntSize(iMatch[i]) );
for(j = 0; j < Vec_IntSize(iMatch[i]); j++)
{
if( vPiValues[Vec_IntEntry(iMatch[i], j)] == '0' )
pModel[Vec_IntEntry(iMatch[i], j)] = 1;
else
pModel[Vec_IntEntry(iMatch[i], j)] = 0;
//output2 = Abc_NtkVerifySimulatePattern( pNtk, pModel );
output2 = Abc_NtkSimulateOneNode( pNtk, pModel, Vec_IntEntry(iMatch[i], j), topOrder );
num = 0;
factor = 1;
for(k = 0; k < Vec_IntSize(iDep[Vec_IntEntry(iMatch[i], j)]); k++)
{
int outputIndex = Vec_IntEntry(iDep[Vec_IntEntry(iMatch[i], j)], k);
if(output2[outputIndex])
num += (oGroup[outputIndex] + 1) * factor;
if(output[outputIndex] != output2[outputIndex])
{
int temp = Vec_IntEntry(oComputedNum, outputIndex) + i + 1;
Vec_IntWriteEntry(oComputedNum, outputIndex, temp);
observability[Vec_IntEntry(iMatch[i], j)]++;
}
}
Vec_IntPush(iComputedNum, num);
Vec_IntPushUniqueOrder(iComputedNumSorted, num);
pModel[Vec_IntEntry(iMatch[i], j)] = vPiValues[Vec_IntEntry(iMatch[i], j)] - '0';
ABC_FREE( output2 );
}
while( Vec_IntSize( iComputedNumSorted ) > 1 )
{
for(k = 0; k < Vec_IntSize(iMatch[i]); k++)
{
if(Vec_IntEntry(iComputedNum, k) == Vec_IntEntryLast(iComputedNumSorted) )
{
Vec_IntPush(iMatch[*iLastItem], Vec_IntEntry(iMatch[i], k));
iGroup[Vec_IntEntry(iMatch[i], k)] = *iLastItem;
Vec_IntRemove( iMatch[i], Vec_IntEntry(iMatch[i], k) );
Vec_IntRemove( iComputedNum, Vec_IntEntry(iComputedNum, k) );
k--;
}
}
(*iLastItem)++;
Vec_IntPop( iComputedNumSorted );
}
Vec_IntFree( iComputedNum );
Vec_IntFree( iComputedNumSorted );
}
if( (*iLastItem) > lastItem )
{
isRefined = TRUE;
oSortDependencies(pNtk, oDep, iGroup);
}
/****************************************************************************************/
/********** encode the number of flips in each output by flipping the outputs ***********/
/********** and group all the outputs that have the same encoding ***********/
lastItem = *oLastItem;
for(i = 0; i < lastItem && (*oLastItem) != Abc_NtkPoNum(pNtk); i++)
{
Vec_Int_t * encode, * sortedEncode; // encoding the number of flips
if(Vec_IntSize(oMatch[i]) == 1)
continue;
encode = Vec_IntAlloc( Vec_IntSize(oMatch[i]) );
sortedEncode = Vec_IntAlloc( Vec_IntSize(oMatch[i]) );
for(j = 0; j < Vec_IntSize(oMatch[i]); j++)
{
Vec_IntPush(encode, Vec_IntEntry(oComputedNum, Vec_IntEntry(oMatch[i], j)) );
Vec_IntPushUniqueOrder( sortedEncode, Vec_IntEntry(encode, j) );
}
while( Vec_IntSize(sortedEncode) > 1 )
{
for(j = 0; j < Vec_IntSize(oMatch[i]); j++)
if(Vec_IntEntry(encode, j) == Vec_IntEntryLast(sortedEncode))
{
Vec_IntPush(oMatch[*oLastItem], Vec_IntEntry(oMatch[i], j));
oGroup[Vec_IntEntry(oMatch[i], j)] = *oLastItem;
Vec_IntRemove( oMatch[i], Vec_IntEntry(oMatch[i], j) );
Vec_IntRemove( encode, Vec_IntEntry(encode, j) );
j --;
}
(*oLastItem)++;
Vec_IntPop( sortedEncode );
}
Vec_IntFree( encode );
Vec_IntFree( sortedEncode );
}
if( (*oLastItem) > lastItem )
isRefined = TRUE;
ABC_FREE( pModel );
ABC_FREE( output );
Vec_IntFree( oComputedNum );
return isRefined;
}
Abc_Ntk_t * Abc_NtkMiterBm( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, Vec_Ptr_t * iCurrMatch, Vec_Ptr_t * oCurrMatch )
{
char Buffer[1000];
Abc_Ntk_t * pNtkMiter;
pNtkMiter = Abc_NtkAlloc( ABC_NTK_STRASH, ABC_FUNC_AIG, 1 );
sprintf( Buffer, "%s_%s_miter", pNtk1->pName, pNtk2->pName );
pNtkMiter->pName = Extra_UtilStrsav(Buffer);
//Abc_NtkMiterPrepare( pNtk1, pNtk2, pNtkMiter, fComb, nPartSize );
{
Abc_Obj_t * pObj, * pObjNew;
int i;
Abc_AigConst1(pNtk1)->pCopy = Abc_AigConst1(pNtkMiter);
Abc_AigConst1(pNtk2)->pCopy = Abc_AigConst1(pNtkMiter);
// create new PIs and remember them in the old PIs
if(iCurrMatch == NULL)
{
Abc_NtkForEachCi( pNtk1, pObj, i )
{
pObjNew = Abc_NtkCreatePi( pNtkMiter );
// remember this PI in the old PIs
pObj->pCopy = pObjNew;
pObj = Abc_NtkCi(pNtk2, i);
pObj->pCopy = pObjNew;
// add name
Abc_ObjAssignName( pObjNew, Abc_ObjName(pObj), NULL );
}
}
else
{
for(i = 0; i < Vec_PtrSize( iCurrMatch ); i += 2)
{
pObjNew = Abc_NtkCreatePi( pNtkMiter );
pObj = (Abc_Obj_t *)Vec_PtrEntry(iCurrMatch, i);
pObj->pCopy = pObjNew;
pObj = (Abc_Obj_t *)Vec_PtrEntry(iCurrMatch, i+1);
pObj->pCopy = pObjNew;
// add name
Abc_ObjAssignName( pObjNew, Abc_ObjName(pObj), NULL );
}
}
// create the only PO
pObjNew = Abc_NtkCreatePo( pNtkMiter );
// add the PO name
Abc_ObjAssignName( pObjNew, "miter", NULL );
}
// Abc_NtkMiterAddOne( pNtk1, pNtkMiter );
{
Abc_Obj_t * pNode;
int i;
assert( Abc_NtkIsDfsOrdered(pNtk1) );
Abc_AigForEachAnd( pNtk1, pNode, i )
pNode->pCopy = Abc_AigAnd( (Abc_Aig_t *)pNtkMiter->pManFunc, Abc_ObjChild0Copy(pNode), Abc_ObjChild1Copy(pNode) );
}
// Abc_NtkMiterAddOne( pNtk2, pNtkMiter );
{
Abc_Obj_t * pNode;
int i;
assert( Abc_NtkIsDfsOrdered(pNtk2) );
Abc_AigForEachAnd( pNtk2, pNode, i )
pNode->pCopy = Abc_AigAnd( (Abc_Aig_t *)pNtkMiter->pManFunc, Abc_ObjChild0Copy(pNode), Abc_ObjChild1Copy(pNode) );
}
// Abc_NtkMiterFinalize( pNtk1, pNtk2, pNtkMiter, fComb, nPartSize );
{
Vec_Ptr_t * vPairs;
Abc_Obj_t * pMiter;
int i;
vPairs = Vec_PtrAlloc( 100 );
// collect the CO nodes for the miter
if(oCurrMatch != NULL)
{
for(i = 0; i < Vec_PtrSize( oCurrMatch ); i += 2)
{
Vec_PtrPush( vPairs, Abc_ObjChild0Copy((Abc_Obj_t *)Vec_PtrEntry(oCurrMatch, i)) );
Vec_PtrPush( vPairs, Abc_ObjChild0Copy((Abc_Obj_t *)Vec_PtrEntry(oCurrMatch, i+1)) );
}
}
else
{
Abc_Obj_t * pNode;
Abc_NtkForEachCo( pNtk1, pNode, i )
{
Vec_PtrPush( vPairs, Abc_ObjChild0Copy(pNode) );
pNode = Abc_NtkCo( pNtk2, i );
Vec_PtrPush( vPairs, Abc_ObjChild0Copy(pNode) );
}
}
pMiter = Abc_AigMiter( (Abc_Aig_t *)pNtkMiter->pManFunc, vPairs, 0 );
Abc_ObjAddFanin( Abc_NtkPo(pNtkMiter,0), pMiter );
Vec_PtrFree(vPairs);
}
//Abc_AigCleanup(pNtkMiter->pManFunc);
return pNtkMiter;
}
int * pValues1__, * pValues2__;
void Abc_NtkVerifyReportError( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int * pModel, Vec_Int_t * mismatch )
{
Vec_Ptr_t * vNodes;
Abc_Obj_t * pNode;
int nErrors, nPrinted, i, iNode = -1;
assert( Abc_NtkCiNum(pNtk1) == Abc_NtkCiNum(pNtk2) );
assert( Abc_NtkCoNum(pNtk1) == Abc_NtkCoNum(pNtk2) );
// get the CO values under this model
pValues1__ = Abc_NtkVerifySimulatePattern( pNtk1, pModel );
pValues2__ = Abc_NtkVerifySimulatePattern( pNtk2, pModel );
// count the mismatches
nErrors = 0;
for ( i = 0; i < Abc_NtkCoNum(pNtk1); i++ )
nErrors += (int)( pValues1__[i] != pValues2__[i] );
//printf( "Verification failed for at least %d outputs: ", nErrors );
// print the first 3 outputs
nPrinted = 0;
for ( i = 0; i < Abc_NtkCoNum(pNtk1); i++ )
if ( pValues1__[i] != pValues2__[i] )
{
if ( iNode == -1 )
iNode = i;
//printf( " %s", Abc_ObjName(Abc_NtkCo(pNtk1,i)) );
if ( ++nPrinted == 3 )
break;
}
/*if ( nPrinted != nErrors )
printf( " ..." );
printf( "\n" );*/
// report mismatch for the first output
if ( iNode >= 0 )
{
/*printf( "Output %s: Value in Network1 = %d. Value in Network2 = %d.\n",
Abc_ObjName(Abc_NtkCo(pNtk1,iNode)), pValues1[iNode], pValues2[iNode] );
printf( "Input pattern: " );*/
// collect PIs in the cone
pNode = Abc_NtkCo(pNtk1,iNode);
vNodes = Abc_NtkNodeSupport( pNtk1, &pNode, 1 );
// set the PI numbers
Abc_NtkForEachCi( pNtk1, pNode, i )
pNode->iTemp = i;
// print the model
pNode = (Abc_Obj_t *)Vec_PtrEntry( vNodes, 0 );
if ( Abc_ObjIsCi(pNode) )
{
Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNode, i )
{
assert( Abc_ObjIsCi(pNode) );
//printf( " %s=%d", Abc_ObjName(pNode), pModel[(int)pNode->pCopy] );
Vec_IntPush(mismatch, Abc_ObjId(pNode)-1);
Vec_IntPush(mismatch, pModel[(int)(size_t)pNode->pCopy]);
}
}
//printf( "\n" );
Vec_PtrFree( vNodes );
}
free( pValues1__ );
free( pValues2__ );
}
int Abc_NtkMiterSatBm( Abc_Ntk_t * pNtk, ABC_INT64_T nConfLimit, ABC_INT64_T nInsLimit, int fVerbose, ABC_INT64_T * pNumConfs, ABC_INT64_T * pNumInspects)
{
static sat_solver * pSat = NULL;
lbool status;
int RetValue = 0;
abctime clk;
extern int Abc_NodeAddClausesTop( sat_solver * pSat, Abc_Obj_t * pNode, Vec_Int_t * vVars );
extern Vec_Int_t * Abc_NtkGetCiSatVarNums( Abc_Ntk_t * pNtk );
if ( pNumConfs )
*pNumConfs = 0;
if ( pNumInspects )
*pNumInspects = 0;
assert( Abc_NtkLatchNum(pNtk) == 0 );
// if ( Abc_NtkPoNum(pNtk) > 1 )
// fprintf( stdout, "Warning: The miter has %d outputs. SAT will try to prove all of them.\n", Abc_NtkPoNum(pNtk) );
// load clauses into the sat_solver
clk = Abc_Clock();
pSat = (sat_solver *)Abc_NtkMiterSatCreate( pNtk, 0 );
if ( pSat == NULL )
return 1;
//printf( "%d \n", pSat->clauses.size );
//sat_solver_delete( pSat );
//return 1;
// printf( "Created SAT problem with %d variable and %d clauses. ", sat_solver_nvars(pSat), sat_solver_nclauses(pSat) );
// PRT( "Time", Abc_Clock() - clk );
// simplify the problem
clk = Abc_Clock();
status = sat_solver_simplify(pSat);
// printf( "Simplified the problem to %d variables and %d clauses. ", sat_solver_nvars(pSat), sat_solver_nclauses(pSat) );
// PRT( "Time", Abc_Clock() - clk );
if ( status == 0 )
{
sat_solver_delete( pSat );
// printf( "The problem is UNSATISFIABLE after simplification.\n" );
return 1;
}
// solve the miter
clk = Abc_Clock();
if ( fVerbose )
pSat->verbosity = 1;
status = sat_solver_solve( pSat, NULL, NULL, (ABC_INT64_T)nConfLimit, (ABC_INT64_T)nInsLimit, (ABC_INT64_T)0, (ABC_INT64_T)0 );
if ( status == l_Undef )
{
// printf( "The problem timed out.\n" );
RetValue = -1;
}
else if ( status == l_True )
{
// printf( "The problem is SATISFIABLE.\n" );
RetValue = 0;
}
else if ( status == l_False )
{
// printf( "The problem is UNSATISFIABLE.\n" );
RetValue = 1;
}
else
assert( 0 );
// PRT( "SAT sat_solver time", Abc_Clock() - clk );
// printf( "The number of conflicts = %d.\n", (int)pSat->sat_solver_stats.conflicts );
// if the problem is SAT, get the counterexample
if ( status == l_True )
{
// Vec_Int_t * vCiIds = Abc_NtkGetCiIds( pNtk );
Vec_Int_t * vCiIds = Abc_NtkGetCiSatVarNums( pNtk );
pNtk->pModel = Sat_SolverGetModel( pSat, vCiIds->pArray, vCiIds->nSize );
Vec_IntFree( vCiIds );
}
// free the sat_solver
if ( fVerbose )
Sat_SolverPrintStats( stdout, pSat );
if ( pNumConfs )
*pNumConfs = (int)pSat->stats.conflicts;
if ( pNumInspects )
*pNumInspects = (int)pSat->stats.inspects;
//sat_solver_store_write( pSat, "trace.cnf" );
sat_solver_store_free( pSat );
sat_solver_delete( pSat );
return RetValue;
}
int Abc_NtkBmSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, Vec_Ptr_t * iMatchPairs, Vec_Ptr_t * oMatchPairs, Vec_Int_t * mismatch, int mode)
{
extern Abc_Ntk_t * Abc_NtkMulti( Abc_Ntk_t * pNtk, int nThresh, int nFaninMax, int fCnf, int fMulti, int fSimple, int fFactor );
Abc_Ntk_t * pMiter = NULL;
Abc_Ntk_t * pCnf;
int RetValue = 0;
// get the miter of the two networks
if( mode == 0 )
{
//Abc_NtkDelete( pMiter );
pMiter = Abc_NtkMiterBm( pNtk1, pNtk2, iMatchPairs, oMatchPairs );
}
else if( mode == 1 ) // add new outputs
{
int i;
Abc_Obj_t * pObj;
Vec_Ptr_t * vPairs;
Abc_Obj_t * pNtkMiter;
vPairs = Vec_PtrAlloc( 100 );
Abc_NtkForEachCo( pMiter, pObj, i )
Abc_ObjRemoveFanins( pObj );
for(i = 0; i < Vec_PtrSize( oMatchPairs ); i += 2)
{
Vec_PtrPush( vPairs, Abc_ObjChild0Copy((Abc_Obj_t *)Vec_PtrEntry(oMatchPairs, i)) );
Vec_PtrPush( vPairs, Abc_ObjChild0Copy((Abc_Obj_t *)Vec_PtrEntry(oMatchPairs, i+1)) );
}
pNtkMiter = Abc_AigMiter( (Abc_Aig_t *)pMiter->pManFunc, vPairs, 0 );
Abc_ObjAddFanin( Abc_NtkPo(pMiter,0), pNtkMiter );
Vec_PtrFree( vPairs);
}
else if( mode == 2 ) // add some outputs
{
}
else if( mode == 3) // remove all outputs
{
}
if ( pMiter == NULL )
{
printf("Miter computation has failed.");
return -1;
}
RetValue = Abc_NtkMiterIsConstant( pMiter );
if ( RetValue == 0)
{
/*printf("Networks are NOT EQUIVALENT after structural hashing."); */
// report the error
if(mismatch != NULL)
{
pMiter->pModel = Abc_NtkVerifyGetCleanModel( pMiter, 1 );
Abc_NtkVerifyReportError( pNtk1, pNtk2, pMiter->pModel, mismatch );
ABC_FREE( pMiter->pModel );
}
Abc_NtkDelete( pMiter );
return RetValue;
}
if( RetValue == 1 )
{
/*printf("Networks are equivalent after structural hashing."); */
Abc_NtkDelete( pMiter );
return RetValue;
}
// convert the miter into a CNF
//if(mode == 0)
pCnf = Abc_NtkMulti( pMiter, 0, 100, 1, 0, 0, 0 );
Abc_NtkDelete( pMiter );
if ( pCnf == NULL )
{
printf("Renoding for CNF has failed.");
return -1;
}
// solve the CNF using the SAT solver
RetValue = Abc_NtkMiterSat( pCnf, (ABC_INT64_T)10000, (ABC_INT64_T)0, 0, NULL, NULL);
/*if ( RetValue == -1 )
printf("Networks are undecided (SAT solver timed out).");
else if ( RetValue == 0 )
printf("Networks are NOT EQUIVALENT after SAT.");
else
printf("Networks are equivalent after SAT."); */
if ( mismatch != NULL && pCnf->pModel )
Abc_NtkVerifyReportError( pNtk1, pNtk2, pCnf->pModel, mismatch );
ABC_FREE( pCnf->pModel );
Abc_NtkDelete( pCnf );
return RetValue;
}
int checkEquivalence( Abc_Ntk_t * pNtk1, Vec_Int_t* matchedInputs1, Vec_Int_t * matchedOutputs1,
Abc_Ntk_t * pNtk2, Vec_Int_t* matchedInputs2, Vec_Int_t * matchedOutputs2)
{
Vec_Ptr_t * iMatchPairs, * oMatchPairs;
int i;
int result;
iMatchPairs = Vec_PtrAlloc( Abc_NtkPiNum( pNtk1 ) * 2);
oMatchPairs = Vec_PtrAlloc( Abc_NtkPoNum( pNtk1 ) * 2);
for(i = 0; i < Abc_NtkPiNum(pNtk1); i++)
{
Vec_PtrPush(iMatchPairs, Abc_NtkPi(pNtk2, Vec_IntEntry(matchedInputs2, i)));
Vec_PtrPush(iMatchPairs, Abc_NtkPi(pNtk1, Vec_IntEntry(matchedInputs1, i)));
}
for(i = 0; i < Abc_NtkPoNum(pNtk1); i++)
{
Vec_PtrPush(oMatchPairs, Abc_NtkPo(pNtk2, Vec_IntEntry(matchedOutputs2, i)));
Vec_PtrPush(oMatchPairs, Abc_NtkPo(pNtk1, Vec_IntEntry(matchedOutputs1, i)));
}
result = Abc_NtkBmSat(pNtk1, pNtk2, iMatchPairs, oMatchPairs, NULL, 0);
if( result )
printf("*** Circuits are equivalent ***\n");
else
printf("*** Circuits are NOT equivalent ***\n");
Vec_PtrFree( iMatchPairs );
Vec_PtrFree( oMatchPairs );
return result;
}
Abc_Ntk_t * computeCofactor(Abc_Ntk_t * pNtk, Vec_Ptr_t ** nodesInLevel, int * bitVector, Vec_Int_t * currInputs)
{
Abc_Ntk_t * subNtk;
Abc_Obj_t * pObj, * pObjNew;
int i, j, numOfLevels;
numOfLevels = Abc_AigLevel( pNtk ); // number of levels excludes PI/POs
// start a new network
subNtk = Abc_NtkAlloc( ABC_NTK_STRASH, ABC_FUNC_AIG, 1 );
subNtk->pName = Extra_UtilStrsav("subNtk");
Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(subNtk);
// clean the node copy fields and mark the nodes that need to be copied to the new network
Abc_NtkCleanCopy( pNtk );
if(bitVector != NULL)
{
for(i = 0; i < Abc_NtkPiNum(pNtk); i++)
if(bitVector[i])
{
pObj = Abc_NtkPi(pNtk, i);
pObj->pCopy = (Abc_Obj_t *)(1);
}
}
for(i = 0; i < Vec_IntSize(currInputs); i++)
{
pObj = Abc_NtkPi(pNtk, Vec_IntEntry(currInputs, i));
pObjNew = Abc_NtkDupObj( subNtk, pObj, 1 );
pObj->pCopy = pObjNew;
}
// i = 0 are the inputs and the inputs are not added to the 2d array ( nodesInLevel )
for( i = 0; i <= numOfLevels; i++ )
for( j = 0; j < Vec_PtrSize( nodesInLevel[i] ); j++)
{
pObj = (Abc_Obj_t *)Vec_PtrEntry( nodesInLevel[i], j );
if(Abc_ObjChild0Copy(pObj) == NULL && Abc_ObjChild1Copy(pObj) == NULL)
pObj->pCopy = NULL;
else if(Abc_ObjChild0Copy(pObj) == NULL && Abc_ObjChild1Copy(pObj) == (void*)(1))
pObj->pCopy = NULL;
else if(Abc_ObjChild0Copy(pObj) == NULL && (Abc_ObjChild1Copy(pObj) != (NULL) && Abc_ObjChild1Copy(pObj) != (void*)(1)) )
pObj->pCopy = NULL;
else if(Abc_ObjChild0Copy(pObj) == (void*)(1) && Abc_ObjChild1Copy(pObj) == NULL)
pObj->pCopy = NULL;
else if(Abc_ObjChild0Copy(pObj) == (void*)(1) && Abc_ObjChild1Copy(pObj) == (void*)(1))
pObj->pCopy = (Abc_Obj_t *)(1);
else if(Abc_ObjChild0Copy(pObj) == (void*)(1) && (Abc_ObjChild1Copy(pObj) != (NULL) && Abc_ObjChild1Copy(pObj) != (void*)(1)) )
pObj->pCopy = Abc_ObjChild1Copy(pObj);
else if( (Abc_ObjChild0Copy(pObj) != (NULL) && Abc_ObjChild0Copy(pObj) != (void*)(1)) && Abc_ObjChild1Copy(pObj) == NULL )
pObj->pCopy = NULL;
else if( (Abc_ObjChild0Copy(pObj) != (NULL) && Abc_ObjChild0Copy(pObj) != (void*)(1)) && Abc_ObjChild1Copy(pObj) == (void*)(1) )
pObj->pCopy = Abc_ObjChild0Copy(pObj);
else if( (Abc_ObjChild0Copy(pObj) != (NULL) && Abc_ObjChild0Copy(pObj) != (void*)(1)) &&
(Abc_ObjChild1Copy(pObj) != (NULL) && Abc_ObjChild1Copy(pObj) != (void*)(1)) )
pObj->pCopy = Abc_AigAnd( (Abc_Aig_t *)subNtk->pManFunc, Abc_ObjChild0Copy(pObj), Abc_ObjChild1Copy(pObj) );
}
for(i = 0; i < Abc_NtkPoNum(pNtk); i++)
{
pObj = Abc_NtkPo(pNtk, i);
pObjNew = Abc_NtkDupObj( subNtk, pObj, 1 );
if( Abc_ObjChild0Copy(pObj) == NULL)
{
Abc_ObjAddFanin( pObjNew, Abc_AigConst1(subNtk));
pObjNew->fCompl0 = 1;
}
else if( Abc_ObjChild0Copy(pObj) == (void*)(1) )
{
Abc_ObjAddFanin( pObjNew, Abc_AigConst1(subNtk));
pObjNew->fCompl0 = 0;
}
else
Abc_ObjAddFanin( pObjNew, Abc_ObjChild0Copy(pObj) );
}
return subNtk;
}
FILE *matchFile;
int matchNonSingletonOutputs(Abc_Ntk_t * pNtk1, Vec_Ptr_t ** nodesInLevel1, Vec_Int_t ** iMatch1, Vec_Int_t ** iDep1, Vec_Int_t * matchedInputs1, int * iGroup1, Vec_Int_t ** oMatch1, int * oGroup1,
Abc_Ntk_t * pNtk2, Vec_Ptr_t ** nodesInLevel2, Vec_Int_t ** iMatch2, Vec_Int_t ** iDep2, Vec_Int_t * matchedInputs2, int * iGroup2, Vec_Int_t ** oMatch2, int * oGroup2,
Vec_Int_t * matchedOutputs1, Vec_Int_t * matchedOutputs2, Vec_Int_t * oMatchedGroups, Vec_Int_t * iNonSingleton,
Abc_Ntk_t * subNtk1, Abc_Ntk_t * subNtk2, Vec_Ptr_t * oMatchPairs,
Vec_Int_t * oNonSingleton, int oI, int idx, int ii, int iidx)
{
static int MATCH_FOUND;
int i;
int j, temp;
Vec_Int_t * mismatch;
int * skipList;
static int counter = 0;
MATCH_FOUND = FALSE;
if( oI == Vec_IntSize( oNonSingleton ) )
{
if( iNonSingleton != NULL)
if( match1by1(pNtk1, nodesInLevel1, iMatch1, iDep1, matchedInputs1, iGroup1, oMatch1, oGroup1,
pNtk2, nodesInLevel2, iMatch2, iDep2, matchedInputs2, iGroup2, oMatch2, oGroup2,
matchedOutputs1, matchedOutputs2, oMatchedGroups, iNonSingleton, ii, iidx) )
MATCH_FOUND = TRUE;
if( iNonSingleton == NULL)
MATCH_FOUND = TRUE;
return MATCH_FOUND;
}
i = Vec_IntEntry(oNonSingleton, oI);
mismatch = Vec_IntAlloc(10);
skipList = ABC_ALLOC(int, Vec_IntSize(oMatch1[i]));
for(j = 0; j < Vec_IntSize(oMatch1[i]); j++)
skipList[j] = FALSE;
Vec_PtrPush(oMatchPairs, Abc_NtkPo(subNtk1, Vec_IntEntry(oMatch1[i], idx)) );
Vec_IntPush(matchedOutputs1, Vec_IntEntry(oMatch1[i], idx));
for(j = 0; j < Vec_IntSize( oMatch2[i] ) && MATCH_FOUND == FALSE; j++)
{
if( Vec_IntEntry(oMatch2[i], j) == -1 || skipList[j] == TRUE)
continue;
Vec_PtrPush(oMatchPairs, Abc_NtkPo(subNtk2, Vec_IntEntry(oMatch2[i], j)));
Vec_IntPush(matchedOutputs2, Vec_IntEntry(oMatch2[i], j));
counter++;
if( Abc_NtkBmSat( subNtk1, subNtk2, NULL, oMatchPairs, mismatch, 0) )
{
/*fprintf(matchFile, "%s matched to %s\n", Abc_ObjName(Abc_NtkPo(pNtk1, Vec_IntEntry(oMatch1[i], idx))),
Abc_ObjName(Abc_NtkPo(pNtk2, Vec_IntEntry(oMatch2[i], j)))); */
temp = Vec_IntEntry(oMatch2[i], j);
Vec_IntWriteEntry(oMatch2[i], j, -1);
if(idx != Vec_IntSize( oMatch1[i] ) - 1)
// call the same function with idx+1
matchNonSingletonOutputs(pNtk1, nodesInLevel1, iMatch1, iDep1, matchedInputs1, iGroup1, oMatch1, oGroup1,
pNtk2, nodesInLevel2, iMatch2, iDep2, matchedInputs2, iGroup2, oMatch2, oGroup2,
matchedOutputs1, matchedOutputs2, oMatchedGroups, iNonSingleton,
subNtk1, subNtk2, oMatchPairs,
oNonSingleton, oI, idx+1, ii, iidx);
else
// call the same function with idx = 0 and oI++
matchNonSingletonOutputs(pNtk1, nodesInLevel1, iMatch1, iDep1, matchedInputs1, iGroup1, oMatch1, oGroup1,
pNtk2, nodesInLevel2, iMatch2, iDep2, matchedInputs2, iGroup2, oMatch2, oGroup2,
matchedOutputs1, matchedOutputs2, oMatchedGroups, iNonSingleton,
subNtk1, subNtk2, oMatchPairs,
oNonSingleton, oI+1, 0, ii, iidx);
Vec_IntWriteEntry(oMatch2[i], j, temp);
}
else
{
int * output1, * output2;
int k;
Abc_Obj_t * pObj;
int * pModel;
char * vPiValues;
vPiValues = ABC_ALLOC( char, Abc_NtkPiNum(subNtk1) + 1);
vPiValues[Abc_NtkPiNum(subNtk1)] = '\0';
for(k = 0; k < Abc_NtkPiNum(subNtk1); k++)
vPiValues[k] = '0';
for(k = 0; k < Vec_IntSize(mismatch); k += 2)
vPiValues[Vec_IntEntry(mismatch, k)] = Vec_IntEntry(mismatch, k+1);
pModel = ABC_ALLOC( int, Abc_NtkCiNum(subNtk1) );
Abc_NtkForEachPi( subNtk1, pObj, k )
pModel[k] = vPiValues[k] - '0';
Abc_NtkForEachLatch( subNtk1, pObj, k )
pModel[Abc_NtkPiNum(subNtk1)+k] = pObj->iData - 1;
output1 = Abc_NtkVerifySimulatePattern( subNtk1, pModel );
Abc_NtkForEachLatch( subNtk2, pObj, k )
pModel[Abc_NtkPiNum(subNtk2)+k] = pObj->iData - 1;
output2 = Abc_NtkVerifySimulatePattern( subNtk2, pModel );
for(k = 0; k < Vec_IntSize( oMatch1[i] ); k++)
if(output1[Vec_IntEntry(oMatch1[i], idx)] != output2[Vec_IntEntry(oMatch2[i], k)])
{
skipList[k] = TRUE;
/*printf("Output is SKIPPED");*/
}
ABC_FREE( vPiValues );
ABC_FREE( pModel );
ABC_FREE( output1 );
ABC_FREE( output2 );
}
if(MATCH_FOUND == FALSE )
{
Vec_PtrPop(oMatchPairs);
Vec_IntPop(matchedOutputs2);
}
}
if(MATCH_FOUND == FALSE )
{
Vec_PtrPop(oMatchPairs);
Vec_IntPop(matchedOutputs1);
}
if(MATCH_FOUND && counter != 0)
{
/*printf("Number of OUTPUT SAT instances = %d", counter);*/
counter = 0;
}
ABC_FREE( mismatch );
ABC_FREE( skipList );
return MATCH_FOUND;
}
int match1by1(Abc_Ntk_t * pNtk1, Vec_Ptr_t ** nodesInLevel1, Vec_Int_t ** iMatch1, Vec_Int_t ** iDep1, Vec_Int_t * matchedInputs1, int * iGroup1, Vec_Int_t ** oMatch1, int * oGroup1,
Abc_Ntk_t * pNtk2, Vec_Ptr_t ** nodesInLevel2, Vec_Int_t ** iMatch2, Vec_Int_t ** iDep2, Vec_Int_t * matchedInputs2, int * iGroup2, Vec_Int_t ** oMatch2, int * oGroup2,
Vec_Int_t * matchedOutputs1, Vec_Int_t * matchedOutputs2, Vec_Int_t * oMatchedGroups, Vec_Int_t * iNonSingleton, int ii, int idx)
{
static int MATCH_FOUND = FALSE;
Abc_Ntk_t * subNtk1, * subNtk2;
Vec_Int_t * oNonSingleton;
Vec_Ptr_t * oMatchPairs;
int * skipList;
int j, m;
int i;
static int counter = 0;
MATCH_FOUND = FALSE;
if( ii == Vec_IntSize(iNonSingleton) )
{
MATCH_FOUND = TRUE;
return TRUE;
}
i = Vec_IntEntry(iNonSingleton, ii);
if( idx == Vec_IntSize(iMatch1[i]) )
{
// call again with the next element in iNonSingleton
return match1by1(pNtk1, nodesInLevel1, iMatch1, iDep1, matchedInputs1, iGroup1, oMatch1, oGroup1,
pNtk2, nodesInLevel2, iMatch2, iDep2, matchedInputs2, iGroup2, oMatch2, oGroup2,
matchedOutputs1, matchedOutputs2, oMatchedGroups, iNonSingleton, ii+1, 0);
}
oNonSingleton = Vec_IntAlloc(10);
oMatchPairs = Vec_PtrAlloc(100);
skipList = ABC_ALLOC(int, Vec_IntSize(iMatch1[i]));
for(j = 0; j < Vec_IntSize(iMatch1[i]); j++)
skipList[j] = FALSE;
Vec_IntPush(matchedInputs1, Vec_IntEntry(iMatch1[i], idx));
idx++;
if(idx == 1)
{
for(j = 0; j < Vec_IntSize(iDep1[Vec_IntEntryLast(iMatch1[i])]); j++)
{
if( Vec_IntSize(oMatch1[oGroup1[Vec_IntEntry(iDep1[Vec_IntEntryLast(iMatch1[i])], j)]]) == 1 )
continue;
if( Vec_IntFind( oMatchedGroups, oGroup1[Vec_IntEntry(iDep1[Vec_IntEntryLast(iMatch1[i])], j)]) != -1)
continue;
Vec_IntPushUnique(oNonSingleton, oGroup1[Vec_IntEntry(iDep1[Vec_IntEntryLast(iMatch1[i])], j)]);
Vec_IntPushUnique(oMatchedGroups, oGroup1[Vec_IntEntry(iDep1[Vec_IntEntryLast(iMatch1[i])], j)]);
}
}
subNtk1 = computeCofactor(pNtk1, nodesInLevel1, NULL, matchedInputs1);
for(j = idx-1; j < Vec_IntSize(iMatch2[i]) && MATCH_FOUND == FALSE; j++)
{
int tempJ;
Vec_Int_t * mismatch;
if( skipList[j] )
continue;
mismatch = Vec_IntAlloc(10);
Vec_IntPush(matchedInputs2, Vec_IntEntry(iMatch2[i], j));
subNtk2 = computeCofactor(pNtk2, nodesInLevel2, NULL, matchedInputs2);
for(m = 0; m < Vec_IntSize(matchedOutputs1); m++)
{
Vec_PtrPush(oMatchPairs, Abc_NtkPo(subNtk1, Vec_IntEntry(matchedOutputs1, m)));
Vec_PtrPush(oMatchPairs, Abc_NtkPo(subNtk2, Vec_IntEntry(matchedOutputs2, m)));
}
counter++;
if( Abc_NtkBmSat( subNtk2, subNtk1, NULL, oMatchPairs, mismatch, 0) )
{
if(idx-1 != j)
{
tempJ = Vec_IntEntry(iMatch2[i], idx-1);
Vec_IntWriteEntry(iMatch2[i], idx-1, Vec_IntEntry(iMatch2[i], j));
Vec_IntWriteEntry(iMatch2[i], j, tempJ);
}
/*fprintf(matchFile, "%s matched to %s\n", Abc_ObjName(Abc_NtkPi(pNtk1, Vec_IntEntry(iMatch1[i], idx-1))),
Abc_ObjName(Abc_NtkPi(pNtk2, Vec_IntEntry(iMatch2[i], j))));*/
// we look for a match for outputs in oNonSingleton
matchNonSingletonOutputs(pNtk1, nodesInLevel1, iMatch1, iDep1, matchedInputs1, iGroup1, oMatch1, oGroup1,
pNtk2, nodesInLevel2, iMatch2, iDep2, matchedInputs2, iGroup2, oMatch2, oGroup2,
matchedOutputs1, matchedOutputs2, oMatchedGroups, iNonSingleton,
subNtk1, subNtk2, oMatchPairs, oNonSingleton, 0, 0, ii, idx);
if(idx-1 != j)
{
tempJ = Vec_IntEntry(iMatch2[i], idx-1);
Vec_IntWriteEntry(iMatch2[i], idx-1, Vec_IntEntry(iMatch2[i], j));
Vec_IntWriteEntry(iMatch2[i], j, tempJ);
}
}
else
{
Abc_Ntk_t * FpNtk1, * FpNtk2;
int * bitVector1, * bitVector2;
Vec_Int_t * currInputs1, * currInputs2;
Vec_Ptr_t * vSupp;
Abc_Obj_t * pObj;
int suppNum1 = 0;
int * suppNum2;
bitVector1 = ABC_ALLOC( int, Abc_NtkPiNum(pNtk1) );
bitVector2 = ABC_ALLOC( int, Abc_NtkPiNum(pNtk2) );
currInputs1 = Vec_IntAlloc(10);
currInputs2 = Vec_IntAlloc(10);
suppNum2 = ABC_ALLOC(int, Vec_IntSize(iMatch2[i])-idx+1);
for(m = 0; m < Abc_NtkPiNum(pNtk1); m++)
{
bitVector1[m] = 0;
bitVector2[m] = 0;
}
for(m = 0; m < Vec_IntSize(iMatch2[i])-idx+1; m++)
suppNum2[m]= 0;
// First of all set the value of the inputs that are already matched and are in mismatch
for(m = 0; m < Vec_IntSize(mismatch); m += 2)
{
int n = Vec_IntEntry(mismatch, m);
bitVector1[Vec_IntEntry(matchedInputs1, n)] = Vec_IntEntry(mismatch, m+1);
bitVector2[Vec_IntEntry(matchedInputs2, n)] = Vec_IntEntry(mismatch, m+1);
}
for(m = idx-1; m < Vec_IntSize(iMatch1[i]); m++)
{
Vec_IntPush(currInputs1, Vec_IntEntry(iMatch1[i], m));
Vec_IntPush(currInputs2, Vec_IntEntry(iMatch2[i], m));
}
// Then add all the inputs that are not yet matched to the currInputs
for(m = 0; m < Abc_NtkPiNum(pNtk1); m++)
{
if(Vec_IntFind( matchedInputs1, m ) == -1)
Vec_IntPushUnique(currInputs1, m);
if(Vec_IntFind( matchedInputs2, m ) == -1)
Vec_IntPushUnique(currInputs2, m);
}
FpNtk1 = computeCofactor(pNtk1, nodesInLevel1, bitVector1, currInputs1);
FpNtk2 = computeCofactor(pNtk2, nodesInLevel2, bitVector2, currInputs2);
Abc_NtkForEachPo( FpNtk1, pObj, m )
{
int n;
vSupp = Abc_NtkNodeSupport( FpNtk1, &pObj, 1 );
for(n = 0; n < vSupp->nSize; n++)
if( Abc_ObjId((Abc_Obj_t *)vSupp->pArray[n]) == 1 )
suppNum1 += Vec_IntFind( matchedOutputs1, m) + 1;
Vec_PtrFree( vSupp );
}
Abc_NtkForEachPo( FpNtk2, pObj, m )
{
int n;
vSupp = Abc_NtkNodeSupport( FpNtk2, &pObj, 1 );
for(n = 0; n < vSupp->nSize; n++)
if( (int)Abc_ObjId((Abc_Obj_t *)vSupp->pArray[n])-1 < (Vec_IntSize(iMatch2[i]))-idx+1 &&
(int)Abc_ObjId((Abc_Obj_t *)vSupp->pArray[n])-1 >= 0)
suppNum2[Abc_ObjId((Abc_Obj_t *)vSupp->pArray[n])-1] += Vec_IntFind( matchedOutputs2, m) + 1;
Vec_PtrFree( vSupp );
}
/*if(suppNum1 != 0)
printf("Ntk1 is trigged");
if(suppNum2[0] != 0)
printf("Ntk2 is trigged");*/
for(m = 0; m < Vec_IntSize(iMatch2[i])-idx+1; m++)
if(suppNum2[m] != suppNum1)
{
skipList[m+idx-1] = TRUE;
/*printf("input is skipped");*/
}
Abc_NtkDelete( FpNtk1 );
Abc_NtkDelete( FpNtk2 );
ABC_FREE( bitVector1 );
ABC_FREE( bitVector2 );
Vec_IntFree( currInputs1 );
Vec_IntFree( currInputs2 );
ABC_FREE( suppNum2 );
}
Vec_PtrClear(oMatchPairs);
Abc_NtkDelete( subNtk2 );
Vec_IntFree(mismatch);
//Vec_IntWriteEntry(iMatch2[i], j, tempJ);
if( MATCH_FOUND == FALSE )
Vec_IntPop(matchedInputs2);
}
if( MATCH_FOUND == FALSE )
{
Vec_IntPop(matchedInputs1);
if(idx == 1)
{
for(m = 0; m < Vec_IntSize(oNonSingleton); m++)
Vec_IntPop( oMatchedGroups );
}
}
Vec_IntFree( oNonSingleton );
Vec_PtrFree( oMatchPairs );
ABC_FREE( skipList );
Abc_NtkDelete( subNtk1 );
if(MATCH_FOUND && counter != 0)
{
/*printf("Number of INPUT SAT instances = %d\n", counter);*/
counter = 0;
}
return MATCH_FOUND;
}
float refineBySAT(Abc_Ntk_t * pNtk1, Vec_Int_t ** iMatch1, int * iGroup1, Vec_Int_t ** iDep1, int* iLastItem1, Vec_Int_t ** oMatch1, int * oGroup1, Vec_Int_t ** oDep1, int* oLastItem1, int * observability1,
Abc_Ntk_t * pNtk2, Vec_Int_t ** iMatch2, int * iGroup2, Vec_Int_t ** iDep2, int* iLastItem2, Vec_Int_t ** oMatch2, int * oGroup2, Vec_Int_t ** oDep2, int* oLastItem2, int * observability2)
{
int i, j;
Abc_Obj_t * pObj;
Vec_Int_t * iNonSingleton;
Vec_Int_t * matchedInputs1, * matchedInputs2;
Vec_Int_t * matchedOutputs1, * matchedOutputs2;
Vec_Ptr_t ** nodesInLevel1, ** nodesInLevel2;
Vec_Int_t * oMatchedGroups;
FILE *result;
int matchFound;
abctime clk = Abc_Clock();
float satTime = 0.0;
/*matchFile = fopen("satmatch.txt", "w");*/
iNonSingleton = Vec_IntAlloc(10);
matchedInputs1 = Vec_IntAlloc( Abc_NtkPiNum(pNtk1) );
matchedInputs2 = Vec_IntAlloc( Abc_NtkPiNum(pNtk2) );
matchedOutputs1 = Vec_IntAlloc( Abc_NtkPoNum(pNtk1) );
matchedOutputs2 = Vec_IntAlloc( Abc_NtkPoNum(pNtk2) );
nodesInLevel1 = ABC_ALLOC( Vec_Ptr_t *, Abc_AigLevel( pNtk1 ) + 1); // why numOfLevels+1? because the inputs are in level 0
for(i = 0; i <= Abc_AigLevel( pNtk1 ); i++)
nodesInLevel1[i] = Vec_PtrAlloc( 20 );
// bucket sort the objects based on their levels
Abc_AigForEachAnd( pNtk1, pObj, i )
Vec_PtrPush(nodesInLevel1[Abc_ObjLevel(pObj)], pObj);
nodesInLevel2 = ABC_ALLOC( Vec_Ptr_t *, Abc_AigLevel( pNtk2 ) + 1); // why numOfLevels+1? because the inputs are in level 0
for(i = 0; i <= Abc_AigLevel( pNtk2 ); i++)
nodesInLevel2[i] = Vec_PtrAlloc( 20 );
// bucket sort the objects based on their levels
Abc_AigForEachAnd( pNtk2, pObj, i )
Vec_PtrPush(nodesInLevel2[Abc_ObjLevel(pObj)], pObj);
oMatchedGroups = Vec_IntAlloc( 10 );
for(i = 0; i < *iLastItem1; i++)
{
if(Vec_IntSize(iMatch1[i]) == 1)
{
Vec_IntPush(matchedInputs1, Vec_IntEntryLast(iMatch1[i]));
Vec_IntPush(matchedInputs2, Vec_IntEntryLast(iMatch2[i]));
}
else
Vec_IntPush(iNonSingleton, i);
}
for(i = 0; i < *oLastItem1; i++)
{
if(Vec_IntSize(oMatch1[i]) == 1)
{
Vec_IntPush(matchedOutputs1, Vec_IntEntryLast(oMatch1[i]));
Vec_IntPush(matchedOutputs2, Vec_IntEntryLast(oMatch2[i]));
}
}
for(i = 0; i < Vec_IntSize(iNonSingleton) - 1; i++)
{
for(j = i + 1; j < Vec_IntSize(iNonSingleton); j++)
if( observability2[Vec_IntEntry(iMatch2[Vec_IntEntry(iNonSingleton, j)], 0)] >
observability2[Vec_IntEntry(iMatch2[Vec_IntEntry(iNonSingleton, i)], 0)] )
{
int temp = Vec_IntEntry(iNonSingleton, i);
Vec_IntWriteEntry( iNonSingleton, i, Vec_IntEntry(iNonSingleton, j) );
Vec_IntWriteEntry( iNonSingleton, j, temp );
}
else if( observability2[Vec_IntEntry(iMatch2[Vec_IntEntry(iNonSingleton, j)], 0)] ==
observability2[Vec_IntEntry(iMatch2[Vec_IntEntry(iNonSingleton, i)], 0)] )
{
if( Vec_IntSize(iMatch2[Vec_IntEntry(iNonSingleton, j)]) < Vec_IntSize(iMatch2[Vec_IntEntry(iNonSingleton, i)]) )
{
int temp = Vec_IntEntry(iNonSingleton, i);
Vec_IntWriteEntry( iNonSingleton, i, Vec_IntEntry(iNonSingleton, j) );
Vec_IntWriteEntry( iNonSingleton, j, temp );
}
}
}
/*for(i = 0; i < Vec_IntSize(iNonSingleton) - 1; i++)
{
for(j = i + 1; j < Vec_IntSize(iNonSingleton); j++)
if( Vec_IntSize(oDep2[oGroup2[Vec_IntEntryLast(iMatch2[Vec_IntEntry(iNonSingleton, j)])]]) >
Vec_IntSize(oDep2[oGroup2[Vec_IntEntryLast(iMatch2[Vec_IntEntry(iNonSingleton, i)])]]) )
{
int temp = Vec_IntEntry(iNonSingleton, i);
Vec_IntWriteEntry( iNonSingleton, i, Vec_IntEntry(iNonSingleton, j) );
Vec_IntWriteEntry( iNonSingleton, j, temp );
}
else if( Vec_IntSize(oDep2[oGroup2[Vec_IntEntryLast(iMatch2[Vec_IntEntry(iNonSingleton, j)])]]) ==
Vec_IntSize(oDep2[oGroup2[Vec_IntEntryLast(iMatch2[Vec_IntEntry(iNonSingleton, i)])]]) )
{
if( observability2[Vec_IntEntry(iMatch2[Vec_IntEntry(iNonSingleton, j)], 0)] >
observability2[Vec_IntEntry(iMatch2[Vec_IntEntry(iNonSingleton, i)], 0)] )
{
int temp = Vec_IntEntry(iNonSingleton, i);
Vec_IntWriteEntry( iNonSingleton, i, Vec_IntEntry(iNonSingleton, j) );
Vec_IntWriteEntry( iNonSingleton, j, temp );
}
}
}*/
matchFound = match1by1(pNtk1, nodesInLevel1, iMatch1, iDep1, matchedInputs1, iGroup1, oMatch1, oGroup1,
pNtk2, nodesInLevel2, iMatch2, iDep2, matchedInputs2, iGroup2, oMatch2, oGroup2,
matchedOutputs1, matchedOutputs2, oMatchedGroups, iNonSingleton, 0, 0);
if( matchFound && Vec_IntSize(matchedOutputs1) != Abc_NtkPoNum(pNtk1) )
{
Vec_Int_t * oNonSingleton;
Vec_Ptr_t * oMatchPairs;
Abc_Ntk_t * subNtk1, * subNtk2;
oNonSingleton = Vec_IntAlloc( 10 );
oMatchPairs = Vec_PtrAlloc(Abc_NtkPoNum(pNtk1) * 2);
for(i = 0; i < *oLastItem1; i++)
if( Vec_IntSize(oMatch1[i]) > 1 && Vec_IntFind( oMatchedGroups, i) == -1 )
Vec_IntPush(oNonSingleton, i);
subNtk1 = computeCofactor(pNtk1, nodesInLevel1, NULL, matchedInputs1);
subNtk2 = computeCofactor(pNtk2, nodesInLevel2, NULL, matchedInputs2);
matchFound = matchNonSingletonOutputs(pNtk1, nodesInLevel1, iMatch1, iDep1, matchedInputs1, iGroup1, oMatch1, oGroup1,
pNtk2, nodesInLevel2, iMatch2, iDep2, matchedInputs2, iGroup1, oMatch2, oGroup2,
matchedOutputs1, matchedOutputs2, oMatchedGroups, NULL,
subNtk1, subNtk2, oMatchPairs, oNonSingleton, 0, 0, 0, 0);
Vec_IntFree( oNonSingleton );
Vec_PtrFree( oMatchPairs );
Abc_NtkDelete(subNtk1);
Abc_NtkDelete(subNtk2);
}
satTime = (float)(Abc_Clock() - clk)/(float)(CLOCKS_PER_SEC);
if( matchFound )
{
checkEquivalence( pNtk1, matchedInputs1, matchedOutputs1, pNtk2, matchedInputs2, matchedOutputs2);
result = fopen("IOmatch.txt", "w");
fprintf(result, "I/O = %d / %d \n\n", Abc_NtkPiNum(pNtk1), Abc_NtkPoNum(pNtk1));
for(i = 0; i < Vec_IntSize(matchedInputs1) ; i++)
fprintf(result, "{%s}\t{%s}\n", Abc_ObjName(Abc_NtkPi(pNtk1, Vec_IntEntry(matchedInputs1, i))), Abc_ObjName(Abc_NtkPi(pNtk2, Vec_IntEntry(matchedInputs2, i))) );
fprintf(result, "\n-----------------------------------------\n");
for(i = 0; i < Vec_IntSize(matchedOutputs1) ; i++)
fprintf(result, "{%s}\t{%s}\n", Abc_ObjName(Abc_NtkPo(pNtk1, Vec_IntEntry(matchedOutputs1, i))), Abc_ObjName(Abc_NtkPo(pNtk2, Vec_IntEntry(matchedOutputs2, i))) );
fclose( result );
}
Vec_IntFree( matchedInputs1 );
Vec_IntFree( matchedInputs2 );
Vec_IntFree( matchedOutputs1 );
Vec_IntFree( matchedOutputs2 );
Vec_IntFree( iNonSingleton );
Vec_IntFree( oMatchedGroups );
for(i = 0; i <= Abc_AigLevel( pNtk1 ); i++)
Vec_PtrFree( nodesInLevel1[i] );
for(i = 0; i <= Abc_AigLevel( pNtk2 ); i++)
Vec_PtrFree( nodesInLevel2[i] );
ABC_FREE( nodesInLevel1 );
ABC_FREE( nodesInLevel2 );
/*fclose(matchFile);*/
return satTime;
}
int checkListConsistency(Vec_Int_t ** iMatch1, Vec_Int_t ** oMatch1, Vec_Int_t ** iMatch2, Vec_Int_t ** oMatch2, int iLastItem1, int oLastItem1, int iLastItem2, int oLastItem2)
{
//int i;
if(iLastItem1 != iLastItem2 || oLastItem1 != oLastItem2)
return FALSE;
/*for(i = 0; i < iLastItem1; i++) {
if(Vec_IntSize(iMatch1[i]) != Vec_IntSize(iMatch2[i]))
return FALSE;
}
for(i = 0; i < oLastItem1; i++) {
if(Vec_IntSize(oMatch1[i]) != Vec_IntSize(oMatch2[i]))
return FALSE;
}*/
return TRUE;
}
void bmGateWay( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int p_equivalence )
{
Vec_Int_t ** iDep1, ** oDep1;
Vec_Int_t ** iDep2, ** oDep2;
Vec_Int_t ** iMatch1, ** oMatch1;
Vec_Int_t ** iMatch2, ** oMatch2;
int * iGroup1, * oGroup1;
int * iGroup2, * oGroup2;
int iLastItem1, oLastItem1;
int iLastItem2, oLastItem2;
int i, j;
char * vPiValues1, * vPiValues2;
int * observability1, * observability2;
abctime clk = Abc_Clock();
float initTime;
float simulTime;
float satTime;
Vec_Ptr_t ** topOrder1 = NULL, ** topOrder2 = NULL;
extern void getDependencies(Abc_Ntk_t *pNtk, Vec_Int_t** iDep, Vec_Int_t** oDep);
extern void initMatchList(Abc_Ntk_t *pNtk, Vec_Int_t** iDep, Vec_Int_t** oDep, Vec_Int_t** iMatch, int* iLastItem, Vec_Int_t** oMatch, int* oLastItem, int* iGroup, int* oGroup, int p_equivalence);
extern void iSortDependencies(Abc_Ntk_t *pNtk, Vec_Int_t** iDep, int* oGroup);
extern void oSortDependencies(Abc_Ntk_t *pNtk, Vec_Int_t** oDep, int* iGroup);
extern int iSplitByDep(Abc_Ntk_t *pNtk, Vec_Int_t** iDep, Vec_Int_t** iMatch, int* iGroup, int* iLastItem, int* oGroup);
extern int oSplitByDep(Abc_Ntk_t *pNtk, Vec_Int_t** oDep, Vec_Int_t** oMatch, int* oGroup, int* oLastItem, int* iGroup);
extern Vec_Ptr_t ** findTopologicalOrder(Abc_Ntk_t * pNtk);
extern int refineIOBySimulation(Abc_Ntk_t *pNtk, Vec_Int_t** iMatch, int* iLastItem, int * iGroup, Vec_Int_t** iDep, Vec_Int_t** oMatch, int* oLastItem, int * oGroup, Vec_Int_t** oDep, char * vPiValues, int * observability, Vec_Ptr_t ** topOrder);
extern float refineBySAT(Abc_Ntk_t * pNtk1, Vec_Int_t ** iMatch1, int * iGroup1, Vec_Int_t ** iDep1, int* iLastItem1, Vec_Int_t ** oMatch1, int * oGroup1, Vec_Int_t ** oDep1, int* oLastItem1, int * observability1,
Abc_Ntk_t * pNtk2, Vec_Int_t ** iMatch2, int * iGroup2, Vec_Int_t ** iDep2, int* iLastItem2, Vec_Int_t ** oMatch2, int * oGroup2, Vec_Int_t ** oDep2, int* oLastItem2, int * observability2);
int checkListConsistency(Vec_Int_t ** iMatch1, Vec_Int_t ** oMatch1, Vec_Int_t ** iMatch2, Vec_Int_t ** oMatch2, int iLastItem1, int oLastItem1, int iLastItem2, int oLastItem2);
iDep1 = ABC_ALLOC( Vec_Int_t*, (unsigned)Abc_NtkPiNum(pNtk1) );
oDep1 = ABC_ALLOC( Vec_Int_t*, (unsigned)Abc_NtkPoNum(pNtk1) );
iDep2 = ABC_ALLOC( Vec_Int_t*, (unsigned)Abc_NtkPiNum(pNtk2) );
oDep2 = ABC_ALLOC( Vec_Int_t*, (unsigned)Abc_NtkPoNum(pNtk2) );
iMatch1 = ABC_ALLOC( Vec_Int_t*, (unsigned)Abc_NtkPiNum(pNtk1) );
oMatch1 = ABC_ALLOC( Vec_Int_t*, (unsigned)Abc_NtkPoNum(pNtk1) );
iMatch2 = ABC_ALLOC( Vec_Int_t*, (unsigned)Abc_NtkPiNum(pNtk2) );
oMatch2 = ABC_ALLOC( Vec_Int_t*, (unsigned)Abc_NtkPoNum(pNtk2) );
iGroup1 = ABC_ALLOC( int, Abc_NtkPiNum(pNtk1) );
oGroup1 = ABC_ALLOC( int, Abc_NtkPoNum(pNtk1) );
iGroup2 = ABC_ALLOC( int, Abc_NtkPiNum(pNtk2) );
oGroup2 = ABC_ALLOC( int, Abc_NtkPoNum(pNtk2) );
vPiValues1 = ABC_ALLOC( char, Abc_NtkPiNum(pNtk1) + 1);
vPiValues1[Abc_NtkPiNum(pNtk1)] = '\0';
vPiValues2 = ABC_ALLOC( char, Abc_NtkPiNum(pNtk2) + 1);
vPiValues2[Abc_NtkPiNum(pNtk2)] = '\0';
observability1 = ABC_ALLOC(int, (unsigned)Abc_NtkPiNum(pNtk1));
observability2 = ABC_ALLOC(int, (unsigned)Abc_NtkPiNum(pNtk2));
for(i = 0; i < Abc_NtkPiNum(pNtk1); i++)
{
iDep1[i] = Vec_IntAlloc( 1 );
iMatch1[i] = Vec_IntAlloc( 1 );
iDep2[i] = Vec_IntAlloc( 1 );
iMatch2[i] = Vec_IntAlloc( 1 );
vPiValues1[i] = '0';
vPiValues2[i] = '0';
observability1[i] = 0;
observability2[i] = 0;
}
for(i = 0; i < Abc_NtkPoNum(pNtk1); i++)
{
oDep1[i] = Vec_IntAlloc( 1 );
oMatch1[i] = Vec_IntAlloc( 1 );
oDep2[i] = Vec_IntAlloc( 1 );
oMatch2[i] = Vec_IntAlloc( 1 );
}
/************* Strashing ************/
pNtk1 = Abc_NtkStrash( pNtk1, 0, 0, 0 );
pNtk2 = Abc_NtkStrash( pNtk2, 0, 0, 0 );
printf("Network strashing is done!\n");
/************************************/
/******* Getting Dependencies *******/
getDependencies(pNtk1, iDep1, oDep1);
getDependencies(pNtk2, iDep2, oDep2);
printf("Getting dependencies is done!\n");
/************************************/
/***** Intializing match lists ******/
initMatchList(pNtk1, iDep1, oDep1, iMatch1, &iLastItem1, oMatch1, &oLastItem1, iGroup1, oGroup1, p_equivalence);
initMatchList(pNtk2, iDep2, oDep2, iMatch2, &iLastItem2, oMatch2, &oLastItem2, iGroup2, oGroup2, p_equivalence);
printf("Initializing match lists is done!\n");
/************************************/
if( !checkListConsistency(iMatch1, oMatch1, iMatch2, oMatch2, iLastItem1, oLastItem1, iLastItem2, oLastItem2) )
{
fprintf( stdout, "I/O dependencies of two circuits are different.\n");
goto freeAndExit;
}
printf("Refining IOs by dependencies ...");
// split match lists further by checking dependencies
do
{
int iNumOfItemsAdded = 1, oNumOfItemsAdded = 1;
do
{
if( oNumOfItemsAdded )
{
iSortDependencies(pNtk1, iDep1, oGroup1);
iSortDependencies(pNtk2, iDep2, oGroup2);
}
if( iNumOfItemsAdded )
{
oSortDependencies(pNtk1, oDep1, iGroup1);
oSortDependencies(pNtk2, oDep2, iGroup2);
}
if( iLastItem1 < Abc_NtkPiNum(pNtk1) )
{
iSplitByDep(pNtk1, iDep1, iMatch1, iGroup1, &iLastItem1, oGroup1);
if( oLastItem1 < Abc_NtkPoNum(pNtk1) )
oSplitByDep(pNtk1, oDep1, oMatch1, oGroup1, &oLastItem1, iGroup1);
}
if( iLastItem2 < Abc_NtkPiNum(pNtk2) )
iNumOfItemsAdded = iSplitByDep(pNtk2, iDep2, iMatch2, iGroup2, &iLastItem2, oGroup2);
else
iNumOfItemsAdded = 0;
if( oLastItem2 < Abc_NtkPoNum(pNtk2) )
oNumOfItemsAdded = oSplitByDep(pNtk2, oDep2, oMatch2, oGroup2, &oLastItem2, iGroup2);
else
oNumOfItemsAdded = 0;
if(!checkListConsistency(iMatch1, oMatch1, iMatch2, oMatch2, iLastItem1, oLastItem1, iLastItem2, oLastItem2))
{
fprintf( stdout, "I/O dependencies of two circuits are different.\n");
goto freeAndExit;
}
}while(iNumOfItemsAdded != 0 || oNumOfItemsAdded != 0);
}while(0);
printf(" done!\n");
initTime = ((float)(Abc_Clock() - clk)/(float)(CLOCKS_PER_SEC));
clk = Abc_Clock();
topOrder1 = findTopologicalOrder(pNtk1);
topOrder2 = findTopologicalOrder(pNtk2);
printf("Refining IOs by simulation ...");
do
{
int counter = 0;
int ioSuccess1, ioSuccess2;
do
{
for(i = 0; i < iLastItem1; i++)
{
int temp = (int)(SIM_RANDOM_UNSIGNED % 2);
if(Vec_IntSize(iMatch1[i]) != Vec_IntSize(iMatch2[i]))
{
fprintf( stdout, "Input refinement by simulation finds two circuits different.\n");
goto freeAndExit;
}
for(j = 0; j < Vec_IntSize(iMatch1[i]); j++)
{
vPiValues1[Vec_IntEntry(iMatch1[i], j)] = temp + '0';
vPiValues2[Vec_IntEntry(iMatch2[i], j)] = temp + '0';
}
}
ioSuccess1 = refineIOBySimulation(pNtk1, iMatch1, &iLastItem1, iGroup1, iDep1, oMatch1, &oLastItem1, oGroup1, oDep1, vPiValues1, observability1, topOrder1);
ioSuccess2 = refineIOBySimulation(pNtk2, iMatch2, &iLastItem2, iGroup2, iDep2, oMatch2, &oLastItem2, oGroup2, oDep2, vPiValues2, observability2, topOrder2);
if(ioSuccess1 && ioSuccess2)
counter = 0;
else
counter++;
if(ioSuccess1 != ioSuccess2 ||
!checkListConsistency(iMatch1, oMatch1, iMatch2, oMatch2, iLastItem1, oLastItem1, iLastItem2, oLastItem2))
{
fprintf( stdout, "Input refinement by simulation finds two circuits different.\n");
goto freeAndExit;
}
}while(counter <= 200);
}while(0);
printf(" done!\n");
simulTime = (float)(Abc_Clock() - clk)/(float)(CLOCKS_PER_SEC);
printf("SAT-based search started ...\n");
satTime = refineBySAT(pNtk1, iMatch1, iGroup1, iDep1, &iLastItem1, oMatch1, oGroup1, oDep1, &oLastItem1, observability1,
pNtk2, iMatch2, iGroup2, iDep2, &iLastItem2, oMatch2, oGroup2, oDep2, &oLastItem2, observability2);
printf( "Init Time = %4.2f\n", initTime );
printf( "Simulation Time = %4.2f\n", simulTime );
printf( "SAT Time = %4.2f\n", satTime );
printf( "Overall Time = %4.2f\n", initTime + simulTime + satTime );
freeAndExit:
for(i = 0; i < iLastItem1 ; i++)
{
Vec_IntFree( iMatch1[i] );
Vec_IntFree( iMatch2[i] );
}
for(i = 0; i < oLastItem1 ; i++)
{
Vec_IntFree( oMatch1[i] );
Vec_IntFree( oMatch2[i] );
}
for(i = 0; i < Abc_NtkPiNum(pNtk1); i++)
{
Vec_IntFree( iDep1[i] );
Vec_IntFree( iDep2[i] );
if(topOrder1 != NULL) {
Vec_PtrFree( topOrder1[i] );
Vec_PtrFree( topOrder2[i] );
}
}
for(i = 0; i < Abc_NtkPoNum(pNtk1); i++)
{
Vec_IntFree( oDep1[i] );
Vec_IntFree( oDep2[i] );
}
ABC_FREE( iMatch1 );
ABC_FREE( iMatch2 );
ABC_FREE( oMatch1 );
ABC_FREE( oMatch2 );
ABC_FREE( iDep1 );
ABC_FREE( iDep2 );
ABC_FREE( oDep1 );
ABC_FREE( oDep2 );
ABC_FREE( iGroup1 );
ABC_FREE( iGroup2 );
ABC_FREE( oGroup1 );
ABC_FREE( oGroup2 );
ABC_FREE( vPiValues1 );
ABC_FREE( vPiValues2 );
ABC_FREE( observability1 );
ABC_FREE( observability2 );
if(topOrder1 != NULL) {
ABC_FREE( topOrder1 );
ABC_FREE( topOrder2 );
}
}ABC_NAMESPACE_IMPL_END