#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "types.h"
#include "globals.h"
#include "errors.h"
#include "netlist_utils.h"
#include "odin_util.h"
#include "ast_util.h"
#include "netlist_create_from_ast.h"
#include "string_cache.h"
#include "netlist_visualizer.h"
#include "parse_making_ast.h"
#include "node_creation_library.h"
#include "util.h"
#include "multipliers.h"
#include "hard_blocks.h"
#include "memories.h"
Go to the source code of this file.
Defines | |
#define | INSTANTIATE_DRIVERS 1 |
#define | ALIAS_INPUTS 2 |
#define | COMBINATIONAL 1 |
#define | SEQUENTIAL 2 |
Functions | |
void | convert_ast_to_netlist_recursing_via_modules (ast_node_t *current_module, char *instance_name, int level) |
signal_list_t * | netlist_expand_ast_of_module (ast_node_t *node, char *instance_name_prefix) |
void | create_all_driver_nets_in_this_module (char *instance_name_prefix) |
ast_node_t * | find_top_module () |
void | create_top_driver_nets (ast_node_t *module, char *instance_name_prefix) |
void | create_top_output_nodes (ast_node_t *module, char *instance_name_prefix) |
nnet_t * | define_nets_with_driver (ast_node_t *var_declare, char *instance_name_prefix) |
nnet_t * | define_nodes_and_nets_with_driver (ast_node_t *var_declare, char *instance_name_prefix) |
void | connect_hard_block_and_alias (ast_node_t *module_instance, char *instance_name_prefix) |
void | connect_module_instantiation_and_alias (short PASS, ast_node_t *module_instance, char *instance_name_prefix) |
void | create_symbol_table_for_module (ast_node_t *module_items) |
signal_list_t * | create_gate (ast_node_t *gate, char *instance_name_prefix) |
signal_list_t * | create_hard_block (ast_node_t *block, char *instance_name_prefix) |
signal_list_t * | create_pins (ast_node_t *var_declare, char *name, char *instance_name_prefix) |
signal_list_t * | create_output_pin (ast_node_t *var_declare, char *instance_name_prefix) |
signal_list_t * | assignment_alias (ast_node_t *assignment, char *instance_name_prefix) |
signal_list_t * | create_operation_node (ast_node_t *op, signal_list_t **input_lists, int list_size, char *instance_name_prefix) |
void | terminate_continuous_assignment (ast_node_t *node, signal_list_t *assignment, char *instance_name_prefix) |
void | terminate_registered_assignment (ast_node_t *always_node, signal_list_t *assignment, signal_list_t *potential_clocks, char *instance_name_prefix) |
signal_list_t * | create_case (ast_node_t *case_ast, char *instance_name_prefix) |
void | create_case_control_signals (ast_node_t *case_list_of_items, ast_node_t *compare_against, nnode_t *case_node, char *instance_name_prefix) |
signal_list_t * | create_case_mux_statements (ast_node_t *case_list_of_items, nnode_t *case_node, char *instance_name_prefix) |
signal_list_t * | create_if (ast_node_t *if_ast, char *instance_name_prefix) |
void | create_if_control_signals (ast_node_t *if_expression, nnode_t *if_node, char *instance_name_prefix) |
signal_list_t * | create_if_mux_statements (ast_node_t *if_ast, nnode_t *if_node, char *instance_name_prefix) |
signal_list_t * | create_if_for_question (ast_node_t *if_ast, char *instance_name_prefix) |
signal_list_t * | create_if_question_mux_expressions (ast_node_t *if_ast, nnode_t *if_node, char *instance_name_prefix) |
signal_list_t * | create_mux_statements (signal_list_t **statement_lists, nnode_t *case_node, int num_statement_lists, char *instance_name_prefix) |
signal_list_t * | create_mux_expressions (signal_list_t **expression_lists, nnode_t *mux_node, int num_expression_lists, char *instance_name_prefix) |
signal_list_t * | evaluate_sensitivity_list (ast_node_t *delay_control, char *instance_name_prefix) |
int | alias_output_assign_pins_to_inputs (char_list_t *output_list, signal_list_t *input_list, ast_node_t *node) |
int | find_smallest_non_numerical (ast_node_t *node, signal_list_t **input_list, int num_input_lists) |
void | pad_with_zeros (ast_node_t *node, signal_list_t *list, int pad_size, char *instance_name_prefix) |
void | look_for_clocks (netlist_t *netlist) |
void | create_netlist () |
Variables | |
STRING_CACHE * | output_nets_sc |
STRING_CACHE * | input_nets_sc |
STRING_CACHE * | local_symbol_table_sc |
ast_node_t ** | local_symbol_table |
int | num_local_symbol_table |
signal_list_t * | local_clock_list |
short | local_clock_found |
int | local_clock_idx |
char * | one_string = "ONE_VCC_CNS" |
char * | zero_string = "ZERO_GND_ZERO" |
char * | pad_string = "ZERO_PAD_ZERO" |
ast_node_t * | top_module |
netlist_t * | verilog_netlist |
int | netlist_create_line_number = -2 |
int | type_of_circuit |
#define ALIAS_INPUTS 2 |
Definition at line 50 of file netlist_create_from_ast.c.
#define COMBINATIONAL 1 |
Definition at line 52 of file netlist_create_from_ast.c.
#define INSTANTIATE_DRIVERS 1 |
Definition at line 49 of file netlist_create_from_ast.c.
#define SEQUENTIAL 2 |
Definition at line 53 of file netlist_create_from_ast.c.
int alias_output_assign_pins_to_inputs | ( | char_list_t * | output_list, | |
signal_list_t * | input_list, | |||
ast_node_t * | node | |||
) |
Definition at line 1843 of file netlist_create_from_ast.c.
01844 { 01845 int i; 01846 01847 if (output_list->num_strings >= input_list->signal_list_size) 01848 { 01849 for (i = 0; i < input_list->signal_list_size; i++) 01850 { 01851 input_list->signal_list[i]->name = output_list->strings[i]; 01852 } 01853 for (i = input_list->signal_list_size; i < output_list->num_strings; i++) 01854 { 01855 warning_message(NETLIST_ERROR, node->line_number, node->file_number, "More nets to drive then drivers, padding with ZEROs for driver %s\n", output_list->strings[i]); 01856 add_pin_to_signal_list(input_list, get_a_zero_pin(verilog_netlist)); 01857 input_list->signal_list[i]->name = output_list->strings[i]; 01858 } 01859 01860 return output_list->num_strings; 01861 } 01862 else 01863 { 01864 for (i = 0; i < output_list->num_strings; i++) 01865 { 01866 input_list->signal_list[i]->name = output_list->strings[i]; 01867 } 01868 warning_message(NETLIST_ERROR, node->line_number, node->file_number, "May be a warning: appears that there are more driver pins then nets to drive, sometimes using decimal numbers causes this problem\n"); 01869 return output_list->num_strings; 01870 } 01871 }
signal_list_t * assignment_alias | ( | ast_node_t * | assignment, | |
char * | instance_name_prefix | |||
) |
Definition at line 1643 of file netlist_create_from_ast.c.
01644 { 01645 signal_list_t *in_1; 01646 signal_list_t *return_list; 01647 char_list_t *out_list; 01648 int i; 01649 int output_size; 01650 01651 /* process the signal for the input gate */ 01652 in_1 = netlist_expand_ast_of_module(assignment->children[1], instance_name_prefix); 01653 oassert(in_1 != NULL); 01654 out_list = get_name_of_pins_with_prefix(assignment->children[0], instance_name_prefix); 01655 oassert(out_list != NULL); 01656 oassert(out_list->strings != NULL); 01657 01658 /* aliases the input pin names to the output names */ 01659 output_size = alias_output_assign_pins_to_inputs(out_list, in_1, assignment); 01660 01661 if (output_size < in_1->signal_list_size) 01662 { 01663 return_list = init_signal_list_structure(); 01664 /* need to shrink the output list */ 01665 for (i = 0; i < output_size; i++) 01666 { 01667 add_pin_to_signal_list(return_list, in_1->signal_list[i]); 01668 } 01669 01670 clean_signal_list_structure(in_1); 01671 } 01672 else 01673 { 01674 return_list = in_1; 01675 } 01676 01677 /* clean the name string list since we don't need it anymore */ 01678 free(out_list->strings); 01679 free(out_list); 01680 01681 return return_list; 01682 }
void connect_hard_block_and_alias | ( | ast_node_t * | module_instance, | |
char * | instance_name_prefix | |||
) |
void connect_module_instantiation_and_alias | ( | short | PASS, | |
ast_node_t * | module_instance, | |||
char * | instance_name_prefix | |||
) |
Definition at line 1309 of file netlist_create_from_ast.c.
01310 { 01311 int i, j; 01312 ast_node_t *module_node; 01313 ast_node_t *module_list; 01314 ast_node_t *module_instance_list = module_instance->children[1]->children[1]; // MODULE_INSTANCE->MODULE_INSTANCE_NAME(child[1])->MODULE_CONNECT_LIST(child[1]) 01315 long sc_spot; 01316 long sc_spot_output; 01317 long sc_spot_input_old; 01318 long sc_spot_input_new; 01319 01320 /* lookup the node of the module associated with this instantiated module */ 01321 if ((sc_spot = sc_add_string(module_names_to_idx, module_instance->children[0]->types.identifier)) == -1) 01322 { 01323 error_message(NETLIST_ERROR, module_instance->line_number, module_instance->file_number, "Can't find module %s\n", module_instance->children[0]->types.identifier); 01324 } 01325 module_node = (ast_node_t*)module_names_to_idx->data[sc_spot]; 01326 module_list = module_node->children[1]; // MODULE->VAR_DECLARE_LIST(child[1]) 01327 01328 if (module_list->num_children != module_instance_list->num_children) 01329 { 01330 error_message(NETLIST_ERROR, module_instance->line_number, module_instance->file_number, "Module instantiation (%s) and definition don't match in terms of ports\n", module_instance->children[0]->types.identifier); 01331 } 01332 01333 for (i = 0; i < module_list->num_children; i++) 01334 { 01335 int port_size; 01336 ast_node_t *module_var_node = module_list->children[i]->children[0]; // VAR_DECLARE_LIST(child[i])->VAR_DECLARE_PORT(child[0])->VAR_DECLARE_input-or-output(child[0]) 01337 ast_node_t *module_instance_var_node = module_instance_list->children[i]->children[1]; // MODULE_CONNECT_LIST(child[i])->MODULE_CONNECT(child[1]) // child[0] is for aliasing 01338 01339 if ( 01340 ((PASS == INSTANTIATE_DRIVERS) && (module_list->children[i]->children[0]->types.variable.is_input)) // skip inputs on pass 1 01341 || 01342 ((PASS == ALIAS_INPUTS) && (module_list->children[i]->children[0]->types.variable.is_output)) // skip outputs on pass 2 01343 ) 01344 { 01345 continue; 01346 } 01347 01348 /* calculate the port details */ 01349 if (module_var_node->children[1] == NULL) 01350 { 01351 port_size = 1; 01352 } 01353 else if (module_var_node->children[3] == NULL) 01354 { 01355 /* assume all arrays declared [largest:smallest] */ 01356 oassert(module_var_node->children[2]->types.number.value <= module_var_node->children[1]->types.number.value); 01357 port_size = module_var_node->children[1]->types.number.value - module_var_node->children[2]->types.number.value +1; 01358 } 01359 else if (module_var_node->children[3] != NULL) 01360 { 01361 /* MEMORY output */ 01362 oassert(FALSE); 01363 } 01364 01365 for (j = 0; j < port_size; j++) 01366 { 01367 if (module_list->children[i]->children[0]->types.variable.is_input) 01368 { 01369 /* IF - this spot in the module list is an input, then we need to find it in the string cache (as its old name), check if the new_name (the instantiation name) 01370 * is already a driver at this level. IF it is a driver then we can hook the two up. IF it's not we need to alias the pin name as it is used here since it 01371 * must be driven at a higher level of hierarchy in the tree of modules */ 01372 char *name_of_module_instance_of_input; 01373 char *full_name; 01374 char *alias_name; 01375 01376 if (port_size > 1) 01377 { 01378 /* Get the name of the module instantiation pin */ 01379 name_of_module_instance_of_input = get_name_of_pin_at_bit(module_instance_var_node, j); 01380 full_name = make_full_ref_name(instance_name_prefix, NULL, NULL, name_of_module_instance_of_input, -1); 01381 free(name_of_module_instance_of_input); 01382 01383 /* make the new string for the alias name - has to be a identifier in the instantiated modules old names */ 01384 name_of_module_instance_of_input = get_name_of_var_declare_at_bit(module_list->children[i]->children[0], j); 01385 alias_name = make_full_ref_name(instance_name_prefix, module_instance->children[0]->types.identifier, module_instance->children[1]->children[0]->types.identifier, name_of_module_instance_of_input, -1); 01386 free(name_of_module_instance_of_input); 01387 } 01388 else 01389 { 01390 oassert(j == 0); 01391 01392 /* Get the name of the module instantiation pin */ 01393 name_of_module_instance_of_input = get_name_of_pin_at_bit(module_instance_var_node, -1); 01394 full_name = make_full_ref_name(instance_name_prefix, NULL, NULL, name_of_module_instance_of_input, -1); 01395 free(name_of_module_instance_of_input); 01396 01397 name_of_module_instance_of_input = get_name_of_var_declare_at_bit(module_list->children[i]->children[0], 0); 01398 alias_name = make_full_ref_name(instance_name_prefix, module_instance->children[0]->types.identifier, module_instance->children[1]->children[0]->types.identifier, name_of_module_instance_of_input, -1); 01399 free(name_of_module_instance_of_input); 01400 } 01401 01402 /* search for the old_input name */ 01403 if ((sc_spot_input_old = sc_lookup_string(input_nets_sc, alias_name)) == -1) 01404 { 01405 /* doesn it have to exist since might only be used in module */ 01406 error_message(NETLIST_ERROR, module_instance->line_number, module_instance->file_number, "This module port %s is unused in module %s", alias_name, module_node->children[0]->types.identifier); 01407 } 01408 01409 /* check if the instantiation pin exists. */ 01410 if ((sc_spot_output = sc_lookup_string(output_nets_sc, full_name)) == -1) 01411 { 01412 /* IF - no driver, then assume that it needs to be aliased to move up as an input */ 01413 if ((sc_spot_input_new = sc_lookup_string(input_nets_sc, full_name)) == -1) 01414 { 01415 /* if this input is not yet used in this module then we'll add it */ 01416 sc_spot_input_new = sc_add_string(input_nets_sc, full_name); 01417 01418 /* copy the pin to the old spot */ 01419 input_nets_sc->data[sc_spot_input_new] = input_nets_sc->data[sc_spot_input_old]; 01420 } 01421 else 01422 { 01423 /* already exists so we'll join the nets */ 01424 combine_nets((nnet_t*)input_nets_sc->data[sc_spot_input_old], (nnet_t*)input_nets_sc->data[sc_spot_input_new], verilog_netlist); 01425 } 01426 } 01427 else 01428 { 01429 /* ELSE - we've found a matching net, so add this pin to the net */ 01430 nnet_t* net = (nnet_t*)output_nets_sc->data[sc_spot_output]; 01431 nnet_t* in_net = (nnet_t*)input_nets_sc->data[sc_spot_input_old]; 01432 01433 if ((net != in_net) && (net->combined == TRUE)) 01434 { 01435 /* if they haven't been combined already, then join the inputs and output */ 01436 join_nets(net, in_net); 01437 /* since the driver net is deleted, copy the spot of the in_net over */ 01438 input_nets_sc->data[sc_spot_input_old] = (void*)net; 01439 } 01440 else if ((net != in_net) && (net->combined == FALSE)) 01441 { 01442 /* if they haven't been combined already, then join the inputs and output */ 01443 combine_nets(net, in_net, verilog_netlist); 01444 /* since the driver net is deleted, copy the spot of the in_net over */ 01445 output_nets_sc->data[sc_spot_output] = (void*)in_net; 01446 } 01447 } 01448 01449 /* IF the designer uses port names then make sure they line up */ 01450 if (module_instance_list->children[i]->children[0] != NULL) 01451 { 01452 if (strcmp(module_instance_list->children[i]->children[0]->types.identifier, module_list->children[i]->children[0]->children[0]->types.identifier) != 0) 01453 { 01454 error_message(NETLIST_ERROR, module_list->children[i]->children[0]->line_number, module_list->children[i]->children[0]->file_number, "This module entry does not match up correctly (%s != %s). Odin expects the order of ports to be the same\n", module_instance_list->children[i]->children[0]->types.identifier, module_list->children[i]->children[0]->children[0]->types.identifier); 01455 } 01456 } 01457 01458 free(full_name); 01459 free(alias_name); 01460 } 01461 else if (module_list->children[i]->children[0]->types.variable.is_output) 01462 { 01463 /* ELSE IF - this is an output pin from the module. We need to alias this output pin with it's calling name here so that everyone can see it at this level */ 01464 char *name_of_module_instance_of_input; 01465 char *full_name; 01466 char *alias_name; 01467 01468 /* make the new string for the alias name - has to be a identifier in the instantiated modules old names */ 01469 if (port_size > 1) 01470 { 01471 /* Get the name of the module instantiation pin */ 01472 name_of_module_instance_of_input = get_name_of_pin_at_bit(module_instance_var_node, j); 01473 full_name = make_full_ref_name(instance_name_prefix, NULL, NULL, name_of_module_instance_of_input, -1); 01474 free(name_of_module_instance_of_input); 01475 01476 name_of_module_instance_of_input = get_name_of_var_declare_at_bit(module_list->children[i]->children[0], j); 01477 alias_name = make_full_ref_name(instance_name_prefix, module_instance->children[0]->types.identifier, module_instance->children[1]->children[0]->types.identifier, name_of_module_instance_of_input, -1); 01478 free(name_of_module_instance_of_input); 01479 } 01480 else 01481 { 01482 oassert(j == 0); 01483 /* Get the name of the module instantiation pin */ 01484 name_of_module_instance_of_input = get_name_of_pin_at_bit(module_instance_var_node, -1); 01485 full_name = make_full_ref_name(instance_name_prefix, NULL, NULL, name_of_module_instance_of_input, -1); 01486 free(name_of_module_instance_of_input); 01487 01488 name_of_module_instance_of_input = get_name_of_var_declare_at_bit(module_list->children[i]->children[0], 0); 01489 alias_name = make_full_ref_name(instance_name_prefix, module_instance->children[0]->types.identifier, module_instance->children[1]->children[0]->types.identifier, name_of_module_instance_of_input, -1); 01490 free(name_of_module_instance_of_input); 01491 } 01492 01493 /* check if the instantiation pin exists. */ 01494 if ((sc_spot_output = sc_lookup_string(output_nets_sc, alias_name)) == -1) 01495 { 01496 error_message(NETLIST_ERROR, module_list->children[i]->children[0]->line_number, module_list->children[i]->children[0]->file_number, "This output (%s) must exist...must be an error\n", alias_name); 01497 } 01498 01499 /* can already be there */ 01500 sc_spot_input_new = sc_add_string(output_nets_sc, full_name); 01501 01502 /* add this alias for the net */ 01503 output_nets_sc->data[sc_spot_input_new] = output_nets_sc->data[sc_spot_output]; 01504 01505 /* IF the designer users port names then make sure they line up */ 01506 if (module_instance_list->children[i]->children[0] != NULL) 01507 { 01508 if (strcmp(module_instance_list->children[i]->children[0]->types.identifier, module_list->children[i]->children[0]->children[0]->types.identifier) != 0) 01509 { 01510 error_message(NETLIST_ERROR, module_list->children[i]->children[0]->line_number, module_list->children[i]->children[0]->file_number, "This module entry does not match up correctly (%s != %s). Odin expects the order of ports to be the same\n", module_instance_list->children[i]->children[0]->types.identifier, module_list->children[i]->children[0]->children[0]->types.identifier); 01511 } 01512 } 01513 01514 free(full_name); 01515 free(alias_name); 01516 } 01517 } 01518 } 01519 }
void convert_ast_to_netlist_recursing_via_modules | ( | ast_node_t * | current_module, | |
char * | instance_name, | |||
int | level | |||
) |
Definition at line 236 of file netlist_create_from_ast.c.
00237 { 00238 int i; 00239 long sc_spot; 00240 signal_list_t *list = NULL; 00241 00242 /* BASE CASE is when there are no other instantiations of modules in this module */ 00243 if (current_module->types.module.size_module_instantiations == 0) 00244 { 00245 list = netlist_expand_ast_of_module(current_module, instance_name); 00246 } 00247 else 00248 { 00249 /* ELSE - we need to visit all the children before */ 00250 for (i = 0; i < current_module->types.module.size_module_instantiations; i++) 00251 { 00252 char *temp_instance_name; 00253 /* make the stringed up module instance name - instance name is MODULE_INSTANCE->MODULE_NAMED_INSTANCE(child[1])->IDENTIFIER(child[0]). module name is MODULE_INSTANCE->IDENTIFIER(child[0]) */ 00254 temp_instance_name = make_full_ref_name(instance_name, current_module->types.module.module_instantiations_instance[i]->children[0]->types.identifier, current_module->types.module.module_instantiations_instance[i]->children[1]->children[0]->types.identifier, NULL, -1); 00255 00256 /* lookup the name of the module associated with this instantiated point */ 00257 if ((sc_spot = sc_lookup_string(module_names_to_idx, current_module->types.module.module_instantiations_instance[i]->children[0]->types.identifier)) == -1) 00258 { 00259 error_message(NETLIST_ERROR, current_module->line_number, current_module->file_number, "Can't find module name %s\n", current_module->types.module.module_instantiations_instance[i]->children[0]->types.identifier); 00260 } 00261 00262 /* recursive call point */ 00263 convert_ast_to_netlist_recursing_via_modules(((ast_node_t*)module_names_to_idx->data[sc_spot]), temp_instance_name, level+1); 00264 00265 /* free the string */ 00266 free(temp_instance_name); 00267 } 00268 00269 /* once we've done everyone lower, we can do this module */ 00270 netlist_expand_ast_of_module(current_module, instance_name); 00271 } 00272 00273 if (list != NULL) 00274 clean_signal_list_structure(list); 00275 }
void create_all_driver_nets_in_this_module | ( | char * | instance_name_prefix | ) |
Definition at line 532 of file netlist_create_from_ast.c.
00533 { 00534 /* with the top module we need to visit the entire ast tree */ 00535 int i; 00536 00537 /* use the symbol table to decide if driver */ 00538 for (i = 0; i < num_local_symbol_table; i++) 00539 { 00540 oassert(local_symbol_table[i]->type == VAR_DECLARE); 00541 if ( (local_symbol_table[i]->types.variable.is_reg) /* all registers are drivers */ 00542 || 00543 ((local_symbol_table[i]->types.variable.is_wire) && (local_symbol_table[i]->types.variable.is_input == FALSE)) /* a wire that is an input can be a driver */ 00544 || 00545 ((local_symbol_table[i]->types.variable.is_output) && (local_symbol_table[i]->types.variable.is_reg == FALSE) && (local_symbol_table[i]->types.variable.is_wire == FALSE)) /* any output that has nothing else is an implied wire driver */ 00546 ) 00547 { 00548 /* create nets based on this driver as the name */ 00549 define_nets_with_driver(local_symbol_table[i], instance_name_prefix); 00550 } 00551 00552 } 00553 }
signal_list_t * create_case | ( | ast_node_t * | case_ast, | |
char * | instance_name_prefix | |||
) |
Definition at line 2383 of file netlist_create_from_ast.c.
02384 { 02385 signal_list_t *return_list; 02386 nnode_t *case_node; 02387 ast_node_t *case_list_of_items; 02388 ast_node_t *case_match_input; 02389 02390 /* create the node */ 02391 case_node = allocate_nnode(); 02392 /* store all the relevant info */ 02393 case_node->related_ast_node = case_ast; 02394 case_node->type = MULTI_PORT_MUX; // port 1 = control, port 2+ = mux options 02395 case_node->name = node_name(case_node, instance_name_prefix); 02396 02397 /* pull out the identifier to match to "i.e. case(a_in)" - this is the pins we match against */ 02398 case_match_input = case_ast->children[0]; 02399 02400 /* point to the case list */ 02401 case_list_of_items = case_ast->children[1]; 02402 02403 /* create all the control structures for the case mux ... each bit will turn on one of the paths ... one hot mux */ 02404 create_case_control_signals(case_list_of_items, case_match_input, case_node, instance_name_prefix); 02405 02406 /* create the statements and integrate them into the mux */ 02407 return_list = create_case_mux_statements(case_list_of_items, case_node, instance_name_prefix); 02408 02409 return return_list; 02410 }
void create_case_control_signals | ( | ast_node_t * | case_list_of_items, | |
ast_node_t * | compare_against, | |||
nnode_t * | case_node, | |||
char * | instance_name_prefix | |||
) |
Definition at line 2415 of file netlist_create_from_ast.c.
02416 { 02417 int i; 02418 signal_list_t *other_expressions_pin_list = init_signal_list_structure(); 02419 02420 /* reserve the first X pins of the mux for the control signals where X is the number of items */ 02421 allocate_more_node_input_pins(case_node, case_list_of_items->num_children); 02422 /* record this port size */ 02423 add_input_port_information(case_node, case_list_of_items->num_children); 02424 02425 /* now go through each of the case items and build the comparison expressions */ 02426 for (i = 0; i < case_list_of_items->num_children; i++) 02427 { 02428 if (case_list_of_items->children[i]->type == CASE_ITEM) 02429 { 02430 /* IF - this is a normal case item, then process the case match and the details of the statement */ 02431 signal_list_t *case_compare_expression; 02432 signal_list_t **case_compares = (signal_list_t **)malloc(sizeof(signal_list_t*)*2); 02433 ast_node_t *logical_equal = create_node_w_type(BINARY_OPERATION, -1, -1); 02434 logical_equal->types.operation.op = LOGICAL_EQUAL; 02435 02436 /* get the signals to compare against */ 02437 case_compares[0] = netlist_expand_ast_of_module(compare_against, instance_name_prefix); 02438 case_compares[1] = netlist_expand_ast_of_module(case_list_of_items->children[i]->children[0], instance_name_prefix); 02439 02440 /* make a LOGIC_EQUAL gate that collects all the other signals and if they're all off */ 02441 case_compare_expression = create_operation_node(logical_equal, case_compares, 2, instance_name_prefix); 02442 oassert(case_compare_expression->signal_list_size == 1); 02443 02444 /* hookup this pin to the spot in the case_node */ 02445 add_a_input_pin_to_node_spot_idx(case_node, case_compare_expression->signal_list[0], i); 02446 02447 /* copy that output pin to be put into the default */ 02448 add_pin_to_signal_list(other_expressions_pin_list, copy_input_npin(case_compare_expression->signal_list[0])); 02449 02450 /* clean up */ 02451 clean_signal_list_structure(case_compare_expression); 02452 02453 free(case_compares); 02454 } 02455 else if (case_list_of_items->children[i]->type == CASE_DEFAULT) 02456 { 02457 /* take all the other pins from the case expressions and intstall in the condition */ 02458 nnode_t *default_node; 02459 signal_list_t *default_expression; 02460 02461 oassert(i == case_list_of_items->num_children - 1); // has to be at the end 02462 02463 /* make a NOR gate that collects all the other signals and if they're all off */ 02464 default_node = make_1port_logic_gate_with_inputs(LOGICAL_NOR, case_list_of_items->num_children-1, other_expressions_pin_list, case_node, -1); 02465 default_expression = make_output_pins_for_existing_node(default_node, 1); 02466 02467 /* copy that output pin to be put into the default */ 02468 add_a_input_pin_to_node_spot_idx(case_node, default_expression->signal_list[0], i); 02469 } 02470 else 02471 { 02472 oassert(FALSE); 02473 } 02474 } 02475 }
signal_list_t * create_case_mux_statements | ( | ast_node_t * | case_list_of_items, | |
nnode_t * | case_node, | |||
char * | instance_name_prefix | |||
) |
Definition at line 2480 of file netlist_create_from_ast.c.
02481 { 02482 signal_list_t **case_statement; 02483 signal_list_t *return_list; 02484 int i; 02485 02486 /* make storage for statements and expressions */ 02487 case_statement = (signal_list_t**)malloc(sizeof(signal_list_t*)*(case_list_of_items->num_children)); 02488 02489 /* now we will process the statements and add to the other ports */ 02490 for (i = 0; i < case_list_of_items->num_children; i++) 02491 { 02492 if (case_list_of_items->children[i]->type == CASE_ITEM) 02493 { 02494 /* IF - this is a normal case item, then process the case match and the details of the statement */ 02495 case_statement[i] = netlist_expand_ast_of_module(case_list_of_items->children[i]->children[1], instance_name_prefix); 02496 sort_signal_list_alphabetically(case_statement[i]); 02497 } 02498 else if (case_list_of_items->children[i]->type == CASE_DEFAULT) 02499 { 02500 oassert(i == case_list_of_items->num_children - 1); // has to be at the end 02501 case_statement[i] = netlist_expand_ast_of_module(case_list_of_items->children[i]->children[0], instance_name_prefix); 02502 sort_signal_list_alphabetically(case_statement[i]); 02503 } 02504 else 02505 { 02506 oassert(FALSE); 02507 } 02508 } 02509 02510 /* now with all the lists sorted, we do the matching and proper propogation */ 02511 return_list = create_mux_statements(case_statement, case_node, case_list_of_items->num_children, instance_name_prefix); 02512 02513 return return_list; 02514 }
signal_list_t * create_gate | ( | ast_node_t * | gate, | |
char * | instance_name_prefix | |||
) |
Definition at line 1878 of file netlist_create_from_ast.c.
01879 { 01880 signal_list_t *in_1, *in_2, *out_1; 01881 nnode_t *gate_node; 01882 ast_node_t *gate_instance = gate->children[0]; 01883 01884 if (gate_instance->children[3] == NULL) 01885 { 01886 /* IF one input gate */ 01887 01888 /* process the signal for the input gate */ 01889 in_1 = netlist_expand_ast_of_module(gate_instance->children[2], instance_name_prefix); 01890 /* process the signal for the input ga$te */ 01891 out_1 = create_output_pin(gate_instance->children[1], instance_name_prefix); 01892 oassert((in_1 != NULL) && (out_1 != NULL)); 01893 01894 /* create the node */ 01895 gate_node = allocate_nnode(); 01896 /* store all the relevant info */ 01897 gate_node->related_ast_node = gate; 01898 gate_node->type = gate->types.operation.op; 01899 oassert(gate_node->type > 0); 01900 gate_node->name = node_name(gate_node, instance_name_prefix); 01901 /* allocate the pins needed */ 01902 allocate_more_node_input_pins(gate_node, 1); 01903 add_input_port_information(gate_node, 1); 01904 allocate_more_node_output_pins(gate_node, 1); 01905 add_output_port_information(gate_node, 1); 01906 01907 /* hookup the input pins */ 01908 hookup_input_pins_from_signal_list(gate_node, 0, in_1, 0, 1, verilog_netlist); 01909 /* hookup the output pins */ 01910 hookup_output_pins_from_signal_list(gate_node, 0, out_1, 0, 1); 01911 01912 clean_signal_list_structure(in_1); 01913 } 01914 else 01915 { 01916 /* ELSE 2 input gate */ 01917 01918 /* process the signal for the input gate */ 01919 in_1 = netlist_expand_ast_of_module(gate_instance->children[2], instance_name_prefix); 01920 in_2 = netlist_expand_ast_of_module(gate_instance->children[3], instance_name_prefix); 01921 /* process the signal for the input gate */ 01922 out_1 = create_output_pin(gate_instance->children[1], instance_name_prefix); 01923 oassert((in_1 != NULL) && (in_2 != NULL) && (out_1 != NULL)); 01924 01925 /* create the node */ 01926 gate_node = allocate_nnode(); 01927 /* store all the relevant info */ 01928 gate_node->related_ast_node = gate; 01929 gate_node->type = gate->types.operation.op; 01930 oassert(gate_node->type > 0); 01931 01932 gate_node->name = node_name(gate_node, instance_name_prefix); 01933 /* allocate the needed pins */ 01934 allocate_more_node_input_pins(gate_node, 2); 01935 add_input_port_information(gate_node, 1); 01936 add_input_port_information(gate_node, 1); 01937 allocate_more_node_output_pins(gate_node, 1); 01938 add_output_port_information(gate_node, 1); 01939 01940 /* hookup the input pins */ 01941 hookup_input_pins_from_signal_list(gate_node, 0, in_1, 0, 1, verilog_netlist); 01942 hookup_input_pins_from_signal_list(gate_node, 1, in_2, 0, 1, verilog_netlist); 01943 /* hookup the output pins */ 01944 hookup_output_pins_from_signal_list(gate_node, 0, out_1, 0, 1); 01945 01946 clean_signal_list_structure(in_1); 01947 clean_signal_list_structure(in_2); 01948 } 01949 01950 return out_1; 01951 }
signal_list_t* create_hard_block | ( | ast_node_t * | block, | |
char * | instance_name_prefix | |||
) |
signal_list_t * create_if | ( | ast_node_t * | if_ast, | |
char * | instance_name_prefix | |||
) |
Definition at line 2269 of file netlist_create_from_ast.c.
02270 { 02271 signal_list_t *return_list; 02272 nnode_t *if_node; 02273 02274 /* create the node */ 02275 if_node = allocate_nnode(); 02276 /* store all the relevant info */ 02277 if_node->related_ast_node = if_ast; 02278 if_node->type = MULTI_PORT_MUX; // port 1 = control, port 2+ = mux options 02279 if_node->name = node_name(if_node, instance_name_prefix); 02280 02281 /* create the control structure for the if node */ 02282 create_if_control_signals(if_ast->children[0], if_node, instance_name_prefix); 02283 02284 /* create the statements and integrate them into the mux */ 02285 return_list = create_if_mux_statements(if_ast, if_node, instance_name_prefix); 02286 02287 return return_list; 02288 }
void create_if_control_signals | ( | ast_node_t * | if_expression, | |
nnode_t * | if_node, | |||
char * | instance_name_prefix | |||
) |
Definition at line 2293 of file netlist_create_from_ast.c.
02294 { 02295 signal_list_t *if_logic_expression; 02296 signal_list_t *if_logic_expression_final; 02297 nnode_t *not_node; 02298 npin_t *not_pin; 02299 signal_list_t *out_pin_list; 02300 02301 /* reserve the first 2 pins of the mux for the control signals */ 02302 allocate_more_node_input_pins(if_node, 2); 02303 /* record this port size */ 02304 add_input_port_information(if_node, 2); 02305 02306 /* get the logic */ 02307 if_logic_expression = netlist_expand_ast_of_module(if_expression, instance_name_prefix); 02308 oassert(if_logic_expression != NULL); 02309 02310 if(if_logic_expression->signal_list_size != 1) 02311 { 02312 nnode_t *or_gate; 02313 signal_list_t *default_expression; 02314 02315 or_gate = make_1port_logic_gate_with_inputs(LOGICAL_OR, if_logic_expression->signal_list_size, if_logic_expression, if_node, -1); 02316 default_expression = make_output_pins_for_existing_node(or_gate, 1); 02317 02318 /* copy that output pin to be put into the default */ 02319 add_a_input_pin_to_node_spot_idx(if_node, default_expression->signal_list[0], 0); 02320 02321 if_logic_expression_final = default_expression; 02322 } 02323 else 02324 { 02325 /* hookup this pin to the spot in the if_node */ 02326 add_a_input_pin_to_node_spot_idx(if_node, if_logic_expression->signal_list[0], 0); 02327 if_logic_expression_final = if_logic_expression; 02328 } 02329 02330 /* hookup pin again to not gate and then to other spot */ 02331 not_pin = copy_input_npin(if_logic_expression_final->signal_list[0]); 02332 02333 /* make a NOT gate that collects all the other signals and if they're all off */ 02334 not_node = make_not_gate_with_input(not_pin, if_node, -1); 02335 02336 /* get the output pin of the not gate .... also adds a net inbetween and the linking output pin to node and net */ 02337 out_pin_list = make_output_pins_for_existing_node(not_node, 1); 02338 oassert(out_pin_list->signal_list_size == 1); 02339 02340 /* copy that output pin to be put into the default */ 02341 add_a_input_pin_to_node_spot_idx(if_node, out_pin_list->signal_list[0], 1); 02342 02343 clean_signal_list_structure(out_pin_list); 02344 }
signal_list_t * create_if_for_question | ( | ast_node_t * | if_ast, | |
char * | instance_name_prefix | |||
) |
Definition at line 2213 of file netlist_create_from_ast.c.
02214 { 02215 signal_list_t *return_list; 02216 nnode_t *if_node; 02217 02218 /* create the node */ 02219 if_node = allocate_nnode(); 02220 /* store all the relevant info */ 02221 if_node->related_ast_node = if_ast; 02222 if_node->type = MULTI_PORT_MUX; // port 1 = control, port 2+ = mux options 02223 if_node->name = node_name(if_node, instance_name_prefix); 02224 02225 /* create the control structure for the if node */ 02226 create_if_control_signals(if_ast->children[0], if_node, instance_name_prefix); 02227 02228 /* create the statements and integrate them into the mux */ 02229 return_list = create_if_question_mux_expressions(if_ast, if_node, instance_name_prefix); 02230 02231 return return_list; 02232 }
signal_list_t * create_if_mux_statements | ( | ast_node_t * | if_ast, | |
nnode_t * | if_node, | |||
char * | instance_name_prefix | |||
) |
Definition at line 2349 of file netlist_create_from_ast.c.
02350 { 02351 signal_list_t **if_statements; 02352 signal_list_t *return_list; 02353 int i; 02354 02355 /* make storage for statements and expressions */ 02356 if_statements = (signal_list_t**)malloc(sizeof(signal_list_t*)*2); 02357 02358 /* now we will process the statements and add to the other ports */ 02359 for (i = 0; i < 2; i++) 02360 { 02361 if (if_ast->children[i+1] != NULL) // checking to see if statement exists. +1 since first child is control expression 02362 { 02363 /* IF - this is a normal case item, then process the case match and the details of the statement */ 02364 if_statements[i] = netlist_expand_ast_of_module(if_ast->children[i+1], instance_name_prefix); 02365 sort_signal_list_alphabetically(if_statements[i]); 02366 } 02367 else 02368 { 02369 /* ELSE - there is no if/else and we need to make a placeholder since it means there will be implied signals */ 02370 if_statements[i] = init_signal_list_structure(); 02371 } 02372 } 02373 02374 /* now with all the lists sorted, we do the matching and proper propogation */ 02375 return_list = create_mux_statements(if_statements, if_node, 2, instance_name_prefix); 02376 02377 return return_list; 02378 }
signal_list_t * create_if_question_mux_expressions | ( | ast_node_t * | if_ast, | |
nnode_t * | if_node, | |||
char * | instance_name_prefix | |||
) |
Definition at line 2237 of file netlist_create_from_ast.c.
02238 { 02239 signal_list_t **if_expressions; 02240 signal_list_t *return_list; 02241 int i; 02242 02243 /* make storage for statements and expressions */ 02244 if_expressions = (signal_list_t**)malloc(sizeof(signal_list_t*)*2); 02245 02246 /* now we will process the statements and add to the other ports */ 02247 for (i = 0; i < 2; i++) 02248 { 02249 if (if_ast->children[i+1] != NULL) // checking to see if expression exists. +1 since first child is control expression 02250 { 02251 /* IF - this is a normal case item, then process the case match and the details of the statement */ 02252 if_expressions[i] = netlist_expand_ast_of_module(if_ast->children[i+1], instance_name_prefix); 02253 } 02254 else 02255 { 02256 error_message(NETLIST_ERROR, if_ast->line_number, if_ast->file_number, "No such thing as a a = b ? z;\n"); 02257 } 02258 } 02259 02260 /* now with all the lists sorted, we do the matching and proper propogation */ 02261 return_list = create_mux_expressions(if_expressions, if_node, 2, instance_name_prefix); 02262 02263 return return_list; 02264 }
signal_list_t * create_mux_expressions | ( | signal_list_t ** | expression_lists, | |
nnode_t * | mux_node, | |||
int | num_expression_lists, | |||
char * | instance_name_prefix | |||
) |
Definition at line 2617 of file netlist_create_from_ast.c.
02618 { 02619 int i, j; 02620 signal_list_t *return_list = init_signal_list_structure(); 02621 int max_index = -1; 02622 02623 /* find the biggest element */ 02624 for (i = 0; i < num_expression_lists; i++) 02625 { 02626 if (max_index < expression_lists[i]->signal_list_size) 02627 { 02628 max_index = expression_lists[i]->signal_list_size; 02629 } 02630 } 02631 02632 for (i = 0; i < max_index; i++) 02633 { 02634 npin_t *new_pin1; 02635 npin_t *new_pin2; 02636 nnet_t *new_net; 02637 new_pin1 = allocate_npin(); 02638 new_pin2 = allocate_npin(); 02639 new_net = allocate_nnet(); 02640 02641 /* allocate a port the width of all the signals ... one MUX */ 02642 allocate_more_node_input_pins(mux_node, num_expression_lists); 02643 /* record the port information */ 02644 add_input_port_information(mux_node, num_expression_lists); 02645 02646 /* allocate the pins for the ouput port and pass out that pin for higher statements */ 02647 allocate_more_node_output_pins(mux_node, 1); 02648 add_a_output_pin_to_node_spot_idx(mux_node, new_pin1, i); 02649 /* hook up new pin 1 into the new net */ 02650 add_a_driver_pin_to_net(new_net, new_pin1); 02651 /* hook up the new pin 2 to this new net */ 02652 add_a_fanout_pin_to_net(new_net, new_pin2); 02653 /* name it with this name */ 02654 new_pin2->name = NULL; 02655 /* add this pin to the return list */ 02656 add_pin_to_signal_list(return_list, new_pin2); 02657 02658 /* going through each of the statement lists looking for common ones and building implied ones if they're not there */ 02659 for (j = 0; j < num_expression_lists; j++) 02660 { 02661 /* check if the current element for this case statement is defined */ 02662 if (i < expression_lists[j]->signal_list_size) 02663 { 02664 /* If there is a signal */ 02665 add_a_input_pin_to_node_spot_idx(mux_node, expression_lists[j]->signal_list[i], (i+1)*num_expression_lists+j); 02666 02667 } 02668 else 02669 { 02670 /* Don't match, so this signal is an IMPLIED SIGNAL !!! */ 02671 02672 /* implied signal for mux */ 02673 /* DON'T CARE - so hookup zero */ 02674 add_a_input_pin_to_node_spot_idx(mux_node, get_a_zero_pin(verilog_netlist), (i+1)*num_expression_lists+j); 02675 } 02676 } 02677 } 02678 02679 /* clean up */ 02680 for (i = 0; i < num_expression_lists; i++) 02681 { 02682 clean_signal_list_structure(expression_lists[i]); 02683 } 02684 02685 return return_list; 02686 }
signal_list_t * create_mux_statements | ( | signal_list_t ** | statement_lists, | |
nnode_t * | case_node, | |||
int | num_statement_lists, | |||
char * | instance_name_prefix | |||
) |
Definition at line 2519 of file netlist_create_from_ast.c.
02520 { 02521 int i, j; 02522 signal_list_t *combined_lists; 02523 int *per_case_statement_idx; 02524 signal_list_t *return_list = init_signal_list_structure(); 02525 int in_index = 1; 02526 int out_index = 0; 02527 02528 /* allocate and initialize indexes */ 02529 per_case_statement_idx = (int*)calloc(sizeof(int), num_statement_lists); 02530 02531 /* make the uber list and sort it */ 02532 combined_lists = combine_lists_without_freeing_originals(statement_lists, num_statement_lists); 02533 sort_signal_list_alphabetically(combined_lists); 02534 02535 for (i = 0; i < combined_lists->signal_list_size; i++) 02536 { 02537 int i_skip = 0; // iskip is the number of statemnts that do have this signal so we can skip in the combine list 02538 npin_t *new_pin1; 02539 npin_t *new_pin2; 02540 nnet_t *new_net; 02541 new_pin1 = allocate_npin(); 02542 new_pin2 = allocate_npin(); 02543 new_net = allocate_nnet(); 02544 02545 /* allocate a port the width of all the signals ... one MUX */ 02546 allocate_more_node_input_pins(mux_node, num_statement_lists); 02547 /* record the port size */ 02548 add_input_port_information(mux_node, num_statement_lists); 02549 02550 /* allocate the pins for the ouput port and pass out that pin for higher statements */ 02551 allocate_more_node_output_pins(mux_node, 1); 02552 add_a_output_pin_to_node_spot_idx(mux_node, new_pin1, out_index); 02553 /* hook up new pin 1 into the new net */ 02554 add_a_driver_pin_to_net(new_net, new_pin1); 02555 /* hook up the new pin 2 to this new net */ 02556 add_a_fanout_pin_to_net(new_net, new_pin2); 02557 /* name it with this name */ 02558 new_pin2->name = combined_lists->signal_list[i]->name; 02559 /* add this pin to the return list */ 02560 add_pin_to_signal_list(return_list, new_pin2); 02561 02562 /* going through each of the statement lists looking for common ones and building implied ones if they're not there */ 02563 for (j = 0; j < num_statement_lists; j++) 02564 { 02565 /* check if the current element for this case statement is defined */ 02566 if ((per_case_statement_idx[j] < statement_lists[j]->signal_list_size) && (strcmp(combined_lists->signal_list[i]->name, statement_lists[j]->signal_list[per_case_statement_idx[j]]->name) == 0)) 02567 { 02568 /* If they match then we have a signal with this name and we can attach the pin */ 02569 add_a_input_pin_to_node_spot_idx(mux_node, statement_lists[j]->signal_list[per_case_statement_idx[j]], in_index*num_statement_lists+j); 02570 02571 per_case_statement_idx[j]++; // increment the local index 02572 i_skip ++; // it's a match so the combo list will have atleast +1 entries the same 02573 } 02574 else 02575 { 02576 /* Don't match, so this signal is an IMPLIED SIGNAL !!! */ 02577 02578 /* implied signal for mux */ 02579 if (type_of_circuit == SEQUENTIAL) 02580 { 02581 /* lookup this driver name */ 02582 signal_list_t *this_pin_list = create_pins(NULL, combined_lists->signal_list[i]->name, instance_name_prefix); 02583 oassert(this_pin_list->signal_list_size == 1); 02584 add_a_input_pin_to_node_spot_idx(mux_node, this_pin_list->signal_list[0], in_index*num_statement_lists+j); 02585 02586 /* clean up */ 02587 clean_signal_list_structure(this_pin_list); 02588 } 02589 else if (type_of_circuit == COMBINATIONAL) 02590 { 02591 /* DON'T CARE - so hookup zero */ 02592 add_a_input_pin_to_node_spot_idx(mux_node, get_a_zero_pin(verilog_netlist), in_index*num_statement_lists+j); 02593 } 02594 else 02595 oassert(FALSE); 02596 } 02597 } 02598 02599 i += i_skip - 1; // for every match move index i forward except this one wihich is handled by for i++ 02600 in_index++; 02601 out_index++; 02602 } 02603 02604 /* clean up */ 02605 for (i = 0; i < num_statement_lists; i++) 02606 { 02607 clean_signal_list_structure(statement_lists[i]); 02608 } 02609 clean_signal_list_structure(combined_lists); 02610 02611 return return_list; 02612 }
void create_netlist | ( | ) |
Definition at line 129 of file netlist_create_from_ast.c.
00130 { 00131 /* just build all the fundamental elements, and then hookup with port definitions...every net has a named net as a variable instance...even modules...the only trick with modules will be instance names. There are a few implied nets as in Muxes for cases, signals for flip-flops and memories */ 00132 00133 /* we will find the top module */ 00134 top_module = find_top_module(); 00135 if (!global_args.output_file) 00136 { 00137 global_args.output_file = malloc(strlen(top_module->children[0]->types.identifier) + 5 + 1); 00138 sprintf(global_args.output_file, "%s.blif", top_module->children[0]->types.identifier); 00139 } 00140 00141 /* Since the modules are in a tree, we will bottom up build the netlist. Essentially, we will go to the leafs of the module tree, build them upwards such that when we search for the nets, we will find them and can hook them up at that point */ 00142 /* PASS 1 - we make all the nets based on registers defined in modules */ 00143 00144 /* initialize the string caches that hold the aliasing of module nets and input pins */ 00145 output_nets_sc = sc_new_string_cache(); 00146 input_nets_sc = sc_new_string_cache(); 00147 /* initialize the storage of the top level drivers. Assigned in create_top_driver_nets */ 00148 verilog_netlist = allocate_netlist(); 00149 00150 /* now recursively parse the modules by going through the tree of modules starting at top */ 00151 create_top_driver_nets(top_module, "top"); 00152 convert_ast_to_netlist_recursing_via_modules(top_module, "top", 0); 00153 create_top_output_nodes(top_module, "top"); 00154 00155 /* now look for high-level signals */ 00156 look_for_clocks(verilog_netlist); 00157 }
signal_list_t * create_operation_node | ( | ast_node_t * | op, | |
signal_list_t ** | input_lists, | |||
int | list_size, | |||
char * | instance_name_prefix | |||
) |
Definition at line 1958 of file netlist_create_from_ast.c.
01959 { 01960 int i; 01961 signal_list_t *return_list = init_signal_list_structure(); 01962 nnode_t *operation_node; 01963 int max_input_port_width = -1; 01964 int output_port_width = -1; 01965 int input_port_width = -1; 01966 int current_idx; 01967 01968 /* create the node */ 01969 operation_node = allocate_nnode(); 01970 /* store all the relevant info */ 01971 operation_node->related_ast_node = op; 01972 operation_node->type = op->types.operation.op; 01973 operation_node->name = node_name(operation_node, instance_name_prefix); 01974 01975 current_idx = 0; 01976 01977 /* analyse the inputs */ 01978 for (i = 0; i < list_size; i++) 01979 { 01980 if (max_input_port_width < input_lists[i]->signal_list_size) 01981 { 01982 max_input_port_width = input_lists[i]->signal_list_size; 01983 } 01984 } 01985 01986 switch(operation_node->type) 01987 { 01988 case BITWISE_NOT: // ~ 01989 /* only one input port */ 01990 output_port_width = max_input_port_width; 01991 input_port_width = output_port_width; 01992 break; 01993 case ADD: // + 01994 /* add the largest bit width + the other input padded with 0's */ 01995 output_port_width = max_input_port_width; 01996 input_port_width = output_port_width; 01997 break; 01998 case MINUS: // - 01999 /* subtract the largest bit width + the other input padded with 0's ... concern for 2's comp */ 02000 output_port_width = max_input_port_width; 02001 input_port_width = output_port_width; 02002 break; 02003 case MULTIPLY: // * 02004 /* pad the smaller one with 0's */ 02005 output_port_width = input_lists[0]->signal_list_size + input_lists[1]->signal_list_size; 02006 input_port_width = -2; 02007 02008 /* Record multiply nodes for netlist optimization */ 02009 mult_list = insert_in_vptr_list(mult_list, operation_node); 02010 break; 02011 case BITWISE_AND: // & 02012 case BITWISE_OR: // | 02013 case BITWISE_NAND: // ~& 02014 case BITWISE_NOR: // ~| 02015 case BITWISE_XNOR: // ~^ 02016 case BITWISE_XOR: // ^ 02017 /* we'll padd the other inputs with 0, do it for the largest and throw a warning */ 02018 if (list_size == 2) 02019 { 02020 output_port_width = max_input_port_width; 02021 input_port_width = output_port_width; 02022 } 02023 else 02024 { 02025 oassert(list_size == 1); 02026 /* Logical reduction - same as a logic function */ 02027 output_port_width = 1; 02028 input_port_width = max_input_port_width; 02029 } 02030 break; 02031 case SR: // >> 02032 case SL: // << 02033 /* Shifts doesn't matter about port size, but second input needs to be a number */ 02034 output_port_width = max_input_port_width; 02035 input_port_width = -2; 02036 break; 02037 case LOGICAL_NOT: // ! 02038 case LOGICAL_OR: // || 02039 case LOGICAL_AND: // && 02040 /* only one input port */ 02041 output_port_width = 1; 02042 input_port_width = max_input_port_width; 02043 break; 02044 case LT: // < 02045 case GT: // > 02046 case LOGICAL_EQUAL: // == 02047 case NOT_EQUAL: // != 02048 case LTE: // <= 02049 case GTE: // >= 02050 { 02051 if (input_lists[0]->signal_list_size != input_lists[1]->signal_list_size) 02052 { 02053 int index_of_smallest = find_smallest_non_numerical(op, input_lists, 2); 02054 02055 input_port_width = input_lists[index_of_smallest]->signal_list_size; 02056 02057 /* pad the input lists */ 02058 pad_with_zeros(op, input_lists[0], input_port_width, instance_name_prefix); 02059 pad_with_zeros(op, input_lists[1], input_port_width, instance_name_prefix); 02060 } 02061 else 02062 { 02063 input_port_width = input_lists[0]->signal_list_size; 02064 } 02065 output_port_width = 1; 02066 break; 02067 } 02068 case DIVIDE: // / 02069 case MODULO: // % 02070 default: 02071 error_message(NETLIST_ERROR, op->line_number, op->file_number, "Operation not supported by Odin\n"); 02072 break; 02073 } 02074 02075 oassert(input_port_width != -1); 02076 oassert(output_port_width != -1); 02077 02078 for (i = 0; i < list_size; i++) 02079 { 02080 if ((operation_node->type == SR) || (operation_node->type == SL)) 02081 { 02082 /* for shift left or right, it's actually a one port operation. Assume the 2nd port is constant */ 02083 if (i == 0) 02084 { 02085 /* allocate the pins needed */ 02086 allocate_more_node_input_pins(operation_node, input_lists[i]->signal_list_size); 02087 /* record this port size */ 02088 add_input_port_information(operation_node, input_lists[i]->signal_list_size); 02089 /* hookup the input pins */ 02090 hookup_input_pins_from_signal_list(operation_node, current_idx, input_lists[i], 0, input_lists[i]->signal_list_size, verilog_netlist); 02091 } 02092 } 02093 else if (input_port_width != -2) 02094 { 02095 /* IF taking port widths based on preset */ 02096 /* allocate the pins needed */ 02097 allocate_more_node_input_pins(operation_node, input_port_width); 02098 /* record this port size */ 02099 add_input_port_information(operation_node, input_port_width); 02100 02101 /* hookup the input pins = will do padding of zeros for smaller port */ 02102 hookup_input_pins_from_signal_list(operation_node, current_idx, input_lists[i], 0, input_port_width, verilog_netlist); 02103 current_idx += input_port_width; 02104 } 02105 else 02106 { 02107 /* ELSE if taking the port widths as they are */ 02108 /* allocate the pins needed */ 02109 allocate_more_node_input_pins(operation_node, input_lists[i]->signal_list_size); 02110 /* record this port size */ 02111 add_input_port_information(operation_node, input_lists[i]->signal_list_size); 02112 02113 /* hookup the input pins */ 02114 hookup_input_pins_from_signal_list(operation_node, current_idx, input_lists[i], 0, input_lists[i]->signal_list_size, verilog_netlist); 02115 02116 current_idx += input_lists[i]->signal_list_size; 02117 } 02118 02119 02120 } 02121 /* allocate the pins for the ouput port */ 02122 allocate_more_node_output_pins(operation_node, output_port_width); 02123 add_output_port_information(operation_node, output_port_width); 02124 02125 /* make the inplicit output list and hook up the outputs */ 02126 for (i = 0; i < output_port_width; i++) 02127 { 02128 npin_t *new_pin1; 02129 npin_t *new_pin2; 02130 nnet_t *new_net; 02131 new_pin1 = allocate_npin(); 02132 new_pin2 = allocate_npin(); 02133 new_net = allocate_nnet(); 02134 new_net->name = operation_node->name; 02135 /* hook the output pin into the node */ 02136 add_a_output_pin_to_node_spot_idx(operation_node, new_pin1, i); 02137 /* hook up new pin 1 into the new net */ 02138 add_a_driver_pin_to_net(new_net, new_pin1); 02139 /* hook up the new pin 2 to this new net */ 02140 add_a_fanout_pin_to_net(new_net, new_pin2); 02141 02142 /* add the new_pin 2 to the list of outputs */ 02143 add_pin_to_signal_list(return_list, new_pin2); 02144 } 02145 02146 for (i = 0; i < list_size; i++) 02147 { 02148 clean_signal_list_structure(input_lists[i]); 02149 } 02150 02151 return return_list; 02152 }
signal_list_t * create_output_pin | ( | ast_node_t * | var_declare, | |
char * | instance_name_prefix | |||
) |
Definition at line 1620 of file netlist_create_from_ast.c.
01621 { 01622 char *name_of_pin; 01623 char *full_name; 01624 signal_list_t *return_sig_list = init_signal_list_structure(); 01625 npin_t *new_pin; 01626 01627 /* get the name of the pin */ 01628 name_of_pin = get_name_of_pin_at_bit(var_declare, -1); 01629 full_name = make_full_ref_name(instance_name_prefix, NULL, NULL, name_of_pin, -1); 01630 free(name_of_pin); 01631 01632 new_pin = allocate_npin(); 01633 new_pin->name = full_name; 01634 01635 add_pin_to_signal_list(return_sig_list, new_pin); 01636 01637 return return_sig_list; 01638 }
signal_list_t * create_pins | ( | ast_node_t * | var_declare, | |
char * | name, | |||
char * | instance_name_prefix | |||
) |
Definition at line 1528 of file netlist_create_from_ast.c.
01529 { 01530 int i; 01531 signal_list_t *return_sig_list = init_signal_list_structure(); 01532 long sc_spot; 01533 long sc_spot_output; 01534 npin_t *new_pin; 01535 nnet_t *new_in_net; 01536 char_list_t *pin_lists; 01537 01538 if (name == NULL) 01539 { 01540 /* get all the pins */ 01541 pin_lists = get_name_of_pins_with_prefix(var_declare, instance_name_prefix); 01542 } 01543 else if (var_declare == NULL) 01544 { 01545 /* if you have the name and just want a pin then use this method */ 01546 pin_lists = (char_list_t*)malloc(sizeof(char_list_t)*1); 01547 pin_lists->strings = (char**)malloc(sizeof(char*)); 01548 pin_lists->strings[0] = name; 01549 pin_lists->num_strings = 1; 01550 } 01551 else 01552 oassert(FALSE); 01553 01554 for (i = 0; i < pin_lists->num_strings; i++) 01555 { 01556 new_pin = allocate_npin(); 01557 new_pin->name = pin_lists->strings[i]; 01558 01559 /* check if the instantiation pin exists. */ 01560 if (strstr(pin_lists->strings[i], "ONE_VCC_CNS") != NULL) 01561 { 01562 add_a_fanout_pin_to_net(verilog_netlist->one_net, new_pin); 01563 sc_spot = sc_add_string(input_nets_sc, pin_lists->strings[i]); 01564 input_nets_sc->data[sc_spot] = (void*)verilog_netlist->one_net; 01565 } 01566 else if (strstr(pin_lists->strings[i], "ZERO_GND_ZERO") != NULL) 01567 { 01568 add_a_fanout_pin_to_net(verilog_netlist->zero_net, new_pin); 01569 sc_spot = sc_add_string(input_nets_sc, pin_lists->strings[i]); 01570 input_nets_sc->data[sc_spot] = (void*)verilog_netlist->zero_net; 01571 } 01572 else 01573 { 01574 /* search for the input name if already exists...needs to be added to string cache in case it's an input pin */ 01575 if ((sc_spot = sc_lookup_string(input_nets_sc, pin_lists->strings[i])) == -1) 01576 { 01577 new_in_net = allocate_nnet(); 01578 01579 sc_spot = sc_add_string(input_nets_sc, pin_lists->strings[i]); 01580 input_nets_sc->data[sc_spot] = (void*)new_in_net; 01581 } 01582 01583 /* store the pin in this net */ 01584 add_a_fanout_pin_to_net((nnet_t*)input_nets_sc->data[sc_spot], new_pin); 01585 01586 if ((sc_spot_output = sc_lookup_string(output_nets_sc, pin_lists->strings[i])) != -1) 01587 { 01588 /* ELSE - we've found a matching net, so add this pin to the net */ 01589 nnet_t* net = (nnet_t*)output_nets_sc->data[sc_spot_output]; 01590 if ((net != (nnet_t*)input_nets_sc->data[sc_spot]) && (net->combined == TRUE)) 01591 { 01592 /* IF - the input and output nets don't match, then they need to be joined */ 01593 join_nets(net, (nnet_t*)input_nets_sc->data[sc_spot]); 01594 /* since the driver net is deleted, copy the spot of the in_net over */ 01595 input_nets_sc->data[sc_spot] = (void*)net; 01596 } 01597 else if ((net != (nnet_t*)input_nets_sc->data[sc_spot]) && (net->combined == FALSE)) 01598 { 01599 /* IF - the input and output nets don't match, then they need to be joined */ 01600 combine_nets(net, (nnet_t*)input_nets_sc->data[sc_spot], verilog_netlist); 01601 /* since the driver net is deleted, copy the spot of the in_net over */ 01602 output_nets_sc->data[sc_spot_output] = (void*)input_nets_sc->data[sc_spot]; 01603 } 01604 } 01605 } 01606 01607 /* add the pin now stored in the string chache to the returned signal list */ 01608 add_pin_to_signal_list(return_sig_list, new_pin); 01609 } 01610 01611 return return_sig_list; 01612 }
void create_symbol_table_for_module | ( | ast_node_t * | module_items | ) |
Definition at line 955 of file netlist_create_from_ast.c.
00956 { 00957 /* with the top module we need to visit the entire ast tree */ 00958 int i, j; 00959 char *temp_string; 00960 long sc_spot; 00961 oassert(module_items->type == MODULE_ITEMS); 00962 00963 /* search for VAR_DECLARE_LISTS */ 00964 if (module_items->num_children > 0) 00965 { 00966 for (i = 0; i < module_items->num_children; i++) 00967 { 00968 if (module_items->children[i]->type == VAR_DECLARE_LIST) 00969 { 00970 /* go through the vars in this declare list */ 00971 for (j = 0; j < module_items->children[i]->num_children; j++) 00972 { 00973 ast_node_t *var_declare = module_items->children[i]->children[j]; 00974 00975 /* parameters are already dealt with */ 00976 if (var_declare->types.variable.is_parameter) 00977 continue; 00978 00979 oassert(module_items->children[i]->children[j]->type == VAR_DECLARE); 00980 oassert( (var_declare->types.variable.is_input) || 00981 (var_declare->types.variable.is_output) || 00982 (var_declare->types.variable.is_reg) || 00983 (var_declare->types.variable.is_wire)); 00984 00985 /* make the string to add to the string cache */ 00986 temp_string = make_full_ref_name(NULL, NULL, NULL, var_declare->children[0]->types.identifier, -1); 00987 /* look for that element */ 00988 sc_spot = sc_add_string(local_symbol_table_sc, temp_string); 00989 if (local_symbol_table_sc->data[sc_spot] != NULL) 00990 { 00991 /* ERROR checks here 00992 * output with reg is fine 00993 * output with wire is fine 00994 * Then update the stored string chache entry with information */ 00995 if ((var_declare->types.variable.is_input) && 00996 ((((ast_node_t*)local_symbol_table_sc->data[sc_spot])->types.variable.is_reg) || (((ast_node_t*)local_symbol_table_sc->data[sc_spot])->types.variable.is_wire))) 00997 { 00998 error_message(NETLIST_ERROR, var_declare->line_number, var_declare->file_number, "Input defined as wire or reg means it is a driver in this module. Not possible\n"); 00999 } 01000 /* MORE ERRORS ... could check for same declaration name ... */ 01001 else if (var_declare->types.variable.is_output) 01002 { 01003 /* copy all the reg and wire info over */ 01004 ((ast_node_t*)local_symbol_table_sc->data[sc_spot])->types.variable.is_output = TRUE; 01005 } 01006 else if ((var_declare->types.variable.is_reg) || (var_declare->types.variable.is_wire)) 01007 { 01008 /* copy the output status over */ 01009 ((ast_node_t*)local_symbol_table_sc->data[sc_spot])->types.variable.is_wire = var_declare->types.variable.is_wire; 01010 ((ast_node_t*)local_symbol_table_sc->data[sc_spot])->types.variable.is_reg = var_declare->types.variable.is_reg; 01011 } 01012 } 01013 else 01014 { 01015 /* store the data which is an idx here */ 01016 local_symbol_table_sc->data[sc_spot] = (void*)var_declare; 01017 01018 /* store the symbol */ 01019 local_symbol_table = (ast_node_t **)realloc(local_symbol_table, sizeof(ast_node_t*)*(num_local_symbol_table+1)); 01020 local_symbol_table[num_local_symbol_table] = var_declare; 01021 num_local_symbol_table ++; 01022 } 01023 free(temp_string); 01024 } 01025 } 01026 } 01027 } 01028 else 01029 { 01030 error_message(NETLIST_ERROR, module_items->line_number, module_items->file_number, "Empty module\n"); 01031 } 01032 }
void create_top_driver_nets | ( | ast_node_t * | module, | |
char * | instance_name_prefix | |||
) |
Definition at line 562 of file netlist_create_from_ast.c.
00563 { 00564 /* with the top module we need to visit the entire ast tree */ 00565 int i, j; 00566 long sc_spot; 00567 ast_node_t *module_items = module->children[2]; 00568 npin_t *new_pin; 00569 00570 oassert(module_items->type == MODULE_ITEMS); 00571 00572 /* search for VAR_DECLARE_LISTS */ 00573 if (module_items->num_children > 0) 00574 { 00575 for (i = 0; i < module_items->num_children; i++) 00576 { 00577 if (module_items->children[i]->type == VAR_DECLARE_LIST) 00578 { 00579 /* go through the vars in this declare list looking for inputs to make drivers */ 00580 for (j = 0; j < module_items->children[i]->num_children; j++) 00581 { 00582 if (module_items->children[i]->children[j]->types.variable.is_input) 00583 { 00584 define_nodes_and_nets_with_driver(module_items->children[i]->children[j], instance_name_prefix); 00585 } 00586 } 00587 } 00588 } 00589 } 00590 else 00591 { 00592 error_message(NETLIST_ERROR, module_items->line_number, module_items->file_number, "Module is empty\n"); 00593 } 00594 00595 /* create the constant nets */ 00596 verilog_netlist->zero_net = allocate_nnet(); 00597 verilog_netlist->gnd_node = allocate_nnode(); 00598 verilog_netlist->gnd_node->type = GND_NODE; 00599 allocate_more_node_output_pins(verilog_netlist->gnd_node, 1); 00600 add_output_port_information(verilog_netlist->gnd_node, 1); 00601 new_pin = allocate_npin(); 00602 add_a_output_pin_to_node_spot_idx(verilog_netlist->gnd_node, new_pin, 0); 00603 add_a_driver_pin_to_net(verilog_netlist->zero_net, new_pin); 00604 00605 verilog_netlist->one_net = allocate_nnet(); 00606 verilog_netlist->vcc_node = allocate_nnode(); 00607 verilog_netlist->vcc_node->type = VCC_NODE; 00608 allocate_more_node_output_pins(verilog_netlist->vcc_node, 1); 00609 add_output_port_information(verilog_netlist->vcc_node, 1); 00610 new_pin = allocate_npin(); 00611 add_a_output_pin_to_node_spot_idx(verilog_netlist->vcc_node, new_pin, 0); 00612 add_a_driver_pin_to_net(verilog_netlist->one_net, new_pin); 00613 00614 verilog_netlist->pad_net = allocate_nnet(); 00615 verilog_netlist->pad_node = allocate_nnode(); 00616 verilog_netlist->pad_node->type = PAD_NODE; 00617 allocate_more_node_output_pins(verilog_netlist->pad_node, 1); 00618 add_output_port_information(verilog_netlist->pad_node, 1); 00619 new_pin = allocate_npin(); 00620 add_a_output_pin_to_node_spot_idx(verilog_netlist->pad_node, new_pin, 0); 00621 add_a_driver_pin_to_net(verilog_netlist->pad_net, new_pin); 00622 00623 /* CREATE the driver for the ZERO */ 00624 zero_string = make_full_ref_name(instance_name_prefix, NULL, NULL, zero_string, -1); 00625 verilog_netlist->gnd_node->name = zero_string; 00626 00627 sc_spot = sc_add_string(output_nets_sc, zero_string); 00628 if (output_nets_sc->data[sc_spot] != NULL) 00629 { 00630 error_message(NETLIST_ERROR, module_items->line_number, module_items->file_number, "Error in Odin\n"); 00631 } 00632 /* store the data which is an idx here */ 00633 output_nets_sc->data[sc_spot] = (void*)verilog_netlist->zero_net; 00634 verilog_netlist->zero_net->name = zero_string; 00635 00636 /* CREATE the driver for the ONE and store twice */ 00637 one_string = make_full_ref_name(instance_name_prefix, NULL, NULL, one_string, -1); 00638 verilog_netlist->vcc_node->name = one_string; 00639 00640 sc_spot = sc_add_string(output_nets_sc, one_string); 00641 if (output_nets_sc->data[sc_spot] != NULL) 00642 { 00643 error_message(NETLIST_ERROR, module_items->line_number, module_items->file_number, "Error in Odin\n"); 00644 } 00645 /* store the data which is an idx here */ 00646 output_nets_sc->data[sc_spot] = (void*)verilog_netlist->one_net; 00647 verilog_netlist->one_net->name = one_string; 00648 00649 /* CREATE the driver for the PAD */ 00650 pad_string = make_full_ref_name(instance_name_prefix, NULL, NULL, pad_string, -1); 00651 verilog_netlist->pad_node->name = pad_string; 00652 00653 sc_spot = sc_add_string(output_nets_sc, pad_string); 00654 if (output_nets_sc->data[sc_spot] != NULL) 00655 { 00656 error_message(NETLIST_ERROR, module_items->line_number, module_items->file_number, "Error in Odin\n"); 00657 } 00658 /* store the data which is an idx here */ 00659 output_nets_sc->data[sc_spot] = (void*)verilog_netlist->pad_net; 00660 verilog_netlist->pad_net->name = pad_string; 00661 }
void create_top_output_nodes | ( | ast_node_t * | module, | |
char * | instance_name_prefix | |||
) |
Definition at line 669 of file netlist_create_from_ast.c.
00670 { 00671 /* with the top module we need to visit the entire ast tree */ 00672 int i, j, k; 00673 long sc_spot; 00674 ast_node_t *module_items = module->children[2]; 00675 nnode_t *new_node; 00676 00677 oassert(module_items->type == MODULE_ITEMS); 00678 00679 /* search for VAR_DECLARE_LISTS */ 00680 if (module_items->num_children > 0) 00681 { 00682 for (i = 0; i < module_items->num_children; i++) 00683 { 00684 if (module_items->children[i]->type == VAR_DECLARE_LIST) 00685 { 00686 /* go through the vars in this declare list */ 00687 for (j = 0; j < module_items->children[i]->num_children; j++) 00688 { 00689 if (module_items->children[i]->children[j]->types.variable.is_output) 00690 { 00691 char *full_name; 00692 ast_node_t *var_declare = module_items->children[i]->children[j]; 00693 npin_t *new_pin; 00694 00695 /* decide what type of variable this is */ 00696 if (var_declare->children[1] == NULL) 00697 { 00698 /* IF - this is a identifier then find it in the output_nets and hook it up to a newly created node */ 00699 /* get the name of the pin */ 00700 full_name = make_full_ref_name(instance_name_prefix, NULL, NULL, var_declare->children[0]->types.identifier, -1); 00701 00702 /* check if the instantiation pin exists. */ 00703 if ((sc_spot = sc_lookup_string(output_nets_sc, full_name)) == -1) 00704 { 00705 error_message(NETLIST_ERROR, var_declare->children[0]->line_number, var_declare->children[0]->file_number, "Output pin (%s) is not hooked up!!!\n", full_name); 00706 } 00707 00708 new_pin = allocate_npin(); 00709 /* hookup this pin to this net */ 00710 add_a_fanout_pin_to_net((nnet_t*)output_nets_sc->data[sc_spot], new_pin); 00711 00712 /* create the node */ 00713 new_node = allocate_nnode(); 00714 new_node->related_ast_node = module_items->children[i]->children[j]; 00715 new_node->name = full_name; 00716 new_node->type = OUTPUT_NODE; 00717 /* allocate the pins needed */ 00718 allocate_more_node_input_pins(new_node, 1); 00719 add_input_port_information(new_node, 1); 00720 00721 /* hookup the pin, and node */ 00722 add_a_input_pin_to_node_spot_idx(new_node, new_pin, 0); 00723 00724 /* record this node */ 00725 verilog_netlist->top_output_nodes = (nnode_t**)realloc(verilog_netlist->top_output_nodes, sizeof(nnode_t*)*(verilog_netlist->num_top_output_nodes+1)); 00726 verilog_netlist->top_output_nodes[verilog_netlist->num_top_output_nodes] = new_node; 00727 verilog_netlist->num_top_output_nodes++; 00728 } 00729 else if (var_declare->children[3] == NULL) 00730 { 00731 /* assume digit 1 is largest */ 00732 for (k = var_declare->children[2]->types.number.value; k <= var_declare->children[1]->types.number.value; k++) 00733 { 00734 /* get the name of the pin */ 00735 full_name = make_full_ref_name(instance_name_prefix, NULL, NULL, var_declare->children[0]->types.identifier, k); 00736 00737 /* check if the instantiation pin exists. */ 00738 if ((sc_spot = sc_lookup_string(output_nets_sc, full_name)) == -1) 00739 { 00740 error_message(NETLIST_ERROR, var_declare->children[0]->line_number, var_declare->children[0]->file_number, "Output pin (%s) is not hooked up!!!\n", full_name); 00741 } 00742 new_pin = allocate_npin(); 00743 /* hookup this pin to this net */ 00744 add_a_fanout_pin_to_net((nnet_t*)output_nets_sc->data[sc_spot], new_pin); 00745 00746 /* create the node */ 00747 new_node = allocate_nnode(); 00748 new_node->related_ast_node = module_items->children[i]->children[j]; 00749 new_node->name = full_name; 00750 new_node->type = OUTPUT_NODE; 00751 /* allocate the pins needed */ 00752 allocate_more_node_input_pins(new_node, 1); 00753 add_input_port_information(new_node, 1); 00754 00755 /* hookup the pin, and node */ 00756 add_a_input_pin_to_node_spot_idx(new_node, new_pin, 0); 00757 00758 /* record this node */ 00759 verilog_netlist->top_output_nodes = (nnode_t**)realloc(verilog_netlist->top_output_nodes, sizeof(nnode_t*)*(verilog_netlist->num_top_output_nodes+1)); 00760 verilog_netlist->top_output_nodes[verilog_netlist->num_top_output_nodes] = new_node; 00761 verilog_netlist->num_top_output_nodes++; 00762 } 00763 } 00764 else 00765 { 00766 /* MEMORY */ 00767 error_message(NETLIST_ERROR, var_declare->children[0]->line_number, var_declare->children[0]->file_number, "Memory not handled ... yet!\n"); 00768 } 00769 } 00770 } 00771 } 00772 } 00773 } 00774 else 00775 { 00776 error_message(NETLIST_ERROR, module_items->line_number, module_items->file_number, "Empty module\n"); 00777 } 00778 }
nnet_t * define_nets_with_driver | ( | ast_node_t * | var_declare, | |
char * | instance_name_prefix | |||
) |
Definition at line 784 of file netlist_create_from_ast.c.
00785 { 00786 int i; 00787 char *temp_string; 00788 long sc_spot; 00789 nnet_t *new_net = NULL; 00790 00791 if (var_declare->children[1] == NULL) 00792 { 00793 /* FOR single driver signal since spots 1, 2, 3, 4 are NULL */ 00794 00795 /* create the net */ 00796 new_net = allocate_nnet(); 00797 00798 /* make the string to add to the string cache */ 00799 temp_string = make_full_ref_name(instance_name_prefix, NULL, NULL, var_declare->children[0]->types.identifier, -1); 00800 00801 /* look for that element */ 00802 sc_spot = sc_add_string(output_nets_sc, temp_string); 00803 if (output_nets_sc->data[sc_spot] != NULL) 00804 { 00805 error_message(NETLIST_ERROR, var_declare->children[0]->line_number, var_declare->children[0]->file_number, "Net (%s) with the same name already created\n", temp_string); 00806 } 00807 /* store the data which is an idx here */ 00808 output_nets_sc->data[sc_spot] = (void*)new_net; 00809 new_net->name = temp_string; 00810 } 00811 else if (var_declare->children[3] == NULL) 00812 { 00813 /* FOR array driver since sport 3 and 4 are NULL */ 00814 oassert((var_declare->children[1]->type == NUMBERS) && (var_declare->children[2]->type == NUMBERS)) ; 00815 00816 /* This register declaration is a range as opposed to a single bit so we need to define each element */ 00817 /* assume digit 1 is largest */ 00818 for (i = var_declare->children[2]->types.number.value; i <= var_declare->children[1]->types.number.value; i++) 00819 { 00820 /* create the net */ 00821 new_net = allocate_nnet(); 00822 00823 /* create the string to add to the cache */ 00824 temp_string = make_full_ref_name(instance_name_prefix, NULL, NULL, var_declare->children[0]->types.identifier, i); 00825 00826 sc_spot = sc_add_string(output_nets_sc, temp_string); 00827 if (output_nets_sc->data[sc_spot] != NULL) 00828 { 00829 error_message(NETLIST_ERROR, var_declare->children[0]->line_number, var_declare->children[0]->file_number, "Net (%s) with the same name already created\n", temp_string); 00830 } 00831 /* store the data which is an idx here */ 00832 output_nets_sc->data[sc_spot] = (void*)new_net; 00833 new_net->name = temp_string; 00834 } 00835 } 00836 else if (var_declare->children[3] != NULL) 00837 { 00838 /* FOR memory */ 00839 oassert(FALSE); 00840 } 00841 00842 return new_net; 00843 }
nnet_t * define_nodes_and_nets_with_driver | ( | ast_node_t * | var_declare, | |
char * | instance_name_prefix | |||
) |
Definition at line 850 of file netlist_create_from_ast.c.
00851 { 00852 int i; 00853 char *temp_string; 00854 long sc_spot; 00855 nnet_t *new_net = NULL; 00856 npin_t *new_pin; 00857 nnode_t *new_node; 00858 00859 if (var_declare->children[1] == NULL) 00860 { 00861 /* FOR single driver signal since spots 1, 2, 3, 4 are NULL */ 00862 00863 /* create the net */ 00864 new_net = allocate_nnet(); 00865 00866 temp_string = make_full_ref_name(instance_name_prefix, NULL, NULL, var_declare->children[0]->types.identifier, -1); 00867 00868 sc_spot = sc_add_string(output_nets_sc, temp_string); 00869 if (output_nets_sc->data[sc_spot] != NULL) 00870 { 00871 error_message(NETLIST_ERROR, var_declare->children[0]->line_number, var_declare->children[0]->file_number, "Net (%s) with the same name already created\n", temp_string); 00872 } 00873 /* store the data which is an idx here */ 00874 output_nets_sc->data[sc_spot] = (void*)new_net; 00875 new_net->name = temp_string; 00876 00877 /* create this node and make the pin connection to the net */ 00878 new_pin = allocate_npin(); 00879 new_node = allocate_nnode(); 00880 new_node->name = temp_string; 00881 00882 new_node->related_ast_node = var_declare; 00883 new_node->type = INPUT_NODE; 00884 /* allocate the pins needed */ 00885 allocate_more_node_output_pins(new_node, 1); 00886 add_output_port_information(new_node, 1); 00887 00888 /* hookup the pin, net, and node */ 00889 add_a_output_pin_to_node_spot_idx(new_node, new_pin, 0); 00890 add_a_driver_pin_to_net(new_net, new_pin); 00891 00892 /* store it in the list of input nodes */ 00893 verilog_netlist->top_input_nodes = (nnode_t**)realloc(verilog_netlist->top_input_nodes, sizeof(nnode_t*)*(verilog_netlist->num_top_input_nodes+1)); 00894 verilog_netlist->top_input_nodes[verilog_netlist->num_top_input_nodes] = new_node; 00895 verilog_netlist->num_top_input_nodes++; 00896 } 00897 else if (var_declare->children[3] == NULL) 00898 { 00899 /* FOR array driver since sport 3 and 4 are NULL */ 00900 oassert((var_declare->children[1]->type == NUMBERS) && (var_declare->children[2]->type == NUMBERS)) ; 00901 00902 /* assume digit 1 is largest */ 00903 for (i = var_declare->children[2]->types.number.value; i <= var_declare->children[1]->types.number.value; i++) 00904 { 00905 /* create the net */ 00906 new_net = allocate_nnet(); 00907 00908 /* FOR single driver signal */ 00909 temp_string = make_full_ref_name(instance_name_prefix, NULL, NULL, var_declare->children[0]->types.identifier, i); 00910 00911 sc_spot = sc_add_string(output_nets_sc, temp_string); 00912 if (output_nets_sc->data[sc_spot] != NULL) 00913 { 00914 error_message(NETLIST_ERROR, var_declare->children[0]->line_number, var_declare->children[0]->file_number, "Net (%s) with the same name already created\n", temp_string); 00915 } 00916 /* store the data which is an idx here */ 00917 output_nets_sc->data[sc_spot] = (void*)new_net; 00918 new_net->name = temp_string; 00919 00920 /* create this node and make the pin connection to the net */ 00921 new_pin = allocate_npin(); 00922 new_node = allocate_nnode(); 00923 00924 new_node->related_ast_node = var_declare; 00925 new_node->name = temp_string; 00926 new_node->type = INPUT_NODE; 00927 /* allocate the pins needed */ 00928 allocate_more_node_output_pins(new_node, 1); 00929 add_output_port_information(new_node, 1); 00930 00931 /* hookup the pin, net, and node */ 00932 add_a_output_pin_to_node_spot_idx(new_node, new_pin, 0); 00933 add_a_driver_pin_to_net(new_net, new_pin); 00934 00935 /* store it in the list of input nodes */ 00936 verilog_netlist->top_input_nodes = (nnode_t**)realloc(verilog_netlist->top_input_nodes, sizeof(nnode_t*)*(verilog_netlist->num_top_input_nodes+1)); 00937 verilog_netlist->top_input_nodes[verilog_netlist->num_top_input_nodes] = new_node; 00938 verilog_netlist->num_top_input_nodes++; 00939 } 00940 } 00941 else if (var_declare->children[3] != NULL) 00942 { 00943 /* FOR memory */ 00944 oassert(FALSE); 00945 } 00946 00947 return new_net; 00948 }
signal_list_t * evaluate_sensitivity_list | ( | ast_node_t * | delay_control, | |
char * | instance_name_prefix | |||
) |
Definition at line 2157 of file netlist_create_from_ast.c.
02158 { 02159 int i; 02160 short edge_type = -1; 02161 signal_list_t *return_sig_list = init_signal_list_structure(); 02162 signal_list_t *temp_list; 02163 02164 oassert(delay_control->type == DELAY_CONTROL); 02165 02166 for (i = 0; i < delay_control->num_children; i++) 02167 { 02168 if ( ((delay_control->children[i]->type == NEGEDGE) || (delay_control->children[i]->type == POSEDGE)) 02169 && 02170 ((edge_type == -1) || (edge_type == SEQUENTIAL))) 02171 { 02172 edge_type = SEQUENTIAL; 02173 02174 temp_list = create_pins(delay_control->children[i]->children[0], NULL, instance_name_prefix); 02175 oassert(temp_list->signal_list_size == 1); 02176 02177 add_pin_to_signal_list(return_sig_list, temp_list->signal_list[0]); 02178 clean_signal_list_structure(temp_list); 02179 } 02180 else if ((edge_type == -1) || (edge_type == COMBINATIONAL)) 02181 { 02182 /* ELSE - a combinational edge and we don't need to do anything */ 02183 edge_type = COMBINATIONAL; 02184 } 02185 else 02186 { 02187 error_message(NETLIST_ERROR, delay_control->line_number, delay_control->file_number, "Sensitivity list switches from sequential and combinational. You can't define somthing like always @(posedgel clock or a).\n"); 02188 } 02189 } 02190 02191 /* update the analysis type of this block of statements */ 02192 if (edge_type == -1) 02193 { 02194 error_message(NETLIST_ERROR, delay_control->line_number, delay_control->file_number, "Sensitivity list error...looks empty?\n"); 02195 } 02196 else if (edge_type == COMBINATIONAL) 02197 { 02198 clean_signal_list_structure(return_sig_list); 02199 return_sig_list = NULL; 02200 type_of_circuit = edge_type; 02201 } 02202 else if (edge_type == SEQUENTIAL) 02203 { 02204 type_of_circuit = edge_type; 02205 } 02206 02207 return return_sig_list; 02208 }
int find_smallest_non_numerical | ( | ast_node_t * | node, | |
signal_list_t ** | input_list, | |||
int | num_input_lists | |||
) |
Definition at line 2691 of file netlist_create_from_ast.c.
02692 { 02693 int i; 02694 int smallest; 02695 int smallest_idx; 02696 short *tested = (short*)calloc(sizeof(short), num_input_lists); 02697 short found_non_numerical = FALSE; 02698 02699 while(found_non_numerical == FALSE) 02700 { 02701 smallest_idx = -1; 02702 smallest = -1; 02703 02704 /* find the smallest width, now verify that it's not a number */ 02705 for (i = 0; i < num_input_lists; i++) 02706 { 02707 if (tested[i] == 1) 02708 { 02709 /* skip the ones we've already tried */ 02710 continue; 02711 } 02712 if ((smallest == -1) || (smallest >= input_list[i]->signal_list_size)) 02713 { 02714 smallest = input_list[i]->signal_list_size; 02715 smallest_idx = i; 02716 } 02717 } 02718 02719 if (smallest_idx == -1) 02720 { 02721 error_message(NETLIST_ERROR, node->line_number, node->file_number, "all numbers in padding non numericals\n"); 02722 } 02723 else 02724 { 02725 /* mark that we're evaluating this input */ 02726 tested[smallest_idx] = TRUE; 02727 02728 /* check if the smallest is not a number */ 02729 for (i = 0; i < input_list[smallest_idx]->signal_list_size; i++) 02730 { 02731 if (input_list[smallest_idx]->signal_list[i]->name == NULL) 02732 { 02733 /* Not a number so this is the smallest */ 02734 found_non_numerical = TRUE; 02735 break; 02736 } 02737 if (!((strstr(input_list[smallest_idx]->signal_list[i]->name, "ONE_VCC_CNS") != NULL) || strstr(input_list[smallest_idx]->signal_list[i]->name, "ZERO_GND_ZERO") != NULL)) 02738 { 02739 /* Not a number so this is the smallest */ 02740 found_non_numerical = TRUE; 02741 break; 02742 } 02743 } 02744 } 02745 } 02746 02747 return smallest_idx; 02748 }
ast_node_t * find_top_module | ( | ) |
Definition at line 180 of file netlist_create_from_ast.c.
00181 { 00182 int i, j; 00183 long sc_spot; 00184 int found_top = -1; 00185 00186 /* go through all the instantiations for each module and mark them if they've be instantiated */ 00187 for (i = 0; i < num_modules; i++) 00188 { 00189 for (j = 0; j < ast_modules[i]->types.module.size_module_instantiations; j++) 00190 { 00191 /* Check to see if the module is a hard block - a hard block is 00192 never the top level! */ 00193 #ifdef VPR6 00194 if ((sc_spot = sc_lookup_string(hard_block_names, ast_modules[i]->types.module.module_instantiations_instance[j]->children[0]->types.identifier)) == -1) 00195 #endif 00196 { 00197 /* get the module index from the string cache */ 00198 if ((sc_spot = sc_lookup_string(module_names_to_idx, ast_modules[i]->types.module.module_instantiations_instance[j]->children[0]->types.identifier)) == -1) 00199 { 00200 error_message(NETLIST_ERROR, ast_modules[i]->line_number, ast_modules[i]->file_number, "Can't find module name (%s)\n", ast_modules[i]->types.module.module_instantiations_instance[j]->types.identifier); 00201 } 00202 00203 /* use that number to mark this module as instantiated */ 00204 ast_modules[((ast_node_t*)module_names_to_idx->data[sc_spot])->types.module.index]->types.module.is_instantiated = TRUE; 00205 } 00206 } 00207 } 00208 00209 /* now check for which module wasn't marked...this one will be the top */ 00210 for (i = 0; i < num_modules; i++) 00211 { 00212 if ((ast_modules[i]->types.module.is_instantiated == FALSE) && (found_top == -1)) 00213 { 00214 found_top = i; 00215 } 00216 else if ((ast_modules[i]->types.module.is_instantiated == FALSE) && (found_top != -1)) 00217 { 00218 error_message(NETLIST_ERROR, ast_modules[i]->line_number, ast_modules[i]->file_number, "Two top level modules - Odin II cannot deal with these types of designs\n"); 00219 } 00220 } 00221 00222 /* check atleast one module is top ... and only one */ 00223 if (found_top == -1) 00224 { 00225 error_message(NETLIST_ERROR, -1, -1, "Could not find a top level module\n"); 00226 } 00227 00228 return ast_modules[found_top]; 00229 }
void look_for_clocks | ( | netlist_t * | netlist | ) |
Definition at line 162 of file netlist_create_from_ast.c.
00163 { 00164 int i; 00165 00166 for (i = 0; i < netlist->num_ff_nodes; i++) 00167 { 00168 if (netlist->ff_nodes[i]->input_pins[1]->net->driver_pin->node->type != CLOCK_NODE) 00169 { 00170 netlist->ff_nodes[i]->input_pins[1]->net->driver_pin->node->type = CLOCK_NODE; 00171 } 00172 } 00173 }
signal_list_t * netlist_expand_ast_of_module | ( | ast_node_t * | node, | |
char * | instance_name_prefix | |||
) |
Definition at line 283 of file netlist_create_from_ast.c.
00284 { 00285 /* with the top module we need to visit the entire ast tree */ 00286 int i; 00287 short *child_skip_list = NULL; // list of children not to traverse into 00288 short skip_children = FALSE; // skips the DFS completely if TRUE 00289 signal_list_t *return_sig_list = NULL; 00290 signal_list_t **children_signal_list = NULL; 00291 00292 if (node == NULL) 00293 { 00294 /* print out the node and label details */ 00295 } 00296 else 00297 { 00298 /* make a skip list of nodes in the tree we don't need to visit for this node. For example, a module we know that the 0th entry is the identifier of the module */ 00299 if (node->num_children > 0) 00300 { 00301 child_skip_list = (short*)calloc(node->num_children, sizeof(short)); 00302 children_signal_list = (signal_list_t**)malloc(sizeof(signal_list_t*)*node->num_children); 00303 } 00304 00305 /* ------------------------------------------------------------------------------*/ 00306 /* PRE AMBLE */ 00307 switch(node->type) 00308 { 00309 case FILE_ITEMS: 00310 oassert(FALSE); 00311 break; 00312 case MODULE: 00313 /* set the skip list */ 00314 child_skip_list[0] = TRUE; /* skip the identifier */ 00315 child_skip_list[1] = TRUE; /* skip portlist ... we'll use where they're defined */ 00316 break; 00317 case MODULE_ITEMS: 00318 /* items include: wire, reg, input, outputs, assign, gate, module_instance, always */ 00319 00320 /* make the symbol table */ 00321 local_symbol_table_sc = sc_new_string_cache(); 00322 local_symbol_table = NULL; 00323 num_local_symbol_table = 0; 00324 create_symbol_table_for_module(node); 00325 local_clock_found = FALSE; 00326 00327 /* create all the driven nets based on the "reg" registers */ 00328 create_all_driver_nets_in_this_module(instance_name_prefix); 00329 00330 /* process elements in the list */ 00331 if (node->num_children > 0) 00332 { 00333 for (i = 0; i < node->num_children; i++) 00334 { 00335 if (node->children[i]->type == VAR_DECLARE_LIST) 00336 { 00337 /* IF - The port lists of this module are handled else where */ 00338 child_skip_list[i] = TRUE; 00339 } 00340 else if (node->children[i]->type == MODULE_INSTANCE) 00341 { 00342 /* ELSE IF - we deal with instantiations of modules twice to alias input and output nets. In this 00343 * pass we are looking for any drivers emerging from a module */ 00344 00345 /* make the aliases for all the drivers as they're passed through modules */ 00346 connect_module_instantiation_and_alias(INSTANTIATE_DRIVERS, node->children[i], instance_name_prefix); 00347 00348 /* is a call site for another module. Alias names to nets and pins */ 00349 child_skip_list[i] = TRUE; 00350 } 00351 } 00352 } 00353 break; 00354 case GATE: 00355 /* create gate instances */ 00356 return_sig_list = create_gate(node, instance_name_prefix); 00357 /* create_gate does it's own instantiations so skip the children in the traverse */ 00358 skip_children = TRUE; 00359 break; 00360 /* ---------------------- */ 00361 /* All these are input references that we need to grab their pins from by create_pin */ 00362 case ARRAY_REF: 00363 case CONCATENATE: 00364 case IDENTIFIERS: 00365 case RANGE_REF: 00366 case NUMBERS: 00367 { 00368 return_sig_list = create_pins(node, NULL, instance_name_prefix); 00369 /* children are traversed in the create_pin function */ 00370 skip_children = TRUE; 00371 break; 00372 } 00373 /* ---------------------- */ 00374 case ASSIGN: 00375 /* combinational path */ 00376 type_of_circuit = COMBINATIONAL; 00377 break; 00378 case BLOCKING_STATEMENT: 00379 if (type_of_circuit == SEQUENTIAL) 00380 { 00381 error_message(NETLIST_ERROR, node->line_number, node->file_number, "ODIN doesn't handle blocking statements in Sequential blocks\n"); 00382 } 00383 else 00384 { 00385 return_sig_list = assignment_alias(node, instance_name_prefix); 00386 skip_children = TRUE; 00387 } 00388 break; 00389 case NON_BLOCKING_STATEMENT: 00390 if (type_of_circuit != SEQUENTIAL) 00391 { 00392 error_message(NETLIST_ERROR, node->line_number, node->file_number, "ODIN doesn't handle non blocking statements in combinational blocks\n"); 00393 } 00394 return_sig_list = assignment_alias(node, instance_name_prefix); 00395 skip_children = TRUE; 00396 break; 00397 case ALWAYS: 00398 /* evaluate if this is a sensitivity list with posedges/negedges (=SEQUENTIAL) or none (=COMBINATIONAL) */ 00399 local_clock_list = evaluate_sensitivity_list(node->children[0], instance_name_prefix); 00400 child_skip_list[0] = TRUE; 00401 break; 00402 case CASE: 00403 return_sig_list = create_case(node, instance_name_prefix); 00404 skip_children = TRUE; 00405 break; 00406 case IF: 00407 return_sig_list = create_if(node, instance_name_prefix); 00408 skip_children = TRUE; 00409 break; 00410 case IF_Q: 00411 return_sig_list = create_if_for_question(node, instance_name_prefix); 00412 skip_children = TRUE; 00413 break; 00414 #ifdef VPR6 00415 case HARD_BLOCK: 00416 /* set the skip list */ 00417 child_skip_list[0] = TRUE; /* skip the identifier */ 00418 child_skip_list[1] = TRUE; /* skip portlist ... we'll use where they're defined */ 00419 return_sig_list = create_hard_block(node, instance_name_prefix); 00420 break; 00421 #endif 00422 default: 00423 break; 00424 } 00425 /* ------------------------------------------------------------------------------*/ 00426 /* This is the depth first traverse (DFT aka DFS) of the ast nodes that make up the netlist. */ 00427 if (skip_children == FALSE) 00428 { 00429 /* traverse all the children */ 00430 for (i = 0; i < node->num_children; i++) 00431 { 00432 if (child_skip_list[i] == FALSE) 00433 { 00434 /* recursively call through the tree going to each instance. This is depth first traverse. */ 00435 children_signal_list[i] = netlist_expand_ast_of_module(node->children[i], instance_name_prefix); 00436 } 00437 } 00438 } 00439 00440 /* ------------------------------------------------------------------------------*/ 00441 /* POST AMBLE - process the children */ 00442 switch(node->type) 00443 { 00444 case FILE_ITEMS: 00445 oassert(FALSE); 00446 break; 00447 case MODULE_ITEMS: 00448 { 00449 if (node->num_children > 0) 00450 { 00451 for (i = 0; i < node->num_children; i++) 00452 { 00453 if (node->children[i]->type == MODULE_INSTANCE) 00454 { 00455 /* make the aliases for all the drivers as they're passed through modules. This is the 00456 second time we call this */ 00457 connect_module_instantiation_and_alias(ALIAS_INPUTS, node->children[i], instance_name_prefix); 00458 } 00459 } 00460 } 00461 00462 /* free the symbol table for this module since we're done processing */ 00463 sc_free_string_cache(local_symbol_table_sc); 00464 free(local_symbol_table); 00465 00466 break; 00467 } 00468 case ASSIGN: 00469 oassert(node->num_children == 1); 00470 /* attach the drivers to the driver nets */ 00471 terminate_continuous_assignment(node, children_signal_list[0], instance_name_prefix); 00472 break; 00473 case ALWAYS: 00474 /* attach the drivers to the driver nets */ 00475 if (type_of_circuit == COMBINATIONAL) 00476 { 00477 /* idx 1 element since alwayss has DELAY Control first */ 00478 terminate_continuous_assignment(node, children_signal_list[1], instance_name_prefix); 00479 } 00480 else if (type_of_circuit == SEQUENTIAL) 00481 { 00482 terminate_registered_assignment(node, children_signal_list[1], local_clock_list, instance_name_prefix); 00483 } 00484 else 00485 oassert(FALSE); 00486 break; 00487 case BINARY_OPERATION: 00488 oassert(node->num_children == 2); 00489 return_sig_list = create_operation_node(node, children_signal_list, node->num_children, instance_name_prefix); 00490 break; 00491 case UNARY_OPERATION: 00492 oassert(node->num_children == 1); 00493 return_sig_list = create_operation_node(node, children_signal_list, node->num_children, instance_name_prefix); 00494 break; 00495 case BLOCK: 00496 return_sig_list = combine_lists(children_signal_list, node->num_children); 00497 break; 00498 #ifdef VPR6 00499 case MEMORY: 00500 connect_memory_and_alias(node, instance_name_prefix); 00501 break; 00502 case HARD_BLOCK: 00503 connect_hard_block_and_alias(node, instance_name_prefix); 00504 break; 00505 #endif 00506 case IF: 00507 default: 00508 break; 00509 } 00510 /* ------------------------------------------------------------------------------*/ 00511 } 00512 00513 /* cleaning */ 00514 if (child_skip_list != NULL) 00515 { 00516 free(child_skip_list); 00517 } 00518 if (children_signal_list != NULL) 00519 { 00520 free(children_signal_list); 00521 } 00522 00523 return return_sig_list; 00524 }
void pad_with_zeros | ( | ast_node_t * | node, | |
signal_list_t * | list, | |||
int | pad_size, | |||
char * | instance_name_prefix | |||
) |
Definition at line 2753 of file netlist_create_from_ast.c.
02754 { 02755 int i; 02756 02757 if (pad_size > list->signal_list_size) 02758 { 02759 for (i = list->signal_list_size; i < pad_size; i++) 02760 { 02761 warning_message(NETLIST_ERROR, node->line_number, node->file_number, "padding an input port with 0 for operation (likely compare)\n"); 02762 add_pin_to_signal_list(list, get_a_zero_pin(verilog_netlist)); 02763 } 02764 } 02765 else if (pad_size < list->signal_list_size) 02766 { 02767 warning_message(NETLIST_ERROR, node->line_number, node->file_number, "May be a warning: appears that there are more driver pins then nets to drive. This means that for this operation you are losing some of the most significant bits\n"); 02768 } 02769 }
void terminate_continuous_assignment | ( | ast_node_t * | node, | |
signal_list_t * | assignment, | |||
char * | instance_name_prefix | |||
) |
Definition at line 1787 of file netlist_create_from_ast.c.
01788 { 01789 int i; 01790 long sc_spot; 01791 npin_t *buf_input_pin; 01792 npin_t *buf_output_pin; 01793 01794 for (i = 0; i < assignment->signal_list_size; i++) 01795 { 01796 nnode_t *buf_node; 01797 01798 /* look up the net */ 01799 if ((sc_spot = sc_lookup_string(output_nets_sc, assignment->signal_list[i]->name)) == -1) 01800 { 01801 error_message(NETLIST_ERROR, node->line_number, node->file_number, "Assignment (%s) is missing driver\n", assignment->signal_list[i]->name); 01802 } 01803 01804 /* check if the instantiation pin exists. */ 01805 if (((nnet_t*)output_nets_sc->data[sc_spot])->name == NULL) 01806 { 01807 ((nnet_t*)output_nets_sc->data[sc_spot])->name = assignment->signal_list[i]->name; 01808 } 01809 01810 buf_node = allocate_nnode(); 01811 buf_node->type = BUF_NODE; 01812 /* create the unique name for this gate */ 01813 buf_node->name = node_name(buf_node, instance_name_prefix); 01814 01815 buf_node->related_ast_node = node; 01816 /* allocate the pins needed */ 01817 allocate_more_node_input_pins(buf_node, 1); 01818 add_input_port_information(buf_node, 1); 01819 allocate_more_node_output_pins(buf_node, 1); 01820 add_output_port_information(buf_node, 1); 01821 01822 /* hookup the driver pin (the in_1) to to this net (the lookup) */ 01823 buf_input_pin = assignment->signal_list[i]; 01824 add_a_input_pin_to_node_spot_idx(buf_node, buf_input_pin, 0); 01825 01826 /* finally hookup the output pin of the flip flop to the orginal driver net */ 01827 buf_output_pin = allocate_npin(); 01828 add_a_output_pin_to_node_spot_idx(buf_node, buf_output_pin, 0); 01829 if(((nnet_t*)output_nets_sc->data[sc_spot])->driver_pin != NULL) 01830 { 01831 error_message(NETLIST_ERROR, node->line_number, node->file_number, "You've defined this driver %s twice (i.e. in the statement block you've probably put the statement as a = b; a = c; in some form that's incorrect)\n", assignment->signal_list[i]->name); 01832 } 01833 add_a_driver_pin_to_net((nnet_t*)output_nets_sc->data[sc_spot], buf_output_pin); 01834 } 01835 01836 clean_signal_list_structure(assignment); 01837 }
void terminate_registered_assignment | ( | ast_node_t * | always_node, | |
signal_list_t * | assignment, | |||
signal_list_t * | potential_clocks, | |||
char * | instance_name_prefix | |||
) |
Definition at line 1687 of file netlist_create_from_ast.c.
01688 { 01689 int i; 01690 long sc_spot; 01691 npin_t *ff_input_pin; 01692 npin_t *ff_output_pin; 01693 01694 oassert(potential_clocks != NULL); 01695 01696 /* figure out which one is the clock */ 01697 if (local_clock_found == FALSE) 01698 { 01699 for (i = 0; i < potential_clocks->signal_list_size; i++) 01700 { 01701 nnet_t *temp_net; 01702 /* searching for the clock with no net */ 01703 if ((sc_spot = sc_lookup_string(output_nets_sc, potential_clocks->signal_list[i]->name)) == -1) 01704 { 01705 if ((sc_spot = sc_lookup_string(input_nets_sc, potential_clocks->signal_list[i]->name)) == -1) 01706 { 01707 error_message(NETLIST_ERROR, always_node->line_number, always_node->file_number, "Sensitivity list element (%s) is not a driver or net ... must be\n", potential_clocks->signal_list[i]->name); 01708 } 01709 temp_net = (nnet_t*)input_nets_sc->data[sc_spot]; 01710 } 01711 else 01712 { 01713 temp_net = (nnet_t*)output_nets_sc->data[sc_spot]; 01714 } 01715 01716 01717 if ( 01718 (((temp_net->num_fanout_pins == 1) && (temp_net->fanout_pins[0]->node == NULL)) || (temp_net->num_fanout_pins == 0)) 01719 && (local_clock_found == TRUE)) 01720 { 01721 error_message(NETLIST_ERROR, always_node->line_number, always_node->file_number, "Suspected second clock (%s). In a sequential sensitivity list, Odin expects the clock not to drive anything and any other signals in this list to drive stuff. For example, a reset in the sensitivy list has to be hooked up to something in the always block.\n", potential_clocks->signal_list[i]->name); 01722 } 01723 else if (temp_net->num_fanout_pins == 0) 01724 { 01725 /* If this element is in the sensitivity list and doesn't drive anything it's the clock */ 01726 local_clock_found = TRUE; 01727 local_clock_idx = i; 01728 } 01729 else if ((temp_net->num_fanout_pins == 1) && (temp_net->fanout_pins[0]->node == NULL)) 01730 { 01731 /* If this element is in the sensitivity list and doesn't drive anything it's the clock */ 01732 local_clock_found = TRUE; 01733 local_clock_idx = i; 01734 } 01735 01736 } 01737 } 01738 01739 /* in continuous assign we can hook up the inputs to the driving side of the nets */ 01740 for (i = 0; i < assignment->signal_list_size; i++) 01741 { 01742 nnode_t *ff_node = allocate_nnode(); 01743 /* look up the net */ 01744 if ((sc_spot = sc_lookup_string(output_nets_sc, assignment->signal_list[i]->name)) == -1) 01745 { 01746 error_message(NETLIST_ERROR, always_node->line_number, always_node->file_number, "Assignment is missing driver (%s)\n", assignment->signal_list[i]->name); 01747 } 01748 01749 /* HERE create the ff node and hookup everything */ 01750 ff_node->related_ast_node = always_node; 01751 01752 ff_node->type = FF_NODE; 01753 /* create the unique name for this gate */ 01754 ff_node->name = node_name(ff_node, instance_name_prefix); 01755 /* allocate the pins needed */ 01756 allocate_more_node_input_pins(ff_node, 2); 01757 add_input_port_information(ff_node, 1); 01758 allocate_more_node_output_pins(ff_node, 1); 01759 add_output_port_information(ff_node, 1); 01760 01761 /* add the clock to the flip_flop */ 01762 /* add a fanout pin */ 01763 npin_t *fanout_pin_of_clock = allocate_npin(); 01764 add_a_fanout_pin_to_net(potential_clocks->signal_list[local_clock_idx]->net, fanout_pin_of_clock); 01765 add_a_input_pin_to_node_spot_idx(ff_node, fanout_pin_of_clock, 1); 01766 01767 /* hookup the driver pin (the in_1) to to this net (the lookup) */ 01768 ff_input_pin = assignment->signal_list[i]; 01769 add_a_input_pin_to_node_spot_idx(ff_node, assignment->signal_list[i], 0); 01770 01771 /* finally hookup the output pin of the flip flop to the orginal driver net */ 01772 ff_output_pin = allocate_npin(); 01773 add_a_output_pin_to_node_spot_idx(ff_node, ff_output_pin, 0); 01774 add_a_driver_pin_to_net((nnet_t*)output_nets_sc->data[sc_spot], ff_output_pin); 01775 01776 verilog_netlist->ff_nodes = (nnode_t**)realloc(verilog_netlist->ff_nodes, sizeof(nnode_t*)*(verilog_netlist->num_ff_nodes+1)); 01777 verilog_netlist->ff_nodes[verilog_netlist->num_ff_nodes] = ff_node; 01778 verilog_netlist->num_ff_nodes++; 01779 } 01780 01781 clean_signal_list_structure(assignment); 01782 }
Definition at line 56 of file netlist_create_from_ast.c.
short local_clock_found |
Definition at line 62 of file netlist_create_from_ast.c.
int local_clock_idx |
Definition at line 63 of file netlist_create_from_ast.c.
Definition at line 61 of file netlist_create_from_ast.c.
Definition at line 59 of file netlist_create_from_ast.c.
Definition at line 58 of file netlist_create_from_ast.c.
int netlist_create_line_number = -2 |
Definition at line 74 of file netlist_create_from_ast.c.
Definition at line 60 of file netlist_create_from_ast.c.
char* one_string = "ONE_VCC_CNS" |
Definition at line 66 of file netlist_create_from_ast.c.
Definition at line 55 of file netlist_create_from_ast.c.
char* pad_string = "ZERO_PAD_ZERO" |
Definition at line 68 of file netlist_create_from_ast.c.
Definition at line 70 of file netlist_create_from_ast.c.
int type_of_circuit |
Definition at line 76 of file netlist_create_from_ast.c.
Definition at line 72 of file netlist_create_from_ast.c.
char* zero_string = "ZERO_GND_ZERO" |
Definition at line 67 of file netlist_create_from_ast.c.