#include "abc.h"
#include "fxuInt.h"
#include "fxu.h"
Go to the source code of this file.
Functions | |
static void | Fxu_CreateMatrixAddCube (Fxu_Matrix *p, Fxu_Cube *pCube, char *pSopCube, Vec_Int_t *vFanins, int *pOrder) |
static int | Fxu_CreateMatrixLitCompare (int *ptrX, int *ptrY) |
static void | Fxu_CreateCoversNode (Fxu_Matrix *p, Fxu_Data_t *pData, int iNode, Fxu_Cube *pCubeFirst, Fxu_Cube *pCubeNext) |
static Fxu_Cube * | Fxu_CreateCoversFirstCube (Fxu_Matrix *p, Fxu_Data_t *pData, int iNode) |
int | Fxu_PreprocessCubePairs (Fxu_Matrix *p, Vec_Ptr_t *vCovers, int nPairsTotal, int nPairsMax) |
Fxu_Matrix * | Fxu_CreateMatrix (Fxu_Data_t *pData) |
void | Fxu_CreateCovers (Fxu_Matrix *p, Fxu_Data_t *pData) |
Variables | |
static int * | s_pLits |
void Fxu_CreateCovers | ( | Fxu_Matrix * | p, | |
Fxu_Data_t * | pData | |||
) |
Function*************************************************************
Synopsis [Creates the new array of Sop covers from the sparse matrix.]
Description []
SideEffects []
SeeAlso []
Definition at line 264 of file fxuCreate.c.
00265 { 00266 Fxu_Cube * pCube, * pCubeFirst, * pCubeNext; 00267 char * pSopCover; 00268 int iNode, n; 00269 00270 // get the first cube of the first internal node 00271 pCubeFirst = Fxu_CreateCoversFirstCube( p, pData, 0 ); 00272 00273 // go through the internal nodes 00274 for ( n = 0; n < pData->nNodesOld; n++ ) 00275 if ( pSopCover = pData->vSops->pArray[n] ) 00276 { 00277 // get the number of this node 00278 iNode = n; 00279 // get the next first cube 00280 pCubeNext = Fxu_CreateCoversFirstCube( p, pData, iNode + 1 ); 00281 // check if there any new variables in these cubes 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 // update the first cube 00288 pCubeFirst = pCubeNext; 00289 } 00290 00291 // add the covers for the extracted nodes 00292 for ( n = 0; n < pData->nNodesNew; n++ ) 00293 { 00294 // get the number of this node 00295 iNode = pData->nNodesOld + n; 00296 // get the next first cube 00297 pCubeNext = Fxu_CreateCoversFirstCube( p, pData, iNode + 1 ); 00298 // the node should be added 00299 Fxu_CreateCoversNode( p, pData, iNode, pCubeFirst, pCubeNext ); 00300 // update the first cube 00301 pCubeFirst = pCubeNext; 00302 } 00303 }
Fxu_Cube * Fxu_CreateCoversFirstCube | ( | Fxu_Matrix * | p, | |
Fxu_Data_t * | pData, | |||
int | iVar | |||
) | [static] |
Function*************************************************************
Synopsis [Adds the var to storage.]
Description []
SideEffects []
SeeAlso []
Definition at line 404 of file fxuCreate.c.
void Fxu_CreateCoversNode | ( | Fxu_Matrix * | p, | |
Fxu_Data_t * | pData, | |||
int | iNode, | |||
Fxu_Cube * | pCubeFirst, | |||
Fxu_Cube * | pCubeNext | |||
) | [static] |
Function*************************************************************
Synopsis [Create Sop covers for one node that has changed.]
Description []
SideEffects []
SeeAlso []
Definition at line 316 of file fxuCreate.c.
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 // collect positive polarity variable in the cubes between pCubeFirst and pCubeNext 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 // collect the variable numbers 00337 vInputsNew = Vec_IntAlloc( 4 ); 00338 Fxu_MatrixForEachVarInRing( p, pVar ) 00339 Vec_IntPush( vInputsNew, pVar->iVar / 2 ); 00340 Fxu_MatrixRingVarsUnmark( p ); 00341 00342 // sort the vars by their number 00343 Vec_IntSort( vInputsNew, 0 ); 00344 00345 // mark the vars with their numbers in the sorted array 00346 for ( v = 0; v < vInputsNew->nSize; v++ ) 00347 { 00348 p->ppVars[ 2 * vInputsNew->pArray[v] + 0 ]->lLits.nItems = v; // hack - reuse lLits.nItems 00349 p->ppVars[ 2 * vInputsNew->pArray[v] + 1 ]->lLits.nItems = v; // hack - reuse lLits.nItems 00350 } 00351 00352 // count the number of cubes 00353 nCubes = 0; 00354 for ( pCube = pCubeFirst; pCube != pCubeNext; pCube = pCube->pNext ) 00355 if ( pCube->lLits.nItems ) 00356 nCubes++; 00357 00358 // allocate room for the new cover 00359 pSopCover = Abc_SopStart( pData->pManSop, nCubes, vInputsNew->nSize ); 00360 // set the correct polarity of the cover 00361 if ( iNode < pData->nNodesOld && Abc_SopGetPhase( pData->vSops->pArray[iNode] ) == 0 ) 00362 Abc_SopComplement( pSopCover ); 00363 00364 // add the cubes 00365 nCubes = 0; 00366 for ( pCube = pCubeFirst; pCube != pCubeNext; pCube = pCube->pNext ) 00367 { 00368 if ( pCube->lLits.nItems == 0 ) 00369 continue; 00370 // get hold of the SOP cube 00371 pSopCube = pSopCover + nCubes * (vInputsNew->nSize + 3); 00372 // insert literals 00373 for ( pLit = pCube->lLits.pHead; pLit; pLit = pLit->pHNext ) 00374 { 00375 iNum = pLit->pVar->lLits.nItems; // hack - reuse lLits.nItems 00376 assert( iNum < vInputsNew->nSize ); 00377 if ( pLit->pVar->iVar / 2 < pData->nNodesOld ) 00378 pSopCube[iNum] = (pLit->pVar->iVar & 1)? '0' : '1'; // reverse CST 00379 else 00380 pSopCube[iNum] = (pLit->pVar->iVar & 1)? '1' : '0'; // no CST 00381 } 00382 // count the cube 00383 nCubes++; 00384 } 00385 assert( nCubes == Abc_SopGetCubeNum(pSopCover) ); 00386 00387 // set the new cover and the array of fanins 00388 pData->vSopsNew->pArray[iNode] = pSopCover; 00389 pData->vFaninsNew->pArray[iNode] = vInputsNew; 00390 }
Fxu_Matrix* Fxu_CreateMatrix | ( | Fxu_Data_t * | pData | ) |
FUNCTION DEFINITIONS ///Function*************************************************************
Synopsis [Creates the sparse matrix from the array of SOPs.]
Description []
SideEffects []
SeeAlso []
Definition at line 50 of file fxuCreate.c.
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 // collect all sorts of statistics 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 // start the matrix 00099 p = Fxu_MatrixAllocate(); 00100 // create the column labels 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 // allocate storage for all cube pairs at once 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 // get the number of cubes 00115 nCubes = Abc_SopGetCubeNum( pSopCover ); 00116 // get the new var in the matrix 00117 pVar = p->ppVars[2*i+1]; 00118 // assign the pair storage 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 // update 00128 iCube += nCubes; 00129 iPair += nCubes * nCubes; 00130 } 00131 assert( iCube == nCubesTotal ); 00132 assert( iPair == nPairsStore ); 00133 00134 00135 // allocate room for the reordered literals 00136 pOrder = ALLOC( int, nBitsMax ); 00137 // create the rows 00138 for ( i = 0; i < pData->nNodesOld; i++ ) 00139 if ( pSopCover = pData->vSops->pArray[i] ) 00140 { 00141 // get the new var in the matrix 00142 pVar = p->ppVars[2*i+1]; 00143 // here we sort the literals of the cover 00144 // in the increasing order of the numbers of the corresponding nodes 00145 // because literals should be added to the matrix in this order 00146 vFanins = pData->vFanins->pArray[i]; 00147 s_pLits = vFanins->pArray; 00148 // start the variable order 00149 nFanins = Abc_SopGetVarNum( pSopCover ); 00150 for ( v = 0; v < nFanins; v++ ) 00151 pOrder[v] = v; 00152 // reorder the fanins 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 // create the corresponding cubes in the matrix 00156 pCubeFirst = NULL; 00157 c = 0; 00158 Abc_SopForEachCube( pSopCover, nFanins, pSopCube ) 00159 { 00160 // create the cube 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 // set the first cube of this var 00168 pVar->pFirst = pCubeFirst; 00169 // create the divisors without preprocessing 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 // consider the case when cube pairs should be preprocessed 00180 // before adding them to the set of divisors 00181 // if ( pData->fVerbose ) 00182 // printf( "The total number of cube pairs is %d.\n", nPairsTotal ); 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 // if ( pData->fVerbose ) 00197 // printf( "Only %d best cube pairs will be used by the fast extract command.\n", pData->nPairsMax ); 00198 00199 // add the var pairs to the heap 00200 Fxu_MatrixComputeSingles( p, pData->fUse0, pData->nSingleMax ); 00201 00202 // print stats 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 // Fxu_MatrixPrint( stdout, p ); 00216 return p; 00217 }
void Fxu_CreateMatrixAddCube | ( | Fxu_Matrix * | p, | |
Fxu_Cube * | pCube, | |||
char * | pSopCube, | |||
Vec_Int_t * | vFanins, | |||
int * | pOrder | |||
) | [static] |
CFile****************************************************************
FileName [fxuCreate.c]
PackageName [MVSIS 2.0: Multi-valued logic synthesis system.]
Synopsis [Create matrix from covers and covers from matrix.]
Author [MVSIS Group]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - February 1, 2003.]
Revision [
] DECLARATIONS ///
Function*************************************************************
Synopsis [Adds one cube with literals to the matrix.]
Description [Create the cube and literals in the matrix corresponding to the given cube in the SOP cover. Co-singleton transform is performed here.]
SideEffects []
SeeAlso []
Definition at line 231 of file fxuCreate.c.
00232 { 00233 Fxu_Var * pVar; 00234 int Value, i; 00235 // add literals to the matrix 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 ]; // CST 00242 Fxu_MatrixAddLiteral( p, pCube, pVar ); 00243 } 00244 else if ( Value == '1' ) 00245 { 00246 pVar = p->ppVars[ 2 * vFanins->pArray[pOrder[i]] ]; // CST 00247 Fxu_MatrixAddLiteral( p, pCube, pVar ); 00248 } 00249 } 00250 }
int Fxu_CreateMatrixLitCompare | ( | int * | ptrX, | |
int * | ptrY | |||
) | [static] |
Function*************************************************************
Synopsis [Compares the vars by their number.]
Description []
SideEffects []
SeeAlso []
Definition at line 424 of file fxuCreate.c.
int Fxu_PreprocessCubePairs | ( | Fxu_Matrix * | p, | |
Vec_Ptr_t * | vCovers, | |||
int | nPairsTotal, | |||
int | nPairsMax | |||
) |
FUNCTION DEFINITIONS ///Function*************************************************************
Synopsis [Precomputes the pairs to use for creating two-cube divisors.]
Description [This procedure takes the matrix with variables and cubes allocated (p), the original covers of the nodes (i-sets) and their number (ppCovers,nCovers). The maximum number of pairs to compute and the total number of pairs in existence. This procedure adds to the storage of divisors exactly the given number of pairs (nPairsMax) while taking first those pairs that have the smallest number of literals in their cube-free form.]
SideEffects []
SeeAlso []
Definition at line 50 of file fxuReduce.c.
00051 { 00052 unsigned char * pnLitsDiff; // storage for the counters of diff literals 00053 int * pnPairCounters; // the counters of pairs for each number of diff literals 00054 Fxu_Cube * pCubeFirst, * pCubeLast; 00055 Fxu_Cube * pCube1, * pCube2; 00056 Fxu_Var * pVar; 00057 int nCubes, nBitsMax, nSum; 00058 int CutOffNum, CutOffQuant; 00059 int iPair, iQuant, k, c; 00060 int clk = clock(); 00061 char * pSopCover; 00062 int nFanins; 00063 00064 assert( nPairsMax < nPairsTotal ); 00065 00066 // allocate storage for counter of diffs 00067 pnLitsDiff = ALLOC( unsigned char, nPairsTotal ); 00068 // go through the covers and precompute the distances between the pairs 00069 iPair = 0; 00070 nBitsMax = -1; 00071 for ( c = 0; c < vCovers->nSize; c++ ) 00072 if ( pSopCover = vCovers->pArray[c] ) 00073 { 00074 nFanins = Abc_SopGetVarNum(pSopCover); 00075 // precompute the differences 00076 Fxu_CountPairDiffs( pSopCover, pnLitsDiff + iPair ); 00077 // update the counter 00078 nCubes = Abc_SopGetCubeNum( pSopCover ); 00079 iPair += nCubes * (nCubes - 1) / 2; 00080 if ( nBitsMax < nFanins ) 00081 nBitsMax = nFanins; 00082 } 00083 assert( iPair == nPairsTotal ); 00084 00085 // allocate storage for counters of cube pairs by difference 00086 pnPairCounters = ALLOC( int, 2 * nBitsMax ); 00087 memset( pnPairCounters, 0, sizeof(int) * 2 * nBitsMax ); 00088 // count the number of different pairs 00089 for ( k = 0; k < nPairsTotal; k++ ) 00090 pnPairCounters[ pnLitsDiff[k] ]++; 00091 // determine what pairs to take starting from the lower 00092 // so that there would be exactly pPairsMax pairs 00093 if ( pnPairCounters[0] != 0 ) 00094 { 00095 printf( "The SOPs of the nodes are not cube-free. Run \"bdd; sop\" before \"fx\".\n" ); 00096 return 0; 00097 } 00098 if ( pnPairCounters[1] != 0 ) 00099 { 00100 printf( "The SOPs of the nodes are not SCC-free. Run \"bdd; sop\" before \"fx\".\n" ); 00101 return 0; 00102 } 00103 assert( pnPairCounters[0] == 0 ); // otherwise, covers are not dup-free 00104 assert( pnPairCounters[1] == 0 ); // otherwise, covers are not SCC-free 00105 nSum = 0; 00106 for ( k = 0; k < 2 * nBitsMax; k++ ) 00107 { 00108 nSum += pnPairCounters[k]; 00109 if ( nSum >= nPairsMax ) 00110 { 00111 CutOffNum = k; 00112 CutOffQuant = pnPairCounters[k] - (nSum - nPairsMax); 00113 break; 00114 } 00115 } 00116 FREE( pnPairCounters ); 00117 00118 // set to 0 all the pairs above the cut-off number and quantity 00119 iQuant = 0; 00120 iPair = 0; 00121 for ( k = 0; k < nPairsTotal; k++ ) 00122 if ( pnLitsDiff[k] > CutOffNum ) 00123 pnLitsDiff[k] = 0; 00124 else if ( pnLitsDiff[k] == CutOffNum ) 00125 { 00126 if ( iQuant++ >= CutOffQuant ) 00127 pnLitsDiff[k] = 0; 00128 else 00129 iPair++; 00130 } 00131 else 00132 iPair++; 00133 assert( iPair == nPairsMax ); 00134 00135 // collect the corresponding pairs and add the divisors 00136 iPair = 0; 00137 for ( c = 0; c < vCovers->nSize; c++ ) 00138 if ( pSopCover = vCovers->pArray[c] ) 00139 { 00140 // get the var 00141 pVar = p->ppVars[2*c+1]; 00142 // get the first cube 00143 pCubeFirst = pVar->pFirst; 00144 // get the last cube 00145 pCubeLast = pCubeFirst; 00146 for ( k = 0; k < pVar->nCubes; k++ ) 00147 pCubeLast = pCubeLast->pNext; 00148 assert( pCubeLast == NULL || pCubeLast->pVar != pVar ); 00149 00150 // go through the cube pairs 00151 for ( pCube1 = pCubeFirst; pCube1 != pCubeLast; pCube1 = pCube1->pNext ) 00152 for ( pCube2 = pCube1->pNext; pCube2 != pCubeLast; pCube2 = pCube2->pNext ) 00153 if ( pnLitsDiff[iPair++] ) 00154 { // create the divisors for this pair 00155 Fxu_MatrixAddDivisor( p, pCube1, pCube2 ); 00156 } 00157 } 00158 assert( iPair == nPairsTotal ); 00159 FREE( pnLitsDiff ); 00160 //PRT( "Preprocess", clock() - clk ); 00161 return 1; 00162 }
int* s_pLits [static] |
Definition at line 31 of file fxuCreate.c.