00001
00021 #include "abc.h"
00022 #include "sim.h"
00023
00027
00028 #define SIM_READ_SYMMS(pNode) ((Vec_Int_t *)pNode->pCopy)
00029 #define SIM_SET_SYMMS(pNode,vVect) (pNode->pCopy = (Abc_Obj_t *)(vVect))
00030
00031 static void Sim_SymmsStructComputeOne( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode, int * pMap );
00032 static void Sim_SymmsBalanceCollect_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes );
00033 static void Sim_SymmsPartitionNodes( Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesPis0, Vec_Ptr_t * vNodesPis1, Vec_Ptr_t * vNodesOther );
00034 static void Sim_SymmsAppendFromGroup( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodesPi, Vec_Ptr_t * vNodesOther, Vec_Int_t * vSymms, int * pMap );
00035 static void Sim_SymmsAppendFromNode( Abc_Ntk_t * pNtk, Vec_Int_t * vSymms0, Vec_Ptr_t * vNodesOther, Vec_Ptr_t * vNodesPi0, Vec_Ptr_t * vNodesPi1, Vec_Int_t * vSymms, int * pMap );
00036 static int Sim_SymmsIsCompatibleWithNodes( Abc_Ntk_t * pNtk, unsigned uSymm, Vec_Ptr_t * vNodesOther, int * pMap );
00037 static int Sim_SymmsIsCompatibleWithGroup( unsigned uSymm, Vec_Ptr_t * vNodesPi, int * pMap );
00038 static void Sim_SymmsPrint( Vec_Int_t * vSymms );
00039 static void Sim_SymmsTrans( Vec_Int_t * vSymms );
00040 static void Sim_SymmsTransferToMatrix( Extra_BitMat_t * pMatSymm, Vec_Int_t * vSymms, unsigned * pSupport );
00041 static int * Sim_SymmsCreateMap( Abc_Ntk_t * pNtk );
00042
00046
00058 void Sim_SymmsStructCompute( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMatrs, Vec_Ptr_t * vSuppFun )
00059 {
00060 Vec_Ptr_t * vNodes;
00061 Abc_Obj_t * pTemp;
00062 int * pMap, i;
00063
00064 assert( Abc_NtkCiNum(pNtk) + 10 < (1<<16) );
00065
00066
00067 pNtk->vSupps = Sim_ComputeStrSupp( pNtk );
00068
00069 Abc_NtkForEachCi( pNtk, pTemp, i )
00070 SIM_SET_SYMMS( pTemp, Vec_IntAlloc(0) );
00071
00072 pMap = Sim_SymmsCreateMap( pNtk );
00073
00074 vNodes = Abc_NtkDfs( pNtk, 0 );
00075 Vec_PtrForEachEntry( vNodes, pTemp, i )
00076 {
00077
00078
00079 Sim_SymmsStructComputeOne( pNtk, pTemp, pMap );
00080 }
00081
00082 Abc_NtkForEachCo( pNtk, pTemp, i )
00083 {
00084
00085 pTemp = Abc_ObjFanin0(pTemp);
00086 if ( Abc_ObjIsCi(pTemp) || Abc_AigNodeIsConst(pTemp) )
00087 continue;
00088 Sim_SymmsTransferToMatrix( Vec_PtrEntry(vMatrs, i), SIM_READ_SYMMS(pTemp), Vec_PtrEntry(vSuppFun, i) );
00089 }
00090
00091 Sim_UtilInfoFree( pNtk->vSupps );
00092 pNtk->vSupps = NULL;
00093 Abc_NtkForEachCi( pNtk, pTemp, i )
00094 Vec_IntFree( SIM_READ_SYMMS(pTemp) );
00095 Vec_PtrForEachEntry( vNodes, pTemp, i )
00096
00097 Vec_IntFree( SIM_READ_SYMMS(pTemp) );
00098 Vec_PtrFree( vNodes );
00099 free( pMap );
00100 }
00101
00113 void Sim_SymmsStructComputeOne( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode, int * pMap )
00114 {
00115 Vec_Ptr_t * vNodes, * vNodesPi0, * vNodesPi1, * vNodesOther;
00116 Vec_Int_t * vSymms;
00117 Abc_Obj_t * pTemp;
00118 int i;
00119
00120
00121 vNodes = Vec_PtrAlloc( 10 );
00122 vNodesPi0 = Vec_PtrAlloc( 10 );
00123 vNodesPi1 = Vec_PtrAlloc( 10 );
00124 vNodesOther = Vec_PtrAlloc( 10 );
00125
00126
00127 Sim_SymmsBalanceCollect_rec( pNode, vNodes );
00128
00129
00130 Sim_SymmsPartitionNodes( vNodes, vNodesPi0, vNodesPi1, vNodesOther );
00131
00132
00133 vSymms = Vec_IntAlloc( 10 );
00134
00135 Sim_SymmsAppendFromGroup( pNtk, vNodesPi0, vNodesOther, vSymms, pMap );
00136 Sim_SymmsAppendFromGroup( pNtk, vNodesPi1, vNodesOther, vSymms, pMap );
00137
00138 for ( i = 0; i < vNodesOther->nSize; i++ )
00139 {
00140 pTemp = Abc_ObjRegular(vNodesOther->pArray[i]);
00141 Sim_SymmsAppendFromNode( pNtk, SIM_READ_SYMMS(pTemp), vNodesOther, vNodesPi0, vNodesPi1, vSymms, pMap );
00142 }
00143 Vec_PtrFree( vNodes );
00144 Vec_PtrFree( vNodesPi0 );
00145 Vec_PtrFree( vNodesPi1 );
00146 Vec_PtrFree( vNodesOther );
00147
00148
00149 SIM_SET_SYMMS( pNode, vSymms );
00150 }
00151
00152
00164 void Sim_SymmsBalanceCollect_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes )
00165 {
00166
00167 if ( Abc_ObjIsComplement(pNode) )
00168 {
00169 Vec_PtrPushUnique( vNodes, pNode );
00170 return;
00171 }
00172
00173 if ( Abc_ObjIsCi(pNode) )
00174 {
00175 Vec_PtrPushUnique( vNodes, pNode );
00176 return;
00177 }
00178
00179 Sim_SymmsBalanceCollect_rec( Abc_ObjChild0(pNode), vNodes );
00180 Sim_SymmsBalanceCollect_rec( Abc_ObjChild1(pNode), vNodes );
00181 }
00182
00194 void Sim_SymmsPartitionNodes( Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesPis0,
00195 Vec_Ptr_t * vNodesPis1, Vec_Ptr_t * vNodesOther )
00196 {
00197 Abc_Obj_t * pNode;
00198 int i;
00199 Vec_PtrForEachEntry( vNodes, pNode, i )
00200 {
00201 if ( !Abc_ObjIsCi(Abc_ObjRegular(pNode)) )
00202 Vec_PtrPush( vNodesOther, pNode );
00203 else if ( Abc_ObjIsComplement(pNode) )
00204 Vec_PtrPush( vNodesPis0, pNode );
00205 else
00206 Vec_PtrPush( vNodesPis1, pNode );
00207 }
00208 }
00209
00221 void Sim_SymmsAppendFromGroup( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodesPi, Vec_Ptr_t * vNodesOther, Vec_Int_t * vSymms, int * pMap )
00222 {
00223 Abc_Obj_t * pNode1, * pNode2;
00224 unsigned uSymm;
00225 int i, k;
00226
00227 if ( vNodesPi->nSize == 0 )
00228 return;
00229
00230
00231 for ( i = 0; i < vNodesPi->nSize; i++ )
00232 for ( k = i+1; k < vNodesPi->nSize; k++ )
00233 {
00234
00235 pNode1 = Abc_ObjRegular(vNodesPi->pArray[i]);
00236 pNode2 = Abc_ObjRegular(vNodesPi->pArray[k]);
00237 assert( pMap[pNode1->Id] != pMap[pNode2->Id] );
00238 assert( pMap[pNode1->Id] >= 0 );
00239 assert( pMap[pNode2->Id] >= 0 );
00240
00241 if ( pMap[pNode1->Id] < pMap[pNode2->Id] )
00242 uSymm = ((pMap[pNode1->Id] << 16) | pMap[pNode2->Id]);
00243 else
00244 uSymm = ((pMap[pNode2->Id] << 16) | pMap[pNode1->Id]);
00245
00246 if ( Sim_SymmsIsCompatibleWithNodes( pNtk, uSymm, vNodesOther, pMap ) )
00247 Vec_IntPushUnique( vSymms, (int)uSymm );
00248 }
00249 }
00250
00262 void Sim_SymmsAppendFromNode( Abc_Ntk_t * pNtk, Vec_Int_t * vSymms0, Vec_Ptr_t * vNodesOther,
00263 Vec_Ptr_t * vNodesPi0, Vec_Ptr_t * vNodesPi1, Vec_Int_t * vSymms, int * pMap )
00264 {
00265 unsigned uSymm;
00266 int i;
00267
00268 if ( vSymms0->nSize == 0 )
00269 return;
00270
00271
00272 for ( i = 0; i < vSymms0->nSize; i++ )
00273 {
00274 uSymm = (unsigned)vSymms0->pArray[i];
00275
00276 if ( Sim_SymmsIsCompatibleWithNodes( pNtk, uSymm, vNodesOther, pMap ) &&
00277 Sim_SymmsIsCompatibleWithGroup( uSymm, vNodesPi0, pMap ) &&
00278 Sim_SymmsIsCompatibleWithGroup( uSymm, vNodesPi1, pMap ) )
00279 Vec_IntPushUnique( vSymms, (int)uSymm );
00280 }
00281 }
00282
00294 int Sim_SymmsIsCompatibleWithNodes( Abc_Ntk_t * pNtk, unsigned uSymm, Vec_Ptr_t * vNodesOther, int * pMap )
00295 {
00296 Vec_Int_t * vSymmsNode;
00297 Abc_Obj_t * pNode;
00298 int i, s, Ind1, Ind2, fIsVar1, fIsVar2;
00299
00300 if ( vNodesOther->nSize == 0 )
00301 return 1;
00302
00303
00304 Ind1 = (uSymm & 0xffff);
00305 Ind2 = (uSymm >> 16);
00306
00307
00308
00309
00310
00311 for ( i = 0; i < vNodesOther->nSize; i++ )
00312 {
00313 pNode = Abc_ObjRegular(vNodesOther->pArray[i]);
00314 fIsVar1 = Sim_SuppStrHasVar( pNtk->vSupps, pNode, Ind1 );
00315 fIsVar2 = Sim_SuppStrHasVar( pNtk->vSupps, pNode, Ind2 );
00316
00317 if ( !fIsVar1 && !fIsVar2 )
00318 continue;
00319 if ( fIsVar1 ^ fIsVar2 )
00320 return 0;
00321
00322
00323 vSymmsNode = SIM_READ_SYMMS( pNode );
00324 for ( s = 0; s < vSymmsNode->nSize; s++ )
00325 if ( uSymm == (unsigned)vSymmsNode->pArray[s] )
00326 break;
00327 if ( s == vSymmsNode->nSize )
00328 return 0;
00329 }
00330 return 1;
00331 }
00332
00344 int Sim_SymmsIsCompatibleWithGroup( unsigned uSymm, Vec_Ptr_t * vNodesPi, int * pMap )
00345 {
00346 Abc_Obj_t * pNode;
00347 int i, Ind1, Ind2, fHasVar1, fHasVar2;
00348
00349 if ( vNodesPi->nSize == 0 )
00350 return 1;
00351
00352
00353 Ind1 = (uSymm & 0xffff);
00354 Ind2 = (uSymm >> 16);
00355
00356
00357 fHasVar1 = fHasVar2 = 0;
00358 for ( i = 0; i < vNodesPi->nSize; i++ )
00359 {
00360 pNode = Abc_ObjRegular(vNodesPi->pArray[i]);
00361 if ( pMap[pNode->Id] == Ind1 )
00362 fHasVar1 = 1;
00363 else if ( pMap[pNode->Id] == Ind2 )
00364 fHasVar2 = 1;
00365 }
00366 return fHasVar1 == fHasVar2;
00367 }
00368
00369
00370
00382 void Sim_SymmsTrans( Vec_Int_t * vSymms )
00383 {
00384 unsigned uSymm, uSymma, uSymmr;
00385 int i, Ind1, Ind2;
00386 int k, Ind1a, Ind2a;
00387 int j;
00388 int nTrans = 0;
00389
00390 for ( i = 0; i < vSymms->nSize; i++ )
00391 {
00392 uSymm = (unsigned)vSymms->pArray[i];
00393 Ind1 = (uSymm & 0xffff);
00394 Ind2 = (uSymm >> 16);
00395
00396 for ( k = i+1; k < vSymms->nSize; k++ )
00397 {
00398 uSymma = (unsigned)vSymms->pArray[k];
00399 if ( uSymma == uSymm )
00400 continue;
00401 Ind1a = (uSymma & 0xffff);
00402 Ind2a = (uSymma >> 16);
00403 if ( Ind1a == Ind1 )
00404 {
00405
00406 if ( Ind2 < Ind2a )
00407 uSymmr = ((Ind2 << 16) | Ind2a);
00408 else
00409 uSymmr = ((Ind2a << 16) | Ind2);
00410 for ( j = 0; j < vSymms->nSize; j++ )
00411 if ( uSymmr == (unsigned)vSymms->pArray[j] )
00412 break;
00413 if ( j == vSymms->nSize )
00414 nTrans++;
00415 }
00416 }
00417
00418 }
00419 printf( "Trans = %d.\n", nTrans );
00420 }
00421
00422
00434 void Sim_SymmsTransferToMatrix( Extra_BitMat_t * pMatSymm, Vec_Int_t * vSymms, unsigned * pSupport )
00435 {
00436 int i, Ind1, Ind2, nInputs;
00437 unsigned uSymm;
00438
00439 nInputs = Extra_BitMatrixReadSize( pMatSymm );
00440 for ( i = 0; i < nInputs; i++ )
00441 Extra_BitMatrixInsert1( pMatSymm, i, i );
00442
00443 for ( i = 0; i < vSymms->nSize; i++ )
00444 {
00445 uSymm = (unsigned)vSymms->pArray[i];
00446 Ind1 = (uSymm & 0xffff);
00447 Ind2 = (uSymm >> 16);
00448
00449
00450 assert( Sim_HasBit(pSupport, Ind1) == Sim_HasBit(pSupport, Ind2) );
00451 if ( !Sim_HasBit(pSupport, Ind1) || !Sim_HasBit(pSupport, Ind2) )
00452 continue;
00453 Extra_BitMatrixInsert1( pMatSymm, Ind1, Ind2 );
00454 Extra_BitMatrixInsert2( pMatSymm, Ind1, Ind2 );
00455 }
00456 }
00457
00469 int * Sim_SymmsCreateMap( Abc_Ntk_t * pNtk )
00470 {
00471 int * pMap;
00472 Abc_Obj_t * pNode;
00473 int i;
00474 pMap = ALLOC( int, Abc_NtkObjNumMax(pNtk) );
00475 for ( i = 0; i < Abc_NtkObjNumMax(pNtk); i++ )
00476 pMap[i] = -1;
00477 Abc_NtkForEachCi( pNtk, pNode, i )
00478 pMap[pNode->Id] = i;
00479 return pMap;
00480 }
00481
00482
00483
00487
00488