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 <assert.h>
00028 #include "globals.h"
00029 #include "types.h"
00030 #include "errors.h"
00031 #include "ast_util.h"
00032 #include "parse_making_ast.h"
00033 #include "string_cache.h"
00034 #include "ast_optimizations.h"
00035 #include "verilog_bison_user_defined.h"
00036 #include "verilog_preprocessor.h"
00037 #include "util.h"
00038 #include "hard_blocks.h"
00039
00040 extern int yylineno;
00041
00042 STRING_CACHE *defines_for_file_sc;
00043 STRING_CACHE **defines_for_module_sc;
00044 STRING_CACHE *modules_inputs_sc;
00045 STRING_CACHE *modules_outputs_sc;
00046
00047 STRING_CACHE *module_names_to_idx;
00048
00049 ast_node_t **block_instantiations_instance;
00050 int size_block_instantiations;
00051
00052 ast_node_t **module_instantiations_instance;
00053 int size_module_instantiations;
00054
00055 int num_modules;
00056 ast_node_t **ast_modules;
00057
00058 ast_node_t **all_file_items_list;
00059 int size_all_file_items_list;
00060
00061 short to_view_parse;
00062
00063 void graphVizOutputPreproc(FILE *yyin, char* path, char *file)
00064 {
00065 char line[MaxLine];
00066 FILE *fp;
00067 char *tmp;
00068
00069
00070 tmp = strrchr(file, '.');
00071 oassert(tmp);
00072 oassert(*(tmp+1) == 'v');
00073 *tmp = '\0';
00074
00075
00076 tmp = strrchr(file, '/');
00077 if (tmp) file = tmp ;
00078
00079 sprintf( line, "%s/%s_preproc.v", path, file ) ;
00080 fp = fopen( line, "w" ) ;
00081 oassert( fp ) ;
00082 while ( fgets( line, MaxLine, yyin ) )
00083 fprintf( fp, "%s", line ) ;
00084 fclose( fp ) ;
00085 rewind( yyin ) ;
00086 }
00087
00088
00089
00090
00091
00092 void parse_to_ast()
00093 {
00094 int i;
00095 extern FILE *yyin;
00096 extern int yylineno;
00097
00098
00099 to_view_parse = configuration.print_parse_tokens;
00100
00101
00102 init_parser();
00103
00104
00105 if (global_args.verilog_file != NULL)
00106 {
00107
00108 configuration.list_of_file_names = (char**)malloc(sizeof(char*));
00109 configuration.num_list_of_file_names = 1;
00110 configuration.list_of_file_names[0] = global_args.verilog_file;
00111
00112 yyin = fopen(global_args.verilog_file, "r");
00113 if (yyin == NULL)
00114 {
00115 error_message(-1, -1, -1, "cannot open file: %s", global_args.verilog_file);
00116 }
00117
00118
00119 init_veri_preproc();
00120 yyin = veri_preproc(yyin);
00121 cleanup_veri_preproc();
00122
00123
00124 if ( configuration.output_preproc_source )
00125 graphVizOutputPreproc( yyin, configuration.debug_output_path, configuration.list_of_file_names[0] ) ;
00126
00127
00128 current_parse_file = 0;
00129
00130
00131 init_parser_for_file();
00132
00133 yyparse();
00134
00135 clean_up_parser_for_file();
00136
00137 fclose(yyin);
00138 }
00139 else if (global_args.config_file != NULL)
00140 {
00141
00142 for (i = 0; i < configuration.num_list_of_file_names; i++)
00143 {
00144 yyin = fopen(configuration.list_of_file_names[i], "r");
00145 if (yyin == NULL)
00146 {
00147 error_message(-1, -1, -1, "cannot open file: %s\n", configuration.list_of_file_names[i]);
00148 }
00149
00150
00151 init_veri_preproc();
00152 yyin = veri_preproc(yyin);
00153 cleanup_veri_preproc();
00154
00155
00156 if ( configuration.output_preproc_source )
00157 graphVizOutputPreproc( yyin, configuration.debug_output_path, configuration.list_of_file_names[i] ) ;
00158
00159
00160 current_parse_file = i;
00161
00162
00163 yylineno = 0;
00164
00165
00166 init_parser_for_file();
00167
00168 yyparse();
00169
00170 clean_up_parser_for_file();
00171
00172 fclose(yyin);
00173 }
00174 }
00175
00176
00177 cleanup_parser();
00178
00179
00180 current_parse_file = -1;
00181 }
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198 void cleanup_hard_blocks()
00199 {
00200 int i, j;
00201 ast_node_t *block_node, *instance_node, *connect_list_node;
00202
00203 for (i = 0; i < size_block_instantiations; i++)
00204 {
00205 block_node = block_instantiations_instance[i];
00206 instance_node = block_node->children[1];
00207 instance_node->type = HARD_BLOCK_NAMED_INSTANCE;
00208 connect_list_node = instance_node->children[1];
00209 connect_list_node->type = HARD_BLOCK_CONNECT_LIST;
00210
00211 for (j = 0; j < connect_list_node->num_children; j++)
00212 {
00213 connect_list_node->children[j]->type = HARD_BLOCK_CONNECT;
00214 }
00215 }
00216 return;
00217 }
00218
00219
00220
00221
00222 void init_parser()
00223 {
00224 defines_for_file_sc = sc_new_string_cache();
00225
00226 defines_for_module_sc = NULL;
00227
00228
00229 num_modules = 0;
00230 ast_modules = NULL;
00231 module_names_to_idx = sc_new_string_cache();
00232 module_instantiations_instance = NULL;
00233 size_module_instantiations = 0;
00234 block_instantiations_instance = NULL;
00235 size_block_instantiations = 0;
00236
00237
00238 all_file_items_list = NULL;
00239 size_all_file_items_list = 0;
00240 }
00241
00242
00243
00244
00245 void cleanup_parser()
00246 {
00247 int i;
00248
00249
00250 if (num_modules > 0)
00251 {
00252 for (i = 0; i < num_modules; i++)
00253 {
00254 sc_free_string_cache(defines_for_module_sc[i]);
00255 }
00256
00257 free(defines_for_module_sc);
00258 }
00259 }
00260
00261
00262
00263
00264 void init_parser_for_file()
00265 {
00266
00267 defines_for_module_sc = (STRING_CACHE**)realloc(defines_for_module_sc, sizeof(STRING_CACHE*)*(num_modules+1));
00268 defines_for_module_sc[num_modules] = sc_new_string_cache();
00269
00270
00271 modules_inputs_sc = sc_new_string_cache();
00272 modules_outputs_sc = sc_new_string_cache();
00273 }
00274
00275
00276
00277
00278 void clean_up_parser_for_file()
00279 {
00280
00281 sc_free_string_cache(defines_for_file_sc);
00282 }
00283
00284
00285
00286
00287 void next_parsed_verilog_file(ast_node_t *file_items_list)
00288 {
00289 int i;
00290
00291 printf("Optimizing module by AST based optimizations\n");
00292 optimizations_on_AST(file_items_list);
00293
00294 if (configuration.output_ast_graphs == 1)
00295 {
00296
00297 for (i = 0; i < file_items_list->num_children; i++)
00298 {
00299 assert(file_items_list->children[i]);
00300 graphVizOutputAst(configuration.debug_output_path, file_items_list->children[i]);
00301 }
00302 }
00303
00304
00305 all_file_items_list = (ast_node_t**)realloc(all_file_items_list, sizeof(ast_node_t*)*(size_all_file_items_list+1));
00306 all_file_items_list[size_all_file_items_list] = file_items_list;
00307 size_all_file_items_list ++;
00308 }
00309
00310
00311
00312
00313 ast_node_t *newSymbolNode(char *id, int line_number)
00314 {
00315 long sc_spot;
00316 ast_node_t *current_node;
00317
00318 if (id[0] == '`')
00319 {
00320
00321
00322
00323
00324 if ((sc_spot = sc_lookup_string(defines_for_file_sc, (id+1))) == -1)
00325 {
00326 error_message(PARSE_ERROR, line_number, current_parse_file, "Define \"%s\" used but not declared\n", id);
00327 }
00328
00329
00330 return (ast_node_t*)defines_for_file_sc->data[sc_spot];
00331 }
00332 else if ((sc_spot = sc_lookup_string(defines_for_module_sc[num_modules], id)) != -1)
00333 {
00334
00335 return (ast_node_t*)defines_for_module_sc[num_modules]->data[sc_spot];
00336 }
00337 else
00338 {
00339
00340 current_node = create_tree_node_id(id, line_number, current_parse_file);
00341 }
00342
00343 return current_node;
00344 }
00345
00346
00347
00348
00349 ast_node_t *newNumberNode(char *num, int line_number)
00350 {
00351 ast_node_t *current_node = create_tree_node_number(num, line_number, current_parse_file);
00352 return current_node;
00353 }
00354
00355
00356
00357
00358 ast_node_t *newList(ids node_type, ast_node_t *child)
00359 {
00360
00361 ast_node_t* new_node = create_node_w_type(node_type, yylineno, current_parse_file);
00362
00363 allocate_children_to_node(new_node, 1, child);
00364
00365 return new_node;
00366 }
00367
00368
00369
00370
00371 ast_node_t *newList_entry(ast_node_t *list, ast_node_t *child)
00372 {
00373
00374 add_child_to_node(list, child);
00375
00376 return list;
00377 }
00378
00379
00380
00381
00382
00383
00384 ast_node_t *newListReplicate(ast_node_t *exp, ast_node_t *child )
00385 {
00386
00387 ast_node_t* new_node = create_node_w_type(CONCATENATE, yylineno, current_parse_file);
00388
00389 new_node->types.concat.num_bit_strings = -1;
00390
00391
00392 allocate_children_to_node(new_node, 1, child);
00393
00394 int i ;
00395 for ( i = 1; i < exp->types.number.value; i++ ) {
00396 add_child_to_node( new_node, child ) ;
00397 }
00398
00399 return new_node;
00400 }
00401
00402
00403
00404
00405 ast_node_t *markAndProcessSymbolListWith(short id, ast_node_t *symbol_list)
00406 {
00407 int i;
00408 long sc_spot;
00409 ast_node_t *range_min = 0;
00410 ast_node_t *range_max = 0;
00411
00412 for (i = 0; i < symbol_list->num_children; i++)
00413 {
00414
00415 get_range(symbol_list->children[i]);
00416
00417 if ((i == 0) && (symbol_list->children[0]->children[1] != NULL)&& (symbol_list->children[0]->children[2] != NULL) && (symbol_list->children[0]->children[1]->type == NUMBERS) && (symbol_list->children[0]->children[2]->type == NUMBERS))
00418 {
00419 range_max = symbol_list->children[0]->children[1];
00420 range_min = symbol_list->children[0]->children[2];
00421 }
00422
00423 if ((symbol_list->children[i]->children[1] == NULL) && (symbol_list->children[i]->children[2] == NULL))
00424 {
00425 symbol_list->children[i]->children[1] = range_max;
00426 symbol_list->children[i]->children[2] = range_min;
00427 }
00428
00429 switch(id)
00430 {
00431 case PORT:
00432 {
00433 short found_match = FALSE;
00434
00435 symbol_list->children[i]->types.variable.is_port = TRUE;
00436
00437
00438 if ((sc_spot = sc_lookup_string(modules_inputs_sc, symbol_list->children[i]->children[0]->types.identifier)) != -1)
00439 {
00440 symbol_list->children[i]->types.variable.is_input = TRUE;
00441 symbol_list->children[i]->children[0] = (ast_node_t*)modules_inputs_sc->data[sc_spot];
00442 found_match = TRUE;
00443 }
00444 if ((found_match == FALSE) && ((sc_spot = sc_lookup_string(modules_outputs_sc, symbol_list->children[i]->children[0]->types.identifier)) != -1))
00445 {
00446 symbol_list->children[i]->types.variable.is_output = TRUE;
00447 symbol_list->children[i]->children[0] = (ast_node_t*)modules_outputs_sc->data[sc_spot];
00448 found_match = TRUE;
00449 }
00450
00451 if (found_match == FALSE)
00452 {
00453 error_message(PARSE_ERROR, symbol_list->children[i]->line_number, current_parse_file, "No matching input declaration for port %s\n", symbol_list->children[i]->children[0]->types.identifier);
00454 }
00455 break;
00456 }
00457 case PARAMETER:
00458 {
00459 int binary_range;
00460 if (i == 0)
00461 {
00462 binary_range = get_range(symbol_list->children[i]);
00463 }
00464
00465
00466 if (binary_range != -1)
00467 {
00468
00469 if((symbol_list->children[i]->children[5]->types.number.size != 0)
00470 && (symbol_list->children[i]->children[5]->types.number.base == BIN)
00471 && (symbol_list->children[i]->children[5]->types.number.size != binary_range))
00472 {
00473 error_message(PARSE_ERROR, symbol_list->children[i]->children[5]->line_number, current_parse_file, "parameter %s and range %d don't match\n", symbol_list->children[i]->children[0]->types.identifier, binary_range);
00474 }
00475 else
00476 {
00477 symbol_list->children[i]->children[5]->types.number.size = binary_range;
00478 }
00479 }
00480
00481
00482 if ((sc_spot = sc_add_string(defines_for_module_sc[num_modules], symbol_list->children[i]->children[0]->types.identifier)) == -1)
00483 {
00484 error_message(PARSE_ERROR, symbol_list->children[i]->children[5]->line_number, current_parse_file, "define has same name (%s). Other define migh be in another file. Odin considers a define as global.\n",
00485 symbol_list->children[i]->children[0]->types.identifier,
00486 ((ast_node_t*)(defines_for_module_sc[num_modules]->data[sc_spot]))->line_number);
00487 }
00488
00489 if (symbol_list->children[i]->children[5]->types.number.base == DEC)
00490 {
00491 error_message(PARSE_ERROR, symbol_list->children[i]->children[5]->line_number, current_parse_file, "Odin only accepts parameter %s with defined width\n", symbol_list->children[i]->children[0]->types.identifier);
00492 }
00493 defines_for_module_sc[num_modules]->data[sc_spot] = (void*)symbol_list->children[i]->children[5];
00494
00495 symbol_list->children[i]->children[5]->shared_node = TRUE;
00496
00497
00498 symbol_list->children[i]->types.variable.is_parameter = TRUE;
00499 break;
00500 }
00501 case INPUT:
00502 symbol_list->children[i]->types.variable.is_input = TRUE;
00503
00504 if ((sc_spot = sc_add_string(modules_inputs_sc, symbol_list->children[i]->children[0]->types.identifier)) == -1)
00505 {
00506 error_message(PARSE_ERROR, symbol_list->children[i]->children[0]->line_number, current_parse_file, "Module already has input with this name %s\n", symbol_list->children[i]->children[0]->types.identifier);
00507 }
00508
00509 modules_inputs_sc->data[sc_spot] = (void*)symbol_list->children[i];
00510 break;
00511 case OUTPUT:
00512 symbol_list->children[i]->types.variable.is_output = TRUE;
00513
00514 if ((sc_spot = sc_add_string(modules_outputs_sc, symbol_list->children[i]->children[0]->types.identifier)) == -1)
00515 {
00516 error_message(PARSE_ERROR, symbol_list->children[i]->children[0]->line_number, current_parse_file, "Module already has input with this name %s\n", symbol_list->children[i]->children[0]->types.identifier);
00517 }
00518
00519 modules_outputs_sc->data[sc_spot] = (void*)symbol_list->children[i];
00520 break;
00521 case INOUT:
00522 symbol_list->children[i]->types.variable.is_inout = TRUE;
00523 error_message(PARSE_ERROR, symbol_list->children[i]->children[0]->line_number, current_parse_file, "Odin does not handle inouts (%s)\n");
00524 break;
00525 case WIRE:
00526 symbol_list->children[i]->types.variable.is_wire = TRUE;
00527 break;
00528 case REG:
00529 symbol_list->children[i]->types.variable.is_reg = TRUE;
00530 break;
00531 default:
00532 oassert(FALSE);
00533 }
00534 }
00535
00536 return symbol_list;
00537 }
00538
00539
00540
00541 ast_node_t *newArrayRef(char *id, ast_node_t *expression, int line_number)
00542 {
00543
00544 ast_node_t *symbol_node = newSymbolNode(id, line_number);
00545
00546 ast_node_t* new_node = create_node_w_type(ARRAY_REF, line_number, current_parse_file);
00547
00548 allocate_children_to_node(new_node, 2, symbol_node, expression);
00549
00550 return new_node;
00551 }
00552
00553
00554
00555
00556 ast_node_t *newRangeRef(char *id, ast_node_t *expression1, ast_node_t *expression2, int line_number)
00557 {
00558
00559 ast_node_t *symbol_node = newSymbolNode(id, line_number);
00560
00561 ast_node_t* new_node = create_node_w_type(RANGE_REF, line_number, current_parse_file);
00562
00563 allocate_children_to_node(new_node, 3, symbol_node, expression1, expression2);
00564
00565 get_range(new_node);
00566
00567 return new_node;
00568 }
00569
00570
00571
00572
00573 ast_node_t *newBinaryOperation(operation_list op_id, ast_node_t *expression1, ast_node_t *expression2, int line_number)
00574 {
00575 info_ast_visit_t *node_details = NULL;
00576
00577 ast_node_t* new_node = create_node_w_type(BINARY_OPERATION, line_number, current_parse_file);
00578
00579 new_node->types.operation.op = op_id;
00580
00581 allocate_children_to_node(new_node, 2, expression1, expression2);
00582
00583
00584 node_details = constantFold(new_node);
00585 if ((node_details != NULL) && (node_details->is_constant_folded == TRUE))
00586 {
00587 new_node = node_details->from;
00588 free(node_details);
00589 }
00590
00591 return new_node;
00592 }
00593
00594
00595
00596
00597 ast_node_t *newUnaryOperation(operation_list op_id, ast_node_t *expression, int line_number)
00598 {
00599 info_ast_visit_t *node_details = NULL;
00600
00601 ast_node_t* new_node = create_node_w_type(UNARY_OPERATION, line_number, current_parse_file);
00602
00603 new_node->types.operation.op = op_id;
00604
00605 allocate_children_to_node(new_node, 1, expression);
00606
00607
00608 node_details = constantFold(new_node);
00609 if ((node_details != NULL) && (node_details->is_constant_folded == TRUE))
00610 {
00611 new_node = node_details->from;
00612 free(node_details);
00613 }
00614
00615 return new_node;
00616 }
00617
00618
00619
00620
00621 ast_node_t *newNegedgeSymbol(char *symbol, int line_number)
00622 {
00623
00624 ast_node_t *symbol_node = newSymbolNode(symbol, line_number);
00625
00626 ast_node_t* new_node = create_node_w_type(NEGEDGE, line_number, current_parse_file);
00627
00628 allocate_children_to_node(new_node, 1, symbol_node);
00629
00630 return new_node;
00631 }
00632
00633
00634
00635
00636 ast_node_t *newPosedgeSymbol(char *symbol, int line_number)
00637 {
00638
00639 ast_node_t *symbol_node = newSymbolNode(symbol, line_number);
00640
00641 ast_node_t* new_node = create_node_w_type(POSEDGE, line_number, current_parse_file);
00642
00643 allocate_children_to_node(new_node, 1, symbol_node);
00644
00645 return new_node;
00646 }
00647
00648
00649
00650
00651 ast_node_t *newCaseItem(ast_node_t *expression, ast_node_t *statement, int line_number)
00652 {
00653
00654 ast_node_t* new_node = create_node_w_type(CASE_ITEM, line_number, current_parse_file);
00655
00656 allocate_children_to_node(new_node, 2, expression, statement);
00657
00658 return new_node;
00659 }
00660
00661
00662
00663
00664 ast_node_t *newDefaultCase(ast_node_t *statement, int line_number)
00665 {
00666
00667 ast_node_t* new_node = create_node_w_type(CASE_DEFAULT, line_number, current_parse_file);
00668
00669 allocate_children_to_node(new_node, 1, statement);
00670
00671 return new_node;
00672 }
00673
00674
00675
00676
00677 ast_node_t *newNonBlocking(ast_node_t *expression1, ast_node_t *expression2, int line_number)
00678 {
00679
00680 ast_node_t* new_node = create_node_w_type(NON_BLOCKING_STATEMENT, line_number, current_parse_file);
00681
00682 allocate_children_to_node(new_node, 2, expression1, expression2);
00683
00684 return new_node;
00685 }
00686
00687
00688
00689
00690 ast_node_t *newBlocking(ast_node_t *expression1, ast_node_t *expression2, int line_number)
00691 {
00692
00693 ast_node_t* new_node = create_node_w_type(BLOCKING_STATEMENT, line_number, current_parse_file);
00694
00695 allocate_children_to_node(new_node, 2, expression1, expression2);
00696
00697 return new_node;
00698 }
00699
00700
00701
00702
00703 ast_node_t *newIf(ast_node_t *compare_expression, ast_node_t *true_expression, ast_node_t *false_expression, int line_number)
00704 {
00705
00706 ast_node_t* new_node = create_node_w_type(IF, line_number, current_parse_file);
00707
00708 allocate_children_to_node(new_node, 3, compare_expression, true_expression, false_expression);
00709
00710 return new_node;
00711 }
00712
00713
00714
00715
00716 ast_node_t *newIfQuestion(ast_node_t *compare_expression, ast_node_t *true_expression, ast_node_t *false_expression, int line_number)
00717 {
00718
00719 ast_node_t* new_node = create_node_w_type(IF_Q, line_number, current_parse_file);
00720
00721 allocate_children_to_node(new_node, 3, compare_expression, true_expression, false_expression);
00722
00723 return new_node;
00724 }
00725
00726
00727
00728 ast_node_t *newCase(ast_node_t *compare_expression, ast_node_t *case_list, int line_number)
00729 {
00730
00731 ast_node_t* new_node = create_node_w_type(CASE, line_number, current_parse_file);
00732
00733 allocate_children_to_node(new_node, 2, compare_expression, case_list);
00734
00735 return new_node;
00736 }
00737
00738
00739
00740
00741 ast_node_t *newAlways(ast_node_t *delay_control, ast_node_t *statement, int line_number)
00742 {
00743
00744 ast_node_t* new_node = create_node_w_type(ALWAYS, line_number, current_parse_file);
00745
00746 allocate_children_to_node(new_node, 2, delay_control, statement);
00747
00748 return new_node;
00749 }
00750
00751
00752
00753
00754 ast_node_t *newModuleConnection(char* id, ast_node_t *expression, int line_number)
00755 {
00756 ast_node_t *symbol_node;
00757
00758 ast_node_t* new_node = create_node_w_type(MODULE_CONNECT, line_number, current_parse_file);
00759 if (id != NULL)
00760 {
00761 symbol_node = newSymbolNode(id, line_number);
00762 }
00763 else
00764 {
00765 symbol_node = NULL;
00766 }
00767
00768
00769 allocate_children_to_node(new_node, 2, symbol_node, expression);
00770
00771 return new_node;
00772 }
00773
00774
00775
00776
00777 ast_node_t *newModuleNamedInstance(char* unique_name, ast_node_t *module_connect_list, int line_number)
00778 {
00779 ast_node_t *symbol_node = newSymbolNode(unique_name, line_number);
00780
00781
00782 ast_node_t* new_node = create_node_w_type(MODULE_NAMED_INSTANCE, line_number, current_parse_file);
00783
00784 allocate_children_to_node(new_node, 2, symbol_node, module_connect_list);
00785
00786 return new_node;
00787 }
00788
00789
00790
00791
00792 ast_node_t *newHardBlockInstance(char* module_ref_name, ast_node_t *module_named_instance, int line_number)
00793 {
00794 ast_node_t *symbol_node = newSymbolNode(module_ref_name, line_number);
00795
00796
00797 ast_node_t* new_node = create_node_w_type(HARD_BLOCK, line_number, current_parse_file);
00798
00799 allocate_children_to_node(new_node, 2, symbol_node, module_named_instance);
00800
00801
00802 block_instantiations_instance = (ast_node_t **)realloc(block_instantiations_instance, sizeof(ast_node_t*)*(size_block_instantiations+1));
00803 block_instantiations_instance[size_block_instantiations] = new_node;
00804 size_block_instantiations++;
00805
00806 return new_node;
00807 }
00808
00809
00810
00811
00812 ast_node_t *newModuleInstance(char* module_ref_name, ast_node_t *module_named_instance, int line_number)
00813 {
00814 #ifdef VPR6
00815 if (sc_lookup_string(hard_block_names, module_ref_name) != -1)
00816 {
00817 return newHardBlockInstance(module_ref_name, module_named_instance, line_number);
00818 }
00819 #endif
00820
00821 ast_node_t *symbol_node = newSymbolNode(module_ref_name, line_number);
00822
00823
00824 ast_node_t* new_node = create_node_w_type(MODULE_INSTANCE, line_number, current_parse_file);
00825
00826 allocate_children_to_node(new_node, 2, symbol_node, module_named_instance);
00827
00828
00829 module_instantiations_instance = (ast_node_t **)realloc(module_instantiations_instance, sizeof(ast_node_t*)*(size_module_instantiations+1));
00830 module_instantiations_instance[size_module_instantiations] = new_node;
00831 size_module_instantiations++;
00832
00833 return new_node;
00834 }
00835
00836
00837
00838
00839 ast_node_t *newGateInstance(char* gate_instance_name, ast_node_t *expression1, ast_node_t *expression2, ast_node_t *expression3, int line_number)
00840 {
00841
00842 ast_node_t* new_node = create_node_w_type(GATE_INSTANCE, line_number, current_parse_file);
00843 ast_node_t *symbol_node = NULL;
00844
00845 if (gate_instance_name != NULL)
00846 {
00847 symbol_node = newSymbolNode(gate_instance_name, line_number);
00848 }
00849
00850
00851 allocate_children_to_node(new_node, 4, symbol_node, expression1, expression2, expression3);
00852
00853 return new_node;
00854 }
00855
00856
00857
00858
00859 ast_node_t *newGate(operation_list op_id, ast_node_t *gate_instance, int line_number)
00860 {
00861
00862 ast_node_t* new_node = create_node_w_type(GATE, line_number, current_parse_file);
00863
00864 new_node->types.operation.op = op_id;
00865
00866 allocate_children_to_node(new_node, 1, gate_instance);
00867
00868 return new_node;
00869 }
00870
00871
00872
00873
00874 ast_node_t *newAssign(ast_node_t *statement, int line_number)
00875 {
00876
00877 ast_node_t* new_node = create_node_w_type(ASSIGN, line_number, current_parse_file);
00878
00879 allocate_children_to_node(new_node, 1, statement);
00880
00881 return new_node;
00882 }
00883
00884
00885
00886
00887 ast_node_t *newVarDeclare(char* symbol, ast_node_t *expression1, ast_node_t *expression2, ast_node_t *expression3, ast_node_t *expression4, ast_node_t *value, int line_number)
00888 {
00889 ast_node_t *symbol_node = newSymbolNode(symbol, line_number);
00890
00891
00892 ast_node_t* new_node = create_node_w_type(VAR_DECLARE, line_number, current_parse_file);
00893
00894
00895 allocate_children_to_node(new_node, 6, symbol_node, expression1, expression2, expression3, expression4, value);
00896
00897 return new_node;
00898 }
00899
00900
00901
00902
00903 ast_node_t *newModule(char* module_name, ast_node_t *list_of_ports, ast_node_t *list_of_module_items, int line_number)
00904 {
00905 long sc_spot;
00906 ast_node_t *symbol_node = newSymbolNode(module_name, line_number);
00907
00908
00909 ast_node_t* new_node = create_node_w_type(MODULE, line_number, current_parse_file);
00910
00911 markAndProcessSymbolListWith(PORT, list_of_ports);
00912
00913 allocate_children_to_node(new_node, 3, symbol_node, list_of_ports, list_of_module_items);
00914
00915
00916 new_node->types.module.module_instantiations_instance = module_instantiations_instance;
00917 new_node->types.module.size_module_instantiations = size_module_instantiations;
00918 new_node->types.module.is_instantiated = FALSE;
00919 new_node->types.module.index = num_modules;
00920
00921
00922 ast_modules = (ast_node_t **)realloc(ast_modules, sizeof(ast_node_t*)*(num_modules+1));
00923 ast_modules[num_modules] = new_node;
00924
00925 if ((sc_spot = sc_add_string(module_names_to_idx, module_name)) == -1)
00926 {
00927 error_message(PARSE_ERROR, line_number, current_parse_file, "module names with the same name -> %s\n", module_name);
00928 }
00929
00930 module_names_to_idx->data[sc_spot] = (void*)new_node;
00931
00932
00933 next_module();
00934
00935 return new_node;
00936 }
00937
00938
00939
00940
00941 void next_module()
00942 {
00943 num_modules ++;
00944
00945
00946 defines_for_module_sc = (STRING_CACHE**)realloc(defines_for_module_sc, sizeof(STRING_CACHE*)*(num_modules+1));
00947 defines_for_module_sc[num_modules] = sc_new_string_cache();
00948
00949
00950 module_instantiations_instance = NULL;
00951 size_module_instantiations = 0;
00952
00953
00954 sc_free_string_cache(modules_inputs_sc);
00955 sc_free_string_cache(modules_outputs_sc);
00956
00957 modules_inputs_sc = sc_new_string_cache();
00958 modules_outputs_sc = sc_new_string_cache();
00959 }
00960
00961
00962
00963
00964 void newDefparam(char *inst, char *param, char *val, int line_number)
00965 {
00966 ast_node_t *sym_node = newSymbolNode(val, line_number);
00967 sym_node->shared_node = TRUE;
00968 }
00969
00970
00971
00972
00973 void newConstant(char *id, char *number, int line_number)
00974 {
00975 long sc_spot;
00976 ast_node_t *number_node = newNumberNode(number, line_number);
00977
00978
00979
00980 if ((sc_spot = sc_add_string(defines_for_file_sc, id)) == -1)
00981 {
00982 error_message(PARSE_ERROR, current_parse_file, line_number, "define with same name (%s) on line %d\n", id, ((ast_node_t*)(defines_for_file_sc->data[sc_spot]))->line_number);
00983 }
00984
00985 defines_for_file_sc->data[sc_spot] = (void*)number_node;
00986
00987 number_node->shared_node = TRUE;
00988 }
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998 int unique_label_count;
00999
01000
01001
01002 void graphVizOutputAst(char* path, ast_node_t *top)
01003 {
01004 char path_and_file[4096];
01005 FILE *fp;
01006 static int file_num = 0;
01007
01008
01009 sprintf(path_and_file, "%s/%s_ast.dot", path, top->children[0]->types.identifier);
01010 fp = fopen(path_and_file, "w");
01011 file_num++;
01012
01013
01014 fprintf(fp, "digraph G {\t\nranksep=.25;\n");
01015 unique_label_count = 0;
01016
01017 graphVizOutputAst_traverse_node(fp, top, NULL, -1);
01018
01019
01020 fprintf(fp, "}\n");
01021 fclose(fp);
01022 }
01023
01024
01025
01026
01027 void graphVizOutputAst_traverse_node(FILE *fp, ast_node_t *node, ast_node_t *from, int from_num)
01028 {
01029 int i;
01030 int my_label = unique_label_count;
01031
01032
01033 unique_label_count++;
01034
01035 if (node == NULL)
01036 {
01037
01038 }
01039 else
01040 {
01041 switch(node->type)
01042 {
01043 case FILE_ITEMS:
01044 fprintf(fp, "\t%d [label=\"FILE_ITEMS\"];\n", my_label);
01045 break;
01046 case MODULE:
01047 fprintf(fp, "\t%d [label=\"MODULE\"];\n", my_label);
01048 break;
01049 case MODULE_ITEMS:
01050 fprintf(fp, "\t%d [label=\"MODULE_ITEMS\"];\n", my_label);
01051 break;
01052 case VAR_DECLARE:
01053 {
01054 char temp[4096] = "";
01055 if(node->types.variable.is_input)
01056 {
01057 sprintf(temp, "%s INPUT", temp);
01058 }
01059 if(node->types.variable.is_output)
01060 {
01061 sprintf(temp, "%s OUTPUT", temp);
01062 }
01063 if(node->types.variable.is_inout)
01064 {
01065 sprintf(temp, "%s INOUT", temp);
01066 }
01067 if(node->types.variable.is_port)
01068 {
01069 sprintf(temp, "%s PORT", temp);
01070 }
01071 if(node->types.variable.is_parameter)
01072 {
01073 sprintf(temp, "%s PARAMETER", temp);
01074 }
01075 if(node->types.variable.is_wire)
01076 {
01077 sprintf(temp, "%s WIRE", temp);
01078 }
01079 if(node->types.variable.is_reg)
01080 {
01081 sprintf(temp, "%s REG", temp);
01082 }
01083 fprintf(fp, "\t%d [label=\"VAR_DECLARE %s\"];\n", my_label, temp);
01084 }
01085 break;
01086 case VAR_DECLARE_LIST:
01087 fprintf(fp, "\t%d [label=\"VAR_DECLARE_LIST\"];\n", my_label);
01088 break;
01089 case ASSIGN:
01090 fprintf(fp, "\t%d [label=\"ASSIGN\"];\n", my_label);
01091 break;
01092 case GATE:
01093 fprintf(fp, "\t%d [label=\"GATE\"];\n", my_label);
01094 break;
01095 case GATE_INSTANCE:
01096 fprintf(fp, "\t%d [label=\"GATE_INSTANCE\"];\n", my_label);
01097 break;
01098 case MODULE_CONNECT_LIST:
01099 fprintf(fp, "\t%d [label=\"MODULE_CONNECT_LIST\"];\n", my_label);
01100 break;
01101 case MODULE_CONNECT:
01102 fprintf(fp, "\t%d [label=\"MODULE_CONNECT\"];\n", my_label);
01103 break;
01104 case MODULE_NAMED_INSTANCE:
01105 fprintf(fp, "\t%d [label=\"MODULE_NAMED_INSTANCE\"];\n", my_label);
01106 break;
01107 case MODULE_INSTANCE:
01108 fprintf(fp, "\t%d [label=\"MODULE_INSTANCE\"];\n", my_label);
01109 break;
01110 case HARD_BLOCK:
01111 fprintf(fp, "\t%d [label=\"HARD_BLOCK\"];\n", my_label);
01112 break;
01113 case HARD_BLOCK_NAMED_INSTANCE:
01114 fprintf(fp, "\t%d [label=\"HARD_BLOCK_NAMED_INSTANCE\"];\n", my_label);
01115 break;
01116 case HARD_BLOCK_CONNECT:
01117 fprintf(fp, "\t%d [label=\"HARD_BLOCK_CONNECT\"];\n", my_label);
01118 break;
01119 case HARD_BLOCK_CONNECT_LIST:
01120 fprintf(fp, "\t%d [label=\"HARD_BLOCK_CONNECT_LIST\"];\n", my_label);
01121 break;
01122 case BLOCK:
01123 fprintf(fp, "\t%d [label=\"BLOCK\"];\n", my_label);
01124 break;
01125 case NON_BLOCKING_STATEMENT:
01126 fprintf(fp, "\t%d [label=\"NON_BLOCKING_STATEMENT\"];\n", my_label);
01127 break;
01128 case BLOCKING_STATEMENT:
01129 fprintf(fp, "\t%d [label=\"BLOCKING_STATEMENT\"];\n", my_label);
01130 break;
01131 case CASE:
01132 fprintf(fp, "\t%d [label=\"CASE\"];\n", my_label);
01133 break;
01134 case CASE_LIST:
01135 fprintf(fp, "\t%d [label=\"CASE_LIST\"];\n", my_label);
01136 break;
01137 case CASE_ITEM:
01138 fprintf(fp, "\t%d [label=\"CASE_ITEM\"];\n", my_label);
01139 break;
01140 case CASE_DEFAULT:
01141 fprintf(fp, "\t%d [label=\"CASE_DEFAULT\"];\n", my_label);
01142 break;
01143 case ALWAYS:
01144 fprintf(fp, "\t%d [label=\"ALWAYS\"];\n", my_label);
01145 break;
01146 case DELAY_CONTROL:
01147 fprintf(fp, "\t%d [label=\"DELAY_CONTROL\"];\n", my_label);
01148 break;
01149 case POSEDGE:
01150 fprintf(fp, "\t%d [label=\"POSEDGE\"];\n", my_label);
01151 break;
01152 case NEGEDGE:
01153 fprintf(fp, "\t%d [label=\"NEGEDGE\"];\n", my_label);
01154 break;
01155 case IF:
01156 fprintf(fp, "\t%d [label=\"IF\"];\n", my_label);
01157 break;
01158 case IF_Q:
01159 fprintf(fp, "\t%d [label=\"IF_Q\"];\n", my_label);
01160 break;
01161 case BINARY_OPERATION:
01162 switch (node->types.operation.op)
01163 {
01164 case ADD:
01165 fprintf(fp, "\t%d [label=\"BINARY_OPERATION ADD\"];\n", my_label);
01166 break;
01167 case MINUS:
01168 fprintf(fp, "\t%d [label=\"BINARY_OPERATION MINUS\"];\n", my_label);
01169 break;
01170 case BITWISE_NOT:
01171 fprintf(fp, "\t%d [label=\"BINARY_OPERATION BITWISE_NOT\"];\n", my_label);
01172 break;
01173 case BITWISE_AND:
01174 fprintf(fp, "\t%d [label=\"BINARY_OPERATION BITWISE_AND\"];\n", my_label);
01175 break;
01176 case BITWISE_OR:
01177 fprintf(fp, "\t%d [label=\"BINARY_OPERATION BITWISE_OR\"];\n", my_label);
01178 break;
01179 case BITWISE_NAND:
01180 fprintf(fp, "\t%d [label=\"BINARY_OPERATION BITWISE_NAND\"];\n", my_label);
01181 break;
01182 case BITWISE_NOR:
01183 fprintf(fp, "\t%d [label=\"BINARY_OPERATION BITWISE_NOR\"];\n", my_label);
01184 break;
01185 case BITWISE_XNOR:
01186 fprintf(fp, "\t%d [label=\"BINARY_OPERATION BITWISE_XNOR\"];\n", my_label);
01187 break;
01188 case BITWISE_XOR:
01189 fprintf(fp, "\t%d [label=\"BINARY_OPERATION BITWISE_XOR\"];\n", my_label);
01190 break;
01191 case LOGICAL_NOT:
01192 fprintf(fp, "\t%d [label=\"BINARY_OPERATION LOGICAL_NOT\"];\n", my_label);
01193 break;
01194 case LOGICAL_OR:
01195 fprintf(fp, "\t%d [label=\"BINARY_OPERATION LOGICAL_OR\"];\n", my_label);
01196 break;
01197 case LOGICAL_AND:
01198 fprintf(fp, "\t%d [label=\"BINARY_OPERATION LOGICAL_AND\"];\n", my_label);
01199 break;
01200 case MULTIPLY:
01201 fprintf(fp, "\t%d [label=\"BINARY_OPERATION MULTIPLY\"];\n", my_label);
01202 break;
01203 case DIVIDE:
01204 fprintf(fp, "\t%d [label=\"BINARY_OPERATION DIVIDE\"];\n", my_label);
01205 break;
01206 case MODULO:
01207 fprintf(fp, "\t%d [label=\"BINARY_OPERATION MODULO\"];\n", my_label);
01208 break;
01209 case LT:
01210 fprintf(fp, "\t%d [label=\"BINARY_OPERATION LT\"];\n", my_label);
01211 break;
01212 case GT:
01213 fprintf(fp, "\t%d [label=\"BINARY_OPERATION GT\"];\n", my_label);
01214 break;
01215 case LOGICAL_EQUAL:
01216 fprintf(fp, "\t%d [label=\"BINARY_OPERATION LOGICAL_EQUAL\"];\n", my_label);
01217 break;
01218 case NOT_EQUAL:
01219 fprintf(fp, "\t%d [label=\"BINARY_OPERATION NOT_EQUAL\"];\n", my_label);
01220 break;
01221 case LTE:
01222 fprintf(fp, "\t%d [label=\"BINARY_OPERATION LTE\"];\n", my_label);
01223 break;
01224 case GTE:
01225 fprintf(fp, "\t%d [label=\"BINARY_OPERATION GTE\"];\n", my_label);
01226 break;
01227 case SR:
01228 fprintf(fp, "\t%d [label=\"BINARY_OPERATION SR\"];\n", my_label);
01229 break;
01230 case SL:
01231 fprintf(fp, "\t%d [label=\"BINARY_OPERATION SL\"];\n", my_label);
01232 break;
01233 case CASE_EQUAL:
01234 fprintf(fp, "\t%d [label=\"BINARY_OPERATION CASE_EQUAL\"];\n", my_label);
01235 break;
01236 case CASE_NOT_EQUAL:
01237 fprintf(fp, "\t%d [label=\"BINARY_OPERATION\"];\n", my_label);
01238 break;
01239 default:
01240 break;
01241 }
01242 break;
01243 case UNARY_OPERATION:
01244 switch (node->types.operation.op)
01245 {
01246 case ADD:
01247 fprintf(fp, "\t%d [label=\"UNARY_OPERATION ADD\"];\n", my_label);
01248 break;
01249 case MINUS:
01250 fprintf(fp, "\t%d [label=\"UNARY_OPERATION MINUS\"];\n", my_label);
01251 break;
01252 case BITWISE_NOT:
01253 fprintf(fp, "\t%d [label=\"UNARY_OPERATION BITWISE_NOT\"];\n", my_label);
01254 break;
01255 case BITWISE_AND:
01256 fprintf(fp, "\t%d [label=\"UNARY_OPERATION BITWISE_AND\"];\n", my_label);
01257 break;
01258 case BITWISE_OR:
01259 fprintf(fp, "\t%d [label=\"UNARY_OPERATION BITWISE_OR\"];\n", my_label);
01260 break;
01261 case BITWISE_NAND:
01262 fprintf(fp, "\t%d [label=\"UNARY_OPERATION BITWISE_NAND\"];\n", my_label);
01263 break;
01264 case BITWISE_NOR:
01265 fprintf(fp, "\t%d [label=\"UNARY_OPERATION BITWISE_NOR\"];\n", my_label);
01266 break;
01267 case BITWISE_XNOR:
01268 fprintf(fp, "\t%d [label=\"UNARY_OPERATION BITWISE_XNOR\"];\n", my_label);
01269 break;
01270 case BITWISE_XOR:
01271 fprintf(fp, "\t%d [label=\"UNARY_OPERATION BITWISE_XOR\"];\n", my_label);
01272 break;
01273 case LOGICAL_NOT:
01274 fprintf(fp, "\t%d [label=\"UNARY_OPERATION LOGICAL_NOT\"];\n", my_label);
01275 break;
01276 default:
01277 break;
01278 }
01279 break;
01280 case ARRAY_REF:
01281 fprintf(fp, "\t%d [label=\"ARRAY_REF\"];\n", my_label);
01282 break;
01283 case RANGE_REF:
01284 fprintf(fp, "\t%d [label=\"RANGE_REF\"];\n", my_label);
01285 break;
01286 case CONCATENATE:
01287 fprintf(fp, "\t%d [label=\"CONCATENATE\"];\n", my_label);
01288 break;
01289 case IDENTIFIERS:
01290 fprintf(fp, "\t%d [label=\"IDENTIFIERS:%s\"];\n", my_label, node->types.identifier);
01291 break;
01292 case NUMBERS:
01293 switch (node->types.number.base)
01294 {
01295 case(DEC):
01296 fprintf(fp, "\t%d [label=\"NUMBERS DEC:%s\"];\n", my_label, node->types.number.number);
01297 break;
01298 case(HEX):
01299 fprintf(fp, "\t%d [label=\"NUMBERS HEX:%s\"];\n", my_label, node->types.number.number);
01300 break;
01301 case(OCT):
01302 fprintf(fp, "\t%d [label=\"NUMBERS OCT:%s\"];\n", my_label, node->types.number.number);
01303 break;
01304 case(BIN):
01305 fprintf(fp, "\t%d [label=\"NUMBERS BIN:%s\"];\n", my_label, node->types.number.number);
01306 break;
01307 case(LONG_LONG):
01308 fprintf(fp, "\t%d [label=\"NUMBERS LONG_LONG:%lld\"];\n", my_label, node->types.number.value);
01309 break;
01310 }
01311 break;
01312 default:
01313 oassert(FALSE);
01314 }
01315 }
01316
01317 if (node != NULL)
01318 {
01319
01320 if (from != NULL)
01321 fprintf(fp, "\t%d -> %d;\n", from_num, my_label);
01322
01323 for (i = 0; i < node->num_children; i++)
01324 {
01325 graphVizOutputAst_traverse_node(fp, node->children[i], node, my_label);
01326 }
01327 }
01328 }