00001
00019 #include "abc.h"
00020 #include "fxuInt.h"
00021 #include "fxu.h"
00022
00026
00027 static void Fxu_CreateMatrixAddCube( Fxu_Matrix * p, Fxu_Cube * pCube, char * pSopCube, Vec_Int_t * vFanins, int * pOrder );
00028 static int Fxu_CreateMatrixLitCompare( int * ptrX, int * ptrY );
00029 static void Fxu_CreateCoversNode( Fxu_Matrix * p, Fxu_Data_t * pData, int iNode, Fxu_Cube * pCubeFirst, Fxu_Cube * pCubeNext );
00030 static Fxu_Cube * Fxu_CreateCoversFirstCube( Fxu_Matrix * p, Fxu_Data_t * pData, int iNode );
00031 static int * s_pLits;
00032
00033 extern int Fxu_PreprocessCubePairs( Fxu_Matrix * p, Vec_Ptr_t * vCovers, int nPairsTotal, int nPairsMax );
00034
00038
00050 Fxu_Matrix * Fxu_CreateMatrix( Fxu_Data_t * pData )
00051 {
00052 Fxu_Matrix * p;
00053 Fxu_Var * pVar;
00054 Fxu_Cube * pCubeFirst, * pCubeNew;
00055 Fxu_Cube * pCube1, * pCube2;
00056 Vec_Int_t * vFanins;
00057 char * pSopCover;
00058 char * pSopCube;
00059 int * pOrder, nBitsMax;
00060 int i, v, c;
00061 int nCubesTotal;
00062 int nPairsTotal;
00063 int nPairsStore;
00064 int nCubes;
00065 int iCube, iPair;
00066 int nFanins;
00067
00068
00069 nCubesTotal = 0;
00070 nPairsTotal = 0;
00071 nPairsStore = 0;
00072 nBitsMax = -1;
00073 for ( i = 0; i < pData->nNodesOld; i++ )
00074 if ( pSopCover = pData->vSops->pArray[i] )
00075 {
00076 nCubes = Abc_SopGetCubeNum( pSopCover );
00077 nFanins = Abc_SopGetVarNum( pSopCover );
00078 assert( nFanins > 1 && nCubes > 0 );
00079
00080 nCubesTotal += nCubes;
00081 nPairsTotal += nCubes * (nCubes - 1) / 2;
00082 nPairsStore += nCubes * nCubes;
00083 if ( nBitsMax < nFanins )
00084 nBitsMax = nFanins;
00085 }
00086 if ( nBitsMax <= 0 )
00087 {
00088 printf( "The current network does not have SOPs to perform extraction.\n" );
00089 return NULL;
00090 }
00091
00092 if ( nPairsStore > 50000000 )
00093 {
00094 printf( "The problem is too large to be solved by \"fxu\" (%d cubes and %d cube pairs)\n", nCubesTotal, nPairsStore );
00095 return NULL;
00096 }
00097
00098
00099 p = Fxu_MatrixAllocate();
00100
00101 p->ppVars = ALLOC( Fxu_Var *, 2 * (pData->nNodesOld + pData->nNodesExt) );
00102 for ( i = 0; i < 2 * pData->nNodesOld; i++ )
00103 p->ppVars[i] = Fxu_MatrixAddVar( p );
00104
00105
00106 p->pppPairs = ALLOC( Fxu_Pair **, nCubesTotal + 100 );
00107 p->ppPairs = ALLOC( Fxu_Pair *, nPairsStore + 100 );
00108 memset( p->ppPairs, 0, sizeof(Fxu_Pair *) * nPairsStore );
00109 iCube = 0;
00110 iPair = 0;
00111 for ( i = 0; i < pData->nNodesOld; i++ )
00112 if ( pSopCover = pData->vSops->pArray[i] )
00113 {
00114
00115 nCubes = Abc_SopGetCubeNum( pSopCover );
00116
00117 pVar = p->ppVars[2*i+1];
00118
00119 pVar->nCubes = nCubes;
00120 if ( nCubes > 0 )
00121 {
00122 pVar->ppPairs = p->pppPairs + iCube;
00123 pVar->ppPairs[0] = p->ppPairs + iPair;
00124 for ( v = 1; v < nCubes; v++ )
00125 pVar->ppPairs[v] = pVar->ppPairs[v-1] + nCubes;
00126 }
00127
00128 iCube += nCubes;
00129 iPair += nCubes * nCubes;
00130 }
00131 assert( iCube == nCubesTotal );
00132 assert( iPair == nPairsStore );
00133
00134
00135
00136 pOrder = ALLOC( int, nBitsMax );
00137
00138 for ( i = 0; i < pData->nNodesOld; i++ )
00139 if ( pSopCover = pData->vSops->pArray[i] )
00140 {
00141
00142 pVar = p->ppVars[2*i+1];
00143
00144
00145
00146 vFanins = pData->vFanins->pArray[i];
00147 s_pLits = vFanins->pArray;
00148
00149 nFanins = Abc_SopGetVarNum( pSopCover );
00150 for ( v = 0; v < nFanins; v++ )
00151 pOrder[v] = v;
00152
00153 qsort( (void *)pOrder, nFanins, sizeof(int),(int (*)(const void *, const void *))Fxu_CreateMatrixLitCompare);
00154 assert( s_pLits[ pOrder[0] ] < s_pLits[ pOrder[nFanins-1] ] );
00155
00156 pCubeFirst = NULL;
00157 c = 0;
00158 Abc_SopForEachCube( pSopCover, nFanins, pSopCube )
00159 {
00160
00161 pCubeNew = Fxu_MatrixAddCube( p, pVar, c++ );
00162 Fxu_CreateMatrixAddCube( p, pCubeNew, pSopCube, vFanins, pOrder );
00163 if ( pCubeFirst == NULL )
00164 pCubeFirst = pCubeNew;
00165 pCubeNew->pFirst = pCubeFirst;
00166 }
00167
00168 pVar->pFirst = pCubeFirst;
00169
00170 if ( nPairsTotal <= pData->nPairsMax )
00171 {
00172 for ( pCube1 = pCubeFirst; pCube1; pCube1 = pCube1->pNext )
00173 for ( pCube2 = pCube1? pCube1->pNext: NULL; pCube2; pCube2 = pCube2->pNext )
00174 Fxu_MatrixAddDivisor( p, pCube1, pCube2 );
00175 }
00176 }
00177 FREE( pOrder );
00178
00179
00180
00181
00182
00183 if ( nPairsTotal > 10000000 )
00184 {
00185 printf( "The total number of cube pairs of the network is more than 10,000,000.\n" );
00186 printf( "Command \"fx\" takes a long time to run in such cases. It is suggested\n" );
00187 printf( "that the user changes the network by reducing the size of logic node and\n" );
00188 printf( "consequently the number of cube pairs to be processed by this command.\n" );
00189 printf( "One way to achieve this is to run the commands \"st; multi -m -F <num>\"\n" );
00190 printf( "as a proprocessing step, while selecting <num> as approapriate.\n" );
00191 return NULL;
00192 }
00193 if ( nPairsTotal > pData->nPairsMax )
00194 if ( !Fxu_PreprocessCubePairs( p, pData->vSops, nPairsTotal, pData->nPairsMax ) )
00195 return NULL;
00196
00197
00198
00199
00200 Fxu_MatrixComputeSingles( p, pData->fUse0, pData->nSingleMax );
00201
00202
00203 if ( pData->fVerbose )
00204 {
00205 double Density;
00206 Density = ((double)p->nEntries) / p->lVars.nItems / p->lCubes.nItems;
00207 fprintf( stdout, "Matrix: [vars x cubes] = [%d x %d] ",
00208 p->lVars.nItems, p->lCubes.nItems );
00209 fprintf( stdout, "Lits = %d Density = %.5f%%\n",
00210 p->nEntries, Density );
00211 fprintf( stdout, "1-cube divs = %6d. (Total = %6d) ", p->lSingles.nItems, p->nSingleTotal );
00212 fprintf( stdout, "2-cube divs = %6d. (Total = %6d)", p->nDivsTotal, nPairsTotal );
00213 fprintf( stdout, "\n" );
00214 }
00215
00216 return p;
00217 }
00218
00231 void Fxu_CreateMatrixAddCube( Fxu_Matrix * p, Fxu_Cube * pCube, char * pSopCube, Vec_Int_t * vFanins, int * pOrder )
00232 {
00233 Fxu_Var * pVar;
00234 int Value, i;
00235
00236 Abc_CubeForEachVar( pSopCube, Value, i )
00237 {
00238 Value = pSopCube[pOrder[i]];
00239 if ( Value == '0' )
00240 {
00241 pVar = p->ppVars[ 2 * vFanins->pArray[pOrder[i]] + 1 ];
00242 Fxu_MatrixAddLiteral( p, pCube, pVar );
00243 }
00244 else if ( Value == '1' )
00245 {
00246 pVar = p->ppVars[ 2 * vFanins->pArray[pOrder[i]] ];
00247 Fxu_MatrixAddLiteral( p, pCube, pVar );
00248 }
00249 }
00250 }
00251
00252
00264 void Fxu_CreateCovers( Fxu_Matrix * p, Fxu_Data_t * pData )
00265 {
00266 Fxu_Cube * pCube, * pCubeFirst, * pCubeNext;
00267 char * pSopCover;
00268 int iNode, n;
00269
00270
00271 pCubeFirst = Fxu_CreateCoversFirstCube( p, pData, 0 );
00272
00273
00274 for ( n = 0; n < pData->nNodesOld; n++ )
00275 if ( pSopCover = pData->vSops->pArray[n] )
00276 {
00277
00278 iNode = n;
00279
00280 pCubeNext = Fxu_CreateCoversFirstCube( p, pData, iNode + 1 );
00281
00282 for ( pCube = pCubeFirst; pCube != pCubeNext; pCube = pCube->pNext )
00283 if ( pCube->lLits.pTail && pCube->lLits.pTail->iVar >= 2 * pData->nNodesOld )
00284 break;
00285 if ( pCube != pCubeNext )
00286 Fxu_CreateCoversNode( p, pData, iNode, pCubeFirst, pCubeNext );
00287
00288 pCubeFirst = pCubeNext;
00289 }
00290
00291
00292 for ( n = 0; n < pData->nNodesNew; n++ )
00293 {
00294
00295 iNode = pData->nNodesOld + n;
00296
00297 pCubeNext = Fxu_CreateCoversFirstCube( p, pData, iNode + 1 );
00298
00299 Fxu_CreateCoversNode( p, pData, iNode, pCubeFirst, pCubeNext );
00300
00301 pCubeFirst = pCubeNext;
00302 }
00303 }
00304
00316 void Fxu_CreateCoversNode( Fxu_Matrix * p, Fxu_Data_t * pData, int iNode, Fxu_Cube * pCubeFirst, Fxu_Cube * pCubeNext )
00317 {
00318 Vec_Int_t * vInputsNew;
00319 char * pSopCover, * pSopCube;
00320 Fxu_Var * pVar;
00321 Fxu_Cube * pCube;
00322 Fxu_Lit * pLit;
00323 int iNum, nCubes, v;
00324
00325
00326 Fxu_MatrixRingVarsStart( p );
00327 for ( pCube = pCubeFirst; pCube != pCubeNext; pCube = pCube->pNext )
00328 for ( pLit = pCube->lLits.pHead; pLit; pLit = pLit->pHNext )
00329 {
00330 pVar = p->ppVars[ 2 * (pLit->pVar->iVar/2) + 1 ];
00331 if ( pVar->pOrder == NULL )
00332 Fxu_MatrixRingVarsAdd( p, pVar );
00333 }
00334 Fxu_MatrixRingVarsStop( p );
00335
00336
00337 vInputsNew = Vec_IntAlloc( 4 );
00338 Fxu_MatrixForEachVarInRing( p, pVar )
00339 Vec_IntPush( vInputsNew, pVar->iVar / 2 );
00340 Fxu_MatrixRingVarsUnmark( p );
00341
00342
00343 Vec_IntSort( vInputsNew, 0 );
00344
00345
00346 for ( v = 0; v < vInputsNew->nSize; v++ )
00347 {
00348 p->ppVars[ 2 * vInputsNew->pArray[v] + 0 ]->lLits.nItems = v;
00349 p->ppVars[ 2 * vInputsNew->pArray[v] + 1 ]->lLits.nItems = v;
00350 }
00351
00352
00353 nCubes = 0;
00354 for ( pCube = pCubeFirst; pCube != pCubeNext; pCube = pCube->pNext )
00355 if ( pCube->lLits.nItems )
00356 nCubes++;
00357
00358
00359 pSopCover = Abc_SopStart( pData->pManSop, nCubes, vInputsNew->nSize );
00360
00361 if ( iNode < pData->nNodesOld && Abc_SopGetPhase( pData->vSops->pArray[iNode] ) == 0 )
00362 Abc_SopComplement( pSopCover );
00363
00364
00365 nCubes = 0;
00366 for ( pCube = pCubeFirst; pCube != pCubeNext; pCube = pCube->pNext )
00367 {
00368 if ( pCube->lLits.nItems == 0 )
00369 continue;
00370
00371 pSopCube = pSopCover + nCubes * (vInputsNew->nSize + 3);
00372
00373 for ( pLit = pCube->lLits.pHead; pLit; pLit = pLit->pHNext )
00374 {
00375 iNum = pLit->pVar->lLits.nItems;
00376 assert( iNum < vInputsNew->nSize );
00377 if ( pLit->pVar->iVar / 2 < pData->nNodesOld )
00378 pSopCube[iNum] = (pLit->pVar->iVar & 1)? '0' : '1';
00379 else
00380 pSopCube[iNum] = (pLit->pVar->iVar & 1)? '1' : '0';
00381 }
00382
00383 nCubes++;
00384 }
00385 assert( nCubes == Abc_SopGetCubeNum(pSopCover) );
00386
00387
00388 pData->vSopsNew->pArray[iNode] = pSopCover;
00389 pData->vFaninsNew->pArray[iNode] = vInputsNew;
00390 }
00391
00392
00404 Fxu_Cube * Fxu_CreateCoversFirstCube( Fxu_Matrix * p, Fxu_Data_t * pData, int iVar )
00405 {
00406 int v;
00407 for ( v = iVar; v < pData->nNodesOld + pData->nNodesNew; v++ )
00408 if ( p->ppVars[ 2*v + 1 ]->pFirst )
00409 return p->ppVars[ 2*v + 1 ]->pFirst;
00410 return NULL;
00411 }
00412
00424 int Fxu_CreateMatrixLitCompare( int * ptrX, int * ptrY )
00425 {
00426 return s_pLits[*ptrX] - s_pLits[*ptrY];
00427 }
00428