VIS
|
00001 00039 #include "ioInt.h" 00040 00041 static char rcsid[] UNUSED = "$Id: ioWriteBlifUtil.c,v 1.12 2005/05/14 02:15:22 fabio Exp $"; 00042 00043 /*---------------------------------------------------------------------------*/ 00044 /* Macro declarations */ 00045 /*---------------------------------------------------------------------------*/ 00046 00047 00050 /*---------------------------------------------------------------------------*/ 00051 /* Static function prototypes */ 00052 /*---------------------------------------------------------------------------*/ 00053 00054 static void _IoWriteEntryToTable(Tbl_Entry_t *entry, Tbl_Table_t *table, int row, int col, int output); 00055 static void _IoWriteValueToTable(int value, Tbl_Table_t *table, int row, int col, int output); 00056 static Tbl_Table_t *_IoTableRemoveEqualsContruct(Tbl_Table_t *origBlifmvTable, array_t *freeVarArray, int verbosity); 00057 static void _IoVarEncEntryFree(IoVarEncEntry_t *varEnc); 00058 static int _IoNumValues(int colnum, array_t *numValuesArray); 00059 static Tbl_Entry_t *_IoCreateBinRange(array_t *mvEntryBinRanges, Tbl_Entry_t *entry, int numBits, int runLength, int skipLength); 00060 static boolean _IoEntryCheckRange(Tbl_Entry_t *entry, int startValue, int runLength, int skipLength); 00061 static Tbl_Entry_t *_IoAddBinRange(array_t *mvEntryBinRanges, Tbl_Entry_t *entry, int startValue, int runLength, int skipLength); 00062 00066 /*---------------------------------------------------------------------------*/ 00067 /* Definition of exported functions */ 00068 /*---------------------------------------------------------------------------*/ 00069 00070 00071 /*---------------------------------------------------------------------------*/ 00072 /* Definition of internal functions */ 00073 /*---------------------------------------------------------------------------*/ 00074 00075 00087 Tbl_Table_t * 00088 IoMakeSingleOutputTable( 00089 Tbl_Table_t *table, 00090 int outputNum 00091 ) 00092 { 00093 Tbl_Table_t * tableDup; 00094 int i, j, numRows, numCols; 00095 Tbl_Entry_t *newEntry, *entry, *parentVarEntry; 00096 Var_Variable_t *var; 00097 00098 tableDup = Tbl_TableAlloc(); 00099 numRows = Tbl_TableReadNumRows(table); 00100 numCols = Tbl_TableReadNumInputs(table); 00101 00102 Tbl_TableForEachInputVar(table,i,var){ 00103 Tbl_TableAddColumn(tableDup,var,0); 00104 } 00105 00106 var = Tbl_TableReadIndexVar(table,outputNum,1); 00107 Tbl_TableAddColumn(tableDup,var,1); 00108 00109 entry = Tbl_TableDefaultReadEntry(table,outputNum); 00110 if (entry != NIL(Tbl_Entry_t)){ 00111 if(Tbl_EntryReadType(entry) != Tbl_EntryNormal_c){ 00112 var = Tbl_EntryReadVar(table, entry); 00113 j = Tbl_TableReadVarIndex(table, var, 1); 00114 parentVarEntry = Tbl_TableDefaultReadEntry(table, j); 00115 newEntry = Tbl_EntryDup(parentVarEntry); 00116 } 00117 else{ 00118 newEntry = Tbl_EntryDup(entry); 00119 } 00120 } 00121 else { 00122 newEntry = NIL(Tbl_Entry_t); 00123 } 00124 (void) Tbl_TableDefaultSetEntry(tableDup,newEntry,0); 00125 00126 for(i = 0; i < numRows; i++){ 00127 (void) Tbl_TableAddRow(tableDup); 00128 for(j = 0; j < numCols; j++){ 00129 entry = Tbl_TableReadEntry(table, i, j, 0); 00130 newEntry = Tbl_EntryDup(entry); 00131 Tbl_TableSetEntry(tableDup, newEntry, i, j, 0); 00132 } 00133 entry = Tbl_TableReadEntry(table, i, outputNum, 1); 00134 newEntry = Tbl_EntryDup(entry); 00135 Tbl_TableSetEntry(tableDup, newEntry, i, 0, 1); 00136 } 00137 return tableDup; 00138 } 00139 00140 00141 00155 boolean 00156 IoOutputExpansionRequired( 00157 Tbl_Table_t *table 00158 ) 00159 { 00160 int numRows, numOutputs, i, colnum, parentVarIndex; 00161 Tbl_Entry_t *entry; 00162 Var_Variable_t *parentVar; 00163 00164 /* previously used to find out the estimated size of the resulting binary 00165 table (in number of entries) and return TRUE if this number was greater 00166 than 250. Removed this check, and now return TRUE if the table is multi- 00167 output. This is at the cost of potentially increasing runtime. 00168 */ 00169 /* if any of the output entries has an =var where var is another output 00170 variable, then output splitting is not done */ 00171 00172 numRows = Tbl_TableReadNumRows(table); 00173 numOutputs = Tbl_TableReadNumOutputs(table); 00174 00175 for(i = 0; i < numRows; i++){ 00176 for(colnum = 0; colnum < numOutputs; colnum++){ 00177 entry = Tbl_TableReadEntry(table, i, colnum, 1); 00178 if(Tbl_EntryReadType(entry) == Tbl_EntryEqual_c){ 00179 parentVar = Tbl_EntryReadVar(table, entry); 00180 parentVarIndex = Tbl_TableReadVarIndex(table, parentVar, 0); 00181 if(parentVarIndex == -1){ 00182 fprintf(vis_stderr, "Output entry mimics another output with an '=' construct - error\n"); 00183 assert(parentVarIndex != -1); 00184 } 00185 } 00186 } 00187 } 00188 if(numOutputs > 1){ 00189 return TRUE; 00190 } 00191 return FALSE; 00192 } 00193 00205 void 00206 IoInitBlifInfo( 00207 IoBlifInfo_t *blifInfo, 00208 Tbl_Table_t *origBlifmvTable, 00209 FILE *fp, 00210 FILE *encFp, 00211 int verbosity 00212 ) 00213 { 00214 blifInfo->varArray = array_alloc(Var_Variable_t *, 0); 00215 blifInfo->blifmvTable = _IoTableRemoveEqualsContruct(origBlifmvTable, blifInfo->varArray, verbosity); 00216 blifInfo->binTable = Tbl_TableAlloc(); 00217 blifInfo->inputEncTblArray = array_alloc(IoVarEncEntry_t *, 0); 00218 blifInfo->outputEncTblArray = array_alloc(IoVarEncEntry_t *, 0); 00219 blifInfo->dcTblArray = array_alloc(Tbl_Table_t *, 0); 00220 blifInfo->verbosity = verbosity; 00221 blifInfo->pseudoinputFlag = FALSE; 00222 blifInfo->BlifFp = fp; 00223 blifInfo->EncFp = encFp; 00224 } 00225 00226 00238 void 00239 IoFreeBlifInfo( 00240 IoBlifInfo_t *blifInfo 00241 ) 00242 { 00243 int i; 00244 00245 Tbl_TableFree(blifInfo->blifmvTable); 00246 Tbl_TableFree(blifInfo->binTable); 00247 00248 for(i=0; i < array_n(blifInfo->inputEncTblArray); i++){ 00249 _IoVarEncEntryFree(array_fetch(IoVarEncEntry_t *, blifInfo->inputEncTblArray, i)); 00250 } 00251 array_free(blifInfo->inputEncTblArray); 00252 00253 for(i=0; i < array_n(blifInfo->outputEncTblArray); i++){ 00254 _IoVarEncEntryFree(array_fetch(IoVarEncEntry_t *, blifInfo->outputEncTblArray, i)); 00255 } 00256 array_free(blifInfo->outputEncTblArray); 00257 00258 for(i=0; i < array_n(blifInfo->varArray); i++){ 00259 Var_VariableFree(array_fetch(Var_Variable_t *, blifInfo->varArray, i)); 00260 } 00261 array_free(blifInfo->varArray); 00262 00263 for(i=0; i < array_n(blifInfo->binTblArray); i++){ 00264 Tbl_TableFree(array_fetch(Tbl_Table_t *, blifInfo->binTblArray, i)); 00265 } 00266 array_free(blifInfo->binTblArray); 00267 00268 for(i=0; i < array_n(blifInfo->dcTblArray); i++){ 00269 Tbl_TableFree(array_fetch(Tbl_Table_t *, blifInfo->dcTblArray, i)); 00270 } 00271 array_free(blifInfo->dcTblArray); 00272 FREE(blifInfo); 00273 00274 } 00275 00276 00288 boolean 00289 IoVarIsHnodePIO( 00290 Hrc_Node_t *hnode, 00291 Var_Variable_t *var 00292 ) 00293 { 00294 boolean test; 00295 00296 test = FALSE; 00297 if(Var_VariableTestIsPO(var) || Var_VariableTestIsPI(var) || Var_VariableTestIsSO(var) || Var_VariableTestIsSI(var)){ 00298 test = TRUE; 00299 } 00300 return test; 00301 } 00302 00303 00315 void 00316 IoEncodeVariable( 00317 IoBlifInfo_t *blifInfo, 00318 Var_Variable_t *var, 00319 int varNum, 00320 int output 00321 ) 00322 { 00323 int range, numEncBits; 00324 IoVarEncEntry_t *varEncEntry; 00325 00326 range = Var_VariableReadNumValues(var); 00327 numEncBits = IoNumEncBits(range); 00328 00329 varEncEntry = ALLOC(IoVarEncEntry_t, 1); 00330 varEncEntry->variable = Var_VariableDup(var, NIL(Hrc_Node_t)); 00331 varEncEntry->index = varNum; 00332 varEncEntry->numEncBits = numEncBits; 00333 if(output == 1){ 00334 array_insert_last(IoVarEncEntry_t *, blifInfo->outputEncTblArray, varEncEntry); 00335 } 00336 else{ 00337 array_insert_last(IoVarEncEntry_t *, blifInfo->inputEncTblArray, varEncEntry); 00338 } 00339 00340 } 00341 00342 00354 int 00355 IoNumEncBits( 00356 int n 00357 ) 00358 { 00359 int i=0; 00360 int j=1; 00361 00362 if (n<2){ 00363 return 1; 00364 } 00365 else{ 00366 while (j < n){ 00367 j = j * 2; 00368 i++; 00369 } 00370 } 00371 return i; 00372 00373 } 00374 00386 int 00387 IoNumDigits( 00388 int n 00389 ) 00390 { 00391 double j; 00392 00393 j = log10((double) n) + 1; 00394 return ((int) j); 00395 } 00396 00408 int 00409 IoLog( 00410 int n 00411 ) 00412 { 00413 int i=0; 00414 int j=1; 00415 00416 while (j < n){ 00417 j = j * 2; 00418 i++; 00419 } 00420 return i; 00421 } 00422 00423 00435 IoVarEncEntry_t * 00436 IoFindSmallestCode( 00437 IoBlifInfo_t *blifInfo 00438 ) 00439 { 00440 int i, smallestCode, index; 00441 IoVarEncEntry_t *varEnc; 00442 00443 index = -1; 00444 smallestCode = VIS_INFINITY; 00445 for(i = 0; i < array_n(blifInfo->inputEncTblArray); i++){ 00446 varEnc = array_fetch(IoVarEncEntry_t *, blifInfo->inputEncTblArray, i); 00447 if((Var_VariableReadNumValues(varEnc->variable)) < smallestCode){ 00448 smallestCode = Var_VariableReadNumValues(varEnc->variable); 00449 index = i; 00450 } 00451 } 00452 00453 assert(index != -1); 00454 varEnc = array_fetch(IoVarEncEntry_t *, blifInfo->inputEncTblArray, index); 00455 return varEnc; 00456 00457 } 00458 00473 void 00474 IoIncreaseCodeSize( 00475 IoVarEncEntry_t *varEnc, 00476 int numValues, 00477 int verbosity 00478 ) 00479 { 00480 int temp1, temp2, range, numAddedPseudovars, numExpand; 00481 00482 range = Var_VariableReadNumValues(varEnc->variable); 00483 numAddedPseudovars = IoNumEncBits(numValues); 00484 temp1 = ((int) pow((double) 2, (double)numAddedPseudovars)) - 1; 00485 temp2 = (int) pow((double) 2, (double)varEnc->numEncBits); 00486 numExpand = (temp1 * temp2) + range; 00487 if(verbosity > 2){ 00488 (void)fprintf(stdout, "New Number of Values for the variable = %d\n", numExpand); 00489 } 00490 Var_VariableExpandRange(varEnc->variable, numExpand); 00491 00492 00493 } 00494 00495 00507 void 00508 IoChangeBlifmvTableRows( 00509 IoBlifInfo_t *blifInfo, 00510 IoVarEncEntry_t *varEnc, 00511 int row1, 00512 int row2 00513 ) 00514 { 00515 int numCurrentBits, i, numRows, colnum, tempCol, reqdColnum; 00516 Tbl_Entry_t *entry; 00517 char *varname, *dupName; 00518 Var_Variable_t *newVar; 00519 IoVarEncEntry_t *tempVarEnc; 00520 00521 /* add a new column to bin table */ 00522 numCurrentBits = varEnc->numEncBits; 00523 varname = Var_VariableReadName(varEnc->variable); 00524 dupName = ALLOC(char, strlen(varname) + IoNumDigits(numCurrentBits) + 2); 00525 sprintf(dupName, "%s%d", varname, numCurrentBits); 00526 newVar = Var_VariableAlloc(NIL(Hrc_Node_t), dupName); 00527 FREE(dupName); 00528 array_insert_last(Var_Variable_t *, blifInfo->varArray, newVar); 00529 colnum = Tbl_TableAddColumn(blifInfo->binTable, newVar, 0); 00530 numRows = Tbl_TableReadNumRows(blifInfo->binTable); 00531 for(i = 0; i < numRows; i++){ 00532 entry = Tbl_EntryAlloc(Tbl_EntryNormal_c); 00533 if(i == row1){ 00534 Tbl_EntrySetValue(entry, 0, 0); 00535 } 00536 if(i == row2){ 00537 Tbl_EntrySetValue(entry, 1, 1); 00538 } 00539 if((i != row1) && (i != row2)){ 00540 Tbl_EntrySetValue(entry, 0, 1); 00541 } 00542 Tbl_TableSetEntry(blifInfo->binTable, entry, i, colnum - 1, 0); 00543 } 00544 tempCol = 0; 00545 reqdColnum = -1; 00546 for(i = 0; i < array_n(blifInfo->inputEncTblArray); i++){ 00547 tempVarEnc = array_fetch(IoVarEncEntry_t *, blifInfo->inputEncTblArray, i); 00548 if(tempVarEnc == varEnc){ 00549 reqdColnum = tempCol + varEnc->numEncBits; 00550 } 00551 tempCol += tempVarEnc->numEncBits; 00552 } 00553 colnum--; 00554 assert(reqdColnum != -1); 00555 while(reqdColnum < colnum){ 00556 Tbl_TableSwapColumns(blifInfo->binTable, colnum, colnum - 1, 0); 00557 colnum--; 00558 } 00559 } 00560 00561 00573 void 00574 IoChangeBlifmvTableEntries( 00575 IoBlifInfo_t *blifInfo, 00576 int rownum, 00577 int numValues, 00578 IoVarEncEntry_t *varEnc, 00579 array_t *MvOutputArray 00580 ) 00581 { 00582 int i, j, k, newrownum, colnum, inputColnumToChange, value, offset; 00583 int numInputs, numOutputs, entryRepetitionCount, numCycles, numNewBits, maxValue, numOldBits; 00584 Tbl_Entry_t *entry, *dupEntry; 00585 lsGen gen; 00586 Tbl_Range_t *range; 00587 00588 numInputs = Tbl_TableReadNumInputs(blifInfo->blifmvTable); 00589 numOutputs = Tbl_TableReadNumOutputs(blifInfo->blifmvTable); 00590 numNewBits = IoNumEncBits(numValues); 00591 numOldBits = varEnc->numEncBits; 00592 maxValue = (int) pow((double) 2, (double)(numNewBits + numOldBits)); 00593 00594 inputColnumToChange = varEnc->index; 00595 for(i = 0; i < Tbl_TableReadNumRows(blifInfo->blifmvTable); i++){ 00596 if (i != rownum){ 00597 entry = Tbl_TableReadEntry(blifInfo->blifmvTable, i, inputColnumToChange, 0); 00598 dupEntry = Tbl_EntryDup(entry); 00599 offset = (int) pow((double) 2, (double)varEnc->numEncBits); 00600 Tbl_EntryForEachValue(entry, value, gen, range){ 00601 for(j = value ; j < maxValue; j = j + offset){ 00602 Tbl_EntrySetValue(dupEntry, j, j); 00603 } 00604 } 00605 Tbl_TableSetEntry(blifInfo->blifmvTable, dupEntry, i, inputColnumToChange, 0); 00606 } 00607 } 00608 newrownum = -1; 00609 for(i = 0; i < numValues; i++){ 00610 00611 /* add a row, and duplicate all entries of the original row except for 00612 the one that needs a new entry (because of the new code). This entry 00613 gets code = oldCode + i * (2^numCurrentEncBits) */ 00614 00615 newrownum = Tbl_TableAddRow(blifInfo->blifmvTable); 00616 assert(newrownum != -1); 00617 for(colnum = 0; colnum < numInputs; colnum++){ 00618 entry = Tbl_TableReadEntry(blifInfo->blifmvTable, rownum, colnum, 0); 00619 if(colnum != inputColnumToChange){ 00620 dupEntry = Tbl_EntryDup(entry); 00621 Tbl_TableSetEntry(blifInfo->blifmvTable, dupEntry, newrownum, colnum, 0); 00622 } 00623 else{ 00624 dupEntry = Tbl_EntryAlloc(Tbl_EntryNormal_c); 00625 offset = i * ((int) pow((double) 2, (double) varEnc->numEncBits)); 00626 Tbl_EntryForEachValue(entry, value, gen, range){ 00627 Tbl_EntrySetValue(dupEntry, value + offset, value + offset); 00628 } 00629 Tbl_TableSetEntry(blifInfo->blifmvTable, dupEntry, newrownum, colnum, 0); 00630 } 00631 } 00632 } 00633 00634 /* This section singleton-izes the output entries of the new row. 00635 Multiple outputs are accounted for. If more than one output has 00636 non-singleton entries, they are all singleton-ized. Finally, 00637 the original row is deleted... */ 00638 00639 entryRepetitionCount = numValues; 00640 numCycles = 1; 00641 newrownum++; 00642 00643 for(colnum = 0; colnum < numOutputs; colnum++){ 00644 newrownum = newrownum - numValues; 00645 numCycles *= _IoNumValues(colnum, MvOutputArray); 00646 entryRepetitionCount /= array_fetch(int, MvOutputArray, colnum); 00647 entry = Tbl_TableReadEntry(blifInfo->blifmvTable, rownum, colnum, 1); 00648 for(j = 0; j < numCycles; j++){ 00649 Tbl_EntryForEachValue(entry, value, gen, range){ 00650 for(k = 0; k < entryRepetitionCount; k++){ 00651 dupEntry = Tbl_EntryAlloc(Tbl_EntryNormal_c); 00652 Tbl_EntrySetValue(dupEntry, value, value); 00653 Tbl_TableSetEntry(blifInfo->blifmvTable, dupEntry, newrownum++, colnum, 1); 00654 } 00655 } 00656 } 00657 } 00658 blifInfo->blifmvTable = Tbl_TableRowDelete(blifInfo->blifmvTable, rownum, blifInfo->varArray); 00659 } 00660 00661 00673 void 00674 IoChangeEncTableEntries( 00675 IoBlifInfo_t *blifInfo, 00676 st_table *blifInputsStTable, 00677 IoVarEncEntry_t *varEnc, 00678 int numValues 00679 ) 00680 { 00681 int numOrigBits, numAddedBits, i; 00682 char *varname, *dupName; 00683 00684 numAddedBits = IoNumEncBits(numValues); 00685 numOrigBits = varEnc->numEncBits; 00686 00687 varname = Var_VariableReadName(varEnc->variable); 00688 for(i=0; i<numAddedBits; i++){ 00689 dupName = ALLOC(char, strlen(varname) + IoNumDigits(numAddedBits + numOrigBits)+ 2); 00690 sprintf(dupName, "%s%d", varname, i + numOrigBits); 00691 if(!st_is_member(blifInputsStTable, (char *)dupName)){ 00692 (void)fprintf(blifInfo->BlifFp, ".inputs %s\n", dupName); 00693 if(blifInfo->pseudoinputFlag == FALSE){ 00694 (void)fprintf(blifInfo->EncFp, ".table %s\n", dupName); 00695 (void)fprintf(blifInfo->EncFp, "-\n"); 00696 } 00697 st_insert(blifInputsStTable, (char *)dupName, (char *)1); 00698 } 00699 else{ 00700 FREE(dupName); 00701 } 00702 } 00703 varEnc->numEncBits += numAddedBits; 00704 00705 } 00706 00707 00708 00709 00721 void 00722 IoInvertBinTableOutput( 00723 IoBlifInfo_t * blifInfo, 00724 int colnumToInvert 00725 ) 00726 { 00727 int i; 00728 char *name, *newname; 00729 Var_Variable_t *var; 00730 00731 var = Tbl_TableReadIndexVar(blifInfo->binTable, colnumToInvert, 1); 00732 name = Var_VariableReadName(var); 00733 newname = ALLOC(char, strlen(name) + 4); 00734 sprintf(newname, "%s_b", name); 00735 (void)fprintf(blifInfo->BlifFp, ".names %s %s\n", newname, name); 00736 (void)fprintf(blifInfo->BlifFp, "0 1\n"); 00737 Var_VariableChangeName(var, newname); 00738 FREE(newname); 00739 for(i = 0; i < Tbl_TableReadNumRows(blifInfo->binTable); i++){ 00740 Tbl_TableComplementEntry(blifInfo->binTable, i, colnumToInvert, 1); 00741 } 00742 } 00743 00744 00759 array_t * 00760 IoMakeBinaryRangesArray( 00761 Tbl_Entry_t *entry, 00762 int colnum, 00763 IoBlifInfo_t *blifInfo 00764 ) 00765 { 00766 array_t *mvEntryBinRanges; 00767 int i, j, numBits, runLength, skipLength; 00768 00769 mvEntryBinRanges = array_alloc(IoBinRangeEntry_t *, 0); 00770 numBits = IoNumBinVars(colnum + 1, blifInfo->inputEncTblArray); 00771 for(i = numBits; i > 0; i--){ 00772 for(j = 0; j < numBits; j++){ 00773 runLength = (int) pow((double) 2, (double) i); 00774 skipLength = (int) pow((double) 2, (double) j); 00775 if((runLength * skipLength) <= (int) pow((double) 2, (double) numBits)){ 00776 /* fprintf(stdout, "run %d, skip %d\n", runLength, skipLength); */ 00777 entry = _IoCreateBinRange(mvEntryBinRanges, entry, numBits, runLength, skipLength); 00778 } 00779 } 00780 } 00781 entry = _IoCreateBinRange(mvEntryBinRanges, entry, numBits, 1, 1); 00782 assert(Tbl_EntryReadNumValues(entry) == 0); 00783 Tbl_EntryFree(entry); 00784 return mvEntryBinRanges; 00785 } 00786 00787 00799 int 00800 IoNumValuesFromBinRangesArray( 00801 int colnum, 00802 array_t *binRangesArray 00803 ) 00804 { 00805 array_t *mvEntryBinRanges; 00806 00807 if(colnum == 0){ 00808 return 1; 00809 } 00810 else{ 00811 mvEntryBinRanges = array_fetch(array_t *, binRangesArray, colnum - 1); 00812 return(array_n(mvEntryBinRanges)); 00813 } 00814 } 00815 00816 00828 int 00829 IoNumBinVars( 00830 int colnum, 00831 array_t *encTblArray 00832 ) 00833 { 00834 IoVarEncEntry_t *varEnc; 00835 00836 if(colnum == 0){ 00837 return 0; 00838 } 00839 else{ 00840 varEnc = array_fetch(IoVarEncEntry_t *, encTblArray, colnum-1); 00841 return(varEnc->numEncBits); 00842 } 00843 } 00844 00845 00846 /*---------------------------------------------------------------------------*/ 00847 /* Definition of static functions */ 00848 /*---------------------------------------------------------------------------*/ 00849 00850 00862 static void 00863 _IoWriteEntryToTable( 00864 Tbl_Entry_t *entry, 00865 Tbl_Table_t *table, 00866 int row, 00867 int col, 00868 int output 00869 ) 00870 { 00871 Tbl_Entry_t *dupEntry; 00872 00873 dupEntry = Tbl_EntryDup(entry); 00874 Tbl_TableSetEntry(table, dupEntry, row, col, output); 00875 } 00876 00877 00889 static void 00890 _IoWriteValueToTable( 00891 int value, 00892 Tbl_Table_t *table, 00893 int row, 00894 int col, 00895 int output 00896 ) 00897 { 00898 Tbl_Entry_t *entry; 00899 00900 entry = Tbl_EntryAlloc(Tbl_EntryNormal_c); 00901 Tbl_EntrySetValue(entry, value, value); 00902 Tbl_TableSetEntry(table, entry, row, col, output); 00903 } 00904 00916 static Tbl_Table_t * 00917 _IoTableRemoveEqualsContruct( 00918 Tbl_Table_t *origBlifmvTable, 00919 array_t *freeVarArray, 00920 int verbosity 00921 ) 00922 { 00923 Tbl_Table_t *resultTable; 00924 int numRows, numInputs, numOutputs, numRowsAfterExpansion, i, j, k, colnum, rownum, currRow, value; 00925 int parentVarnumValues, parentVarIndex, rootRow, entryRepetitionCount ; 00926 st_table *parentsStTable; 00927 Tbl_Entry_t *entry, *parentVarEntry, *dupEntry; 00928 Var_Variable_t *parentVar, *var; 00929 boolean parentVarIsOutput, rowContainsEqualEntries, insertedI; 00930 st_generator *gen; 00931 Tbl_Range_t *range; 00932 lsGen listgen; 00933 array_t *rowDeleteArray; 00934 char *dummy; 00935 00936 resultTable = Tbl_TableHardDup(origBlifmvTable); 00937 /* remove "="s in original defaults table*/ 00938 for(i = 0; i < Tbl_TableReadNumOutputs(resultTable); i++){ 00939 entry = Tbl_TableDefaultReadEntry(resultTable, i); 00940 if(entry != NIL(Tbl_Entry_t)){ 00941 if(Tbl_EntryReadType(entry) != Tbl_EntryNormal_c){ 00942 var = Tbl_EntryReadVar(resultTable, entry); 00943 j = Tbl_TableReadVarIndex(resultTable, var, 1); 00944 parentVarEntry = Tbl_TableDefaultReadEntry(resultTable, j); 00945 dupEntry = Tbl_EntryDup(parentVarEntry); 00946 Tbl_TableDefaultSetEntry(resultTable, dupEntry, i); 00947 Tbl_EntryFree(entry); 00948 } 00949 } 00950 } 00951 00952 /* first expand all rows with "=" constructs, in the same table */ 00953 numRows = Tbl_TableReadNumRows(resultTable); 00954 numInputs = Tbl_TableReadNumInputs(resultTable); 00955 numOutputs = Tbl_TableReadNumOutputs(resultTable); 00956 rootRow = numRows; 00957 00958 for(i = 0; i < numRows; i++){ 00959 numRowsAfterExpansion = 1; 00960 rowContainsEqualEntries = FALSE; 00961 parentsStTable = st_init_table(st_ptrcmp, st_ptrhash); 00962 00963 /* find variables that are parent variables, ie variables 'var' that 00964 have =var references in that row of the table */ 00965 for(colnum = 0; colnum < numInputs; colnum++){ 00966 entry = Tbl_TableReadEntry(resultTable, i, colnum, 0); 00967 if(Tbl_EntryReadType(entry) == Tbl_EntryEqual_c){ 00968 rowContainsEqualEntries = TRUE; 00969 parentVar = Tbl_EntryReadVar(resultTable, entry); 00970 st_insert(parentsStTable, (char *) parentVar, (char *) 1); 00971 } 00972 } 00973 for(colnum = 0; colnum < numOutputs; colnum++){ 00974 entry = Tbl_TableReadEntry(resultTable, i, colnum, 1); 00975 if(Tbl_EntryReadType(entry) == Tbl_EntryEqual_c){ 00976 rowContainsEqualEntries = TRUE; 00977 parentVar = Tbl_EntryReadVar(resultTable, entry); 00978 st_insert(parentsStTable, (char *) parentVar, (char *) 1); 00979 } 00980 } 00981 if(rowContainsEqualEntries == FALSE){ 00982 st_free_table(parentsStTable); 00983 continue; 00984 } 00985 00986 /* find the number of rows after expansion */ 00987 st_foreach_item(parentsStTable, gen, &parentVar, &dummy){ 00988 parentVarIndex = Tbl_TableReadVarIndex(resultTable, parentVar, 0); 00989 if(parentVarIndex != -1){ 00990 parentVarIsOutput = 0; 00991 } 00992 else{ 00993 parentVarIsOutput = 1; 00994 parentVarIndex = Tbl_TableReadVarIndex(resultTable, parentVar, 1); 00995 } 00996 parentVarEntry = Tbl_TableReadEntry(resultTable, i, parentVarIndex, parentVarIsOutput); 00997 numRowsAfterExpansion *= Tbl_EntryReadNumValues(parentVarEntry); 00998 } 00999 01000 /* write out expanded form of this row */ 01001 for(j = 0; j < numRowsAfterExpansion; j++){ 01002 Tbl_TableAddRow(resultTable); 01003 } 01004 /* expand parent variables first */ 01005 entryRepetitionCount = numRowsAfterExpansion; 01006 st_foreach_item(parentsStTable, gen, &parentVar, &dummy){ 01007 parentVarIndex = Tbl_TableReadVarIndex(resultTable, parentVar, 0); 01008 if(parentVarIndex != -1){ 01009 parentVarIsOutput = 0; 01010 } 01011 else{ 01012 parentVarIsOutput = 1; 01013 parentVarIndex = Tbl_TableReadVarIndex(resultTable, parentVar, 1); 01014 } 01015 parentVarEntry = Tbl_TableReadEntry(resultTable, i, parentVarIndex, 01016 parentVarIsOutput); 01017 parentVarnumValues = Tbl_EntryReadNumValues(parentVarEntry); 01018 currRow = rootRow; 01019 entryRepetitionCount = entryRepetitionCount / parentVarnumValues; 01020 while(currRow < rootRow + numRowsAfterExpansion){ 01021 Tbl_EntryForEachValue(parentVarEntry, value, listgen, range){ 01022 for(k = 0; k < entryRepetitionCount; k++){ 01023 _IoWriteValueToTable(value, resultTable, currRow, parentVarIndex, 01024 parentVarIsOutput); 01025 currRow++; 01026 } 01027 } 01028 } 01029 } 01030 01031 /* next expand variables that reference parent vars */ 01032 for(colnum = 0; colnum < numInputs; colnum++){ 01033 entry = Tbl_TableReadEntry(resultTable, i, colnum, 0); 01034 if(Tbl_EntryReadType(entry) == Tbl_EntryEqual_c){ 01035 parentVar = Tbl_EntryReadVar(resultTable, entry); 01036 parentVarIndex = Tbl_TableReadVarIndex(resultTable, parentVar, 0); 01037 if(parentVarIndex != -1){ 01038 parentVarIsOutput = 0; 01039 } 01040 else{ 01041 parentVarIsOutput = 1; 01042 parentVarIndex = Tbl_TableReadVarIndex(resultTable, parentVar, 1); 01043 } 01044 parentVarEntry = Tbl_TableReadEntry(resultTable, i, parentVarIndex, 01045 parentVarIsOutput); 01046 for(k = rootRow; k < rootRow + numRowsAfterExpansion; k++){ 01047 entry = Tbl_TableReadEntry(resultTable, k, parentVarIndex, 01048 parentVarIsOutput); 01049 _IoWriteEntryToTable(entry, resultTable, k, colnum, 0); 01050 } 01051 } 01052 else{ 01053 if(!st_is_member(parentsStTable, (char *) Tbl_TableReadIndexVar(resultTable, 01054 colnum, 0))){ 01055 for(k = rootRow; k < rootRow + numRowsAfterExpansion; k++){ 01056 _IoWriteEntryToTable(entry, resultTable, k, colnum, 0); 01057 } 01058 } 01059 } 01060 } 01061 for(colnum = 0; colnum < numOutputs; colnum++){ 01062 entry = Tbl_TableReadEntry(resultTable, i, colnum, 1); 01063 if(Tbl_EntryReadType(entry) == Tbl_EntryEqual_c){ 01064 parentVar = Tbl_EntryReadVar(resultTable, entry); 01065 parentVarIndex = Tbl_TableReadVarIndex(resultTable, parentVar, 0); 01066 if(parentVarIndex != -1){ 01067 parentVarIsOutput = 0; 01068 } 01069 else{ 01070 parentVarIsOutput = 1; 01071 parentVarIndex = Tbl_TableReadVarIndex(resultTable, parentVar, 1); 01072 } 01073 parentVarEntry = Tbl_TableReadEntry(resultTable, i, parentVarIndex, 01074 parentVarIsOutput); 01075 for(k = rootRow; k < rootRow + numRowsAfterExpansion; k++){ 01076 entry = Tbl_TableReadEntry(resultTable, k, parentVarIndex, 01077 parentVarIsOutput); 01078 _IoWriteEntryToTable(entry, resultTable, k, colnum, 1); 01079 } 01080 } 01081 else{ 01082 if(!st_is_member(parentsStTable, (char *) Tbl_TableReadIndexVar(resultTable, 01083 colnum, 1))){ 01084 for(k = rootRow; k < rootRow + numRowsAfterExpansion; k++){ 01085 _IoWriteEntryToTable(entry, resultTable, k, colnum, 1); 01086 } 01087 } 01088 } 01089 } 01090 rootRow += numRowsAfterExpansion; 01091 st_free_table(parentsStTable); 01092 } 01093 01094 01095 /* now delete rows with "=" constructs */ 01096 rowDeleteArray = array_alloc(int, 0); 01097 for(i = 0; i < numRows; i++){ 01098 insertedI = FALSE; 01099 for(colnum = 0; colnum < numInputs; colnum++){ 01100 entry = Tbl_TableReadEntry(resultTable, i, colnum, 0); 01101 if(Tbl_EntryReadType(entry) == Tbl_EntryEqual_c){ 01102 if(!insertedI){ 01103 array_insert_last(int, rowDeleteArray, i); 01104 insertedI = TRUE; 01105 } 01106 } 01107 } 01108 for(colnum = 0; colnum < numOutputs; colnum++){ 01109 entry = Tbl_TableReadEntry(resultTable, i, colnum, 1); 01110 if(Tbl_EntryReadType(entry) == Tbl_EntryEqual_c){ 01111 if(!insertedI){ 01112 array_insert_last(int, rowDeleteArray, i); 01113 insertedI = TRUE; 01114 } 01115 } 01116 } 01117 } 01118 /* array of vars that are to be freed. Since these are called with 01119 a NIL(Hrc_Node_t), they need to be freed separately, and kept track 01120 of 01121 */ 01122 for(i = 0; i < array_n(rowDeleteArray); i++){ 01123 rownum = array_fetch(int, rowDeleteArray, i) - i; 01124 resultTable = Tbl_TableRowDelete(resultTable, rownum, freeVarArray); 01125 } 01126 array_free(rowDeleteArray); 01127 01128 01129 if(verbosity > 1){ 01130 (void)fprintf(stdout, "Blifmv Table after = removal is\n"); 01131 Tbl_TableWriteBlifMvToFile(resultTable, 0, stdout); 01132 } 01133 return resultTable; 01134 01135 } 01136 01137 01149 static void 01150 _IoVarEncEntryFree( 01151 IoVarEncEntry_t *varEnc 01152 ) 01153 { 01154 Var_VariableFree(varEnc->variable); 01155 free(varEnc); 01156 } 01157 01158 01171 static boolean 01172 _IoEntryCheckRange( 01173 Tbl_Entry_t *entry, 01174 int startValue, 01175 int runLength, 01176 int skipLength 01177 ) 01178 { 01179 boolean startFound; 01180 int value, i; 01181 lsGen gen; 01182 Tbl_Range_t *range; 01183 01184 startFound = FALSE; 01185 i = 1; 01186 Tbl_EntryForEachValue(entry, value, gen, range){ 01187 if(value == startValue){ 01188 startFound = TRUE; 01189 } 01190 if((!startFound) && (value > startValue)){ 01191 lsFinish(gen); 01192 return FALSE; 01193 } 01194 if(value == startValue + (i * skipLength)){ 01195 i++; 01196 } 01197 if(value > startValue + (i * skipLength)){ 01198 lsFinish(gen); 01199 return FALSE; 01200 } 01201 if(i == runLength){ 01202 lsFinish(gen); 01203 return TRUE; 01204 } 01205 } 01206 return FALSE; 01207 } 01208 01209 01225 static Tbl_Entry_t * 01226 _IoCreateBinRange( 01227 array_t *mvEntryBinRanges, 01228 Tbl_Entry_t *entry, 01229 int numBits, 01230 int runLength, 01231 int skipLength 01232 ) 01233 { 01234 int i, j, bitPos, tempI, numDash, end, numStartValues, startValue; 01235 array_t *freeBitsArray; 01236 01237 numDash = IoLog(runLength); 01238 end = IoLog(skipLength); 01239 freeBitsArray = array_alloc(int, 0); 01240 for(i = 0; i < numBits; i++){ 01241 if(i < end){ 01242 array_insert_last(int, freeBitsArray, i); 01243 } 01244 if(i >= end + numDash){ 01245 array_insert_last(int, freeBitsArray, i); 01246 } 01247 } 01248 numStartValues = (int) pow((double) 2, (double) array_n(freeBitsArray)); 01249 for(i = 0; i < numStartValues; i++){ 01250 startValue = 0; 01251 tempI = i; 01252 for(j = array_n(freeBitsArray) - 1; j >= 0; j--){ 01253 if(tempI >= (int) pow((double) 2, (double) j)){ 01254 bitPos = array_fetch(int, freeBitsArray, j); 01255 startValue += (int) pow((double) 2, (double) bitPos); 01256 tempI -= (int) pow((double) 2, (double) j); 01257 } 01258 } 01259 /* fprintf(stdout, "trying start %d, run %d, skip %d\n", startValue, runLength, skipLength); */ 01260 if(_IoEntryCheckRange(entry, startValue, runLength, skipLength)){ 01261 entry = _IoAddBinRange(mvEntryBinRanges, entry, startValue, runLength, skipLength); 01262 } 01263 } 01264 array_free(freeBitsArray); 01265 return entry; 01266 } 01267 01279 static Tbl_Entry_t * 01280 _IoAddBinRange( 01281 array_t *mvEntryBinRanges, 01282 Tbl_Entry_t *entry, 01283 int startValue, 01284 int runLength, 01285 int skipLength 01286 ) 01287 { 01288 IoBinRangeEntry_t *binRangeEntry; 01289 int i, value; 01290 Tbl_Entry_t *newEntry; 01291 lsGen gen; 01292 Tbl_Range_t *range; 01293 01294 binRangeEntry = ALLOC(IoBinRangeEntry_t, 1); 01295 binRangeEntry->startValue = startValue; 01296 binRangeEntry->runLength = runLength; 01297 binRangeEntry->skipLength = skipLength; 01298 array_insert_last(IoBinRangeEntry_t *, mvEntryBinRanges, binRangeEntry); 01299 newEntry = Tbl_EntryAlloc(Tbl_EntryNormal_c); 01300 i = 0; 01301 Tbl_EntryForEachValue(entry, value, gen, range){ 01302 if((value == startValue + (i * skipLength)) && (i < runLength)){ 01303 i++; 01304 } 01305 else{ 01306 Tbl_EntrySetValue(newEntry, value, value); 01307 } 01308 } 01309 Tbl_EntryFree(entry); 01310 return newEntry; 01311 } 01312 01313 01325 static int 01326 _IoNumValues( 01327 int colnum, 01328 array_t *numValuesArray 01329 ) 01330 { 01331 if(colnum == 0){ 01332 return 1; 01333 } 01334 else{ 01335 return(array_fetch(int, numValuesArray, colnum - 1)); 01336 } 01337 } 01338 01339