00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <string.h>
00025 #include <stdio.h>
00026 #include <stdlib.h>
00027 #include <stdarg.h>
00028 #include "types.h"
00029 #include "globals.h"
00030 #include "errors.h"
00031 #include "netlist_utils.h"
00032 #include "odin_util.h"
00033 #include "outputs.h"
00034 #include "util.h"
00035 #include "multipliers.h"
00036 #include "hard_blocks.h"
00037
00038 void depth_first_traversal_to_output(short marker_value, FILE *fp, netlist_t *netlist);
00039 void depth_traverse_output_blif(nnode_t *node, int traverse_mark_number, FILE *fp);
00040 void output_node(nnode_t *node, short traverse_number, FILE *fp);
00041 void define_logical_function(nnode_t *node, short type, FILE *out);
00042 void define_set_input_logical_function(nnode_t *node, char *bit_output, FILE *out);
00043 void define_ff(nnode_t *node, FILE *out);
00044 void define_decoded_mux(nnode_t *node, FILE *out);
00045 void output_blif_pin_connect(nnode_t *node, FILE *out);
00046
00047
00048
00049
00050
00051 void output_blif(char *file_name, netlist_t *netlist)
00052 {
00053 int i;
00054 int count = 0;
00055 short first_time_inputs = FALSE;
00056 short first_time_outputs = FALSE;
00057 FILE *out;
00058 char *out_file;
00059
00060
00061 if (global_args.high_level_block != NULL)
00062 {
00063 out_file = (char*)malloc(sizeof(char)*(1+strlen(file_name)+strlen(global_args.high_level_block)+6));
00064 sprintf(out_file, "%s_%s.blif", file_name, global_args.high_level_block);
00065 out = fopen(out_file, "w");
00066 }
00067 else
00068 {
00069 out = fopen(file_name, "w");
00070 }
00071
00072 if (out == NULL)
00073 {
00074 error_message(NETLIST_ERROR, -1, -1, "Could not open output file %s\n", file_name);
00075 }
00076
00077 fprintf(out, ".model %s\n", top_module->children[0]->types.identifier);
00078
00079
00080 for (i = 0; i < netlist->num_top_input_nodes; i++)
00081 {
00082 if (first_time_inputs == FALSE)
00083 {
00084 count = fprintf(out, ".inputs");
00085 first_time_inputs = TRUE;
00086 }
00087
00088 if (global_args.high_level_block != NULL)
00089 {
00090 if (strlen(netlist->top_input_nodes[i]->name) + count < 79)
00091 count = count + fprintf(out, " %s^^%i-%i", netlist->top_input_nodes[i]->name, netlist->top_input_nodes[i]->related_ast_node->far_tag, netlist->top_input_nodes[i]->related_ast_node->high_number);
00092 else
00093 {
00094
00095 count = fprintf(out, " \\\n %s^^%i-%i", netlist->top_input_nodes[i]->name,netlist->top_input_nodes[i]->related_ast_node->far_tag, netlist->top_input_nodes[i]->related_ast_node->high_number);
00096 count = count - 3;
00097 }
00098 }
00099 else
00100 {
00101 if (strlen(netlist->top_input_nodes[i]->name) + count < 79)
00102 {
00103 count = count + fprintf(out, " %s", netlist->top_input_nodes[i]->name);
00104 }
00105 else
00106 {
00107
00108 count = fprintf(out, " \\\n %s", netlist->top_input_nodes[i]->name);
00109 count = count - 3;
00110 }
00111 }
00112 }
00113 fprintf(out, "\n");
00114
00115 count = 0;
00116 for (i = 0; i < netlist->num_top_output_nodes; i++)
00117 {
00118 if (netlist->top_output_nodes[i]->input_pins[0]->net->driver_pin == NULL)
00119 {
00120 warning_message(NETLIST_ERROR, netlist->top_output_nodes[i]->related_ast_node->line_number, netlist->top_output_nodes[i]->related_ast_node->file_number, "This output is undriven (%s) and will be removed\n", netlist->top_output_nodes[i]->name);
00121 }
00122 else
00123 {
00124 if (first_time_outputs == FALSE)
00125 {
00126 count = fprintf(out, ".outputs");
00127 first_time_outputs = TRUE;
00128 }
00129
00130 if (global_args.high_level_block != NULL)
00131 {
00132 if ((strlen(netlist->top_output_nodes[i]->name) + count) < 79)
00133 count = count + fprintf(out, " %s^^%i-%i", netlist->top_output_nodes[i]->name,netlist->top_output_nodes[i]->related_ast_node->far_tag, netlist->top_output_nodes[i]->related_ast_node->high_number);
00134 else
00135 {
00136
00137 count = fprintf(out, "\\\n %s^^%i-%i", netlist->top_output_nodes[i]->name,netlist->top_output_nodes[i]->related_ast_node->far_tag, netlist->top_output_nodes[i]->related_ast_node->high_number);
00138 count = count - 3;
00139 }
00140 }
00141 else
00142 {
00143 if ((strlen(netlist->top_output_nodes[i]->name) + count) < 79)
00144 count = count + fprintf(out, " %s", netlist->top_output_nodes[i]->name);
00145 else
00146 {
00147
00148 count = fprintf(out, "\\\n %s", netlist->top_output_nodes[i]->name);
00149 count = count - 3;
00150 }
00151 }
00152 }
00153 }
00154 fprintf(out, "\n");
00155
00156
00157 fprintf(out, "\n.names gnd\n.names unconn\n.names vcc\n1\n");
00158 fprintf(out, "\n");
00159
00160
00161 if (strcmp(configuration.output_type, "blif") == 0)
00162 {
00163 depth_first_traversal_to_output(OUTPUT_TRAVERSE_VALUE, out, netlist);
00164 }
00165 else
00166 oassert(FALSE);
00167
00168
00169 for (i = 0; i < netlist->num_top_output_nodes; i++)
00170 {
00171
00172 if (netlist->top_output_nodes[i]->input_pins[0]->net->driver_pin != NULL)
00173 {
00174 if (global_args.high_level_block != NULL)
00175 {
00176 fprintf(out, ".names %s^^%i-%i %s^^%i-%i\n1 1\n", netlist->top_output_nodes[i]->input_pins[0]->net->driver_pin->node->name,netlist->top_output_nodes[i]->input_pins[0]->net->driver_pin->node->related_ast_node->far_tag, netlist->top_output_nodes[i]->input_pins[0]->net->driver_pin->node->related_ast_node->high_number, netlist->top_output_nodes[i]->name, netlist->top_output_nodes[i]->related_ast_node->far_tag, netlist->top_output_nodes[i]->related_ast_node->high_number);
00177 }
00178 else
00179 {
00180 if (netlist->top_output_nodes[i]->input_pins[0]->net->driver_pin->mapping != NULL)
00181 fprintf(out, ".names %s %s\n1 1\n", netlist->top_output_nodes[i]->input_pins[0]->net->driver_pin->name, netlist->top_output_nodes[i]->name);
00182 else
00183 fprintf(out, ".names %s %s\n1 1\n", netlist->top_output_nodes[i]->input_pins[0]->net->driver_pin->node->name, netlist->top_output_nodes[i]->name);
00184 }
00185
00186 }
00187 }
00188
00189
00190 fprintf(out, ".end\n");
00191 fprintf(out, "\n");
00192
00193
00194 #ifdef VPR6
00195 add_the_blackbox_for_mults(out);
00196 output_hard_blocks(out);
00197 #endif
00198
00199 fclose(out);
00200 }
00201
00202
00203
00204
00205 void depth_first_traversal_to_output(short marker_value, FILE *fp, netlist_t *netlist)
00206 {
00207 int i;
00208
00209 netlist->gnd_node->name = "gnd";
00210 netlist->vcc_node->name = "vcc";
00211 netlist->pad_node->name = "unconn";
00212
00213 depth_traverse_output_blif(netlist->gnd_node, marker_value, fp);
00214 depth_traverse_output_blif(netlist->vcc_node, marker_value, fp);
00215 depth_traverse_output_blif(netlist->pad_node, marker_value, fp);
00216
00217
00218 for (i = 0; i < netlist->num_top_input_nodes; i++)
00219 {
00220 if (netlist->top_input_nodes[i] != NULL)
00221 {
00222 depth_traverse_output_blif(netlist->top_input_nodes[i], marker_value, fp);
00223 }
00224 }
00225 }
00226
00227
00228
00229
00230 void depth_traverse_output_blif(nnode_t *node, int traverse_mark_number, FILE *fp)
00231 {
00232 int i, j;
00233 nnode_t *next_node;
00234 nnet_t *next_net;
00235
00236 if (node->traverse_visited == traverse_mark_number)
00237 {
00238 return;
00239 }
00240 else
00241 {
00242
00243
00244
00245 output_node(node, traverse_mark_number, fp);
00246
00247
00248 node->traverse_visited = traverse_mark_number;
00249
00250 for (i = 0; i < node->num_output_pins; i++)
00251 {
00252 if (node->output_pins[i]->net == NULL)
00253 continue;
00254
00255 next_net = node->output_pins[i]->net;
00256 for (j = 0; j < next_net->num_fanout_pins; j++)
00257 {
00258 if (next_net->fanout_pins[j] == NULL)
00259 continue;
00260
00261 next_node = next_net->fanout_pins[j]->node;
00262 if (next_node == NULL)
00263 continue;
00264
00265
00266 depth_traverse_output_blif(next_node, traverse_mark_number, fp);
00267 }
00268 }
00269
00270 }
00271 }
00272
00273
00274
00275
00276 void output_node(nnode_t *node, short traverse_number, FILE *fp)
00277 {
00278 switch (node->type)
00279 {
00280 case GT:
00281 define_set_input_logical_function(node, "100 1\n", fp);
00282 oassert(node->num_input_pins == 3);
00283 oassert(node->input_pins[2] != NULL);
00284 break;
00285 case LT:
00286 define_set_input_logical_function(node, "010 1\n", fp);
00287 oassert(node->num_input_pins == 3);
00288 oassert(node->input_pins[2] != NULL);
00289 break;
00290 case ADDER_FUNC:
00291 define_set_input_logical_function(node, "001 1\n010 1\n100 1\n111 1\n", fp);
00292 break;
00293 case CARRY_FUNC:
00294 define_set_input_logical_function(node, "011 1\n100 1\n110 1\n111 1\n", fp);
00295 break;
00296 case BITWISE_NOT:
00297 define_set_input_logical_function(node, "0 1\n", fp);
00298 break;
00299
00300 case LOGICAL_AND:
00301 case LOGICAL_OR:
00302 case LOGICAL_XOR:
00303 case LOGICAL_XNOR:
00304 case LOGICAL_NAND:
00305 case LOGICAL_NOR:
00306 case LOGICAL_EQUAL:
00307 case NOT_EQUAL:
00308 case LOGICAL_NOT:
00309 define_logical_function(node, node->type, fp);
00310 break;
00311
00312 case MUX_2:
00313 define_decoded_mux(node, fp);
00314 break;
00315
00316 case FF_NODE:
00317 define_ff(node, fp);
00318 break;
00319
00320 case MULTIPLY:
00321 if (hard_multipliers == NULL)
00322 oassert(FALSE);
00323 #ifdef VPR6
00324 define_mult_function(node, node->type, fp);
00325 #endif
00326 break;
00327
00328 case MEMORY:
00329 case HARD_IP:
00330 #ifdef VPR6
00331 define_hard_block(node, node->type, fp);
00332 #endif
00333 break;
00334
00335 case INPUT_NODE:
00336 case OUTPUT_NODE:
00337 case PAD_NODE:
00338 case CLOCK_NODE:
00339 case GND_NODE:
00340 case VCC_NODE:
00341
00342 break;
00343
00344 case BITWISE_AND:
00345 case BITWISE_NAND:
00346 case BITWISE_NOR:
00347 case BITWISE_XNOR:
00348 case BITWISE_XOR:
00349 case BITWISE_OR:
00350 case BUF_NODE:
00351 case MULTI_PORT_MUX:
00352 case SL:
00353 case SR:
00354 case CASE_EQUAL:
00355 case CASE_NOT_EQUAL:
00356 case DIVIDE:
00357 case MODULO:
00358 case GTE:
00359 case LTE:
00360 case ADD:
00361 case MINUS:
00362 default:
00363
00364 oassert(FALSE);
00365 break;
00366 }
00367 }
00368
00369
00370
00371
00372 void define_logical_function(nnode_t *node, short type, FILE *out)
00373 {
00374 int i, j;
00375 char *temp_string;
00376 int flag = 0;
00377
00378 fprintf(out, ".names");
00379
00380
00381 if (global_args.high_level_block != NULL)
00382 {
00383
00384 for (i = 0; i < node->num_input_pins; i++)
00385 {
00386
00387 if (node->input_pins[i]->net->driver_pin->node->related_ast_node != NULL)
00388 fprintf(out, " %s^^%i-%i", node->input_pins[i]->net->driver_pin->node->name, node->input_pins[i]->net->driver_pin->node->related_ast_node->far_tag, node->input_pins[i]->net->driver_pin->node->related_ast_node->high_number);
00389 else
00390 fprintf(out, " %s", node->input_pins[i]->net->driver_pin->node->name);
00391 }
00392
00393 if (node->related_ast_node != NULL)
00394 fprintf(out, " %s^^%i-%i", node->name, node->related_ast_node->far_tag, node->related_ast_node->high_number);
00395 else
00396 fprintf(out, " %s", node->name);
00397 }
00398 else
00399 {
00400
00401 for (i = 0; i < node->num_input_pins; i++)
00402 {
00403
00404
00405 if ((node->input_pins[i]->net->driver_pin->node->type == MULTIPLY) ||
00406 (node->input_pins[i]->net->driver_pin->node->type == HARD_IP) ||
00407 (node->input_pins[i]->net->driver_pin->node->type == MEMORY))
00408 {
00409 fprintf(out, " %s", node->input_pins[i]->net->driver_pin->name);
00410 }
00411 else
00412 {
00413 fprintf(out, " %s", node->input_pins[i]->net->driver_pin->node->name);
00414 }
00415 }
00416
00417 fprintf(out, " %s", node->name);
00418 }
00419 fprintf(out, "\n");
00420
00421 oassert(node->num_output_pins == 1);
00422
00423
00424 switch (node->type)
00425 {
00426 case LOGICAL_AND:
00427 {
00428
00429 for (i = 0; i < node->num_input_pins; i++)
00430 {
00431 fprintf(out, "1");
00432 }
00433 fprintf(out, " 1\n");
00434 break;
00435 }
00436 case LOGICAL_OR:
00437 {
00438
00439 for (i = 0; i < node->num_input_pins; i++)
00440 {
00441 for (j = 0; j < node->num_input_pins; j++)
00442 {
00443 if (i == j)
00444 fprintf(out, "1");
00445 else
00446 fprintf(out, "-");
00447 }
00448 fprintf(out, " 1\n");
00449 }
00450 break;
00451 }
00452 case LOGICAL_NAND:
00453 {
00454
00455 for (i = 0; i < node->num_input_pins; i++)
00456 {
00457 for (j = 0; j < node->num_input_pins; j++)
00458 {
00459 if (i == j)
00460 fprintf(out, "0");
00461 else
00462 fprintf(out, "-");
00463 }
00464 fprintf(out, " 1\n");
00465 }
00466 break;
00467 }
00468 case LOGICAL_NOT:
00469 case LOGICAL_NOR:
00470 {
00471
00472 for (i = 0; i < node->num_input_pins; i++)
00473 {
00474 fprintf(out, "0");
00475 }
00476 fprintf(out, " 1\n");
00477 break;
00478 }
00479 case LOGICAL_EQUAL:
00480 case LOGICAL_XOR:
00481 {
00482 oassert(node->num_input_pins <= 3);
00483
00484 for (i = 0; i < my_power(2, node->num_input_pins); i++)
00485 {
00486 if ((i % 8 == 1) || (i % 8 == 2) || (i % 8 == 4) || (i % 8 == 7))
00487 {
00488 temp_string = convert_long_to_bit_string(i, node->num_input_pins);
00489 fprintf(out, "%s", temp_string);
00490 free(temp_string);
00491 fprintf(out, " 1\n");
00492 }
00493 }
00494 break;
00495 }
00496 case NOT_EQUAL:
00497 case LOGICAL_XNOR:
00498 {
00499 oassert(node->num_input_pins <= 3);
00500 for (i = 0; i < my_power(2, node->num_input_pins); i++)
00501 {
00502 if ((i % 8 == 0) || (i % 8 == 3) || (i % 8 == 5) || (i % 8 == 6))
00503 {
00504 temp_string = convert_long_to_bit_string(i, node->num_input_pins);
00505 fprintf(out, "%s", temp_string);
00506 free(temp_string);
00507 fprintf(out, " 1\n");
00508 }
00509 }
00510 break;
00511 }
00512 default:
00513 oassert(FALSE);
00514 break;
00515 }
00516
00517 fprintf(out, "\n");
00518 if (flag == 1)
00519 output_blif_pin_connect(node, out);
00520 }
00521
00522
00523
00524
00525 void define_set_input_logical_function(nnode_t *node, char *bit_output, FILE *out)
00526 {
00527 int i;
00528 int flag = 0;
00529
00530 fprintf(out, ".names");
00531
00532 oassert(node->num_output_pins == 1);
00533 oassert(node->num_input_pins >= 1);
00534
00535
00536 if (global_args.high_level_block != NULL)
00537 {
00538
00539 for (i = 0; i < node->num_input_pins; i++)
00540 {
00541
00542 if (node->input_pins[i]->net->driver_pin->node->related_ast_node != NULL)
00543 fprintf(out, " %s^^%i-%i", node->input_pins[i]->net->driver_pin->node->name, node->input_pins[i]->net->driver_pin->node->related_ast_node->far_tag, node->input_pins[i]->net->driver_pin->node->related_ast_node->high_number);
00544 else
00545 fprintf(out, " %s", node->input_pins[i]->net->driver_pin->node->name);
00546 }
00547
00548
00549 if (node->related_ast_node != NULL)
00550 fprintf(out, " %s^^%i-%i", node->name, node->related_ast_node->far_tag, node->related_ast_node->high_number);
00551 else
00552 fprintf(out, " %s", node->name);
00553 fprintf(out, "\n");
00554
00555
00556 if (bit_output != NULL)
00557 {
00558 fprintf(out, "%s", bit_output);
00559 }
00560 fprintf(out, "\n");
00561 }
00562 else
00563 {
00564
00565 for (i = 0; i < node->num_input_pins; i++)
00566 {
00567
00568
00569 if ((node->input_pins[i]->net->driver_pin->node->type == MULTIPLY) ||
00570 (node->input_pins[i]->net->driver_pin->node->type == HARD_IP) ||
00571 (node->input_pins[i]->net->driver_pin->node->type == MEMORY))
00572 {
00573 fprintf(out, " %s", node->input_pins[i]->net->driver_pin->name);
00574 }
00575 else
00576 {
00577 fprintf(out, " %s", node->input_pins[i]->net->driver_pin->node->name);
00578 }
00579 }
00580
00581
00582 fprintf(out, " %s", node->name);
00583 fprintf(out, "\n");
00584
00585
00586 if (bit_output != NULL)
00587 {
00588 fprintf(out, "%s", bit_output);
00589 }
00590 fprintf(out, "\n");
00591 }
00592
00593 if ((flag == 1) && (node->type == HARD_IP))
00594 output_blif_pin_connect(node, out);
00595 }
00596
00597
00598
00599
00600
00601 void define_ff(nnode_t *node, FILE *out)
00602 {
00603 oassert(node->num_output_pins == 1);
00604 oassert(node->num_input_pins == 2);
00605
00606
00607 if (global_args.high_level_block != NULL)
00608 fprintf(out, ".latch %s^^%i-%i %s^^%i-%i re %s^^%i-%i 0", node->input_pins[0]->net->driver_pin->node->name, node->input_pins[0]->net->driver_pin->node->related_ast_node->far_tag, node->input_pins[0]->net->driver_pin->node->related_ast_node->high_number, node->name, node->related_ast_node->far_tag, node->related_ast_node->high_number, node->input_pins[1]->net->driver_pin->node->name, node->input_pins[1]->net->driver_pin->node->related_ast_node->far_tag, node->input_pins[1]->net->driver_pin->node->related_ast_node->high_number);
00609 else
00610 {
00611 if (node->input_pins[1]->net->driver_pin != NULL)
00612 fprintf(out, ".latch %s %s re %s 0\n", node->input_pins[0]->net->driver_pin->name, node->name, node->input_pins[1]->net->driver_pin->node->name);
00613 else
00614 fprintf(out, ".latch %s %s re %s 0\n", node->input_pins[0]->net->driver_pin->node->name, node->name, node->input_pins[1]->net->driver_pin->node->name);
00615 }
00616
00617 fprintf(out, "\n");
00618 }
00619
00620
00621
00622
00623 void define_decoded_mux(nnode_t *node, FILE *out)
00624 {
00625 int i, j;
00626
00627 oassert(node->input_port_sizes[0] == node->input_port_sizes[1]);
00628
00629 fprintf(out, ".names");
00630
00631 if (global_args.high_level_block != NULL)
00632 {
00633
00634 for (i = 0; i < node->num_input_pins; i++)
00635 {
00636
00637 if (node->input_pins[i]->net->driver_pin->node->related_ast_node != NULL)
00638 {
00639 fprintf(out, " %s^^%i-%i", node->input_pins[i]->net->driver_pin->node->name, node->input_pins[i]->net->driver_pin->node->related_ast_node->far_tag, node->input_pins[i]->net->driver_pin->node->related_ast_node->high_number);
00640 }
00641 else
00642 {
00643 fprintf(out, " %s", node->input_pins[i]->net->driver_pin->node->name);
00644 }
00645 }
00646
00647 if (node->related_ast_node != NULL)
00648 fprintf(out, " %s^^%i-%i", node->name, node->related_ast_node->far_tag, node->related_ast_node->high_number);
00649 else
00650 fprintf(out, " %s", node->name);
00651 }
00652 else
00653 {
00654
00655 for (i = 0; i < node->num_input_pins; i++)
00656 {
00657
00658
00659 if ((node->input_pins[i]->net->driver_pin->node->type == MULTIPLY) ||
00660 (node->input_pins[i]->net->driver_pin->node->type == HARD_IP) ||
00661 (node->input_pins[i]->net->driver_pin->node->type == MEMORY))
00662 {
00663 fprintf(out, " %s", node->input_pins[i]->net->driver_pin->name);
00664 }
00665 else
00666 {
00667 fprintf(out, " %s", node->input_pins[i]->net->driver_pin->node->name);
00668 }
00669 }
00670
00671 fprintf(out, " %s", node->name);
00672 }
00673 fprintf(out, "\n");
00674
00675 oassert(node->num_output_pins == 1);
00676
00677
00678 for (i = 0; i < node->input_port_sizes[0]; i++)
00679 {
00680 for (j = 0; j < node->num_input_pins; j++)
00681 {
00682 if (i == j)
00683 fprintf(out, "1");
00684 else if (i+node->input_port_sizes[0] == j)
00685 fprintf(out, "1");
00686 else if (i > node->input_port_sizes[0])
00687 fprintf(out, "0");
00688 else
00689 fprintf(out, "-");
00690 }
00691 fprintf(out, " 1\n");
00692 }
00693
00694 fprintf(out, "\n");
00695 }
00696
00697
00698
00699
00700 void output_blif_pin_connect(nnode_t *node, FILE *out)
00701 {
00702 int i;
00703
00704
00705 for (i = 0; i < node->num_input_pins; i++)
00706 {
00707
00708 if (node->input_pins[i]->net->driver_pin->name != NULL)
00709 fprintf(out, ".names %s %s\n1 1\n\n", node->input_pins[i]->net->driver_pin->node->name, node->input_pins[i]->net->driver_pin->name);
00710 }
00711
00712 return;
00713 }
00714