#include "fxuInt.h"
Go to the source code of this file.
Defines | |
#define | MAX_SIZE_LOOKAHEAD 20 |
Functions | |
static int | Fxu_MatrixFindComplement (Fxu_Matrix *p, int iVar) |
static Fxu_Double * | Fxu_MatrixFindComplementSingle (Fxu_Matrix *p, Fxu_Single *pSingle) |
static Fxu_Single * | Fxu_MatrixFindComplementDouble2 (Fxu_Matrix *p, Fxu_Double *pDouble) |
static Fxu_Double * | Fxu_MatrixFindComplementDouble4 (Fxu_Matrix *p, Fxu_Double *pDouble) |
Fxu_Double * | Fxu_MatrixFindDouble (Fxu_Matrix *p, int piVarsC1[], int piVarsC2[], int nVarsC1, int nVarsC2) |
void | Fxu_MatrixGetDoubleVars (Fxu_Matrix *p, Fxu_Double *pDouble, int piVarsC1[], int piVarsC2[], int *pnVarsC1, int *pnVarsC2) |
int | Fxu_Select (Fxu_Matrix *p, Fxu_Single **ppSingle, Fxu_Double **ppDouble) |
int | Fxu_SelectSCD (Fxu_Matrix *p, int WeightLimit, Fxu_Var **ppVar1, Fxu_Var **ppVar2) |
#define MAX_SIZE_LOOKAHEAD 20 |
CFile****************************************************************
FileName [fxuSelect.c]
PackageName [MVSIS 2.0: Multi-valued logic synthesis system.]
Synopsis [Procedures to select the best divisor/complement pair.]
Author [MVSIS Group]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - February 1, 2003.]
Revision [
] DECLARATIONS ///
Definition at line 25 of file fxuSelect.c.
int Fxu_MatrixFindComplement | ( | Fxu_Matrix * | p, | |
int | iVar | |||
) | [static] |
Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
Definition at line 345 of file fxuSelect.c.
00346 { 00347 return iVar ^ 1; 00348 /* 00349 // int * pValue2Node = p->pValue2Node; 00350 int iVarC; 00351 int iNode; 00352 int Beg, End; 00353 00354 // get the nodes 00355 iNode = pValue2Node[iVar]; 00356 // get the first node with the same var 00357 for ( Beg = iVar; Beg >= 0; Beg-- ) 00358 if ( pValue2Node[Beg] != iNode ) 00359 { 00360 Beg++; 00361 break; 00362 } 00363 // get the last node with the same var 00364 for ( End = iVar; ; End++ ) 00365 if ( pValue2Node[End] != iNode ) 00366 { 00367 End--; 00368 break; 00369 } 00370 00371 // if one of the vars is not binary, quit 00372 if ( End - Beg > 1 ) 00373 return -1; 00374 00375 // get the complements 00376 if ( iVar == Beg ) 00377 iVarC = End; 00378 else if ( iVar == End ) 00379 iVarC = Beg; 00380 else 00381 { 00382 assert( 0 ); 00383 } 00384 return iVarC; 00385 */ 00386 }
Fxu_Single * Fxu_MatrixFindComplementDouble2 | ( | Fxu_Matrix * | p, | |
Fxu_Double * | pDouble | |||
) | [static] |
Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
Definition at line 246 of file fxuSelect.c.
00247 { 00248 // int * pValue2Node = p->pValue2Node; 00249 int piVarsC1[10], piVarsC2[10]; 00250 int nVarsC1, nVarsC2; 00251 int iVar1, iVar2, iVarTemp; 00252 int iVar1C, iVar2C; 00253 Fxu_Single * pSingle; 00254 00255 // get the variables of this double div 00256 Fxu_MatrixGetDoubleVars( p, pDouble, piVarsC1, piVarsC2, &nVarsC1, &nVarsC2 ); 00257 assert( nVarsC1 == 1 ); 00258 assert( nVarsC2 == 1 ); 00259 iVar1 = piVarsC1[0]; 00260 iVar2 = piVarsC2[0]; 00261 assert( iVar1 < iVar2 ); 00262 00263 iVar1C = Fxu_MatrixFindComplement( p, iVar1 ); 00264 iVar2C = Fxu_MatrixFindComplement( p, iVar2 ); 00265 if ( iVar1C == -1 || iVar2C == -1 ) 00266 return NULL; 00267 00268 // go through the queque and find this one 00269 // assert( iVar1C < iVar2C ); 00270 if ( iVar1C > iVar2C ) 00271 { 00272 iVarTemp = iVar1C; 00273 iVar1C = iVar2C; 00274 iVar2C = iVarTemp; 00275 } 00276 00277 Fxu_MatrixForEachSingle( p, pSingle ) 00278 if ( pSingle->pVar1->iVar == iVar1C && pSingle->pVar2->iVar == iVar2C ) 00279 return pSingle; 00280 return NULL; 00281 }
Fxu_Double * Fxu_MatrixFindComplementDouble4 | ( | Fxu_Matrix * | p, | |
Fxu_Double * | pDouble | |||
) | [static] |
Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
Definition at line 294 of file fxuSelect.c.
00295 { 00296 // int * pValue2Node = p->pValue2Node; 00297 int piVarsC1[10], piVarsC2[10]; 00298 int nVarsC1, nVarsC2; 00299 int iVar11, iVar12, iVar21, iVar22; 00300 int iVar11C, iVar12C, iVar21C, iVar22C; 00301 int RetValue; 00302 00303 // get the variables of this double div 00304 Fxu_MatrixGetDoubleVars( p, pDouble, piVarsC1, piVarsC2, &nVarsC1, &nVarsC2 ); 00305 assert( nVarsC1 == 2 && nVarsC2 == 2 ); 00306 00307 iVar11 = piVarsC1[0]; 00308 iVar12 = piVarsC1[1]; 00309 iVar21 = piVarsC2[0]; 00310 iVar22 = piVarsC2[1]; 00311 assert( iVar11 < iVar21 ); 00312 00313 iVar11C = Fxu_MatrixFindComplement( p, iVar11 ); 00314 iVar12C = Fxu_MatrixFindComplement( p, iVar12 ); 00315 iVar21C = Fxu_MatrixFindComplement( p, iVar21 ); 00316 iVar22C = Fxu_MatrixFindComplement( p, iVar22 ); 00317 if ( iVar11C == -1 || iVar12C == -1 || iVar21C == -1 || iVar22C == -1 ) 00318 return NULL; 00319 if ( iVar11C != iVar21 || iVar12C != iVar22 || 00320 iVar21C != iVar11 || iVar22C != iVar12 ) 00321 return NULL; 00322 00323 // a'b' + ab => a'b + ab' 00324 // a'b + ab' => a'b' + ab 00325 // swap the second pair in each cube 00326 RetValue = piVarsC1[1]; 00327 piVarsC1[1] = piVarsC2[1]; 00328 piVarsC2[1] = RetValue; 00329 00330 return Fxu_MatrixFindDouble( p, piVarsC1, piVarsC2, 2, 2 ); 00331 }
Fxu_Double * Fxu_MatrixFindComplementSingle | ( | Fxu_Matrix * | p, | |
Fxu_Single * | pSingle | |||
) | [static] |
Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
Definition at line 219 of file fxuSelect.c.
00220 { 00221 // int * pValue2Node = p->pValue2Node; 00222 int iVar1, iVar2; 00223 int iVar1C, iVar2C; 00224 // get the variables of this single div 00225 iVar1 = pSingle->pVar1->iVar; 00226 iVar2 = pSingle->pVar2->iVar; 00227 iVar1C = Fxu_MatrixFindComplement( p, iVar1 ); 00228 iVar2C = Fxu_MatrixFindComplement( p, iVar2 ); 00229 if ( iVar1C == -1 || iVar2C == -1 ) 00230 return NULL; 00231 assert( iVar1C < iVar2C ); 00232 return Fxu_MatrixFindDouble( p, &iVar1C, &iVar2C, 1, 1 ); 00233 }
Fxu_Double * Fxu_MatrixFindDouble | ( | Fxu_Matrix * | p, | |
int | piVarsC1[], | |||
int | piVarsC2[], | |||
int | nVarsC1, | |||
int | nVarsC2 | |||
) |
Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
Definition at line 463 of file fxuSelect.c.
00465 { 00466 int piVarsC1_[100], piVarsC2_[100]; 00467 int nVarsC1_, nVarsC2_, i; 00468 Fxu_Double * pDouble; 00469 Fxu_Pair * pPair; 00470 unsigned Key; 00471 00472 assert( nVarsC1 > 0 ); 00473 assert( nVarsC2 > 0 ); 00474 assert( piVarsC1[0] < piVarsC2[0] ); 00475 00476 // get the hash key 00477 Key = Fxu_PairHashKeyArray( p, piVarsC1, piVarsC2, nVarsC1, nVarsC2 ); 00478 00479 // check if the divisor for this pair already exists 00480 Key %= p->nTableSize; 00481 Fxu_TableForEachDouble( p, Key, pDouble ) 00482 { 00483 pPair = pDouble->lPairs.pHead; 00484 if ( pPair->nLits1 != nVarsC1 ) 00485 continue; 00486 if ( pPair->nLits2 != nVarsC2 ) 00487 continue; 00488 // get the cubes of this divisor 00489 Fxu_MatrixGetDoubleVars( p, pDouble, piVarsC1_, piVarsC2_, &nVarsC1_, &nVarsC2_ ); 00490 // compare lits of the first cube 00491 for ( i = 0; i < nVarsC1; i++ ) 00492 if ( piVarsC1[i] != piVarsC1_[i] ) 00493 break; 00494 if ( i != nVarsC1 ) 00495 continue; 00496 // compare lits of the second cube 00497 for ( i = 0; i < nVarsC2; i++ ) 00498 if ( piVarsC2[i] != piVarsC2_[i] ) 00499 break; 00500 if ( i != nVarsC2 ) 00501 continue; 00502 return pDouble; 00503 } 00504 return NULL; 00505 }
void Fxu_MatrixGetDoubleVars | ( | Fxu_Matrix * | p, | |
Fxu_Double * | pDouble, | |||
int | piVarsC1[], | |||
int | piVarsC2[], | |||
int * | pnVarsC1, | |||
int * | pnVarsC2 | |||
) |
Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
Definition at line 400 of file fxuSelect.c.
00402 { 00403 Fxu_Pair * pPair; 00404 Fxu_Lit * pLit1, * pLit2; 00405 int nLits1, nLits2; 00406 00407 // get the first pair 00408 pPair = pDouble->lPairs.pHead; 00409 // init the parameters 00410 nLits1 = 0; 00411 nLits2 = 0; 00412 pLit1 = pPair->pCube1->lLits.pHead; 00413 pLit2 = pPair->pCube2->lLits.pHead; 00414 while ( 1 ) 00415 { 00416 if ( pLit1 && pLit2 ) 00417 { 00418 if ( pLit1->iVar == pLit2->iVar ) 00419 { // ensure cube-free 00420 pLit1 = pLit1->pHNext; 00421 pLit2 = pLit2->pHNext; 00422 } 00423 else if ( pLit1->iVar < pLit2->iVar ) 00424 { 00425 piVarsC1[nLits1++] = pLit1->iVar; 00426 pLit1 = pLit1->pHNext; 00427 } 00428 else 00429 { 00430 piVarsC2[nLits2++] = pLit2->iVar; 00431 pLit2 = pLit2->pHNext; 00432 } 00433 } 00434 else if ( pLit1 && !pLit2 ) 00435 { 00436 piVarsC1[nLits1++] = pLit1->iVar; 00437 pLit1 = pLit1->pHNext; 00438 } 00439 else if ( !pLit1 && pLit2 ) 00440 { 00441 piVarsC2[nLits2++] = pLit2->iVar; 00442 pLit2 = pLit2->pHNext; 00443 } 00444 else 00445 break; 00446 } 00447 *pnVarsC1 = nLits1; 00448 *pnVarsC2 = nLits2; 00449 }
int Fxu_Select | ( | Fxu_Matrix * | p, | |
Fxu_Single ** | ppSingle, | |||
Fxu_Double ** | ppDouble | |||
) |
FUNCTION DEFINITIONS ///Function*************************************************************
Synopsis [Selects the best pair (Single,Double) and returns their weight.]
Description []
SideEffects []
SeeAlso []
Definition at line 54 of file fxuSelect.c.
00055 { 00056 // the top entries 00057 Fxu_Single * pSingles[MAX_SIZE_LOOKAHEAD]; 00058 Fxu_Double * pDoubles[MAX_SIZE_LOOKAHEAD]; 00059 // the complements 00060 Fxu_Double * pSCompl[MAX_SIZE_LOOKAHEAD]; 00061 Fxu_Single * pDComplS[MAX_SIZE_LOOKAHEAD]; 00062 Fxu_Double * pDComplD[MAX_SIZE_LOOKAHEAD]; 00063 Fxu_Pair * pPair; 00064 int nSingles; 00065 int nDoubles; 00066 int i; 00067 int WeightBest; 00068 int WeightCur; 00069 int iNum, fBestS; 00070 00071 // collect the top entries from the queues 00072 for ( nSingles = 0; nSingles < MAX_SIZE_LOOKAHEAD; nSingles++ ) 00073 { 00074 pSingles[nSingles] = Fxu_HeapSingleGetMax( p->pHeapSingle ); 00075 if ( pSingles[nSingles] == NULL ) 00076 break; 00077 } 00078 // put them back into the queue 00079 for ( i = 0; i < nSingles; i++ ) 00080 if ( pSingles[i] ) 00081 Fxu_HeapSingleInsert( p->pHeapSingle, pSingles[i] ); 00082 00083 // the same for doubles 00084 // collect the top entries from the queues 00085 for ( nDoubles = 0; nDoubles < MAX_SIZE_LOOKAHEAD; nDoubles++ ) 00086 { 00087 pDoubles[nDoubles] = Fxu_HeapDoubleGetMax( p->pHeapDouble ); 00088 if ( pDoubles[nDoubles] == NULL ) 00089 break; 00090 } 00091 // put them back into the queue 00092 for ( i = 0; i < nDoubles; i++ ) 00093 if ( pDoubles[i] ) 00094 Fxu_HeapDoubleInsert( p->pHeapDouble, pDoubles[i] ); 00095 00096 // for each single, find the complement double (if any) 00097 for ( i = 0; i < nSingles; i++ ) 00098 if ( pSingles[i] ) 00099 pSCompl[i] = Fxu_MatrixFindComplementSingle( p, pSingles[i] ); 00100 00101 // for each double, find the complement single or double (if any) 00102 for ( i = 0; i < nDoubles; i++ ) 00103 if ( pDoubles[i] ) 00104 { 00105 pPair = pDoubles[i]->lPairs.pHead; 00106 if ( pPair->nLits1 == 1 && pPair->nLits2 == 1 ) 00107 { 00108 pDComplS[i] = Fxu_MatrixFindComplementDouble2( p, pDoubles[i] ); 00109 pDComplD[i] = NULL; 00110 } 00111 // else if ( pPair->nLits1 == 2 && pPair->nLits2 == 2 ) 00112 // { 00113 // pDComplS[i] = NULL; 00114 // pDComplD[i] = Fxu_MatrixFindComplementDouble4( p, pDoubles[i] ); 00115 // } 00116 else 00117 { 00118 pDComplS[i] = NULL; 00119 pDComplD[i] = NULL; 00120 } 00121 } 00122 00123 // select the best pair 00124 WeightBest = -1; 00125 for ( i = 0; i < nSingles; i++ ) 00126 { 00127 WeightCur = pSingles[i]->Weight; 00128 if ( pSCompl[i] ) 00129 { 00130 // add the weight of the double 00131 WeightCur += pSCompl[i]->Weight; 00132 // there is no need to implement this double, so... 00133 pPair = pSCompl[i]->lPairs.pHead; 00134 WeightCur += pPair->nLits1 + pPair->nLits2; 00135 } 00136 if ( WeightBest < WeightCur ) 00137 { 00138 WeightBest = WeightCur; 00139 *ppSingle = pSingles[i]; 00140 *ppDouble = pSCompl[i]; 00141 fBestS = 1; 00142 iNum = i; 00143 } 00144 } 00145 for ( i = 0; i < nDoubles; i++ ) 00146 { 00147 WeightCur = pDoubles[i]->Weight; 00148 if ( pDComplS[i] ) 00149 { 00150 // add the weight of the single 00151 WeightCur += pDComplS[i]->Weight; 00152 // there is no need to implement this double, so... 00153 pPair = pDoubles[i]->lPairs.pHead; 00154 WeightCur += pPair->nLits1 + pPair->nLits2; 00155 } 00156 if ( WeightBest < WeightCur ) 00157 { 00158 WeightBest = WeightCur; 00159 *ppSingle = pDComplS[i]; 00160 *ppDouble = pDoubles[i]; 00161 fBestS = 0; 00162 iNum = i; 00163 } 00164 } 00165 /* 00166 // print the statistics 00167 printf( "\n" ); 00168 for ( i = 0; i < nSingles; i++ ) 00169 { 00170 printf( "Single #%d: Weight = %3d. ", i, pSingles[i]->Weight ); 00171 printf( "Compl: " ); 00172 if ( pSCompl[i] == NULL ) 00173 printf( "None." ); 00174 else 00175 printf( "D Weight = %3d Sum = %3d", 00176 pSCompl[i]->Weight, pSCompl[i]->Weight + pSingles[i]->Weight ); 00177 printf( "\n" ); 00178 } 00179 printf( "\n" ); 00180 for ( i = 0; i < nDoubles; i++ ) 00181 { 00182 printf( "Double #%d: Weight = %3d. ", i, pDoubles[i]->Weight ); 00183 printf( "Compl: " ); 00184 if ( pDComplS[i] == NULL && pDComplD[i] == NULL ) 00185 printf( "None." ); 00186 else if ( pDComplS[i] ) 00187 printf( "S Weight = %3d Sum = %3d", 00188 pDComplS[i]->Weight, pDComplS[i]->Weight + pDoubles[i]->Weight ); 00189 else if ( pDComplD[i] ) 00190 printf( "D Weight = %3d Sum = %3d", 00191 pDComplD[i]->Weight, pDComplD[i]->Weight + pDoubles[i]->Weight ); 00192 printf( "\n" ); 00193 } 00194 if ( WeightBest == -1 ) 00195 printf( "Selected NONE\n" ); 00196 else 00197 { 00198 printf( "Selected = %s. ", fBestS? "S": "D" ); 00199 printf( "Number = %d. ", iNum ); 00200 printf( "Weight = %d.\n", WeightBest ); 00201 } 00202 printf( "\n" ); 00203 */ 00204 return WeightBest; 00205 }
int Fxu_SelectSCD | ( | Fxu_Matrix * | p, | |
int | WeightLimit, | |||
Fxu_Var ** | ppVar1, | |||
Fxu_Var ** | ppVar2 | |||
) |
Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
Definition at line 522 of file fxuSelect.c.
00523 { 00524 // int * pValue2Node = p->pValue2Node; 00525 Fxu_Var * pVar1; 00526 Fxu_Var * pVar2, * pVarTemp; 00527 Fxu_Lit * pLitV, * pLitH; 00528 int Coin; 00529 int CounterAll; 00530 int CounterTest; 00531 int WeightCur; 00532 int WeightBest; 00533 00534 CounterAll = 0; 00535 CounterTest = 0; 00536 00537 WeightBest = -10; 00538 00539 // iterate through the columns in the matrix 00540 Fxu_MatrixForEachVariable( p, pVar1 ) 00541 { 00542 // start collecting the affected vars 00543 Fxu_MatrixRingVarsStart( p ); 00544 00545 // go through all the literals of this variable 00546 for ( pLitV = pVar1->lLits.pHead; pLitV; pLitV = pLitV->pVNext ) 00547 { 00548 // for this literal, go through all the horizontal literals 00549 for ( pLitH = pLitV->pHNext; pLitH; pLitH = pLitH->pHNext ) 00550 { 00551 // get another variable 00552 pVar2 = pLitH->pVar; 00553 CounterAll++; 00554 // skip the var if it is already used 00555 if ( pVar2->pOrder ) 00556 continue; 00557 // skip the var if it belongs to the same node 00558 // if ( pValue2Node[pVar1->iVar] == pValue2Node[pVar2->iVar] ) 00559 // continue; 00560 // collect the var 00561 Fxu_MatrixRingVarsAdd( p, pVar2 ); 00562 } 00563 } 00564 // stop collecting the selected vars 00565 Fxu_MatrixRingVarsStop( p ); 00566 00567 // iterate through the selected vars 00568 Fxu_MatrixForEachVarInRing( p, pVar2 ) 00569 { 00570 CounterTest++; 00571 00572 // count the coincidence 00573 Coin = Fxu_SingleCountCoincidence( p, pVar1, pVar2 ); 00574 assert( Coin > 0 ); 00575 00576 // get the new weight 00577 WeightCur = Coin - 2; 00578 00579 // compare the weights 00580 if ( WeightBest < WeightCur ) 00581 { 00582 WeightBest = WeightCur; 00583 *ppVar1 = pVar1; 00584 *ppVar2 = pVar2; 00585 } 00586 } 00587 // unmark the vars 00588 Fxu_MatrixForEachVarInRingSafe( p, pVar2, pVarTemp ) 00589 pVar2->pOrder = NULL; 00590 Fxu_MatrixRingVarsReset( p ); 00591 } 00592 00593 // if ( WeightBest == WeightLimit ) 00594 // return -1; 00595 return WeightBest; 00596 }