00001
00021 #include "abc.h"
00022 #include "resInt.h"
00023
00027
00031
00043 Res_Sim_t * Res_SimAlloc( int nWords )
00044 {
00045 Res_Sim_t * p;
00046 p = ALLOC( Res_Sim_t, 1 );
00047 memset( p, 0, sizeof(Res_Sim_t) );
00048
00049 p->nWords = nWords;
00050 p->nPats = p->nWords * 8 * sizeof(unsigned);
00051 p->nWordsIn = p->nPats;
00052 p->nBytesIn = p->nPats * sizeof(unsigned);
00053 p->nPatsIn = p->nPats * 8 * sizeof(unsigned);
00054 p->nWordsOut = p->nPats * p->nWords;
00055 p->nPatsOut = p->nPats * p->nPats;
00056
00057 p->vPats = Vec_PtrAllocSimInfo( 1024, p->nWordsIn );
00058 p->vPats0 = Vec_PtrAllocSimInfo( 128, p->nWords );
00059 p->vPats1 = Vec_PtrAllocSimInfo( 128, p->nWords );
00060 p->vOuts = Vec_PtrAllocSimInfo( 128, p->nWordsOut );
00061
00062 p->vCands = Vec_VecStart( 16 );
00063 return p;
00064 }
00065
00077 void Res_SimAdjust( Res_Sim_t * p, Abc_Ntk_t * pAig, int nTruePis )
00078 {
00079 srand( 0xABC );
00080
00081 assert( Abc_NtkIsStrash(pAig) );
00082 p->pAig = pAig;
00083 p->nTruePis = nTruePis;
00084 if ( Vec_PtrSize(p->vPats) < Abc_NtkObjNumMax(pAig)+1 )
00085 {
00086 Vec_PtrFree( p->vPats );
00087 p->vPats = Vec_PtrAllocSimInfo( Abc_NtkObjNumMax(pAig)+1, p->nWordsIn );
00088 }
00089 if ( Vec_PtrSize(p->vPats0) < nTruePis )
00090 {
00091 Vec_PtrFree( p->vPats0 );
00092 p->vPats0 = Vec_PtrAllocSimInfo( nTruePis, p->nWords );
00093 }
00094 if ( Vec_PtrSize(p->vPats1) < nTruePis )
00095 {
00096 Vec_PtrFree( p->vPats1 );
00097 p->vPats1 = Vec_PtrAllocSimInfo( nTruePis, p->nWords );
00098 }
00099 if ( Vec_PtrSize(p->vOuts) < Abc_NtkPoNum(pAig) )
00100 {
00101 Vec_PtrFree( p->vOuts );
00102 p->vOuts = Vec_PtrAllocSimInfo( Abc_NtkPoNum(pAig), p->nWordsOut );
00103 }
00104
00105 Abc_InfoClear( Vec_PtrEntry(p->vPats0,0), p->nWords * nTruePis );
00106 Abc_InfoClear( Vec_PtrEntry(p->vPats1,0), p->nWords * nTruePis );
00107 p->nPats0 = 0;
00108 p->nPats1 = 0;
00109 p->fConst0 = 0;
00110 p->fConst1 = 0;
00111 }
00112
00124 void Res_SimFree( Res_Sim_t * p )
00125 {
00126 Vec_PtrFree( p->vPats );
00127 Vec_PtrFree( p->vPats0 );
00128 Vec_PtrFree( p->vPats1 );
00129 Vec_PtrFree( p->vOuts );
00130 Vec_VecFree( p->vCands );
00131 free( p );
00132 }
00133
00134
00146 void Abc_InfoRandomBytes( unsigned * p, int nWords )
00147 {
00148 int i, Num;
00149 for ( i = nWords - 1; i >= 0; i-- )
00150 {
00151 Num = rand();
00152 p[i] = (Num & 1)? 0xff : 0;
00153 p[i] = (p[i] << 8) | ((Num & 2)? 0xff : 0);
00154 p[i] = (p[i] << 8) | ((Num & 4)? 0xff : 0);
00155 p[i] = (p[i] << 8) | ((Num & 8)? 0xff : 0);
00156 }
00157
00158 }
00159
00171 void Res_SimSetRandomBytes( Res_Sim_t * p )
00172 {
00173 Abc_Obj_t * pObj;
00174 unsigned * pInfo;
00175 int i;
00176 Abc_NtkForEachPi( p->pAig, pObj, i )
00177 {
00178 pInfo = Vec_PtrEntry( p->vPats, pObj->Id );
00179 if ( i < p->nTruePis )
00180 Abc_InfoRandomBytes( pInfo, p->nWordsIn );
00181 else
00182 Abc_InfoRandom( pInfo, p->nWordsIn );
00183 }
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195 }
00196
00208 void Res_SimSetDerivedBytes( Res_Sim_t * p, int fUseWalk )
00209 {
00210 Vec_Ptr_t * vPatsSource[2];
00211 int nPatsSource[2];
00212 Abc_Obj_t * pObj;
00213 unsigned char * pInfo;
00214 int i, k, z, s, nPats;
00215
00216
00217 assert( p->nBytesIn % 32 == 0 );
00218 nPats = p->nBytesIn/8;
00219 Abc_NtkForEachPi( p->pAig, pObj, i )
00220 {
00221 if ( i == p->nTruePis )
00222 break;
00223 Abc_InfoRandomBytes( Vec_PtrEntry(p->vPats, pObj->Id), nPats/4 );
00224 }
00225
00226
00227 if ( fUseWalk )
00228 {
00229 for ( z = 0; z < 2; z++ )
00230 {
00231
00232 Abc_NtkForEachPi( p->pAig, pObj, i )
00233 {
00234 if ( i == p->nTruePis )
00235 break;
00236 pInfo = (unsigned char *)Vec_PtrEntry( p->vPats, pObj->Id );
00237 pInfo[nPats] = z ? 0xff : 0;
00238 }
00239 if ( ++nPats == p->nBytesIn )
00240 return;
00241
00242 for ( k = 0; k < p->nTruePis; k++ )
00243 {
00244 Abc_NtkForEachPi( p->pAig, pObj, i )
00245 {
00246 if ( i == p->nTruePis )
00247 break;
00248 pInfo = (unsigned char *)Vec_PtrEntry( p->vPats, pObj->Id );
00249 pInfo[nPats] = ((i == k) ^ z) ? 0xff : 0;
00250 }
00251 if ( ++nPats == p->nBytesIn )
00252 return;
00253 }
00254 }
00255 }
00256
00257
00258 if ( p->nPats0 < p->nPats1 )
00259 {
00260 nPatsSource[0] = p->nPats0;
00261 vPatsSource[0] = p->vPats0;
00262 nPatsSource[1] = p->nPats1;
00263 vPatsSource[1] = p->vPats1;
00264 }
00265 else
00266 {
00267 nPatsSource[0] = p->nPats1;
00268 vPatsSource[0] = p->vPats1;
00269 nPatsSource[1] = p->nPats0;
00270 vPatsSource[1] = p->vPats0;
00271 }
00272 for ( z = 0; z < 2; z++ )
00273 {
00274 for ( s = nPatsSource[z] - 1; s >= 0; s-- )
00275 {
00276
00277
00278
00279 for ( k = 0; k < p->nTruePis; k++ )
00280 {
00281 Abc_NtkForEachPi( p->pAig, pObj, i )
00282 {
00283 if ( i == p->nTruePis )
00284 break;
00285 pInfo = (unsigned char *)Vec_PtrEntry( p->vPats, pObj->Id );
00286 if ( (i == k) ^ Abc_InfoHasBit( Vec_PtrEntry(vPatsSource[z], i), s ) )
00287 {
00288 pInfo[nPats] = 0xff;
00289
00290
00291 }
00292 else
00293 {
00294 pInfo[nPats] = 0;
00295
00296
00297 }
00298 }
00299
00300
00301 if ( ++nPats == p->nBytesIn )
00302 return;
00303 }
00304 }
00305 }
00306
00307 for ( z = nPats; z < p->nBytesIn; z++ )
00308 {
00309 Abc_NtkForEachPi( p->pAig, pObj, i )
00310 {
00311 if ( i == p->nTruePis )
00312 break;
00313 pInfo = (unsigned char *)Vec_PtrEntry( p->vPats, pObj->Id );
00314 memset( pInfo + nPats, 0, p->nBytesIn - nPats );
00315 }
00316 }
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328 }
00329
00341 void Res_SimSetGiven( Res_Sim_t * p, Vec_Ptr_t * vInfo )
00342 {
00343 Abc_Obj_t * pObj;
00344 unsigned * pInfo, * pInfo2;
00345 int i, w;
00346 Abc_NtkForEachPi( p->pAig, pObj, i )
00347 {
00348 if ( i == p->nTruePis )
00349 break;
00350 pInfo = Vec_PtrEntry( p->vPats, pObj->Id );
00351 pInfo2 = Vec_PtrEntry( vInfo, i );
00352 for ( w = 0; w < p->nWords; w++ )
00353 pInfo[w] = pInfo2[w];
00354 }
00355 }
00356
00368 void Res_SimPerformOne( Abc_Obj_t * pNode, Vec_Ptr_t * vSimInfo, int nSimWords )
00369 {
00370 unsigned * pInfo, * pInfo1, * pInfo2;
00371 int k, fComp1, fComp2;
00372
00373 assert( Abc_ObjIsNode(pNode) );
00374 pInfo = Vec_PtrEntry(vSimInfo, pNode->Id);
00375 pInfo1 = Vec_PtrEntry(vSimInfo, Abc_ObjFaninId0(pNode));
00376 pInfo2 = Vec_PtrEntry(vSimInfo, Abc_ObjFaninId1(pNode));
00377 fComp1 = Abc_ObjFaninC0(pNode);
00378 fComp2 = Abc_ObjFaninC1(pNode);
00379 if ( fComp1 && fComp2 )
00380 for ( k = 0; k < nSimWords; k++ )
00381 pInfo[k] = ~pInfo1[k] & ~pInfo2[k];
00382 else if ( fComp1 && !fComp2 )
00383 for ( k = 0; k < nSimWords; k++ )
00384 pInfo[k] = ~pInfo1[k] & pInfo2[k];
00385 else if ( !fComp1 && fComp2 )
00386 for ( k = 0; k < nSimWords; k++ )
00387 pInfo[k] = pInfo1[k] & ~pInfo2[k];
00388 else
00389 for ( k = 0; k < nSimWords; k++ )
00390 pInfo[k] = pInfo1[k] & pInfo2[k];
00391 }
00392
00404 void Res_SimTransferOne( Abc_Obj_t * pNode, Vec_Ptr_t * vSimInfo, int nSimWords )
00405 {
00406 unsigned * pInfo, * pInfo1;
00407 int k, fComp1;
00408
00409 assert( Abc_ObjIsCo(pNode) );
00410 pInfo = Vec_PtrEntry(vSimInfo, pNode->Id);
00411 pInfo1 = Vec_PtrEntry(vSimInfo, Abc_ObjFaninId0(pNode));
00412 fComp1 = Abc_ObjFaninC0(pNode);
00413 if ( fComp1 )
00414 for ( k = 0; k < nSimWords; k++ )
00415 pInfo[k] = ~pInfo1[k];
00416 else
00417 for ( k = 0; k < nSimWords; k++ )
00418 pInfo[k] = pInfo1[k];
00419 }
00420
00432 void Res_SimPerformRound( Res_Sim_t * p, int nWords )
00433 {
00434 Abc_Obj_t * pObj;
00435 int i;
00436 Abc_InfoFill( Vec_PtrEntry(p->vPats,0), nWords );
00437 Abc_AigForEachAnd( p->pAig, pObj, i )
00438 Res_SimPerformOne( pObj, p->vPats, nWords );
00439 Abc_NtkForEachPo( p->pAig, pObj, i )
00440 Res_SimTransferOne( pObj, p->vPats, nWords );
00441 }
00442
00443
00455 void Res_SimPadSimInfo( Vec_Ptr_t * vPats, int nPats, int nWords )
00456 {
00457 unsigned * pInfo;
00458 int i, w, iWords;
00459 assert( nPats > 0 && nPats < nWords * 8 * (int) sizeof(unsigned) );
00460
00461 if ( nPats < 8 * sizeof(unsigned) )
00462 {
00463 Vec_PtrForEachEntry( vPats, pInfo, i )
00464 if ( pInfo[0] & 1 )
00465 pInfo[0] |= ((~0) << nPats);
00466 nPats = 8 * sizeof(unsigned);
00467 }
00468
00469 iWords = nPats / (8 * sizeof(unsigned));
00470 Vec_PtrForEachEntry( vPats, pInfo, i )
00471 {
00472 for ( w = iWords; w < nWords; w++ )
00473 pInfo[w] = pInfo[0];
00474 }
00475 }
00476
00488 void Res_SimDeriveInfoReplicate( Res_Sim_t * p )
00489 {
00490 unsigned * pInfo, * pInfo2;
00491 Abc_Obj_t * pObj;
00492 int i, j, w;
00493 Abc_NtkForEachPo( p->pAig, pObj, i )
00494 {
00495 pInfo = Vec_PtrEntry( p->vPats, pObj->Id );
00496 pInfo2 = Vec_PtrEntry( p->vOuts, i );
00497 for ( j = 0; j < p->nPats; j++ )
00498 for ( w = 0; w < p->nWords; w++ )
00499 *pInfo2++ = pInfo[w];
00500 }
00501 }
00502
00514 void Res_SimDeriveInfoComplement( Res_Sim_t * p )
00515 {
00516 unsigned * pInfo, * pInfo2;
00517 Abc_Obj_t * pObj;
00518 int i, j, w;
00519 Abc_NtkForEachPo( p->pAig, pObj, i )
00520 {
00521 pInfo = Vec_PtrEntry( p->vPats, pObj->Id );
00522 pInfo2 = Vec_PtrEntry( p->vOuts, i );
00523 for ( j = 0; j < p->nPats; j++, pInfo2 += p->nWords )
00524 if ( Abc_InfoHasBit( pInfo, j ) )
00525 for ( w = 0; w < p->nWords; w++ )
00526 pInfo2[w] = ~pInfo2[w];
00527 }
00528 }
00529
00541 void Res_SimPrintOutPatterns( Res_Sim_t * p, Abc_Ntk_t * pAig )
00542 {
00543 Abc_Obj_t * pObj;
00544 unsigned * pInfo2;
00545 int i;
00546 Abc_NtkForEachPo( pAig, pObj, i )
00547 {
00548 pInfo2 = Vec_PtrEntry( p->vOuts, i );
00549 Extra_PrintBinary( stdout, pInfo2, p->nPatsOut );
00550 printf( "\n" );
00551 }
00552 }
00553
00565 void Res_SimPrintNodePatterns( Res_Sim_t * p, Abc_Ntk_t * pAig )
00566 {
00567 unsigned * pInfo;
00568 pInfo = Vec_PtrEntry( p->vPats, Abc_NtkPo(p->pAig, 1)->Id );
00569 Extra_PrintBinary( stdout, pInfo, p->nPats );
00570 printf( "\n" );
00571 }
00572
00584 void Res_SimCountResults( Res_Sim_t * p, int * pnDcs, int * pnOnes, int * pnZeros, int fVerbose )
00585 {
00586 unsigned char * pInfoCare, * pInfoNode;
00587 int i, nTotal = 0;
00588 pInfoCare = (unsigned char *)Vec_PtrEntry( p->vPats, Abc_NtkPo(p->pAig, 0)->Id );
00589 pInfoNode = (unsigned char *)Vec_PtrEntry( p->vPats, Abc_NtkPo(p->pAig, 1)->Id );
00590 for ( i = 0; i < p->nBytesIn; i++ )
00591 {
00592 if ( !pInfoCare[i] )
00593 (*pnDcs)++;
00594 else if ( !pInfoNode[i] )
00595 (*pnZeros)++;
00596 else
00597 (*pnOnes)++;
00598 }
00599 nTotal += *pnDcs;
00600 nTotal += *pnZeros;
00601 nTotal += *pnOnes;
00602 if ( fVerbose )
00603 {
00604 printf( "Dc = %7.2f %% ", 100.0*(*pnDcs) /nTotal );
00605 printf( "On = %7.2f %% ", 100.0*(*pnOnes) /nTotal );
00606 printf( "Off = %7.2f %% ", 100.0*(*pnZeros)/nTotal );
00607 }
00608 }
00609
00621 void Res_SimCollectPatterns( Res_Sim_t * p, int fVerbose )
00622 {
00623 Abc_Obj_t * pObj;
00624 unsigned char * pInfoCare, * pInfoNode, * pInfo;
00625 int i, j;
00626 pInfoCare = (unsigned char *)Vec_PtrEntry( p->vPats, Abc_NtkPo(p->pAig, 0)->Id );
00627 pInfoNode = (unsigned char *)Vec_PtrEntry( p->vPats, Abc_NtkPo(p->pAig, 1)->Id );
00628 for ( i = 0; i < p->nBytesIn; i++ )
00629 {
00630
00631 if ( !pInfoCare[i] )
00632 continue;
00633
00634 assert( pInfoNode[i] == 0 || pInfoNode[i] == 0xff );
00635 if ( !pInfoNode[i] )
00636 {
00637 if ( p->nPats0 >= p->nPats )
00638 continue;
00639 Abc_NtkForEachPi( p->pAig, pObj, j )
00640 {
00641 if ( j == p->nTruePis )
00642 break;
00643 pInfo = (unsigned char *)Vec_PtrEntry( p->vPats, pObj->Id );
00644 assert( pInfo[i] == 0 || pInfo[i] == 0xff );
00645 if ( pInfo[i] )
00646 Abc_InfoSetBit( Vec_PtrEntry(p->vPats0, j), p->nPats0 );
00647 }
00648 p->nPats0++;
00649 }
00650 else
00651 {
00652 if ( p->nPats1 >= p->nPats )
00653 continue;
00654 Abc_NtkForEachPi( p->pAig, pObj, j )
00655 {
00656 if ( j == p->nTruePis )
00657 break;
00658 pInfo = (unsigned char *)Vec_PtrEntry( p->vPats, pObj->Id );
00659 assert( pInfo[i] == 0 || pInfo[i] == 0xff );
00660 if ( pInfo[i] )
00661 Abc_InfoSetBit( Vec_PtrEntry(p->vPats1, j), p->nPats1 );
00662 }
00663 p->nPats1++;
00664 }
00665 if ( p->nPats0 >= p->nPats && p->nPats1 >= p->nPats )
00666 break;
00667 }
00668 if ( fVerbose )
00669 {
00670 printf( "| " );
00671 printf( "On = %3d ", p->nPats1 );
00672 printf( "Off = %3d ", p->nPats0 );
00673 printf( "\n" );
00674 }
00675 }
00676
00688 int Res_SimVerifyValue( Res_Sim_t * p, int fOnSet )
00689 {
00690 Abc_Obj_t * pObj;
00691 unsigned * pInfo, * pInfo2;
00692 int i, value;
00693 Abc_NtkForEachPi( p->pAig, pObj, i )
00694 {
00695 if ( i == p->nTruePis )
00696 break;
00697 if ( fOnSet )
00698 {
00699 pInfo2 = Vec_PtrEntry( p->vPats1, i );
00700 value = Abc_InfoHasBit( pInfo2, p->nPats1 - 1 );
00701 }
00702 else
00703 {
00704 pInfo2 = Vec_PtrEntry( p->vPats0, i );
00705 value = Abc_InfoHasBit( pInfo2, p->nPats0 - 1 );
00706 }
00707 pInfo = Vec_PtrEntry( p->vPats, pObj->Id );
00708 pInfo[0] = value ? ~0 : 0;
00709 }
00710 Res_SimPerformRound( p, 1 );
00711 pObj = Abc_NtkPo( p->pAig, 1 );
00712 pInfo = Vec_PtrEntry( p->vPats, pObj->Id );
00713 assert( pInfo[0] == 0 || pInfo[0] == ~0 );
00714 return pInfo[0] > 0;
00715 }
00716
00728 int Res_SimPrepare( Res_Sim_t * p, Abc_Ntk_t * pAig, int nTruePis, int fVerbose )
00729 {
00730 int i, nOnes = 0, nZeros = 0, nDcs = 0;
00731 if ( fVerbose )
00732 printf( "\n" );
00733
00734 Res_SimAdjust( p, pAig, nTruePis );
00735
00736 Res_SimSetRandomBytes( p );
00737 Res_SimPerformRound( p, p->nWordsIn );
00738 Res_SimCountResults( p, &nDcs, &nOnes, &nZeros, fVerbose );
00739
00740 Res_SimCollectPatterns( p, fVerbose );
00741
00742 if ( p->nPats0 < 8 )
00743 {
00744 if ( !Res_SatSimulate( p, 16, 0 ) )
00745 return p->fConst0 || p->fConst1;
00746
00747
00748 }
00749 if ( p->nPats1 < 8 )
00750 {
00751 if ( !Res_SatSimulate( p, 16, 1 ) )
00752 return p->fConst0 || p->fConst1;
00753
00754
00755 }
00756
00757 for ( i = 0; i < 2; i++ )
00758 {
00759 if ( p->nPats0 > p->nPats*7/8 && p->nPats1 > p->nPats*7/8 )
00760 break;
00761 Res_SimSetDerivedBytes( p, i==0 );
00762 Res_SimPerformRound( p, p->nWordsIn );
00763 Res_SimCountResults( p, &nDcs, &nOnes, &nZeros, fVerbose );
00764 Res_SimCollectPatterns( p, fVerbose );
00765 }
00766
00767 if ( p->nPats0 < p->nPats )
00768 Res_SimPadSimInfo( p->vPats0, p->nPats0, p->nWords );
00769 if ( p->nPats1 < p->nPats )
00770 Res_SimPadSimInfo( p->vPats1, p->nPats1, p->nWords );
00771
00772 Res_SimSetGiven( p, p->vPats0 );
00773 Res_SimPerformRound( p, p->nWords );
00774
00775 Res_SimDeriveInfoReplicate( p );
00776
00777 Res_SimSetGiven( p, p->vPats1 );
00778 Res_SimPerformRound( p, p->nWords );
00779
00780 Res_SimDeriveInfoComplement( p );
00781
00782
00783 return 1;
00784 }
00785
00789
00790