VIS
|
00001 00038 #include "ioInt.h" 00039 00040 static char rcsid[] UNUSED = "$Id: ioWriteBlif.c,v 1.14 2005/04/29 14:23:29 fabio Exp $"; 00041 00042 /*---------------------------------------------------------------------------*/ 00043 /* Constant declarations */ 00044 /*---------------------------------------------------------------------------*/ 00045 #define MAX_NUMBER_BDD_VARS 500 00046 00047 /*---------------------------------------------------------------------------*/ 00048 /* Macro declarations */ 00049 /*---------------------------------------------------------------------------*/ 00050 00051 00052 00055 /*---------------------------------------------------------------------------*/ 00056 /* Static function prototypes */ 00057 /*---------------------------------------------------------------------------*/ 00058 00059 static int _IoTableWriteBlif(Io_Encoding_Type_t encodingType, Hrc_Node_t *hnode, Tbl_Table_t *origBlifmvTable, st_table *blifInputsStTable, FILE *fp, FILE *encFp, int verbosity); 00060 static int _IoMakeInitialEncodings(IoBlifInfo_t *blifInfo, Hrc_Node_t *hnode); 00061 static void _IoDeterminizeEncodeOutputPart(IoBlifInfo_t *blifInfo, st_table *blifInputsStTable); 00062 static void _IoDeterminizeEncodeRows(IoBlifInfo_t *blifInfo, st_table *blifInputsStTable); 00063 static void _IoMakeDcTables(IoBlifInfo_t *blifInfo); 00064 static void _IoMakeBinTable(IoBlifInfo_t *blifInfo); 00065 static int _IoCheckHnodeTreeIsBooleanAndDeterministic(mdd_manager **mddMgr, Hrc_Node_t *hnode, st_table *modelTable, boolean *pSymVarsPresent, int verbosity); 00066 static int _IoCheckHnodeVarsAreBoolean(Hrc_Node_t *hnode, boolean *pSymVarsPresent); 00067 static int _IoCheckHnodeLatchResetIsConstant(Hrc_Node_t *hnode); 00068 static int _IoCheckHnodeTablesAreDeterministic(mdd_manager **mddMgr, Hrc_Node_t *hnode); 00069 static void _MddManagerResetIfNecessary(mdd_manager **mddMgr); 00070 static void _IoHnodeWriteBlifRecursively(Io_Encoding_Type_t encodingType, Hrc_Node_t *hnode, st_table *modelTable, FILE *fp, FILE *encFp, int verbosity); 00071 static int _IoHnodeWriteBlifRecursivelyStep(Io_Encoding_Type_t encodingType, Hrc_Node_t *hnode, FILE *fp, FILE *encFp, int verbosity); 00072 static int _IoCheckHnodeIsBooleanAndDeterministic(mdd_manager **mddMgr, Hrc_Node_t *hnode, boolean *pSymVarsPresent); 00073 static int _IoCheckPseudoinputIsPO(Tbl_Table_t *table); 00074 00078 /*---------------------------------------------------------------------------*/ 00079 /* Definition of exported functions */ 00080 /*---------------------------------------------------------------------------*/ 00081 00107 int 00108 Io_HnodeWriteBlifTotal( 00109 Io_Encoding_Type_t encodingType, 00110 Hrc_Node_t *hnode, 00111 FILE *fp, 00112 int verbosity) 00113 { 00114 st_table *modelTable; 00115 Hrc_Manager_t *manager; 00116 mdd_manager *mddMgr; 00117 FILE *encFp; 00118 boolean symVarsPresent; 00119 00120 manager = Hrc_NodeReadManager(hnode); 00121 modelTable = st_init_table(st_ptrcmp, st_ptrhash); 00122 mddMgr = mdd_init_empty(); 00123 bdd_dynamic_reordering(mddMgr, BDD_REORDER_SIFT, BDD_REORDER_VERBOSITY_DEFAULT); 00124 symVarsPresent = FALSE; 00125 00126 /* check that the node and all its children are boolean and deterministic. */ 00127 if(_IoCheckHnodeTreeIsBooleanAndDeterministic(&mddMgr, hnode, modelTable, &symVarsPresent, verbosity)){ 00128 mdd_quit(mddMgr); 00129 st_free_table(modelTable); 00130 return 1; 00131 } 00132 if(verbosity > 0){ 00133 fprintf(vis_stderr, "Done with hierarcy checks\n"); 00134 } 00135 00136 if(symVarsPresent == TRUE){ 00137 fprintf(vis_stderr, "Warning - some variables in the hierarchy are symbolic\n"); 00138 } 00139 00140 st_free_table(modelTable); 00141 modelTable = st_init_table(st_ptrcmp, st_ptrhash); 00142 encFp = Cmd_FileOpen("/dev/null", "w", NIL(char *), 1); 00143 00144 _IoHnodeWriteBlifRecursively(encodingType, hnode, modelTable, fp, encFp, verbosity); 00145 Hrc_ManagerSetCurrentNode(manager, hnode); 00146 00147 st_free_table(modelTable); 00148 mdd_quit(mddMgr); 00149 return 0; 00150 } 00151 00152 00184 int 00185 Io_HnodeWriteBlif( 00186 Io_Encoding_Type_t encodingType, 00187 Hrc_Node_t *hnode, 00188 FILE *fp, 00189 FILE *encFp, 00190 int verbosity, 00191 int combinationalOnly, 00192 int makeLatchIOsPOs) 00193 { 00194 Tbl_Table_t *table, *singleOutputTable; 00195 Tbl_Entry_t *entry; 00196 int i, j, k, numVal, numInputs, numOutputs; 00197 Var_Variable_t *var, *actualVar, *outputVar; 00198 char *name, *instanceName, *modelName, *newModelName; 00199 st_generator *gen; 00200 st_table *blifInputsStTable, *blifOutputsStTable, *printedMvsStTable; 00201 st_table *encOutputsStTable, *encInputsStTable; 00202 Hrc_Node_t *subcktHnode; 00203 Hrc_Model_t *model, *subcktModel; 00204 Hrc_Subckt_t *subckt; 00205 Hrc_Manager_t *manager; 00206 array_t *subcktActualInputVars, *subcktActualOutputVars; 00207 00208 00209 Hrc_NodeForEachNameTable(hnode, i, table){ 00210 if(_IoCheckPseudoinputIsPO(table)){ 00211 fprintf(stdout, "Hnode contains a pseudoinput which is also a primary output - quitting\n"); 00212 return 1; 00213 } 00214 for(j = 0; j < Tbl_TableReadNumOutputs(table); j++){ 00215 entry = Tbl_TableDefaultReadEntry(table, j); 00216 if(entry != NIL(Tbl_Entry_t)){ 00217 if(Tbl_EntryReadType(entry) == Tbl_EntryNormal_c){ 00218 if(Tbl_EntryReadNumValues(entry) > 1){ 00219 outputVar = Tbl_TableReadIndexVar(table, j, 1); 00220 (void)fprintf(stdout, "The table with %s as an output has non-singleton default values - quitting\n", Var_VariableReadName(outputVar)); 00221 return 1; 00222 } 00223 } 00224 else{ 00225 var = Tbl_EntryReadVar(table, entry); 00226 k = Tbl_TableReadVarIndex(table, var, 1); 00227 if(k<0){ 00228 outputVar = Tbl_TableReadIndexVar(table, j, 1); 00229 (void)fprintf(stdout, "Output %s has a default value that refers to an input variable - quitting\n", Var_VariableReadName(outputVar)); 00230 return 1; 00231 } 00232 } 00233 } 00234 } 00235 } 00236 00237 printedMvsStTable = st_init_table(strcmp, st_strhash); 00238 00239 if(!(combinationalOnly || makeLatchIOsPOs)){ 00240 fprintf(encFp,"# This encoding file and the blif file that was written out with it cannot\n"); 00241 fprintf(encFp,"# currently be read back into VIS. If you would like to read the blif and\n"); 00242 fprintf(encFp,"# encoding files back into VIS, then use the 'write_blif -l' or\n"); 00243 fprintf(encFp,"#'write_blif -c' options.\n"); 00244 } 00245 00246 /* .model */ 00247 modelName = Hrc_NodeReadModelName(hnode); 00248 manager = Hrc_NodeReadManager(hnode); 00249 model = Hrc_ManagerFindModelByName(manager, modelName); 00250 newModelName = ALLOC(char, strlen(modelName) + 256); 00251 i = 0; 00252 sprintf(newModelName, "%s[%d]", modelName, i); 00253 00254 while(Hrc_ManagerFindModelByName(manager, newModelName) != NIL(Hrc_Model_t)){ 00255 i++; 00256 sprintf(newModelName, "%s[%d]", modelName, i); 00257 } 00258 (void)fprintf(encFp,".model %s\n",newModelName); 00259 FREE(newModelName); 00260 /* .inputs line of enc file*/ 00261 if (Hrc_NodeReadNumFormalInputs(hnode) != 0){ 00262 (void)fprintf(encFp,".inputs "); 00263 Hrc_NodeForEachFormalInput(hnode,i,var){ 00264 (void)fprintf(encFp,"%s ",Var_VariableReadName(var)); 00265 } 00266 (void)fprintf(encFp,"\n"); 00267 } 00268 00269 /* .outputs line of enc file*/ 00270 if (Hrc_NodeReadNumFormalOutputs(hnode) != 0){ 00271 (void)fprintf(encFp,".outputs "); 00272 Hrc_NodeForEachFormalOutput(hnode,i,var){ 00273 (void)fprintf(encFp,"%s ",Var_VariableReadName(var)); 00274 } 00275 (void)fprintf(encFp,"\n"); 00276 } 00277 00278 /* .mv for primary inputs, printed to enc file*/ 00279 Hrc_NodeForEachFormalInput(hnode,i,var){ 00280 IoMvCheckPrint(encFp,var,printedMvsStTable); 00281 } 00282 /* .mv for primary outputs, printed to enc file*/ 00283 Hrc_NodeForEachFormalOutput(hnode,i,var){ 00284 IoMvCheckPrint(encFp,var,printedMvsStTable); 00285 } 00286 00287 /* .subckt stuff */ 00288 Hrc_ModelForEachSubckt(model,gen,instanceName,subckt){ 00289 subcktModel = Hrc_SubcktReadModel(subckt); 00290 subcktHnode = Hrc_ModelReadMasterNode(subcktModel); 00291 subcktActualInputVars = Hrc_SubcktReadActualInputVars(subckt); 00292 subcktActualOutputVars = Hrc_SubcktReadActualOutputVars(subckt); 00293 00294 /* .mv for subckt inputs */ 00295 for (i=0; i < array_n(subcktActualInputVars); i++){ 00296 var = array_fetch(Var_Variable_t *,subcktActualInputVars,i); 00297 IoMvCheckPrint(encFp,var,printedMvsStTable); 00298 } 00299 00300 /* .mv for subckt outputs */ 00301 for (i=0; i < array_n(subcktActualOutputVars); i++){ 00302 var = array_fetch(Var_Variable_t *,subcktActualOutputVars,i); 00303 IoMvCheckPrint(encFp,var,printedMvsStTable); 00304 } 00305 00306 /* .subckt declarations */ 00307 (void)fprintf(encFp,".subckt %s %s ", 00308 Hrc_ModelReadName(subcktModel), Hrc_SubcktReadInstanceName(subckt)); 00309 Hrc_NodeForEachFormalInput(subcktHnode,i,var){ 00310 actualVar = array_fetch(Var_Variable_t *,subcktActualInputVars,i); 00311 (void)fprintf(encFp,"%s = %s ",Var_VariableReadName(var),Var_VariableReadName(actualVar)); 00312 } 00313 Hrc_NodeForEachFormalOutput(subcktHnode,i,var){ 00314 actualVar = array_fetch(Var_Variable_t *,subcktActualOutputVars,i); 00315 (void)fprintf(encFp,"%s = %s ",Var_VariableReadName(var),Var_VariableReadName(actualVar)); 00316 } 00317 (void)fprintf(encFp,"\n"); 00318 } 00319 00320 encOutputsStTable = st_init_table(st_ptrcmp, st_ptrhash); 00321 encInputsStTable = st_init_table(st_ptrcmp, st_ptrhash); 00322 blifInputsStTable = st_init_table(strcmp, st_strhash); 00323 blifOutputsStTable = st_init_table(strcmp, st_strhash); 00324 00325 /* encoding tables to .enc file */ 00326 IoEncWriteMvToBinTables(hnode, encFp, encOutputsStTable, encInputsStTable, combinationalOnly); 00327 00328 /* decoding tables to .enc file */ 00329 IoEncWriteBinToMvTables(hnode, encFp, encOutputsStTable, encInputsStTable, combinationalOnly, makeLatchIOsPOs); 00330 00331 /* if write_blif called without -c or -l options, then print a warning saying 00332 that the files cant be read back into vis.. 00333 */ 00334 if(!(combinationalOnly || makeLatchIOsPOs)){ 00335 fprintf(fp,"# This blif file and the encoding file that was written out with it cannot\n"); 00336 fprintf(fp,"# currently be read back into VIS. If you would like to read the blif and\n"); 00337 fprintf(fp,"# encoding files back into VIS, then use the 'write_blif -l' or\n"); 00338 fprintf(fp,"#'write_blif -c' options.\n"); 00339 } 00340 00341 /* .inputs declarations for blif file */ 00342 fprintf(fp,".model %s\n",modelName ); 00343 numInputs = IoBlifWriteInputs(hnode, fp, blifInputsStTable, combinationalOnly, makeLatchIOsPOs); 00344 00345 /* .outputs declarations for blif file */ 00346 numOutputs = IoBlifWriteOutputs(hnode, fp, blifOutputsStTable, combinationalOnly, makeLatchIOsPOs); 00347 00348 if((numInputs == 0) && (numOutputs != 0)){ 00349 fprintf(vis_stderr, "Warning: Blif file has zero inputs\n"); 00350 } 00351 if((numOutputs == 0) && (numInputs != 0)){ 00352 fprintf(vis_stderr, "Warning: Blif file has zero outputs\n"); 00353 } 00354 if((numInputs == 0) && (numOutputs == 0)){ 00355 fprintf(vis_stderr, "Warning: Blif file has zero inputs and zero outputs\n"); 00356 } 00357 00358 /* .latch declarations for blif file */ 00359 IoWriteLatches(hnode, fp, encFp, printedMvsStTable, blifOutputsStTable, blifInputsStTable, encOutputsStTable, encInputsStTable, combinationalOnly, makeLatchIOsPOs, verbosity); 00360 Hrc_NodeForEachNameTable(hnode, i, table){ 00361 if((Tbl_TableReadNumInputs(table) == 0) && (Tbl_TableReadNumOutputs(table) > 1)){ 00362 (void)fprintf(stdout, "Warning: "); 00363 Tbl_TableForEachOutputVar(table, j, var){ 00364 (void)fprintf(stdout, "%s, ", Var_VariableReadName(var)); 00365 } 00366 (void)fprintf(stdout, "assumed to be pseudoinputs\n"); 00367 Tbl_TableForEachOutputVar(table, j, var){ 00368 singleOutputTable = Tbl_TableAlloc(); 00369 Tbl_TableAddColumn(singleOutputTable, var, 1); 00370 (void) Tbl_TableAddRow(singleOutputTable); 00371 entry = Tbl_EntryAlloc(Tbl_EntryNormal_c); 00372 numVal = Var_VariableReadNumValues(var); 00373 Tbl_EntrySetValue(entry, 0, numVal - 1); 00374 Tbl_TableSetEntry(singleOutputTable, entry, 0, 0, 1); 00375 _IoTableWriteBlif(encodingType, hnode, singleOutputTable, blifInputsStTable, fp, encFp, 00376 verbosity); 00377 Tbl_TableFree(singleOutputTable); 00378 } 00379 } 00380 else{ 00381 if(IoOutputExpansionRequired(table)){ 00382 if(verbosity > 0){ 00383 (void)fprintf(stdout, "Splitting into Single Output Table before Processing\n"); 00384 } 00385 for(j = 0; j < Tbl_TableReadNumOutputs(table); j++){ 00386 singleOutputTable = IoMakeSingleOutputTable(table, j); 00387 _IoTableWriteBlif(encodingType, hnode, singleOutputTable, blifInputsStTable, fp, encFp, 00388 verbosity); 00389 Tbl_TableFree(singleOutputTable); 00390 } 00391 } 00392 else{ 00393 if(!((Tbl_TableReadNumInputs(table) == 0) && (Tbl_TableReadNumOutputs(table) > 1))){ 00394 _IoTableWriteBlif(encodingType, hnode, table, blifInputsStTable, fp, encFp, 00395 verbosity); 00396 } 00397 } 00398 } 00399 } 00400 st_foreach_item_int(blifInputsStTable, gen, &name, &i){ 00401 FREE(name); 00402 } 00403 st_free_table(blifInputsStTable); 00404 st_foreach_item_int(blifOutputsStTable, gen, &name, &i){ 00405 FREE(name); 00406 } 00407 st_free_table(blifOutputsStTable); 00408 st_free_table(encInputsStTable); 00409 st_free_table(encOutputsStTable); 00410 st_foreach_item_int(printedMvsStTable, gen, &name, &i){ 00411 FREE(name); 00412 } 00413 st_free_table(printedMvsStTable); 00414 /* printing an empty .exdc network keeps sis from sweeping away the 00415 dummy buffers that latch outputs are made to drive as a result of the 00416 "write_blif -l" cmd. The dummy buffers were added because if they were 00417 not present, sis would introduce buffers whenever latch outputs drive POs 00418 directly (in the "xdc" command), ruining the name correspondence required 00419 for read_blif to work and reinstate mv latches. 00420 */ 00421 fprintf(fp,".exdc\n"); 00422 fprintf(fp,".end\n"); 00423 if(encFp != stdout){ 00424 (void) fclose(encFp); 00425 } 00426 return 0; 00427 } 00428 00429 00430 /*---------------------------------------------------------------------------*/ 00431 /* Definition of internal functions */ 00432 /*---------------------------------------------------------------------------*/ 00433 00434 00435 /*---------------------------------------------------------------------------*/ 00436 /* Definition of static functions */ 00437 /*---------------------------------------------------------------------------*/ 00438 00439 00453 static int 00454 _IoTableWriteBlif( 00455 Io_Encoding_Type_t encodingType, 00456 Hrc_Node_t *hnode, 00457 Tbl_Table_t *origBlifmvTable, 00458 st_table *blifInputsStTable, 00459 FILE *fp, 00460 FILE *encFp, 00461 int verbosity ) 00462 { 00463 IoBlifInfo_t *blifInfo; 00464 00465 blifInfo = ALLOC(IoBlifInfo_t, 1); 00466 if(verbosity > 1){ 00467 (void)fprintf(stdout, "Original Blifmv Table :\n"); 00468 Tbl_TableWriteBlifMvToFile(origBlifmvTable, 0, stdout); 00469 } 00470 IoInitBlifInfo(blifInfo, origBlifmvTable, fp, encFp, verbosity); 00471 if(encodingType == SIMPLE){ 00472 if(_IoMakeInitialEncodings(blifInfo, hnode)){ 00473 blifInfo->binTblArray = array_alloc(Tbl_Table_t *, 0); 00474 IoFreeBlifInfo(blifInfo); 00475 return 0; 00476 } 00477 _IoDeterminizeEncodeOutputPart(blifInfo, blifInputsStTable); 00478 _IoMakeBinTable(blifInfo); 00479 if(blifInfo->verbosity > 0){ 00480 (void)fprintf(stdout, "Done with Output Singletonization\n"); 00481 } 00482 if(blifInfo->verbosity > 1){ 00483 (void)fprintf(stdout, "Final Blifmv Table After Output Singletonization:\n"); 00484 Tbl_TableWriteBlifMvToFile(blifInfo->blifmvTable, 0, stdout); 00485 (void)fprintf(stdout, "Bin Table After Output Singletonization:\n"); 00486 Tbl_TableWriteBlifMvToFile(blifInfo->binTable, 0, stdout); 00487 } 00488 _IoDeterminizeEncodeRows(blifInfo, blifInputsStTable); 00489 if(blifInfo->verbosity > 0){ 00490 (void)fprintf(stdout, "Done with Row Intersection and Determinization\n"); 00491 } 00492 if(blifInfo->verbosity > 1){ 00493 (void)fprintf(stdout, "Final Bin Table After Determinization \n"); 00494 Tbl_TableWriteBlifMvToFile(blifInfo->binTable, 0, stdout); 00495 } 00496 _IoMakeDcTables(blifInfo); 00497 blifInfo->binTblArray = Tbl_TableSplit(blifInfo->binTable); 00498 IoWriteBinTablesToFile(blifInfo); 00499 IoFreeBlifInfo(blifInfo); 00500 return 0; 00501 } 00502 else{ 00503 (void)fprintf(vis_stderr, "This encoding strategy has not been implemented yet\n"); 00504 return 1; 00505 } 00506 } 00507 00508 00521 static int 00522 _IoMakeInitialEncodings( 00523 IoBlifInfo_t *blifInfo, 00524 Hrc_Node_t *hnode 00525 ) 00526 { 00527 Var_Variable_t *var, *origVar; 00528 int i, colnum, numRows, numValues, varRange, value, numEncBits; 00529 char *name, *varname, *dupName; 00530 Tbl_Entry_t *entry, *newEntry, *defEntry, *newDefEntry; 00531 lsGen gen; 00532 Tbl_Range_t *range; 00533 Tbl_Table_t *table, *origTable; 00534 00535 if(Tbl_TableReadNumInputs(blifInfo->blifmvTable) == 0){ 00536 value = -1; 00537 if(Tbl_TableReadNumRows(blifInfo->blifmvTable) != 0){ 00538 entry = Tbl_TableReadEntry(blifInfo->blifmvTable, 0, 0, 1); 00539 numValues = Tbl_EntryReadNumValues(entry); 00540 } 00541 else{ 00542 entry = Tbl_TableDefaultReadEntry(blifInfo->blifmvTable, 0); 00543 numValues = Tbl_EntryReadNumValues(entry); 00544 } 00545 origTable = Tbl_TableHardDup(blifInfo->blifmvTable); 00546 00547 if(Tbl_TableReadNumRows(blifInfo->blifmvTable) <= 1){ 00548 if(numValues == 1){ 00549 /* not a pseudoinput */ 00550 Tbl_EntryForEachValue(entry, value, gen, range); 00551 assert(value != -1); 00552 var = Tbl_TableReadIndexVar(blifInfo->blifmvTable, 0, 1); 00553 varRange = Var_VariableReadNumValues(var); 00554 numEncBits = IoNumEncBits(varRange); 00555 varname = Var_VariableReadName(var); 00556 for(i = numEncBits - 1; i >= 0; i--){ 00557 dupName = ALLOC(char, strlen(varname) + IoNumDigits(numEncBits) + 2); 00558 sprintf(dupName, "%s%d", varname, i); 00559 (void)fprintf(blifInfo->BlifFp, ".names %s\n", dupName); 00560 FREE(dupName); 00561 if(value > (int) pow((double) 2, (double) i)){ 00562 (void)fprintf(blifInfo->BlifFp, "1\n"); 00563 value -= (int) pow((double) 2, (double) i); 00564 } 00565 else{ 00566 (void)fprintf(blifInfo->BlifFp, "0\n"); 00567 } 00568 } 00569 Tbl_TableFree(origTable); 00570 return 1; 00571 } 00572 else{ 00573 /* is a pseudoinput! */ 00574 /* make it look like a table with many rows, and singleton output entries per row */ 00575 table = Tbl_TableAlloc(); 00576 00577 Tbl_TableForEachOutputVar(blifInfo->blifmvTable, i, var){ 00578 Tbl_TableAddColumn(table, var, 1); 00579 } 00580 Tbl_TableForEachDefaultEntry(blifInfo->blifmvTable, defEntry, i) { 00581 if (defEntry != NIL(Tbl_Entry_t)) { 00582 newDefEntry = Tbl_EntryDup(defEntry); 00583 } 00584 else { 00585 newDefEntry = NIL(Tbl_Entry_t); 00586 } 00587 (void) Tbl_TableDefaultSetEntry(table, newDefEntry, i); 00588 } 00589 Tbl_EntryForEachValue(entry, value, gen, range){ 00590 i = Tbl_TableAddRow(table); 00591 newEntry = Tbl_EntryAlloc(Tbl_EntryNormal_c); 00592 Tbl_EntrySetValue(newEntry, value, value); 00593 Tbl_TableSetEntry(table, newEntry, i, 0, 1); 00594 } 00595 Tbl_TableFree(blifInfo->blifmvTable); 00596 blifInfo->blifmvTable = table; 00597 } 00598 } 00599 /* it is a pseudoinput, and has been singletonized wrt outputs */ 00600 if(Tbl_TableReadNumRows(blifInfo->blifmvTable) > 1){ 00601 name = ALLOC(char, 256); 00602 i = 0; 00603 sprintf(name, "[%d]", i); 00604 while(!(Hrc_NodeFindVariableByName(hnode, name) == NULL)){ 00605 i++; 00606 sprintf(name, "[%d]", i); 00607 } 00608 00609 blifInfo->pseudoinputFlag = TRUE; 00610 var = Var_VariableAlloc(hnode, name); 00611 Tbl_TableAddColumn(blifInfo->blifmvTable, var, 0); 00612 (void)fprintf(blifInfo->BlifFp, ".inputs %s0\n", name); 00613 origVar = Tbl_TableReadIndexVar(origTable, 0, 1); 00614 IoMvPrint(blifInfo->EncFp, origVar); 00615 Tbl_TableWriteBlifMvToFile(origTable, 0, blifInfo->EncFp); 00616 Tbl_TableFree(origTable); 00617 numRows = Tbl_TableReadNumRows(blifInfo->blifmvTable); 00618 for(i = 0; i < numRows; i++){ 00619 if(i % 2 == 1){ 00620 entry = Tbl_EntryAlloc(Tbl_EntryNormal_c); 00621 Tbl_EntrySetValue(entry, 1, 1); 00622 Tbl_TableSetEntry(blifInfo->blifmvTable, entry, i, 0, 0); 00623 } 00624 else{ 00625 entry = Tbl_EntryAlloc(Tbl_EntryNormal_c); 00626 Tbl_EntrySetValue(entry, 0, 0); 00627 Tbl_TableSetEntry(blifInfo->blifmvTable, entry, i, 0, 0); 00628 } 00629 } 00630 FREE(name); 00631 } 00632 } 00633 00634 Tbl_TableForEachInputVar(blifInfo->blifmvTable, colnum, var){ 00635 IoEncodeVariable(blifInfo, var, colnum, 0); 00636 } 00637 00638 Tbl_TableForEachOutputVar(blifInfo->blifmvTable, colnum, var){ 00639 IoEncodeVariable(blifInfo, var, colnum, 1); 00640 } 00641 return 0; 00642 } 00643 00644 00659 static void 00660 _IoDeterminizeEncodeOutputPart( 00661 IoBlifInfo_t *blifInfo, 00662 st_table *blifInputsStTable 00663 ) 00664 { 00665 Tbl_Entry_t *entry; 00666 int numValues, i, j, numRows, numOutputs; 00667 IoVarEncEntry_t *varEnc; 00668 array_t *MvOutputArray; 00669 00670 numRows = Tbl_TableReadNumRows(blifInfo->blifmvTable); 00671 numOutputs = Tbl_TableReadNumOutputs(blifInfo->blifmvTable); 00672 for(i = 0; i < numRows; i++){ 00673 MvOutputArray = array_alloc(int, 0); 00674 numValues = 1; 00675 for(j = 0; j < numOutputs; j++){ 00676 entry = Tbl_TableReadEntry(blifInfo->blifmvTable, i, j, 1); 00677 numValues *= Tbl_EntryReadNumValues(entry); 00678 array_insert_last(int, MvOutputArray, Tbl_EntryReadNumValues(entry)); 00679 } 00680 if(numValues > 1){ 00681 varEnc = IoFindSmallestCode(blifInfo); 00682 if(blifInfo->verbosity > 2){ 00683 (void)fprintf(stdout, "Singletonizing Outputs in Row %d\n", i); 00684 (void)fprintf(stdout, "Best Variable is %s\n", Var_VariableReadName(varEnc->variable)); 00685 } 00686 IoIncreaseCodeSize(varEnc, numValues, blifInfo->verbosity); 00687 IoChangeBlifmvTableEntries(blifInfo, i, numValues, varEnc, MvOutputArray); 00688 IoChangeEncTableEntries(blifInfo, blifInputsStTable, varEnc, numValues); 00689 i = -1; 00690 array_free(MvOutputArray); 00691 00692 if(blifInfo->verbosity > 2){ 00693 (void)fprintf(stdout, "Blifmv Table After Output Singletonization\n"); 00694 Tbl_TableWriteBlifMvToFile(blifInfo->blifmvTable, 0, stdout); 00695 } 00696 } 00697 else{ 00698 array_free(MvOutputArray); 00699 } 00700 } 00701 } 00702 00703 00718 static void 00719 _IoDeterminizeEncodeRows( 00720 IoBlifInfo_t *blifInfo, 00721 st_table *blifInputsStTable 00722 ) 00723 { 00724 int i, j, k, numRows, numOutputs, numInputs, mvValue; 00725 boolean rowsIntersect; 00726 IoVarEncEntry_t *varEnc; 00727 char *pseudoInputName, *realPseudoInputName; 00728 Var_Variable_t *outvar, *var, *origVar; 00729 Tbl_Entry_t *entry; 00730 00731 00732 numRows = Tbl_TableReadNumRows(blifInfo->binTable); 00733 for(i = 0; i < numRows; i++){ 00734 for(j = i + 1; j < numRows; j++){ 00735 if(blifInfo->verbosity > 2){ 00736 (void)fprintf(stdout, "Intersecting Rows %d and %d \n", i, j); 00737 } 00738 rowsIntersect = Tbl_RowInputIntersect(blifInfo->binTable, i, j); 00739 if(rowsIntersect == 1){ 00740 if(blifInfo->verbosity > 2){ 00741 (void)fprintf(stdout, "Input Intersection non-null\n"); 00742 } 00743 if(!Tbl_RowOutputIntersect(blifInfo->binTable, i, j)){ 00744 varEnc = IoFindSmallestCode(blifInfo); 00745 if(blifInfo->verbosity > 2){ 00746 (void)fprintf(stdout, "Output Intersection null\n"); 00747 (void)fprintf(stdout, "Best Variable is %s\n", Var_VariableReadName(varEnc->variable)); 00748 00749 } 00750 IoIncreaseCodeSize(varEnc, 2, blifInfo->verbosity); 00751 IoChangeBlifmvTableRows(blifInfo, varEnc, i, j); 00752 IoChangeEncTableEntries(blifInfo, blifInputsStTable, varEnc, 2); 00753 00754 if(blifInfo->verbosity > 2){ 00755 (void)fprintf(stdout, "Bin Table After Row Overlap elimination \n"); 00756 Tbl_TableWriteBlifMvToFile(blifInfo->binTable, 0, stdout); 00757 } 00758 } 00759 } 00760 } 00761 } 00762 if(blifInfo->pseudoinputFlag == TRUE){ 00763 /* pseudoinput cant have .def construct */ 00764 outvar = Tbl_TableReadIndexVar(blifInfo->binTable, 0, 1); 00765 pseudoInputName = Var_VariableReadName(outvar); 00766 realPseudoInputName = ALLOC(char, strlen(pseudoInputName) + 2); 00767 sprintf(realPseudoInputName, "%s", pseudoInputName); 00768 realPseudoInputName[strlen(pseudoInputName) - 1] = '\0'; 00769 numOutputs = Tbl_TableReadNumOutputs(blifInfo->binTable); 00770 numInputs = Tbl_TableReadNumInputs(blifInfo->binTable); 00771 for(i = 0; i < numInputs; i++){ 00772 (void)fprintf(blifInfo->EncFp, ".table %s ->", realPseudoInputName); 00773 var = Tbl_TableReadIndexVar(blifInfo->binTable, i, 0); 00774 (void)fprintf(blifInfo->EncFp, "%s\n", Var_VariableReadName(var)); 00775 (void)fprintf(blifInfo->EncFp, ".default 0\n"); 00776 for(j = 0; j < numRows; j++){ 00777 mvValue = 0; 00778 for(k = 0; k < numOutputs; k++){ 00779 entry = Tbl_TableReadEntry(blifInfo->binTable, j, k, 1); 00780 if(Tbl_EntryCheckRange(entry, 1, 1)){ 00781 mvValue += (int) pow((double)2, (double) k); 00782 } 00783 } 00784 origVar = Tbl_TableReadIndexVar(blifInfo->blifmvTable, 0, 1); 00785 if(Var_VariableTestIsSymbolic(origVar)){ 00786 (void)fprintf(blifInfo->EncFp, "%s ", 00787 Var_VariableReadSymbolicValueFromIndex(origVar, mvValue)); 00788 } 00789 else{ 00790 (void)fprintf(blifInfo->EncFp, "%d ", mvValue); 00791 } 00792 00793 entry = Tbl_TableReadEntry(blifInfo->binTable, j, i, 0); 00794 if(Tbl_EntryCheckRange(entry, 1, 1)){ 00795 (void)fprintf(blifInfo->EncFp, "%d\n", 1); 00796 } 00797 else{ 00798 if(Tbl_EntryCheckRange(entry, 0, 0)){ 00799 (void)fprintf(blifInfo->EncFp, "%d\n", 0); 00800 } 00801 else{ 00802 (void)fprintf(blifInfo->EncFp, "-\n"); 00803 } 00804 } 00805 } 00806 } 00807 FREE(realPseudoInputName); 00808 } 00809 } 00810 00811 00824 static void 00825 _IoMakeDcTables( 00826 IoBlifInfo_t *blifInfo 00827 ) 00828 { 00829 } 00830 00831 00832 00844 static void 00845 _IoMakeBinTable( 00846 IoBlifInfo_t *blifInfo 00847 ) 00848 { 00849 int i, j, k, m, n, colnum, numRowsAfterExpansion, numEncBits; 00850 int rootCol, rootRow, entryRepetitionCount, numCycles, value, numBits, currRow; 00851 int numOutputs, numRows, numInputs, defValue, varRange; 00852 Tbl_Entry_t *entry, *workingEntry; 00853 array_t *binRangesArray, *mvEntryBinRanges; 00854 IoVarEncEntry_t *varEnc; 00855 char *varname, *dupName; 00856 Var_Variable_t *var; 00857 lsGen gen, gen2; 00858 Tbl_Range_t *range, *range2; 00859 IoBinRangeEntry_t *binRangeEntry; 00860 00861 00862 /* initialize the binTable, defining input vars etc */ 00863 00864 numRows = Tbl_TableReadNumRows(blifInfo->blifmvTable); 00865 numInputs = Tbl_TableReadNumInputs(blifInfo->blifmvTable); 00866 numOutputs = Tbl_TableReadNumOutputs(blifInfo->blifmvTable); 00867 for(j = 0; j < Tbl_TableReadNumInputs(blifInfo->blifmvTable); j++){ 00868 varEnc = array_fetch(IoVarEncEntry_t *, blifInfo->inputEncTblArray, j); 00869 numEncBits = varEnc->numEncBits; 00870 for(k = 0; k < numEncBits ; k++){ 00871 varname = Var_VariableReadName(varEnc->variable); 00872 dupName = ALLOC(char, strlen(varname) + IoNumDigits(numEncBits) + 2); 00873 sprintf(dupName, "%s%d", varname, k); 00874 var = Var_VariableAlloc(NIL(Hrc_Node_t), dupName); 00875 FREE(dupName); 00876 array_insert_last(Var_Variable_t *, blifInfo->varArray, var); 00877 colnum = Tbl_TableAddColumn(blifInfo->binTable, var, 0); 00878 } 00879 } 00880 00881 for(j = 0; j < Tbl_TableReadNumOutputs(blifInfo->blifmvTable); j++){ 00882 varEnc = array_fetch(IoVarEncEntry_t *, blifInfo->outputEncTblArray, j); 00883 numEncBits = varEnc->numEncBits; 00884 for(k = 0; k < numEncBits ; k++){ 00885 varname = Var_VariableReadName(varEnc->variable); 00886 dupName = ALLOC(char, strlen(varname) + IoNumDigits(numEncBits) + 2); 00887 sprintf(dupName, "%s%d", varname, k); 00888 var = Var_VariableAlloc(NIL(Hrc_Node_t), dupName); 00889 FREE(dupName); 00890 array_insert_last(Var_Variable_t *, blifInfo->varArray, var); 00891 colnum = Tbl_TableAddColumn(blifInfo->binTable, var, 1); 00892 } 00893 } 00894 00895 00896 /* 00897 fprintf(stdout, "\n"); 00898 */ 00899 for(i = 0; i < numRows; i++){ 00900 00901 /* make temp array of number of values for each input var */ 00902 numRowsAfterExpansion = 1; 00903 binRangesArray = array_alloc(array_t *, 0); 00904 00905 for(colnum = 0; colnum < numInputs; colnum++){ 00906 entry = Tbl_TableReadEntry(blifInfo->blifmvTable, i, colnum, 0); 00907 workingEntry = Tbl_EntryDup(entry); 00908 mvEntryBinRanges = IoMakeBinaryRangesArray(workingEntry, colnum, blifInfo); 00909 numRowsAfterExpansion *= array_n(mvEntryBinRanges); 00910 array_insert_last(array_t *, binRangesArray, mvEntryBinRanges); 00911 } 00912 00913 /* 00914 for(j = 0; j < array_n(binRangesArray); j++){ 00915 mvEntryBinRanges = array_fetch(array_t *, binRangesArray, j); 00916 for(k = 0; k < array_n(mvEntryBinRanges); k++){ 00917 binRangeEntry = array_fetch(IoBinRangeEntry_t *, mvEntryBinRanges, k); 00918 fprintf(stdout, "start %d\t runlen%d\t skip %d\n", binRangeEntry->startValue, binRangeEntry->runLength, binRangeEntry->skipLength); 00919 } 00920 (void)fprintf(stdout, "\n"); 00921 } 00922 fprintf(stdout, "numRowsAfterExpansion %d\n", numRowsAfterExpansion); 00923 00924 */ 00925 /* add numRowsAfterExpansion rows to binTable */ 00926 00927 rootCol = 0; 00928 rootRow = Tbl_TableReadNumRows(blifInfo->binTable); 00929 for(j = 0; j < numRowsAfterExpansion; j++){ 00930 Tbl_TableAddRow(blifInfo->binTable); 00931 } 00932 00933 /* write out binary encoded variable values for the determinized, encoded blifmvTable 00934 (input parts) */ 00935 00936 entryRepetitionCount = numRowsAfterExpansion; 00937 m = 0; 00938 numCycles = 1; 00939 00940 for(colnum = 0; colnum < numInputs; colnum++){ 00941 mvEntryBinRanges = array_fetch(array_t *, binRangesArray, colnum); 00942 currRow = rootRow; 00943 rootCol += IoNumBinVars(colnum, blifInfo->inputEncTblArray); 00944 entryRepetitionCount = entryRepetitionCount / array_n(array_fetch(array_t *, binRangesArray, m)); 00945 numCycles *= IoNumValuesFromBinRangesArray(colnum, binRangesArray); 00946 numBits = IoNumBinVars(colnum + 1, blifInfo->inputEncTblArray); 00947 for(k=0; k<numCycles; k++){ 00948 for(n = 0; n < array_n(mvEntryBinRanges); n++){ 00949 binRangeEntry = array_fetch(IoBinRangeEntry_t *, mvEntryBinRanges, n); 00950 IoWriteExpandedValueToBinTable(blifInfo->binTable, currRow, rootCol, binRangeEntry, entryRepetitionCount, numBits, 0); 00951 currRow = currRow + entryRepetitionCount; 00952 } 00953 } 00954 m++; 00955 } 00956 00957 /* write out binary encoded variable values for the determinized, encoded blifmvTable 00958 (output parts) */ 00959 00960 rootCol = 0; 00961 00962 for(colnum = 0; colnum < numOutputs; colnum++){ 00963 entry = Tbl_TableReadEntry(blifInfo->blifmvTable, i, colnum, 1); 00964 rootCol += IoNumBinVars(colnum, blifInfo->outputEncTblArray); 00965 numBits = IoNumBinVars(colnum + 1, blifInfo->outputEncTblArray); 00966 Tbl_EntryForEachValue(entry, value, gen, range){ 00967 binRangeEntry = ALLOC(IoBinRangeEntry_t, 1); 00968 binRangeEntry->startValue = value; 00969 binRangeEntry->runLength = 1; 00970 binRangeEntry->skipLength = 1; 00971 IoWriteExpandedValueToBinTable(blifInfo->binTable, rootRow, rootCol, binRangeEntry, numRowsAfterExpansion, numBits, 1); 00972 FREE(binRangeEntry); 00973 } 00974 } 00975 for(j = 0; j < array_n(binRangesArray); j++){ 00976 mvEntryBinRanges = array_fetch(array_t *, binRangesArray, j); 00977 for(n = 0; n < array_n(mvEntryBinRanges); n++){ 00978 binRangeEntry = array_fetch(IoBinRangeEntry_t *, mvEntryBinRanges, n); 00979 FREE(binRangeEntry); 00980 } 00981 array_free(mvEntryBinRanges); 00982 } 00983 array_free(binRangesArray); 00984 } 00985 00986 rootCol = 0; 00987 Tbl_TableForEachOutputVar(blifInfo->blifmvTable, colnum, var){ 00988 entry = Tbl_TableDefaultReadEntry(blifInfo->blifmvTable, colnum); 00989 if(entry != NIL(Tbl_Entry_t)){ 00990 varRange = Var_VariableReadNumValues(var); 00991 numEncBits = IoNumEncBits(varRange); 00992 defValue = -1; 00993 Tbl_EntryForEachValue(entry, value, gen2, range2){ 00994 defValue = value; 00995 assert(defValue != -1); 00996 } 00997 for(j = numEncBits - 1; j >= 0; j--){ 00998 if(((int)(defValue / pow((double) 2, (double) j))) == 1){ 00999 IoInvertBinTableOutput(blifInfo, rootCol + j); 01000 defValue = defValue - (int)pow((double)2,(double)j); 01001 } 01002 } 01003 rootCol += numEncBits; 01004 } 01005 } 01006 } 01007 01008 01021 static int 01022 _IoCheckHnodeTreeIsBooleanAndDeterministic( 01023 mdd_manager **mddMgr, 01024 Hrc_Node_t *hnode, 01025 st_table *modelTable, 01026 boolean *pSymVarsPresent, 01027 int verbosity 01028 ) 01029 { 01030 char *modelName, *childName; 01031 Hrc_Model_t *model; 01032 st_generator *stGen; 01033 Hrc_Manager_t *manager; 01034 Hrc_Node_t *childNode; 01035 01036 manager = Hrc_NodeReadManager(hnode); 01037 /* enter current model in modelTable */ 01038 modelName = Hrc_NodeReadModelName(hnode); 01039 model = Hrc_ManagerFindModelByName(manager, modelName); 01040 if(st_is_member(modelTable, (char *) model)){ 01041 return 0; 01042 } 01043 else{ 01044 st_insert(modelTable, (char *)model, (char *) (long) (-1)); 01045 } 01046 01047 if(_IoCheckHnodeIsBooleanAndDeterministic(mddMgr, hnode, pSymVarsPresent)){ 01048 if(verbosity > 1){ 01049 fprintf(vis_stderr, "Model %s is NOT boolean and deterministic\n", modelName); 01050 } 01051 return 1; 01052 } 01053 if(verbosity > 1){ 01054 fprintf(vis_stderr, "Model %s is boolean and deterministic\n", modelName); 01055 } 01056 Hrc_NodeForEachChild(hnode, stGen, childName, childNode){ 01057 if(_IoCheckHnodeTreeIsBooleanAndDeterministic(mddMgr, childNode, modelTable, pSymVarsPresent, verbosity)){ 01058 st_free_gen(stGen); 01059 return 1; 01060 } 01061 } 01062 return 0; 01063 } 01064 01065 01077 static int 01078 _IoCheckHnodeIsBooleanAndDeterministic( 01079 mdd_manager **mddMgr, 01080 Hrc_Node_t *hnode, 01081 boolean *pSymVarsPresent 01082 ) 01083 { 01084 01085 /* check that variables of all models are boolean */ 01086 if(_IoCheckHnodeVarsAreBoolean(hnode, pSymVarsPresent)){ 01087 return 1; 01088 } 01089 01090 /* check that latch resets of all models are either 0/1/2 */ 01091 if(_IoCheckHnodeLatchResetIsConstant(hnode)){ 01092 return 1; 01093 } 01094 01095 /* check that tables of all models are deterministic */ 01096 if(_IoCheckHnodeTablesAreDeterministic(mddMgr, hnode)){ 01097 return 1; 01098 } 01099 01100 return 0; 01101 } 01102 01114 static int 01115 _IoCheckHnodeVarsAreBoolean( 01116 Hrc_Node_t *hnode, 01117 boolean *pSymVarsPresent 01118 ) 01119 { 01120 st_generator *stGen; 01121 char *varName; 01122 Var_Variable_t *var; 01123 01124 Hrc_NodeForEachVariable(hnode, stGen, varName, var){ 01125 if(Var_VariableReadNumValues(var) > 2){ 01126 fprintf(vis_stderr, "Variable %s is not boolean - quitting.\n", varName); 01127 st_free_gen(stGen); 01128 return 1; 01129 } 01130 if(Var_VariableTestIsSymbolic(var)){ 01131 *pSymVarsPresent = TRUE; 01132 } 01133 } 01134 return 0; 01135 } 01136 01137 01149 static int 01150 _IoCheckHnodeLatchResetIsConstant( 01151 Hrc_Node_t *hnode 01152 ) 01153 { 01154 st_generator *stGen; 01155 char *latchName; 01156 Hrc_Latch_t *latch; 01157 boolean test; 01158 Tbl_Table_t *table, *resetTable; 01159 Tbl_Entry_t *entry; 01160 Var_Variable_t *var, *parentVar; 01161 int i, j; 01162 01163 Hrc_NodeForEachLatch(hnode, stGen, latchName, latch){ 01164 resetTable = Hrc_LatchReadResetTable(latch); 01165 test = Tbl_TableTestIsConstant(resetTable, 0); 01166 /* 01167 Tbl_TableTestIsConstant gives 0 result for reset tables of 01168 the type .reset a ->b; - =a; where a is a constant defined 01169 in another table. So check for this case as well. 01170 */ 01171 if(test == FALSE){ 01172 if(Tbl_TableReadNumRows(resetTable) == 1){ 01173 entry = Tbl_TableReadEntry(resetTable, 0, 0, 1); 01174 if(Tbl_EntryReadType(entry) == Tbl_EntryEqual_c){ 01175 parentVar = Tbl_EntryReadVar(resetTable, entry); 01176 Hrc_NodeForEachNameTable(hnode, i, table){ 01177 Tbl_TableForEachOutputVar(table, j, var){ 01178 if(var == parentVar){ 01179 test = Tbl_TableTestIsConstant(table, j); 01180 } 01181 } 01182 } 01183 } 01184 } 01185 } 01186 if (test == FALSE){ 01187 fprintf(vis_stderr, "Latch %s has a non-constant reset value - quitting.\n", latchName); 01188 st_free_gen(stGen); 01189 return 1; 01190 } 01191 } 01192 return 0; 01193 } 01194 01206 static int 01207 _IoCheckHnodeTablesAreDeterministic( 01208 mdd_manager **mddMgr, 01209 Hrc_Node_t *hnode 01210 ) 01211 { 01212 int i, j, k, index, colNum, offset, numInputs; 01213 Tbl_Table_t *table; 01214 Var_Variable_t *inputVar, *outputVar, *var; 01215 Mvf_Function_t *faninMvf, *outMvf; 01216 array_t *faninMvfArray; 01217 array_t *mvarValues; 01218 Tbl_Entry_t *entry; 01219 01220 01221 /* note that reset tables are not handled here */ 01222 Hrc_NodeForEachNameTable(hnode, i, table){ 01223 Tbl_TableForEachOutputVar(table, index, outputVar){ 01224 01225 faninMvfArray = array_alloc(Mvf_Function_t *, 0); 01226 mvarValues = array_alloc(int, 0); 01227 01228 /* Create MDD variables for the table inputs. */ 01229 Tbl_TableForEachInputVar(table, colNum, inputVar) { 01230 array_insert_last(int, mvarValues, Var_VariableReadNumValues(inputVar)); 01231 } 01232 offset = array_n(mdd_ret_mvar_list(*mddMgr)); /* number of existing mvars */ 01233 mdd_create_variables(*mddMgr, mvarValues, NIL(array_t), NIL(array_t)); 01234 array_free(mvarValues); 01235 01236 /* 01237 * Construct an MVF for each table input. The MVF for column j is the MVF 01238 * for MDD variable j. 01239 */ 01240 01241 numInputs = Tbl_TableReadNumInputs(table ); 01242 for (j = 0; j < numInputs; j++) { 01243 faninMvf = Mvf_FunctionCreateFromVariable(*mddMgr, (j + offset)); 01244 array_insert_last(Mvf_Function_t *, faninMvfArray, faninMvf); 01245 } 01246 01247 /* Compute the MVF of the output indexed by index. */ 01248 outMvf = Tbl_TableBuildMvfFromFanins(table, index, faninMvfArray, *mddMgr); 01249 Mvf_FunctionArrayFree(faninMvfArray); 01250 01251 /* 01252 * If the function is a non-deterministic constant, or it has some 01253 * inputs, and is non-deterministic, then fail 01254 */ 01255 if((numInputs > 0) && !Mvf_FunctionTestIsDeterministic(outMvf)){ 01256 (void) fprintf(vis_stderr, "Table %s is non-deterministic - quitting\n", Var_VariableReadName(outputVar)); 01257 Mvf_FunctionFree(outMvf); 01258 return 1; 01259 } 01260 if(Mvf_FunctionTestIsNonDeterministicConstant(outMvf)){ 01261 (void) fprintf(vis_stderr, "Table %s is a non-deterministic constant - quitting\n", Var_VariableReadName(outputVar)); 01262 Mvf_FunctionFree(outMvf); 01263 return 1; 01264 } 01265 if (!Mvf_FunctionTestIsCompletelySpecified(outMvf)) { 01266 (void) fprintf(vis_stderr, "Table %s is not completely specified - quitting\n", Var_VariableReadName(outputVar)); 01267 Mvf_FunctionFree(outMvf); 01268 return 1; 01269 } 01270 Mvf_FunctionFree(outMvf); 01271 _MddManagerResetIfNecessary(mddMgr); 01272 01273 } 01274 } 01275 01276 Hrc_NodeForEachNameTable(hnode, i, table){ 01277 for(j = 0; j < Tbl_TableReadNumOutputs(table); j++){ 01278 entry = Tbl_TableDefaultReadEntry(table, j); 01279 if(entry != NIL(Tbl_Entry_t)){ 01280 if(Tbl_EntryReadType(entry) == Tbl_EntryNormal_c){ 01281 if(Tbl_EntryReadNumValues(entry) > 1){ 01282 outputVar = Tbl_TableReadIndexVar(table, j, 1); 01283 (void)fprintf(stdout, "The table with %s as an output has non-singleton default values - quitting\n", Var_VariableReadName(outputVar)); 01284 return 1; 01285 } 01286 } 01287 else{ 01288 var = Tbl_EntryReadVar(table, entry); 01289 k = Tbl_TableReadVarIndex(table, var, 1); 01290 if(k<0){ 01291 outputVar = Tbl_TableReadIndexVar(table, j, 1); 01292 (void)fprintf(stdout, "Output %s has a default value that refers to an input variable - quitting\n", Var_VariableReadName(outputVar)); 01293 return 1; 01294 } 01295 } 01296 } 01297 } 01298 } 01299 return 0; 01300 } 01301 01302 01317 static void 01318 _MddManagerResetIfNecessary( 01319 mdd_manager **mddMgr) 01320 { 01321 if (bdd_num_vars(*mddMgr) > MAX_NUMBER_BDD_VARS) { 01322 mdd_quit(*mddMgr); 01323 *mddMgr = mdd_init_empty(); 01324 } 01325 } 01326 01327 01328 01339 static void 01340 _IoHnodeWriteBlifRecursively( 01341 Io_Encoding_Type_t encodingType, 01342 Hrc_Node_t *hnode, 01343 st_table *modelTable, 01344 FILE *fp, 01345 FILE *encFp, 01346 int verbosity 01347 ) 01348 { 01349 char *modelName, *childName; 01350 Hrc_Model_t *model; 01351 Hrc_Manager_t *manager; 01352 st_generator *stGen; 01353 Hrc_Node_t *childNode; 01354 01355 manager = Hrc_NodeReadManager(hnode); 01356 /* enter current model in modelTable */ 01357 modelName = Hrc_NodeReadModelName(hnode); 01358 model = Hrc_ManagerFindModelByName(manager, modelName); 01359 if(st_is_member(modelTable, (char *) model)){ 01360 return; 01361 } 01362 else{ 01363 st_insert(modelTable, (char *)model, (char *) (long) (-1)); 01364 } 01365 01366 _IoHnodeWriteBlifRecursivelyStep(encodingType, hnode, fp, encFp, verbosity); 01367 Hrc_NodeForEachChild(hnode, stGen, childName, childNode){ 01368 _IoHnodeWriteBlifRecursively(encodingType, childNode, modelTable, fp, encFp, verbosity); 01369 } 01370 return; 01371 } 01372 01373 01386 static int 01387 _IoHnodeWriteBlifRecursivelyStep( 01388 Io_Encoding_Type_t encodingType, 01389 Hrc_Node_t *hnode, 01390 FILE *fp, 01391 FILE *encFp, 01392 int verbosity) 01393 { 01394 Tbl_Table_t *table, *singleOutputTable; 01395 int i, j; 01396 Var_Variable_t *var, *actualVar; 01397 char *name, *instanceName, *modelName; 01398 st_generator *gen; 01399 st_table *blifInputsStTable, *blifOutputsStTable, *printedMvsStTable; 01400 st_table *encOutputsStTable, *encInputsStTable; 01401 Hrc_Node_t *subcktHnode; 01402 Hrc_Model_t *model, *subcktModel; 01403 Hrc_Subckt_t *subckt; 01404 Hrc_Manager_t *manager; 01405 array_t *subcktActualInputVars, *subcktActualOutputVars; 01406 01407 01408 printedMvsStTable = st_init_table(strcmp, st_strhash); 01409 01410 /* .model */ 01411 modelName = Hrc_NodeReadModelName(hnode); 01412 manager = Hrc_NodeReadManager(hnode); 01413 model = Hrc_ManagerFindModelByName(manager, modelName); 01414 (void)fprintf(fp,".model %s\n", modelName); 01415 01416 /* .inputs line of blif file*/ 01417 if (Hrc_NodeReadNumFormalInputs(hnode) != 0){ 01418 (void)fprintf(fp,".inputs "); 01419 Hrc_NodeForEachFormalInput(hnode,i,var){ 01420 (void)fprintf(fp,"%s0 ",Var_VariableReadName(var)); 01421 } 01422 (void)fprintf(fp,"\n"); 01423 } 01424 01425 /* .outputs line of blif file*/ 01426 if (Hrc_NodeReadNumFormalOutputs(hnode) != 0){ 01427 (void)fprintf(fp,".outputs "); 01428 Hrc_NodeForEachFormalOutput(hnode,i,var){ 01429 (void)fprintf(fp,"%s0 ",Var_VariableReadName(var)); 01430 } 01431 (void)fprintf(fp,"\n"); 01432 } 01433 01434 /* .subckt stuff */ 01435 Hrc_ModelForEachSubckt(model,gen,instanceName,subckt){ 01436 subcktModel = Hrc_SubcktReadModel(subckt); 01437 subcktHnode = Hrc_ModelReadMasterNode(subcktModel); 01438 subcktActualInputVars = Hrc_SubcktReadActualInputVars(subckt); 01439 subcktActualOutputVars = Hrc_SubcktReadActualOutputVars(subckt); 01440 01441 /* .subckt declarations */ 01442 (void)fprintf(fp,".subckt %s ", 01443 Hrc_ModelReadName(subcktModel)); 01444 Hrc_NodeForEachFormalInput(subcktHnode,i,var){ 01445 actualVar = array_fetch(Var_Variable_t *,subcktActualInputVars,i); 01446 (void)fprintf(fp,"%s0=%s0 ",Var_VariableReadName(var),Var_VariableReadName(actualVar)); 01447 } 01448 Hrc_NodeForEachFormalOutput(subcktHnode,i,var){ 01449 actualVar = array_fetch(Var_Variable_t *,subcktActualOutputVars,i); 01450 (void)fprintf(fp,"%s0=%s0 ",Var_VariableReadName(var),Var_VariableReadName(actualVar)); 01451 } 01452 (void)fprintf(fp,"\n"); 01453 } 01454 01455 encOutputsStTable = st_init_table(st_ptrcmp, st_ptrhash); 01456 encInputsStTable = st_init_table(st_ptrcmp, st_ptrhash); 01457 blifInputsStTable = st_init_table(strcmp, st_strhash); 01458 blifOutputsStTable = st_init_table(strcmp, st_strhash); 01459 01460 /* .latch declarations for blif file */ 01461 IoWriteLatches(hnode, fp, encFp, printedMvsStTable, blifOutputsStTable, blifInputsStTable, encOutputsStTable, encInputsStTable, 0, 0, verbosity); 01462 Hrc_NodeForEachNameTable(hnode, i, table){ 01463 if(IoOutputExpansionRequired(table)){ 01464 if(verbosity > 0){ 01465 (void)fprintf(stdout, "Splitting into Single Output Table before Processing\n"); 01466 } 01467 for(j = 0; j < Tbl_TableReadNumOutputs(table); j++){ 01468 singleOutputTable = IoMakeSingleOutputTable(table, j); 01469 _IoTableWriteBlif(encodingType, hnode, singleOutputTable, blifInputsStTable, fp, encFp, 01470 verbosity); 01471 Tbl_TableFree(singleOutputTable); 01472 } 01473 } 01474 else{ 01475 if(!((Tbl_TableReadNumInputs(table) == 0) && (Tbl_TableReadNumOutputs(table) > 1))){ 01476 _IoTableWriteBlif(encodingType, hnode, table, blifInputsStTable, fp, encFp, 01477 verbosity); 01478 } 01479 } 01480 } 01481 st_foreach_item_int(blifInputsStTable, gen, &name, &i){ 01482 FREE(name); 01483 } 01484 st_foreach_item_int(blifOutputsStTable, gen, &name, &i){ 01485 FREE(name); 01486 } 01487 st_free_table(blifInputsStTable); 01488 st_free_table(blifOutputsStTable); 01489 st_free_table(encInputsStTable); 01490 st_free_table(encOutputsStTable); 01491 st_foreach_item_int(printedMvsStTable, gen, &name, &i){ 01492 FREE(name); 01493 } 01494 st_free_table(printedMvsStTable); 01495 fprintf(fp,".end\n"); 01496 return 1; 01497 } 01498 01499 01500 01513 static int 01514 _IoCheckPseudoinputIsPO( 01515 Tbl_Table_t *table) 01516 { 01517 int j; 01518 Var_Variable_t *var = NIL(Var_Variable_t); /* to suppress warning */ 01519 Tbl_Entry_t *entry; 01520 int numValues; 01521 01522 if((Tbl_TableReadNumInputs(table) == 0) && (Tbl_TableReadNumOutputs(table) > 1)){ 01523 /* assume all are pseudoinputs */ 01524 Tbl_TableForEachOutputVar(table, j, var){ 01525 if(Var_VariableTestIsPO(var)){ 01526 return 1; 01527 } 01528 } 01529 } 01530 01531 if(Tbl_TableReadNumInputs(table) == 0){ 01532 if(Tbl_TableReadNumRows(table) != 0){ 01533 entry = Tbl_TableReadEntry(table, 0, 0, 1); 01534 numValues = Tbl_EntryReadNumValues(entry); 01535 } 01536 else{ 01537 entry = Tbl_TableDefaultReadEntry(table, 0); 01538 numValues = Tbl_EntryReadNumValues(entry); 01539 } 01540 01541 Tbl_TableForEachOutputVar(table, j, var); 01542 if(Tbl_TableReadNumRows(table) <= 1){ 01543 if(numValues > 1){ 01544 if(Var_VariableTestIsPO(var)){ 01545 return 1; 01546 } 01547 } 01548 } 01549 else{ 01550 if(Var_VariableTestIsPO(var)){ 01551 return 1; 01552 } 01553 } 01554 } 01555 01556 return 0; 01557 }