Go to the source code of this file.
#define CUT_SIZE_MIN 3 |
CFile****************************************************************
FileName [cut.h]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [K-feasible cut computation package.]
Synopsis [External declarations.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [
] INCLUDES /// PARAMETERS ///
typedef struct Cut_CutStruct_t_ Cut_Cut_t |
typedef struct Cut_ManStruct_t_ Cut_Man_t |
typedef struct Cut_OracleStruct_t_ Cut_Oracle_t |
typedef struct Cut_ParamsStruct_t_ Cut_Params_t |
void Cut_CellDumpToFile | ( | ) |
Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
Definition at line 831 of file cutPre22.c.
00832 { 00833 FILE * pFile; 00834 Cut_CMan_t * p = s_pCMan; 00835 Cut_Cell_t * pTemp; 00836 char * pFileName = "celllib22.txt"; 00837 int NumUsed[10][5] = {{0}}; 00838 int BoxUsed[22][5] = {{0}}; 00839 int i, k, Counter; 00840 int clk = clock(); 00841 00842 if ( p == NULL ) 00843 { 00844 printf( "Cut_CellDumpToFile: Cell manager is not defined.\n" ); 00845 return; 00846 } 00847 00848 // count the number of cells used 00849 for ( k = CUT_CELL_MVAR; k >= 0; k-- ) 00850 { 00851 for ( pTemp = p->pSameVar[k]; pTemp; pTemp = pTemp->pNextVar ) 00852 { 00853 if ( pTemp->nUsed == 0 ) 00854 NumUsed[k][0]++; 00855 else if ( pTemp->nUsed < 10 ) 00856 NumUsed[k][1]++; 00857 else if ( pTemp->nUsed < 100 ) 00858 NumUsed[k][2]++; 00859 else if ( pTemp->nUsed < 1000 ) 00860 NumUsed[k][3]++; 00861 else 00862 NumUsed[k][4]++; 00863 00864 for ( i = 0; i < 4; i++ ) 00865 if ( pTemp->nUsed == 0 ) 00866 BoxUsed[ pTemp->Box[i] ][0]++; 00867 else if ( pTemp->nUsed < 10 ) 00868 BoxUsed[ pTemp->Box[i] ][1]++; 00869 else if ( pTemp->nUsed < 100 ) 00870 BoxUsed[ pTemp->Box[i] ][2]++; 00871 else if ( pTemp->nUsed < 1000 ) 00872 BoxUsed[ pTemp->Box[i] ][3]++; 00873 else 00874 BoxUsed[ pTemp->Box[i] ][4]++; 00875 } 00876 } 00877 00878 printf( "Functions found = %10d. Functions not found = %10d.\n", p->nCellFound, p->nCellNotFound ); 00879 for ( k = 0; k <= CUT_CELL_MVAR; k++ ) 00880 { 00881 printf( "%3d : ", k ); 00882 for ( i = 0; i < 5; i++ ) 00883 printf( "%8d ", NumUsed[k][i] ); 00884 printf( "\n" ); 00885 } 00886 printf( "Box usage:\n" ); 00887 for ( k = 0; k < 22; k++ ) 00888 { 00889 printf( "%3d : ", k ); 00890 for ( i = 0; i < 5; i++ ) 00891 printf( "%8d ", BoxUsed[k][i] ); 00892 printf( " %s", s_NP3Names[k] ); 00893 printf( "\n" ); 00894 } 00895 00896 pFile = fopen( pFileName, "w" ); 00897 if ( pFile == NULL ) 00898 { 00899 printf( "Cut_CellDumpToFile: Cannout open output file.\n" ); 00900 return; 00901 } 00902 00903 Counter = 0; 00904 for ( k = 0; k <= CUT_CELL_MVAR; k++ ) 00905 { 00906 for ( pTemp = p->pSameVar[k]; pTemp; pTemp = pTemp->pNextVar ) 00907 if ( pTemp->nUsed > 0 ) 00908 { 00909 Extra_PrintHexadecimal( pFile, pTemp->uTruth, (k <= 5? 5 : k) ); 00910 fprintf( pFile, "\n" ); 00911 Counter++; 00912 } 00913 fprintf( pFile, "\n" ); 00914 } 00915 fclose( pFile ); 00916 00917 printf( "Library composed of %d functions is written into file \"%s\". ", Counter, pFileName ); 00918 00919 PRT( "Time", clock() - clk ); 00920 }
int Cut_CellIsRunning | ( | ) |
Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
Definition at line 815 of file cutPre22.c.
void Cut_CellLoad | ( | ) |
FUNCTION DEFINITIONS ///Function*************************************************************
Synopsis [Start the precomputation manager.]
Description []
SideEffects []
SeeAlso []
Definition at line 166 of file cutPre22.c.
00167 { 00168 FILE * pFile; 00169 char * pFileName = "cells22_daomap_iwls.txt"; 00170 char pString[1000]; 00171 Cut_CMan_t * p; 00172 Cut_Cell_t * pCell; 00173 int Length; //, i; 00174 pFile = fopen( pFileName, "r" ); 00175 if ( pFile == NULL ) 00176 { 00177 printf( "Cannot open file \"%s\".\n", pFileName ); 00178 return; 00179 } 00180 // start the manager 00181 p = Cut_CManStart(); 00182 // load truth tables 00183 while ( fgets(pString, 1000, pFile) ) 00184 { 00185 Length = strlen(pString); 00186 pString[Length--] = 0; 00187 if ( Length == 0 ) 00188 continue; 00189 // derive the cell 00190 pCell = (Cut_Cell_t *)Extra_MmFixedEntryFetch( p->pMem ); 00191 memset( pCell, 0, sizeof(Cut_Cell_t) ); 00192 pCell->nVars = Extra_Base2Log(Length*4); 00193 pCell->nUsed = 1; 00194 // Extra_TruthCopy( pCell->uTruth, pTruth, nVars ); 00195 Extra_ReadHexadecimal( pCell->uTruth, pString, pCell->nVars ); 00196 Cut_CellSuppMin( pCell ); 00197 /* 00198 // set the elementary permutation 00199 for ( i = 0; i < (int)pCell->nVars; i++ ) 00200 pCell->CanonPerm[i] = i; 00201 // canonicize 00202 pCell->CanonPhase = Extra_TruthSemiCanonicize( pCell->uTruth, p->puAux, pCell->nVars, pCell->CanonPerm, pCell->Store ); 00203 */ 00204 // add to the table 00205 p->nTotal++; 00206 00207 // Extra_PrintHexadecimal( stdout, pCell->uTruth, pCell->nVars ); printf( "\n" ); 00208 // if ( p->nTotal == 500 ) 00209 // break; 00210 00211 if ( !Cut_CellTableLookup( p, pCell ) ) // new cell 00212 p->nGood++; 00213 } 00214 printf( "Read %d cells from file \"%s\". Added %d cells to the table.\n", p->nTotal, pFileName, p->nGood ); 00215 fclose( pFile ); 00216 // return p; 00217 }
void Cut_CellPrecompute | ( | ) |
Function*************************************************************
Synopsis [Precomputes truth tables for the 2x2 macro cell.]
Description []
SideEffects []
SeeAlso []
Definition at line 230 of file cutPre22.c.
00231 { 00232 Cut_CMan_t * p; 00233 Cut_Cell_t * pCell, * pTemp; 00234 int i1, i2, i3, i, j, k, c, clk = clock(), clk2 = clock(); 00235 00236 p = Cut_CManStart(); 00237 00238 // precompute truth tables 00239 for ( i = 0; i < 22; i++ ) 00240 Cut_CellTruthElem( p->uInputs[0], p->uInputs[1], p->uInputs[2], p->uTemp1[i], 9, i ); 00241 for ( i = 0; i < 22; i++ ) 00242 Cut_CellTruthElem( p->uInputs[3], p->uInputs[4], p->uInputs[5], p->uTemp2[i], 9, i ); 00243 for ( i = 0; i < 22; i++ ) 00244 Cut_CellTruthElem( p->uInputs[6], p->uInputs[7], p->uInputs[8], p->uTemp3[i], 9, i ); 00245 /* 00246 if ( k == 8 && ((i1 == 6 && i2 == 14 && i3 == 20) || (i1 == 20 && i2 == 6 && i3 == 14)) ) 00247 { 00248 Extra_PrintBinary( stdout, &pCell->CanonPhase, pCell->nVars+1 ); printf( " : " ); 00249 for ( i = 0; i < pCell->nVars; i++ ) 00250 printf( "%d=%d/%d ", pCell->CanonPerm[i], pCell->Store[2*i], pCell->Store[2*i+1] ); 00251 Extra_PrintHexadecimal( stdout, pCell->uTruth, pCell->nVars ); 00252 printf( "\n" ); 00253 } 00254 */ 00255 /* 00256 // go through symmetric roots 00257 for ( k = 0; k < 5; k++ ) 00258 for ( i1 = 0; i1 < 22; i1++ ) 00259 for ( i2 = i1; i2 < 22; i2++ ) 00260 for ( i3 = i2; i3 < 22; i3++ ) 00261 { 00262 // derive the cell 00263 pCell = (Cut_Cell_t *)Extra_MmFixedEntryFetch( p->pMem ); 00264 memset( pCell, 0, sizeof(Cut_Cell_t) ); 00265 pCell->nVars = 9; 00266 pCell->Box[0] = s_NPNe3s[k]; 00267 pCell->Box[1] = i1; 00268 pCell->Box[2] = i2; 00269 pCell->Box[3] = i3; 00270 // fill in the truth table 00271 Cut_CellTruthElem( p->uTemp1[i1], p->uTemp2[i2], p->uTemp3[i3], pCell->uTruth, 9, s_NPNe3s[k] ); 00272 // canonicize 00273 Cut_CellCanonicize( pCell ); 00274 00275 // add to the table 00276 p->nTotal++; 00277 if ( Cut_CellTableLookup( p, pCell ) ) // already exists 00278 Extra_MmFixedEntryRecycle( p->pMem, (char *)pCell ); 00279 else 00280 p->nGood++; 00281 } 00282 00283 // go through partially symmetric roots 00284 for ( k = 0; k < 4; k++ ) 00285 for ( i1 = 0; i1 < 22; i1++ ) 00286 for ( i2 = 0; i2 < 22; i2++ ) 00287 for ( i3 = i2; i3 < 22; i3++ ) 00288 { 00289 // derive the cell 00290 pCell = (Cut_Cell_t *)Extra_MmFixedEntryFetch( p->pMem ); 00291 memset( pCell, 0, sizeof(Cut_Cell_t) ); 00292 pCell->nVars = 9; 00293 pCell->Box[0] = s_NPNe3p[k]; 00294 pCell->Box[1] = i1; 00295 pCell->Box[2] = i2; 00296 pCell->Box[3] = i3; 00297 // fill in the truth table 00298 Cut_CellTruthElem( p->uTemp1[i1], p->uTemp2[i2], p->uTemp3[i3], pCell->uTruth, 9, s_NPNe3p[k] ); 00299 // canonicize 00300 Cut_CellCanonicize( pCell ); 00301 00302 // add to the table 00303 p->nTotal++; 00304 if ( Cut_CellTableLookup( p, pCell ) ) // already exists 00305 Extra_MmFixedEntryRecycle( p->pMem, (char *)pCell ); 00306 else 00307 p->nGood++; 00308 } 00309 00310 // go through non-symmetric functions 00311 for ( i1 = 0; i1 < 22; i1++ ) 00312 for ( i2 = 0; i2 < 22; i2++ ) 00313 for ( i3 = 0; i3 < 22; i3++ ) 00314 { 00315 // derive the cell 00316 pCell = (Cut_Cell_t *)Extra_MmFixedEntryFetch( p->pMem ); 00317 memset( pCell, 0, sizeof(Cut_Cell_t) ); 00318 pCell->nVars = 9; 00319 pCell->Box[0] = 17; 00320 pCell->Box[1] = i1; 00321 pCell->Box[2] = i2; 00322 pCell->Box[3] = i3; 00323 // fill in the truth table 00324 Cut_CellTruthElem( p->uTemp1[i1], p->uTemp2[i2], p->uTemp3[i3], pCell->uTruth, 9, 17 ); 00325 // canonicize 00326 Cut_CellCanonicize( pCell ); 00327 00328 // add to the table 00329 p->nTotal++; 00330 if ( Cut_CellTableLookup( p, pCell ) ) // already exists 00331 Extra_MmFixedEntryRecycle( p->pMem, (char *)pCell ); 00332 else 00333 p->nGood++; 00334 } 00335 */ 00336 00337 // go through non-symmetric functions 00338 for ( k = 0; k < 10; k++ ) 00339 for ( i1 = 0; i1 < 22; i1++ ) 00340 for ( i2 = 0; i2 < 22; i2++ ) 00341 for ( i3 = 0; i3 < 22; i3++ ) 00342 { 00343 // derive the cell 00344 pCell = (Cut_Cell_t *)Extra_MmFixedEntryFetch( p->pMem ); 00345 memset( pCell, 0, sizeof(Cut_Cell_t) ); 00346 pCell->nVars = 9; 00347 pCell->Box[0] = s_NPNe3[k]; 00348 pCell->Box[1] = i1; 00349 pCell->Box[2] = i2; 00350 pCell->Box[3] = i3; 00351 // set the elementary permutation 00352 for ( i = 0; i < (int)pCell->nVars; i++ ) 00353 pCell->CanonPerm[i] = i; 00354 // fill in the truth table 00355 Cut_CellTruthElem( p->uTemp1[i1], p->uTemp2[i2], p->uTemp3[i3], pCell->uTruth, 9, s_NPNe3[k] ); 00356 // minimize the support 00357 Cut_CellSuppMin( pCell ); 00358 00359 // canonicize 00360 pCell->CanonPhase = Extra_TruthSemiCanonicize( pCell->uTruth, p->puAux, pCell->nVars, pCell->CanonPerm, pCell->Store ); 00361 00362 // add to the table 00363 p->nTotal++; 00364 if ( Cut_CellTableLookup( p, pCell ) ) // already exists 00365 Extra_MmFixedEntryRecycle( p->pMem, (char *)pCell ); 00366 else 00367 { 00368 p->nGood++; 00369 p->nVarCounts[pCell->nVars]++; 00370 00371 if ( pCell->nVars ) 00372 for ( i = 0; i < (int)pCell->nVars-1; i++ ) 00373 { 00374 if ( pCell->Store[2*i] != pCell->Store[2*(i+1)] ) // i and i+1 cannot be symmetric 00375 continue; 00376 // i and i+1 can be symmetric 00377 // find the end of this group 00378 for ( j = i+1; j < (int)pCell->nVars; j++ ) 00379 if ( pCell->Store[2*i] != pCell->Store[2*j] ) 00380 break; 00381 00382 if ( pCell->Store[2*i] == pCell->Store[2*i+1] ) 00383 p->nSymGroupsE[j-i]++; 00384 else 00385 p->nSymGroups[j-i]++; 00386 i = j - 1; 00387 } 00388 /* 00389 if ( pCell->nVars == 3 ) 00390 { 00391 Extra_PrintBinary( stdout, pCell->uTruth, 32 ); printf( "\n" ); 00392 for ( i = 0; i < (int)pCell->nVars; i++ ) 00393 printf( "%d=%d/%d ", pCell->CanonPerm[i], pCell->Store[2*i], pCell->Store[2*i+1] ); 00394 printf( "\n" ); 00395 } 00396 */ 00397 } 00398 } 00399 00400 printf( "BASIC: Total = %d. Good = %d. Entry = %d. ", p->nTotal, p->nGood, sizeof(Cut_Cell_t) ); 00401 PRT( "Time", clock() - clk ); 00402 printf( "Cells: " ); 00403 for ( i = 0; i <= 9; i++ ) 00404 printf( "%d=%d ", i, p->nVarCounts[i] ); 00405 printf( "\nDiffs: " ); 00406 for ( i = 0; i <= 9; i++ ) 00407 printf( "%d=%d ", i, p->nSymGroups[i] ); 00408 printf( "\nEquals: " ); 00409 for ( i = 0; i <= 9; i++ ) 00410 printf( "%d=%d ", i, p->nSymGroupsE[i] ); 00411 printf( "\n" ); 00412 00413 // continue adding new cells using support 00414 for ( k = CUT_CELL_MVAR; k > 3; k-- ) 00415 { 00416 for ( pTemp = p->pSameVar[k]; pTemp; pTemp = pTemp->pNextVar ) 00417 for ( i1 = 0; i1 < k; i1++ ) 00418 for ( i2 = i1+1; i2 < k; i2++ ) 00419 for ( c = 0; c < 3; c++ ) 00420 { 00421 // derive the cell 00422 pCell = (Cut_Cell_t *)Extra_MmFixedEntryFetch( p->pMem ); 00423 memset( pCell, 0, sizeof(Cut_Cell_t) ); 00424 pCell->nVars = pTemp->nVars; 00425 pCell->pParent = pTemp; 00426 // set the elementary permutation 00427 for ( i = 0; i < (int)pCell->nVars; i++ ) 00428 pCell->CanonPerm[i] = i; 00429 // fill in the truth table 00430 Extra_TruthCopy( pCell->uTruth, pTemp->uTruth, pTemp->nVars ); 00431 // create the cross-bar 00432 pCell->CrossBar0 = i1; 00433 pCell->CrossBar1 = i2; 00434 pCell->CrossBarPhase = c; 00435 Cut_CellCrossBar( pCell ); 00436 // minimize the support 00437 //clk2 = clock(); 00438 Cut_CellSuppMin( pCell ); 00439 //p->timeSupp += clock() - clk2; 00440 // canonicize 00441 //clk2 = clock(); 00442 pCell->CanonPhase = Extra_TruthSemiCanonicize( pCell->uTruth, p->puAux, pCell->nVars, pCell->CanonPerm, pCell->Store ); 00443 //p->timeCanon += clock() - clk2; 00444 00445 // add to the table 00446 //clk2 = clock(); 00447 p->nTotal++; 00448 if ( Cut_CellTableLookup( p, pCell ) ) // already exists 00449 Extra_MmFixedEntryRecycle( p->pMem, (char *)pCell ); 00450 else 00451 { 00452 p->nGood++; 00453 p->nVarCounts[pCell->nVars]++; 00454 00455 for ( i = 0; i < (int)pCell->nVars-1; i++ ) 00456 { 00457 if ( pCell->Store[2*i] != pCell->Store[2*(i+1)] ) // i and i+1 cannot be symmetric 00458 continue; 00459 // i and i+1 can be symmetric 00460 // find the end of this group 00461 for ( j = i+1; j < (int)pCell->nVars; j++ ) 00462 if ( pCell->Store[2*i] != pCell->Store[2*j] ) 00463 break; 00464 00465 if ( pCell->Store[2*i] == pCell->Store[2*i+1] ) 00466 p->nSymGroupsE[j-i]++; 00467 else 00468 p->nSymGroups[j-i]++; 00469 i = j - 1; 00470 } 00471 /* 00472 if ( pCell->nVars == 3 ) 00473 { 00474 Extra_PrintBinary( stdout, pCell->uTruth, 32 ); printf( "\n" ); 00475 for ( i = 0; i < (int)pCell->nVars; i++ ) 00476 printf( "%d=%d/%d ", pCell->CanonPerm[i], pCell->Store[2*i], pCell->Store[2*i+1] ); 00477 printf( "\n" ); 00478 } 00479 */ 00480 } 00481 //p->timeTable += clock() - clk2; 00482 } 00483 00484 printf( "VAR %d: Total = %d. Good = %d. Entry = %d. ", k, p->nTotal, p->nGood, sizeof(Cut_Cell_t) ); 00485 PRT( "Time", clock() - clk ); 00486 printf( "Cells: " ); 00487 for ( i = 0; i <= 9; i++ ) 00488 printf( "%d=%d ", i, p->nVarCounts[i] ); 00489 printf( "\nDiffs: " ); 00490 for ( i = 0; i <= 9; i++ ) 00491 printf( "%d=%d ", i, p->nSymGroups[i] ); 00492 printf( "\nEquals: " ); 00493 for ( i = 0; i <= 9; i++ ) 00494 printf( "%d=%d ", i, p->nSymGroupsE[i] ); 00495 printf( "\n" ); 00496 } 00497 // printf( "\n" ); 00498 PRT( "Supp ", p->timeSupp ); 00499 PRT( "Canon", p->timeCanon ); 00500 PRT( "Table", p->timeTable ); 00501 // Cut_CManStop( p ); 00502 }
int Cut_CellTruthLookup | ( | unsigned * | pTruth, | |
int | nVars | |||
) |
Function*************************************************************
Synopsis [Looks up if the given function exists in the hash table.]
Description [If the function exists, returns 1, meaning that it can be implemented using two levels of 3-input LUTs. If the function does not exist, return 0.]
SideEffects []
SeeAlso []
Definition at line 936 of file cutPre22.c.
00937 { 00938 Cut_CMan_t * p = s_pCMan; 00939 Cut_Cell_t * pTemp; 00940 Cut_Cell_t Cell, * pCell = &Cell; 00941 unsigned Hash; 00942 int i; 00943 00944 // cell manager is not defined 00945 if ( p == NULL ) 00946 { 00947 printf( "Cut_CellTruthLookup: Cell manager is not defined.\n" ); 00948 return 0; 00949 } 00950 00951 // canonicize 00952 memset( pCell, 0, sizeof(Cut_Cell_t) ); 00953 pCell->nVars = nVars; 00954 Extra_TruthCopy( pCell->uTruth, pTruth, nVars ); 00955 Cut_CellSuppMin( pCell ); 00956 // set the elementary permutation 00957 for ( i = 0; i < (int)pCell->nVars; i++ ) 00958 pCell->CanonPerm[i] = i; 00959 // canonicize 00960 pCell->CanonPhase = Extra_TruthSemiCanonicize( pCell->uTruth, p->puAux, pCell->nVars, pCell->CanonPerm, pCell->Store ); 00961 00962 00963 // check if the cell exists 00964 Hash = Extra_TruthHash( pCell->uTruth, Extra_TruthWordNum(pCell->nVars) ); 00965 if ( st_lookup( p->tTable, (char *)Hash, (char **)&pTemp ) ) 00966 { 00967 for ( ; pTemp; pTemp = pTemp->pNext ) 00968 { 00969 if ( pTemp->nVars != pCell->nVars ) 00970 continue; 00971 if ( Extra_TruthIsEqual(pTemp->uTruth, pCell->uTruth, pCell->nVars) ) 00972 { 00973 pTemp->nUsed++; 00974 p->nCellFound++; 00975 return 1; 00976 } 00977 } 00978 } 00979 p->nCellNotFound++; 00980 return 0; 00981 }
int Cut_CutCountList | ( | Cut_Cut_t * | pList | ) |
Function*************************************************************
Synopsis [Counts the number of cuts in the list.]
Description []
SideEffects []
SeeAlso []
Definition at line 163 of file cutCut.c.
00164 { 00165 int Counter = 0; 00166 Cut_ListForEachCut( pList, pList ) 00167 Counter++; 00168 return Counter; 00169 }
void Cut_CutPrint | ( | Cut_Cut_t * | pCut, | |
int | fSeq | |||
) |
Function*************************************************************
Synopsis [Print the cut.]
Description []
SideEffects []
SeeAlso []
Definition at line 273 of file cutCut.c.
00274 { 00275 int i; 00276 assert( pCut->nLeaves > 0 ); 00277 printf( "%d : {", pCut->nLeaves ); 00278 for ( i = 0; i < (int)pCut->nLeaves; i++ ) 00279 { 00280 if ( fSeq ) 00281 { 00282 printf( " %d", pCut->pLeaves[i] >> CUT_SHIFT ); 00283 if ( pCut->pLeaves[i] & CUT_MASK ) 00284 printf( "(%d)", pCut->pLeaves[i] & CUT_MASK ); 00285 } 00286 else 00287 printf( " %d", pCut->pLeaves[i] ); 00288 } 00289 printf( " }" ); 00290 // printf( "\nSign = " ); 00291 // Extra_PrintBinary( stdout, &pCut->uSign, 32 ); 00292 }
void Cut_CutPrintList | ( | Cut_Cut_t * | pList, | |
int | fSeq | |||
) |
Function*************************************************************
Synopsis [Print the cut.]
Description []
SideEffects []
SeeAlso []
Definition at line 305 of file cutCut.c.
00306 { 00307 Cut_Cut_t * pCut; 00308 for ( pCut = pList; pCut; pCut = pCut->pNext ) 00309 Cut_CutPrint( pCut, fSeq ), printf( "\n" ); 00310 }
static int Cut_CutReadLeaveNum | ( | Cut_Cut_t * | p | ) | [inline, static] |
static int* Cut_CutReadLeaves | ( | Cut_Cut_t * | p | ) | [inline, static] |
static unsigned* Cut_CutReadTruth | ( | Cut_Cut_t * | p | ) | [inline, static] |
static void Cut_CutWriteTruth | ( | Cut_Cut_t * | p, | |
unsigned * | puTruth | |||
) | [inline, static] |
void Cut_ManIncrementDagNodes | ( | Cut_Man_t * | p | ) |
int Cut_ManMappingArea_rec | ( | Cut_Man_t * | p, | |
int | Node | |||
) |
Function*************************************************************
Synopsis [Computes area after mapping.]
Description []
SideEffects []
SeeAlso []
Definition at line 534 of file cutNode.c.
00535 { 00536 Cut_Cut_t * pCut; 00537 int i, Counter; 00538 if ( p->vCutsMax == NULL ) 00539 return 0; 00540 pCut = Vec_PtrEntry( p->vCutsMax, Node ); 00541 if ( pCut == NULL || pCut->nLeaves == 1 ) 00542 return 0; 00543 Counter = 0; 00544 for ( i = 0; i < (int)pCut->nLeaves; i++ ) 00545 Counter += Cut_ManMappingArea_rec( p, pCut->pLeaves[i] ); 00546 Vec_PtrWriteEntry( p->vCutsMax, Node, NULL ); 00547 return 1 + Counter; 00548 }
void Cut_ManPrintStats | ( | Cut_Man_t * | p | ) |
Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
Definition at line 163 of file cutMan.c.
00164 { 00165 if ( p->pReady ) 00166 { 00167 Cut_CutRecycle( p, p->pReady ); 00168 p->pReady = NULL; 00169 } 00170 printf( "Cut computation statistics:\n" ); 00171 printf( "Current cuts = %8d. (Trivial = %d.)\n", p->nCutsCur-p->nCutsTriv, p->nCutsTriv ); 00172 printf( "Peak cuts = %8d.\n", p->nCutsPeak ); 00173 printf( "Total allocated = %8d.\n", p->nCutsAlloc ); 00174 printf( "Total deallocated = %8d.\n", p->nCutsDealloc ); 00175 printf( "Cuts filtered = %8d.\n", p->nCutsFilter ); 00176 printf( "Nodes saturated = %8d. (Max cuts = %d.)\n", p->nCutsLimit, p->pParams->nKeepMax ); 00177 printf( "Cuts per node = %8.1f\n", ((float)(p->nCutsCur-p->nCutsTriv))/p->nNodes ); 00178 printf( "The cut size = %8d bytes.\n", p->EntrySize ); 00179 printf( "Peak memory = %8.2f Mb.\n", (float)p->nCutsPeak * p->EntrySize / (1<<20) ); 00180 printf( "Total nodes = %8d.\n", p->nNodes ); 00181 if ( p->pParams->fDag || p->pParams->fTree ) 00182 { 00183 printf( "DAG nodes = %8d.\n", p->nNodesDag ); 00184 printf( "Tree nodes = %8d.\n", p->nNodes - p->nNodesDag ); 00185 } 00186 printf( "Nodes w/o cuts = %8d.\n", p->nNodesNoCuts ); 00187 if ( p->pParams->fMap && !p->pParams->fSeq ) 00188 printf( "Mapping delay = %8d.\n", p->nDelayMin ); 00189 00190 PRT( "Merge ", p->timeMerge ); 00191 PRT( "Union ", p->timeUnion ); 00192 PRT( "Filter", p->timeFilter ); 00193 PRT( "Truth ", p->timeTruth ); 00194 PRT( "Map ", p->timeMap ); 00195 // printf( "Nodes = %d. Multi = %d. Cuts = %d. Multi = %d.\n", 00196 // p->nNodes, p->nNodesMulti, p->nCutsCur-p->nCutsTriv, p->nCutsMulti ); 00197 // printf( "Count0 = %d. Count1 = %d. Count2 = %d.\n\n", p->Count0, p->Count1, p->Count2 ); 00198 }
void Cut_ManPrintStatsToFile | ( | Cut_Man_t * | p, | |
char * | pFileName, | |||
int | TimeTotal | |||
) |
Function*************************************************************
Synopsis [Prints some interesting stats.]
Description []
SideEffects []
SeeAlso []
Definition at line 212 of file cutMan.c.
00213 { 00214 FILE * pTable; 00215 pTable = fopen( "cut_stats.txt", "a+" ); 00216 fprintf( pTable, "%-20s ", pFileName ); 00217 fprintf( pTable, "%8d ", p->nNodes ); 00218 fprintf( pTable, "%6.1f ", ((float)(p->nCutsCur))/p->nNodes ); 00219 fprintf( pTable, "%6.2f ", ((float)(100.0 * p->nCutsLimit))/p->nNodes ); 00220 fprintf( pTable, "%6.2f ", (float)p->nCutsPeak * p->EntrySize / (1<<20) ); 00221 fprintf( pTable, "%6.2f ", (float)(TimeTotal)/(float)(CLOCKS_PER_SEC) ); 00222 fprintf( pTable, "\n" ); 00223 fclose( pTable ); 00224 }
Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
Definition at line 301 of file cutMan.c.
00302 { 00303 return p->vNodeAttrs; 00304 }
Cut_Params_t* Cut_ManReadParams | ( | Cut_Man_t * | p | ) |
int Cut_ManReadVarsMax | ( | Cut_Man_t * | p | ) |
Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
Definition at line 237 of file cutMan.c.
00238 { 00239 p->vFanCounts = vFanCounts; 00240 }
Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
Definition at line 253 of file cutMan.c.
00254 { 00255 p->vNodeAttrs = vNodeAttrs; 00256 }
Cut_Man_t* Cut_ManStart | ( | Cut_Params_t * | pParams | ) |
FUNCTION DEFINITIONS ///Function*************************************************************
Synopsis [Starts the cut manager.]
Description []
SideEffects []
SeeAlso []
Definition at line 44 of file cutMan.c.
00045 { 00046 Cut_Man_t * p; 00047 int clk = clock(); 00048 // extern int nTruthDsd; 00049 // nTruthDsd = 0; 00050 assert( pParams->nVarsMax >= 3 && pParams->nVarsMax <= CUT_SIZE_MAX ); 00051 p = ALLOC( Cut_Man_t, 1 ); 00052 memset( p, 0, sizeof(Cut_Man_t) ); 00053 // set and correct parameters 00054 p->pParams = pParams; 00055 // prepare storage for cuts 00056 p->vCutsNew = Vec_PtrAlloc( pParams->nIdsMax ); 00057 Vec_PtrFill( p->vCutsNew, pParams->nIdsMax, NULL ); 00058 // prepare storage for sequential cuts 00059 if ( pParams->fSeq ) 00060 { 00061 p->pParams->fFilter = 1; 00062 p->vCutsOld = Vec_PtrAlloc( pParams->nIdsMax ); 00063 Vec_PtrFill( p->vCutsOld, pParams->nIdsMax, NULL ); 00064 p->vCutsTemp = Vec_PtrAlloc( pParams->nCutSet ); 00065 Vec_PtrFill( p->vCutsTemp, pParams->nCutSet, NULL ); 00066 if ( pParams->fTruth && pParams->nVarsMax > 5 ) 00067 { 00068 pParams->fTruth = 0; 00069 printf( "Skipping computation of truth tables for sequential cuts with more than 5 inputs.\n" ); 00070 } 00071 } 00072 // entry size 00073 p->EntrySize = sizeof(Cut_Cut_t) + pParams->nVarsMax * sizeof(int); 00074 if ( pParams->fTruth ) 00075 { 00076 if ( pParams->nVarsMax > 14 ) 00077 { 00078 pParams->fTruth = 0; 00079 printf( "Skipping computation of truth table for more than %d inputs.\n", 14 ); 00080 } 00081 else 00082 { 00083 p->nTruthWords = Cut_TruthWords( pParams->nVarsMax ); 00084 p->EntrySize += p->nTruthWords * sizeof(unsigned); 00085 } 00086 p->puTemp[0] = ALLOC( unsigned, 4 * p->nTruthWords ); 00087 p->puTemp[1] = p->puTemp[0] + p->nTruthWords; 00088 p->puTemp[2] = p->puTemp[1] + p->nTruthWords; 00089 p->puTemp[3] = p->puTemp[2] + p->nTruthWords; 00090 } 00091 // enable cut computation recording 00092 if ( pParams->fRecord ) 00093 { 00094 p->vNodeCuts = Vec_IntStart( pParams->nIdsMax ); 00095 p->vNodeStarts = Vec_IntStart( pParams->nIdsMax ); 00096 p->vCutPairs = Vec_IntAlloc( 0 ); 00097 } 00098 // allocate storage for delays 00099 if ( pParams->fMap && !p->pParams->fSeq ) 00100 { 00101 p->vDelays = Vec_IntStart( pParams->nIdsMax ); 00102 p->vDelays2 = Vec_IntStart( pParams->nIdsMax ); 00103 p->vCutsMax = Vec_PtrStart( pParams->nIdsMax ); 00104 } 00105 // memory for cuts 00106 p->pMmCuts = Extra_MmFixedStart( p->EntrySize ); 00107 p->vTemp = Vec_PtrAlloc( 100 ); 00108 return p; 00109 }
void Cut_ManStop | ( | Cut_Man_t * | p | ) |
Function*************************************************************
Synopsis [Stops the cut manager.]
Description []
SideEffects []
SeeAlso []
Definition at line 122 of file cutMan.c.
00123 { 00124 Cut_Cut_t * pCut; 00125 int i; 00126 // extern int nTruthDsd; 00127 // printf( "Decomposable cuts = %d.\n", nTruthDsd ); 00128 00129 Vec_PtrForEachEntry( p->vCutsNew, pCut, i ) 00130 if ( pCut != NULL ) 00131 { 00132 int k = 0; 00133 } 00134 if ( p->vCutsNew ) Vec_PtrFree( p->vCutsNew ); 00135 if ( p->vCutsOld ) Vec_PtrFree( p->vCutsOld ); 00136 if ( p->vCutsTemp ) Vec_PtrFree( p->vCutsTemp ); 00137 if ( p->vFanCounts ) Vec_IntFree( p->vFanCounts ); 00138 if ( p->vTemp ) Vec_PtrFree( p->vTemp ); 00139 00140 if ( p->vCutsMax ) Vec_PtrFree( p->vCutsMax ); 00141 if ( p->vDelays ) Vec_IntFree( p->vDelays ); 00142 if ( p->vDelays2 ) Vec_IntFree( p->vDelays2 ); 00143 if ( p->vNodeCuts ) Vec_IntFree( p->vNodeCuts ); 00144 if ( p->vNodeStarts ) Vec_IntFree( p->vNodeStarts ); 00145 if ( p->vCutPairs ) Vec_IntFree( p->vCutPairs ); 00146 if ( p->puTemp[0] ) free( p->puTemp[0] ); 00147 00148 Extra_MmFixedStop( p->pMmCuts ); 00149 free( p ); 00150 }
Cut_Cut_t* Cut_NodeComputeCuts | ( | Cut_Man_t * | p, | |
int | Node, | |||
int | Node0, | |||
int | Node1, | |||
int | fCompl0, | |||
int | fCompl1, | |||
int | fTriv, | |||
int | TreeCode | |||
) |
Function*************************************************************
Synopsis [Computes the cuts by merging cuts at two nodes.]
Description []
SideEffects []
SeeAlso []
Definition at line 366 of file cutNode.c.
00367 { 00368 Cut_List_t Super, * pSuper = &Super; 00369 Cut_Cut_t * pList, * pCut; 00370 int clk; 00371 // start the number of cuts at the node 00372 p->nNodes++; 00373 p->nNodeCuts = 0; 00374 // prepare information for recording 00375 if ( p->pParams->fRecord ) 00376 { 00377 Cut_CutNumberList( Cut_NodeReadCutsNew(p, Node0) ); 00378 Cut_CutNumberList( Cut_NodeReadCutsNew(p, Node1) ); 00379 } 00380 // compute the cuts 00381 clk = clock(); 00382 Cut_ListStart( pSuper ); 00383 Cut_NodeDoComputeCuts( p, pSuper, Node, fCompl0, fCompl1, Cut_NodeReadCutsNew(p, Node0), Cut_NodeReadCutsNew(p, Node1), fTriv, TreeCode ); 00384 pList = Cut_ListFinish( pSuper ); 00385 p->timeMerge += clock() - clk; 00386 // verify the result of cut computation 00387 // Cut_CutListVerify( pList ); 00388 // performing the recording 00389 if ( p->pParams->fRecord ) 00390 { 00391 Vec_IntWriteEntry( p->vNodeStarts, Node, Vec_IntSize(p->vCutPairs) ); 00392 Cut_ListForEachCut( pList, pCut ) 00393 Vec_IntPush( p->vCutPairs, ((pCut->Num1 << 16) | pCut->Num0) ); 00394 Vec_IntWriteEntry( p->vNodeCuts, Node, Vec_IntSize(p->vCutPairs) - Vec_IntEntry(p->vNodeStarts, Node) ); 00395 } 00396 // check if the node is over the list 00397 if ( p->nNodeCuts == p->pParams->nKeepMax ) 00398 p->nCutsLimit++; 00399 // set the list at the node 00400 Vec_PtrFillExtra( p->vCutsNew, Node + 1, NULL ); 00401 assert( Cut_NodeReadCutsNew(p, Node) == NULL ); 00403 // pList->pNext = NULL; 00405 Cut_NodeWriteCutsNew( p, Node, pList ); 00406 // filter the cuts 00407 //clk = clock(); 00408 // if ( p->pParams->fFilter ) 00409 // Cut_CutFilter( p, pList0 ); 00410 //p->timeFilter += clock() - clk; 00411 // perform mapping of this node with these cuts 00412 clk = clock(); 00413 if ( p->pParams->fMap && !p->pParams->fSeq ) 00414 { 00415 // int Delay1, Delay2; 00416 // Delay1 = Cut_NodeMapping( p, pList, Node, Node0, Node1 ); 00417 // Delay2 = Cut_NodeMapping2( p, pList, Node, Node0, Node1 ); 00418 // assert( Delay1 >= Delay2 ); 00419 Cut_NodeMapping( p, pList, Node, Node0, Node1 ); 00420 } 00421 p->timeMap += clock() - clk; 00422 return pList; 00423 }
void Cut_NodeComputeCutsSeq | ( | Cut_Man_t * | p, | |
int | Node, | |||
int | Node0, | |||
int | Node1, | |||
int | fCompl0, | |||
int | fCompl1, | |||
int | nLat0, | |||
int | nLat1, | |||
int | fTriv, | |||
int | CutSetNum | |||
) |
Function*************************************************************
Synopsis [Computes sequential cuts for the node from its fanins.]
Description []
SideEffects []
SeeAlso []
Definition at line 69 of file cutSeq.c.
00070 { 00071 Cut_List_t Super, * pSuper = &Super; 00072 Cut_Cut_t * pListNew; 00073 int clk; 00074 00075 // get the number of cuts at the node 00076 p->nNodeCuts = Cut_CutCountList( Cut_NodeReadCutsOld(p, Node) ); 00077 if ( p->nNodeCuts >= p->pParams->nKeepMax ) 00078 return; 00079 00080 // count only the first visit 00081 if ( p->nNodeCuts == 0 ) 00082 p->nNodes++; 00083 00084 // store the fanin lists 00085 p->pStore0[0] = Cut_NodeReadCutsOld( p, Node0 ); 00086 p->pStore0[1] = Cut_NodeReadCutsNew( p, Node0 ); 00087 p->pStore1[0] = Cut_NodeReadCutsOld( p, Node1 ); 00088 p->pStore1[1] = Cut_NodeReadCutsNew( p, Node1 ); 00089 00090 // duplicate the cut lists if fanin nodes are non-standard 00091 if ( Node == Node0 || Node == Node1 || Node0 == Node1 ) 00092 { 00093 p->pStore0[0] = Cut_CutDupList( p, p->pStore0[0] ); 00094 p->pStore0[1] = Cut_CutDupList( p, p->pStore0[1] ); 00095 p->pStore1[0] = Cut_CutDupList( p, p->pStore1[0] ); 00096 p->pStore1[1] = Cut_CutDupList( p, p->pStore1[1] ); 00097 } 00098 00099 // shift the cuts by as many latches and recompute signatures 00100 if ( nLat0 ) Cut_NodeShiftCutLeaves( p->pStore0[0], nLat0 ); 00101 if ( nLat0 ) Cut_NodeShiftCutLeaves( p->pStore0[1], nLat0 ); 00102 if ( nLat1 ) Cut_NodeShiftCutLeaves( p->pStore1[0], nLat1 ); 00103 if ( nLat1 ) Cut_NodeShiftCutLeaves( p->pStore1[1], nLat1 ); 00104 00105 // store the original lists for comparison 00106 p->pCompareOld = Cut_NodeReadCutsOld( p, Node ); 00107 p->pCompareNew = Cut_NodeReadCutsNew( p, Node ); 00108 00109 // merge the old and the new 00110 clk = clock(); 00111 Cut_ListStart( pSuper ); 00112 Cut_NodeDoComputeCuts( p, pSuper, Node, fCompl0, fCompl1, p->pStore0[0], p->pStore1[1], 0, 0 ); 00113 Cut_NodeDoComputeCuts( p, pSuper, Node, fCompl0, fCompl1, p->pStore0[1], p->pStore1[0], 0, 0 ); 00114 Cut_NodeDoComputeCuts( p, pSuper, Node, fCompl0, fCompl1, p->pStore0[1], p->pStore1[1], fTriv, 0 ); 00115 pListNew = Cut_ListFinish( pSuper ); 00116 p->timeMerge += clock() - clk; 00117 00118 // shift the cuts by as many latches and recompute signatures 00119 if ( Node == Node0 || Node == Node1 || Node0 == Node1 ) 00120 { 00121 Cut_CutRecycleList( p, p->pStore0[0] ); 00122 Cut_CutRecycleList( p, p->pStore0[1] ); 00123 Cut_CutRecycleList( p, p->pStore1[0] ); 00124 Cut_CutRecycleList( p, p->pStore1[1] ); 00125 } 00126 else 00127 { 00128 if ( nLat0 ) Cut_NodeShiftCutLeaves( p->pStore0[0], -nLat0 ); 00129 if ( nLat0 ) Cut_NodeShiftCutLeaves( p->pStore0[1], -nLat0 ); 00130 if ( nLat1 ) Cut_NodeShiftCutLeaves( p->pStore1[0], -nLat1 ); 00131 if ( nLat1 ) Cut_NodeShiftCutLeaves( p->pStore1[1], -nLat1 ); 00132 } 00133 00134 // set the lists at the node 00135 if ( CutSetNum >= 0 ) 00136 { 00137 assert( Cut_NodeReadCutsTemp(p, CutSetNum) == NULL ); 00138 Cut_NodeWriteCutsTemp( p, CutSetNum, pListNew ); 00139 } 00140 else 00141 { 00142 assert( Cut_NodeReadCutsNew(p, Node) == NULL ); 00143 Cut_NodeWriteCutsNew( p, Node, pListNew ); 00144 } 00145 00146 // mark the node if we exceeded the number of cuts 00147 if ( p->nNodeCuts >= p->pParams->nKeepMax ) 00148 p->nCutsLimit++; 00149 }
void Cut_NodeFreeCuts | ( | Cut_Man_t * | p, | |
int | Node | |||
) |
Function*************************************************************
Synopsis [Deallocates the cuts at the node.]
Description []
SideEffects []
SeeAlso []
Definition at line 181 of file cutApi.c.
00182 { 00183 Cut_Cut_t * pList, * pCut, * pCut2; 00184 pList = Cut_NodeReadCutsNew( p, Node ); 00185 if ( pList == NULL ) 00186 return; 00187 Cut_ListForEachCutSafe( pList, pCut, pCut2 ) 00188 Cut_CutRecycle( p, pCut ); 00189 Cut_NodeWriteCutsNew( p, Node, NULL ); 00190 }
void Cut_NodeNewMergeWithOld | ( | Cut_Man_t * | p, | |
int | Node | |||
) |
Function*************************************************************
Synopsis [Merges the new cuts with the old cuts.]
Description []
SideEffects []
SeeAlso []
Definition at line 162 of file cutSeq.c.
00163 { 00164 Cut_Cut_t * pListOld, * pListNew, * pList; 00165 // get the new cuts 00166 pListNew = Cut_NodeReadCutsNew( p, Node ); 00167 if ( pListNew == NULL ) 00168 return; 00169 Cut_NodeWriteCutsNew( p, Node, NULL ); 00170 // get the old cuts 00171 pListOld = Cut_NodeReadCutsOld( p, Node ); 00172 if ( pListOld == NULL ) 00173 { 00174 Cut_NodeWriteCutsOld( p, Node, pListNew ); 00175 return; 00176 } 00177 // merge the lists 00178 pList = Cut_CutMergeLists( pListOld, pListNew ); 00179 Cut_NodeWriteCutsOld( p, Node, pList ); 00180 }
void Cut_NodeOldTransferToNew | ( | Cut_Man_t * | p, | |
int | Node | |||
) |
Function*************************************************************
Synopsis [Transfers the old cuts to be the new cuts.]
Description []
SideEffects []
SeeAlso []
Definition at line 214 of file cutSeq.c.
00215 { 00216 Cut_Cut_t * pList; 00217 pList = Cut_NodeReadCutsOld( p, Node ); 00218 Cut_NodeWriteCutsOld( p, Node, NULL ); 00219 Cut_NodeWriteCutsNew( p, Node, pList ); 00220 // Cut_CutListVerify( pList ); 00221 }
MACRO DEFINITIONS /// FUNCTION DECLARATIONS ///
CFile****************************************************************
FileName [cutNode.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [K-feasible cut computation package.]
Synopsis [Procedures to compute cuts for a node.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [
] DECLARATIONS /// FUNCTION DEFINITIONS ///Function*************************************************************
Synopsis [Returns the pointer to the linked list of cuts.]
Description []
SideEffects []
SeeAlso []
Definition at line 42 of file cutApi.c.
00043 { 00044 if ( Node >= p->vCutsNew->nSize ) 00045 return NULL; 00046 return Vec_PtrEntry( p->vCutsNew, Node ); 00047 }
Function*************************************************************
Synopsis [Returns the pointer to the linked list of cuts.]
Description []
SideEffects []
SeeAlso []
Definition at line 60 of file cutApi.c.
00061 { 00062 assert( Node < p->vCutsOld->nSize ); 00063 return Vec_PtrEntry( p->vCutsOld, Node ); 00064 }
Function*************************************************************
Synopsis [Returns the pointer to the linked list of cuts.]
Description []
SideEffects []
SeeAlso []
Definition at line 77 of file cutApi.c.
00078 { 00079 assert( Node < p->vCutsTemp->nSize ); 00080 return Vec_PtrEntry( p->vCutsTemp, Node ); 00081 }
void Cut_NodeSetTriv | ( | Cut_Man_t * | p, | |
int | Node | |||
) |
Function*************************************************************
Synopsis [Sets the trivial cut for the node.]
Description []
SideEffects []
SeeAlso []
Definition at line 142 of file cutApi.c.
00143 { 00144 assert( Cut_NodeReadCutsNew(p, Node) == NULL ); 00145 Cut_NodeWriteCutsNew( p, Node, Cut_CutCreateTriv(p, Node) ); 00146 }
int Cut_NodeTempTransferToNew | ( | Cut_Man_t * | p, | |
int | Node, | |||
int | CutSetNum | |||
) |
Function*************************************************************
Synopsis [Transfers the temporary cuts to be the new cuts.]
Description [Returns 1 if something was transferred.]
SideEffects []
SeeAlso []
Definition at line 194 of file cutSeq.c.
00195 { 00196 Cut_Cut_t * pList; 00197 pList = Cut_NodeReadCutsTemp( p, CutSetNum ); 00198 Cut_NodeWriteCutsTemp( p, CutSetNum, NULL ); 00199 Cut_NodeWriteCutsNew( p, Node, pList ); 00200 return pList != NULL; 00201 }
void Cut_NodeTryDroppingCuts | ( | Cut_Man_t * | p, | |
int | Node | |||
) |
Function*************************************************************
Synopsis [Consider dropping cuts if they are useless by now.]
Description []
SideEffects []
SeeAlso []
Definition at line 159 of file cutApi.c.
00160 { 00161 int nFanouts; 00162 assert( p->vFanCounts ); 00163 nFanouts = Vec_IntEntry( p->vFanCounts, Node ); 00164 assert( nFanouts > 0 ); 00165 if ( --nFanouts == 0 ) 00166 Cut_NodeFreeCuts( p, Node ); 00167 Vec_IntWriteEntry( p->vFanCounts, Node, nFanouts ); 00168 }
Function*************************************************************
Synopsis [Computes the cuts by unioning cuts at a choice node.]
Description []
SideEffects []
SeeAlso []
Definition at line 667 of file cutNode.c.
00668 { 00669 Cut_List_t Super, * pSuper = &Super; 00670 Cut_Cut_t * pList, * pListStart, * pCut, * pCut2, * pTop; 00671 int i, k, Node, Root, Limit = p->pParams->nVarsMax; 00672 int clk = clock(); 00673 00674 // start the new list 00675 Cut_ListStart( pSuper ); 00676 00677 // remember the root node to save the resulting cuts 00678 Root = Vec_IntEntry( vNodes, 0 ); 00679 p->nNodeCuts = 1; 00680 00681 // collect small cuts first 00682 Vec_PtrClear( p->vTemp ); 00683 Vec_IntForEachEntry( vNodes, Node, i ) 00684 { 00685 // get the cuts of this node 00686 pList = Cut_NodeReadCutsNew( p, Node ); 00687 Cut_NodeWriteCutsNew( p, Node, NULL ); 00688 assert( pList ); 00689 // remember the starting point 00690 pListStart = pList->pNext; 00691 pList->pNext = NULL; 00692 // save or recycle the elementary cut 00693 if ( i == 0 ) 00694 Cut_ListAdd( pSuper, pList ), pTop = pList; 00695 else 00696 Cut_CutRecycle( p, pList ); 00697 // save all the cuts that are smaller than the limit 00698 Cut_ListForEachCutSafe( pListStart, pCut, pCut2 ) 00699 { 00700 if ( pCut->nLeaves == (unsigned)Limit ) 00701 { 00702 Vec_PtrPush( p->vTemp, pCut ); 00703 break; 00704 } 00705 // check containment 00706 if ( p->pParams->fFilter && Cut_CutFilterOne( p, pSuper, pCut ) ) 00707 continue; 00708 // set the complemented bit by comparing the first cut with the current cut 00709 pCut->fCompl = pTop->fSimul ^ pCut->fSimul; 00710 pListStart = pCut->pNext; 00711 pCut->pNext = NULL; 00712 // add to the list 00713 Cut_ListAdd( pSuper, pCut ); 00714 if ( ++p->nNodeCuts == p->pParams->nKeepMax ) 00715 { 00716 // recycle the rest of the cuts of this node 00717 Cut_ListForEachCutSafe( pListStart, pCut, pCut2 ) 00718 Cut_CutRecycle( p, pCut ); 00719 // recycle all cuts of other nodes 00720 Vec_IntForEachEntryStart( vNodes, Node, k, i+1 ) 00721 Cut_NodeFreeCuts( p, Node ); 00722 // recycle the saved cuts of other nodes 00723 Vec_PtrForEachEntry( p->vTemp, pList, k ) 00724 Cut_ListForEachCutSafe( pList, pCut, pCut2 ) 00725 Cut_CutRecycle( p, pCut ); 00726 goto finish; 00727 } 00728 } 00729 } 00730 // collect larger cuts next 00731 Vec_PtrForEachEntry( p->vTemp, pList, i ) 00732 { 00733 Cut_ListForEachCutSafe( pList, pCut, pCut2 ) 00734 { 00735 // check containment 00736 if ( p->pParams->fFilter && Cut_CutFilterOne( p, pSuper, pCut ) ) 00737 continue; 00738 // set the complemented bit 00739 pCut->fCompl = pTop->fSimul ^ pCut->fSimul; 00740 pListStart = pCut->pNext; 00741 pCut->pNext = NULL; 00742 // add to the list 00743 Cut_ListAdd( pSuper, pCut ); 00744 if ( ++p->nNodeCuts == p->pParams->nKeepMax ) 00745 { 00746 // recycle the rest of the cuts 00747 Cut_ListForEachCutSafe( pListStart, pCut, pCut2 ) 00748 Cut_CutRecycle( p, pCut ); 00749 // recycle the saved cuts of other nodes 00750 Vec_PtrForEachEntryStart( p->vTemp, pList, k, i+1 ) 00751 Cut_ListForEachCutSafe( pList, pCut, pCut2 ) 00752 Cut_CutRecycle( p, pCut ); 00753 goto finish; 00754 } 00755 } 00756 } 00757 finish : 00758 // set the cuts at the node 00759 assert( Cut_NodeReadCutsNew(p, Root) == NULL ); 00760 pList = Cut_ListFinish( pSuper ); 00761 Cut_NodeWriteCutsNew( p, Root, pList ); 00762 p->timeUnion += clock() - clk; 00763 // filter the cuts 00764 //clk = clock(); 00765 // if ( p->pParams->fFilter ) 00766 // Cut_CutFilter( p, pList ); 00767 //p->timeFilter += clock() - clk; 00768 p->nNodes -= vNodes->nSize - 1; 00769 return pList; 00770 }
Function*************************************************************
Synopsis [Computes the cuts by unioning cuts at a choice node.]
Description []
SideEffects []
SeeAlso []
Definition at line 783 of file cutNode.c.
00784 { 00785 Cut_List_t Super, * pSuper = &Super; 00786 Cut_Cut_t * pList, * pListStart, * pCut, * pCut2, * pTop; 00787 int i, k, Node, Root, Limit = p->pParams->nVarsMax; 00788 int clk = clock(); 00789 00790 // start the new list 00791 Cut_ListStart( pSuper ); 00792 00793 // remember the root node to save the resulting cuts 00794 Root = Vec_IntEntry( vNodes, 0 ); 00795 p->nNodeCuts = 1; 00796 00797 // store the original lists for comparison 00798 p->pCompareOld = Cut_NodeReadCutsOld( p, Root ); 00799 p->pCompareNew = (CutSetNum >= 0)? Cut_NodeReadCutsNew( p, Root ) : NULL; 00800 00801 // get the topmost cut 00802 pTop = NULL; 00803 if ( (pTop = Cut_NodeReadCutsOld( p, Root )) == NULL ) 00804 pTop = Cut_NodeReadCutsNew( p, Root ); 00805 assert( pTop != NULL ); 00806 00807 // collect small cuts first 00808 Vec_PtrClear( p->vTemp ); 00809 Vec_IntForEachEntry( vNodes, Node, i ) 00810 { 00811 // get the cuts of this node 00812 if ( i == 0 && CutSetNum >= 0 ) 00813 { 00814 pList = Cut_NodeReadCutsTemp( p, CutSetNum ); 00815 Cut_NodeWriteCutsTemp( p, CutSetNum, NULL ); 00816 } 00817 else 00818 { 00819 pList = Cut_NodeReadCutsNew( p, Node ); 00820 Cut_NodeWriteCutsNew( p, Node, NULL ); 00821 } 00822 if ( pList == NULL ) 00823 continue; 00824 00825 // process the cuts 00826 if ( fFirst ) 00827 { 00828 // remember the starting point 00829 pListStart = pList->pNext; 00830 pList->pNext = NULL; 00831 // save or recycle the elementary cut 00832 if ( i == 0 ) 00833 Cut_ListAdd( pSuper, pList ); 00834 else 00835 Cut_CutRecycle( p, pList ); 00836 } 00837 else 00838 pListStart = pList; 00839 00840 // save all the cuts that are smaller than the limit 00841 Cut_ListForEachCutSafe( pListStart, pCut, pCut2 ) 00842 { 00843 if ( pCut->nLeaves == (unsigned)Limit ) 00844 { 00845 Vec_PtrPush( p->vTemp, pCut ); 00846 break; 00847 } 00848 // check containment 00849 // if ( p->pParams->fFilter && Cut_CutFilterOne( p, pSuper, pCut ) ) 00850 // continue; 00851 if ( p->pParams->fFilter ) 00852 { 00853 if ( Cut_CutFilterOne(p, pSuper, pCut) ) 00854 continue; 00855 if ( p->pParams->fSeq ) 00856 { 00857 if ( p->pCompareOld && Cut_CutFilterOld(p, p->pCompareOld, pCut) ) 00858 continue; 00859 if ( p->pCompareNew && Cut_CutFilterOld(p, p->pCompareNew, pCut) ) 00860 continue; 00861 } 00862 } 00863 00864 // set the complemented bit by comparing the first cut with the current cut 00865 pCut->fCompl = pTop->fSimul ^ pCut->fSimul; 00866 pListStart = pCut->pNext; 00867 pCut->pNext = NULL; 00868 // add to the list 00869 Cut_ListAdd( pSuper, pCut ); 00870 if ( ++p->nNodeCuts == p->pParams->nKeepMax ) 00871 { 00872 // recycle the rest of the cuts of this node 00873 Cut_ListForEachCutSafe( pListStart, pCut, pCut2 ) 00874 Cut_CutRecycle( p, pCut ); 00875 // recycle all cuts of other nodes 00876 Vec_IntForEachEntryStart( vNodes, Node, k, i+1 ) 00877 Cut_NodeFreeCuts( p, Node ); 00878 // recycle the saved cuts of other nodes 00879 Vec_PtrForEachEntry( p->vTemp, pList, k ) 00880 Cut_ListForEachCutSafe( pList, pCut, pCut2 ) 00881 Cut_CutRecycle( p, pCut ); 00882 goto finish; 00883 } 00884 } 00885 } 00886 // collect larger cuts next 00887 Vec_PtrForEachEntry( p->vTemp, pList, i ) 00888 { 00889 Cut_ListForEachCutSafe( pList, pCut, pCut2 ) 00890 { 00891 // check containment 00892 // if ( p->pParams->fFilter && Cut_CutFilterOne( p, pSuper, pCut ) ) 00893 // continue; 00894 if ( p->pParams->fFilter ) 00895 { 00896 if ( Cut_CutFilterOne(p, pSuper, pCut) ) 00897 continue; 00898 if ( p->pParams->fSeq ) 00899 { 00900 if ( p->pCompareOld && Cut_CutFilterOld(p, p->pCompareOld, pCut) ) 00901 continue; 00902 if ( p->pCompareNew && Cut_CutFilterOld(p, p->pCompareNew, pCut) ) 00903 continue; 00904 } 00905 } 00906 00907 // set the complemented bit 00908 pCut->fCompl = pTop->fSimul ^ pCut->fSimul; 00909 pListStart = pCut->pNext; 00910 pCut->pNext = NULL; 00911 // add to the list 00912 Cut_ListAdd( pSuper, pCut ); 00913 if ( ++p->nNodeCuts == p->pParams->nKeepMax ) 00914 { 00915 // recycle the rest of the cuts 00916 Cut_ListForEachCutSafe( pListStart, pCut, pCut2 ) 00917 Cut_CutRecycle( p, pCut ); 00918 // recycle the saved cuts of other nodes 00919 Vec_PtrForEachEntryStart( p->vTemp, pList, k, i+1 ) 00920 Cut_ListForEachCutSafe( pList, pCut, pCut2 ) 00921 Cut_CutRecycle( p, pCut ); 00922 goto finish; 00923 } 00924 } 00925 } 00926 finish : 00927 // set the cuts at the node 00928 pList = Cut_ListFinish( pSuper ); 00929 00930 // set the lists at the node 00931 // assert( Cut_NodeReadCutsNew(p, Root) == NULL ); 00932 // Cut_NodeWriteCutsNew( p, Root, pList ); 00933 if ( CutSetNum >= 0 ) 00934 { 00935 assert( Cut_NodeReadCutsTemp(p, CutSetNum) == NULL ); 00936 Cut_NodeWriteCutsTemp( p, CutSetNum, pList ); 00937 } 00938 else 00939 { 00940 assert( Cut_NodeReadCutsNew(p, Root) == NULL ); 00941 Cut_NodeWriteCutsNew( p, Root, pList ); 00942 } 00943 00944 p->timeUnion += clock() - clk; 00945 // filter the cuts 00946 //clk = clock(); 00947 // if ( p->pParams->fFilter ) 00948 // Cut_CutFilter( p, pList ); 00949 //p->timeFilter += clock() - clk; 00950 // if ( fFirst ) 00951 // p->nNodes -= vNodes->nSize - 1; 00952 return pList; 00953 }
Function*************************************************************
Synopsis [Returns the pointer to the linked list of cuts.]
Description []
SideEffects []
SeeAlso []
Definition at line 94 of file cutApi.c.
00095 { 00096 Vec_PtrWriteEntry( p->vCutsNew, Node, pList ); 00097 }
Function*************************************************************
Synopsis [Returns the pointer to the linked list of cuts.]
Description []
SideEffects []
SeeAlso []
Definition at line 110 of file cutApi.c.
00111 { 00112 Vec_PtrWriteEntry( p->vCutsOld, Node, pList ); 00113 }
Function*************************************************************
Synopsis [Returns the pointer to the linked list of cuts.]
Description []
SideEffects []
SeeAlso []
Definition at line 126 of file cutApi.c.
00127 { 00128 Vec_PtrWriteEntry( p->vCutsTemp, Node, pList ); 00129 }
Cut_Cut_t* Cut_OracleComputeCuts | ( | Cut_Oracle_t * | p, | |
int | Node, | |||
int | Node0, | |||
int | Node1, | |||
int | fCompl0, | |||
int | fCompl1 | |||
) |
Function*************************************************************
Synopsis [Reconstruct the cuts of the node.]
Description []
SideEffects []
SeeAlso []
Definition at line 326 of file cutOracle.c.
00327 { 00328 Cut_Cut_t * pList = NULL, ** ppTail = &pList; 00329 Cut_Cut_t * pCut, * pCut0, * pCut1, * pList0, * pList1; 00330 int iCutStart, nCuts, i, Entry; 00331 int clk = clock(); 00332 00333 // get the cuts of the children 00334 pList0 = Vec_PtrEntry( p->vCutsNew, Node0 ); 00335 pList1 = Vec_PtrEntry( p->vCutsNew, Node1 ); 00336 assert( pList0 && pList1 ); 00337 00338 // get the complemented attribute of the cut 00339 p->fSimul = (fCompl0 ^ pList0->fSimul) & (fCompl1 ^ pList1->fSimul); 00340 00341 // collect the cuts 00342 Vec_PtrClear( p->vCuts0 ); 00343 Cut_ListForEachCut( pList0, pCut ) 00344 Vec_PtrPush( p->vCuts0, pCut ); 00345 Vec_PtrClear( p->vCuts1 ); 00346 Cut_ListForEachCut( pList1, pCut ) 00347 Vec_PtrPush( p->vCuts1, pCut ); 00348 00349 // get the first and last cuts of this node 00350 nCuts = Vec_IntEntry(p->vNodeCuts, Node); 00351 iCutStart = Vec_IntEntry(p->vNodeStarts, Node); 00352 00353 // create trivial cut 00354 assert( Vec_IntEntry(p->vCutPairs, iCutStart) == 0 ); 00355 pCut = Cut_CutTriv( p, Node ); 00356 *ppTail = pCut; 00357 ppTail = &pCut->pNext; 00358 // create other cuts 00359 for ( i = 1; i < nCuts; i++ ) 00360 { 00361 Entry = Vec_IntEntry( p->vCutPairs, iCutStart + i ); 00362 pCut0 = Vec_PtrEntry( p->vCuts0, Entry & 0xFFFF ); 00363 pCut1 = Vec_PtrEntry( p->vCuts1, Entry >> 16 ); 00364 pCut = Cut_CutMerge( p, pCut0, pCut1 ); 00365 *ppTail = pCut; 00366 ppTail = &pCut->pNext; 00367 // compute the truth table 00368 if ( p->pParams->fTruth ) 00369 Cut_TruthComputeOld( pCut, pCut0, pCut1, fCompl0, fCompl1 ); 00370 } 00371 *ppTail = NULL; 00372 00373 // write the new cut 00374 assert( Vec_PtrEntry( p->vCutsNew, Node ) == NULL ); 00375 Vec_PtrWriteEntry( p->vCutsNew, Node, pList ); 00376 p->timeTotal += clock() - clk; 00377 return pList; 00378 }
void Cut_OracleNodeSetTriv | ( | Cut_Oracle_t * | p, | |
int | Node | |||
) |
Function*************************************************************
Synopsis [Sets the trivial cut for the node.]
Description []
SideEffects []
SeeAlso []
Definition at line 198 of file cutOracle.c.
00199 { 00200 assert( Vec_PtrEntry( p->vCutsNew, Node ) == NULL ); 00201 Vec_PtrWriteEntry( p->vCutsNew, Node, Cut_CutTriv(p, Node) ); 00202 }
int Cut_OracleReadDrop | ( | Cut_Oracle_t * | p | ) |
Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
Definition at line 182 of file cutOracle.c.
void Cut_OracleSetFanoutCounts | ( | Cut_Oracle_t * | p, | |
Vec_Int_t * | vFanCounts | |||
) |
Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
Definition at line 166 of file cutOracle.c.
00167 { 00168 p->vFanCounts = vFanCounts; 00169 }
Cut_Oracle_t* Cut_OracleStart | ( | Cut_Man_t * | pMan | ) |
FUNCTION DEFINITIONS ///Function*************************************************************
Synopsis [Starts the cut oracle.]
Description []
SideEffects []
SeeAlso []
Definition at line 70 of file cutOracle.c.
00071 { 00072 Cut_Oracle_t * p; 00073 int clk = clock(); 00074 00075 assert( pMan->pParams->nVarsMax >= 3 && pMan->pParams->nVarsMax <= CUT_SIZE_MAX ); 00076 assert( pMan->pParams->fRecord ); 00077 00078 p = ALLOC( Cut_Oracle_t, 1 ); 00079 memset( p, 0, sizeof(Cut_Oracle_t) ); 00080 00081 // set and correct parameters 00082 p->pParams = pMan->pParams; 00083 00084 // transfer the recording info 00085 p->vNodeCuts = pMan->vNodeCuts; pMan->vNodeCuts = NULL; 00086 p->vNodeStarts = pMan->vNodeStarts; pMan->vNodeStarts = NULL; 00087 p->vCutPairs = pMan->vCutPairs; pMan->vCutPairs = NULL; 00088 00089 // prepare storage for cuts 00090 p->vCutsNew = Vec_PtrAlloc( p->pParams->nIdsMax ); 00091 Vec_PtrFill( p->vCutsNew, p->pParams->nIdsMax, NULL ); 00092 p->vCuts0 = Vec_PtrAlloc( 100 ); 00093 p->vCuts1 = Vec_PtrAlloc( 100 ); 00094 00095 // entry size 00096 p->EntrySize = sizeof(Cut_Cut_t) + p->pParams->nVarsMax * sizeof(int); 00097 if ( p->pParams->fTruth ) 00098 { 00099 if ( p->pParams->nVarsMax > 8 ) 00100 { 00101 p->pParams->fTruth = 0; 00102 printf( "Skipping computation of truth table for more than 8 inputs.\n" ); 00103 } 00104 else 00105 { 00106 p->nTruthWords = Cut_TruthWords( p->pParams->nVarsMax ); 00107 p->EntrySize += p->nTruthWords * sizeof(unsigned); 00108 } 00109 } 00110 // memory for cuts 00111 p->pMmCuts = Extra_MmFixedStart( p->EntrySize ); 00112 return p; 00113 }
void Cut_OracleStop | ( | Cut_Oracle_t * | p | ) |
Function*************************************************************
Synopsis [Stop the cut oracle.]
Description []
SideEffects []
SeeAlso []
Definition at line 125 of file cutOracle.c.
00126 { 00127 Cut_Cut_t * pCut; 00128 int i; 00129 00130 // if ( p->pParams->fVerbose ) 00131 { 00132 printf( "Cut computation statistics with oracle:\n" ); 00133 printf( "Current cuts = %8d. (Trivial = %d.)\n", p->nCuts-p->nCutsTriv, p->nCutsTriv ); 00134 PRT( "Total time ", p->timeTotal ); 00135 } 00136 00137 Vec_PtrForEachEntry( p->vCutsNew, pCut, i ) 00138 if ( pCut != NULL ) 00139 { 00140 int k = 0; 00141 } 00142 if ( p->vCuts0 ) Vec_PtrFree( p->vCuts0 ); 00143 if ( p->vCuts1 ) Vec_PtrFree( p->vCuts1 ); 00144 if ( p->vCutsNew ) Vec_PtrFree( p->vCutsNew ); 00145 if ( p->vFanCounts ) Vec_IntFree( p->vFanCounts ); 00146 00147 if ( p->vNodeCuts ) Vec_IntFree( p->vNodeCuts ); 00148 if ( p->vNodeStarts ) Vec_IntFree( p->vNodeStarts ); 00149 if ( p->vCutPairs ) Vec_IntFree( p->vCutPairs ); 00150 00151 Extra_MmFixedStop( p->pMmCuts ); 00152 free( p ); 00153 }
void Cut_OracleTryDroppingCuts | ( | Cut_Oracle_t * | p, | |
int | Node | |||
) |
Function*************************************************************
Synopsis [Consider dropping cuts if they are useless by now.]
Description []
SideEffects []
SeeAlso []
Definition at line 413 of file cutOracle.c.
00414 { 00415 int nFanouts; 00416 assert( p->vFanCounts ); 00417 nFanouts = Vec_IntEntry( p->vFanCounts, Node ); 00418 assert( nFanouts > 0 ); 00419 if ( --nFanouts == 0 ) 00420 Cut_OracleFreeCuts( p, Node ); 00421 Vec_IntWriteEntry( p->vFanCounts, Node, nFanouts ); 00422 }
void Cut_TruthNCanonicize | ( | Cut_Cut_t * | pCut | ) |
Function*************************************************************
Synopsis [Performs truth table computation.]
Description [This procedure cannot be used while recording oracle because it will overwrite Num0 and Num1.]
SideEffects []
SeeAlso []
Definition at line 81 of file cutTruth.c.
00082 { 00083 unsigned uTruth; 00084 unsigned * uCanon2; 00085 char * pPhases2; 00086 assert( pCut->nVarsMax < 6 ); 00087 00088 // get the direct truth table 00089 uTruth = *Cut_CutReadTruth(pCut); 00090 00091 // compute the direct truth table 00092 Extra_TruthCanonFastN( pCut->nVarsMax, pCut->nLeaves, &uTruth, &uCanon2, &pPhases2 ); 00093 // uCanon[0] = uCanon2[0]; 00094 // uCanon[1] = (p->nVarsMax == 6)? uCanon2[1] : uCanon2[0]; 00095 // uPhases[0] = pPhases2[0]; 00096 pCut->uCanon0 = uCanon2[0]; 00097 pCut->Num0 = pPhases2[0]; 00098 00099 // get the complemented truth table 00100 uTruth = ~*Cut_CutReadTruth(pCut); 00101 00102 // compute the direct truth table 00103 Extra_TruthCanonFastN( pCut->nVarsMax, pCut->nLeaves, &uTruth, &uCanon2, &pPhases2 ); 00104 // uCanon[0] = uCanon2[0]; 00105 // uCanon[1] = (p->nVarsMax == 6)? uCanon2[1] : uCanon2[0]; 00106 // uPhases[0] = pPhases2[0]; 00107 pCut->uCanon1 = uCanon2[0]; 00108 pCut->Num1 = pPhases2[0]; 00109 }