/*--------------------------------------------------------------------------------------------- * (function: free_nnode) *-------------------------------------------------------------------------------------------*/ void free_nnode(nnode_t *to_free) { int i; if (to_free != NULL) { /* need to free node_data */ for (i = 0; i < to_free->num_input_pins; i++) { if (to_free->input_pins[i] != NULL) { free_npin(to_free->input_pins[i]); to_free->input_pins[i] = NULL; } } if (to_free->input_pins != NULL) { free(to_free->input_pins); to_free->input_pins = NULL; } for (i = 0; i < to_free->num_output_pins; i++) { if (to_free->output_pins[i] != NULL) { free_npin(to_free->output_pins[i]); to_free->output_pins[i] = NULL; } } if (to_free->output_pins != NULL) { free(to_free->output_pins); to_free->output_pins = NULL; } if (to_free->input_port_sizes != NULL) free(to_free->input_port_sizes); if (to_free->output_port_sizes != NULL) free(to_free->output_port_sizes); if (to_free->undriven_pins) free(to_free->undriven_pins); /* now free the node */ free(to_free); } }
/*------------------------------------------------------------------------- * (function: split_dp_memory_width) * * This function works to split the width of a memory into several smaller * memories. *------------------------------------------------------------------------ */ void split_dp_memory_width(nnode_t *node) { int data_port1, data_port2; int i, j, k, idx, old_idx, data_diff1, data_diff2; nnode_t *new_node; char *tmp_name; oassert(node->type == MEMORY); /* Find which port is the data port on the input! */ idx = 0; data_port1 = -1; data_port2 = -1; data_diff1 = 0; data_diff2 = 0; for (i = 0; i < node->num_input_port_sizes; i++) { if (strcmp("data1", node->input_pins[idx]->mapping) == 0) { data_port1 = i; data_diff1 = node->input_port_sizes[data_port1] - 1; } if (strcmp("data2", node->input_pins[idx]->mapping) == 0) { data_port2 = i; data_diff2 = node->input_port_sizes[data_port2] - 1; } idx += node->input_port_sizes[i]; } if (data_port1 == -1) { error_message(1, 0, -1, "No \"data1\" port on dual port RAM"); return; } /* Need to create a new node for every data bit */ for (i = 1; i < node->input_port_sizes[data_port1]; i++) { char BUF[10]; new_node = allocate_nnode(); dp_memory_list = insert_in_vptr_list(dp_memory_list, new_node); new_node->name = (char *)malloc(strlen(node->name) + 10); strcpy(new_node->name, node->name); strcat(new_node->name, "-"); sprintf(BUF, "%d", i); strcat(new_node->name, BUF); /* Copy properties from the original node */ new_node->type = node->type; new_node->related_ast_node = node->related_ast_node; new_node->traverse_visited = node->traverse_visited; new_node->node_data = NULL; new_node->num_input_port_sizes = node->num_input_port_sizes; new_node->input_port_sizes = (int *)malloc(node->num_input_port_sizes * sizeof(int)); for (j = 0; j < node->num_input_port_sizes; j++) new_node->input_port_sizes[j] = node->input_port_sizes[j]; new_node->input_port_sizes[data_port1] = 1; if (data_port2 != -1) new_node->input_port_sizes[data_port2] = 1; if (data_port2 == -1) { new_node->num_output_port_sizes = 1; new_node->output_port_sizes = (int *)malloc(sizeof(int)); } else { new_node->num_output_port_sizes = 2; new_node->output_port_sizes = (int *)malloc(sizeof(int)*2); new_node->output_port_sizes[1] = 1; } new_node->output_port_sizes[0] = 1; /* Set the number of input pins and pin entires */ new_node->num_input_pins = node->num_input_pins - data_diff1 - data_diff2; new_node->input_pins = (npin_t**)malloc(sizeof(void *) * new_node->num_input_pins); idx = 0; old_idx = 0; for (j = 0; j < new_node->num_input_port_sizes; j++) { if (j == data_port1) { new_node->input_pins[idx] = node->input_pins[old_idx + i]; node->input_pins[old_idx+i] = NULL; new_node->input_pins[idx]->node = new_node; new_node->input_pins[idx]->pin_node_idx = idx; old_idx = old_idx + node->input_port_sizes[data_port1]; idx++; } else if (j == data_port2) { new_node->input_pins[idx] = node->input_pins[old_idx + i]; node->input_pins[old_idx+i] = NULL; new_node->input_pins[idx]->node = new_node; new_node->input_pins[idx]->pin_node_idx = idx; old_idx = old_idx + node->input_port_sizes[data_port2]; idx++; } else { for (k = 0; k < new_node->input_port_sizes[j]; k++) { new_node->input_pins[idx] = copy_input_npin(node->input_pins[old_idx]); new_node->input_pins[idx]->pin_node_idx = idx; new_node->input_pins[idx]->node = new_node; idx++; old_idx++; } } } /* Set the number of output pins and pin entry */ if (data_port2 == -1) { new_node->num_output_pins = 1; new_node->output_pins = (npin_t **)malloc(sizeof(void*)); new_node->output_pins[0] = node->output_pins[i]; node->output_pins[i] = NULL; new_node->output_pins[0]->pin_node_idx = 0; new_node->output_pins[0]->node = new_node; } else { new_node->num_output_pins = 2; new_node->output_pins = (npin_t **)malloc(sizeof(void*)*2); new_node->output_pins[0] = node->output_pins[i]; node->output_pins[i] = NULL; new_node->output_pins[0]->pin_node_idx = 0; new_node->output_pins[0]->node = new_node; new_node->output_pins[1] = node->output_pins[i+data_diff1+1]; node->output_pins[i+data_diff1+1] = NULL; new_node->output_pins[1]->pin_node_idx = 1; new_node->output_pins[1]->node = new_node; } } /* Now need to clean up the original to do 1 bit output - first bit */ /* Name the node to show first bit! */ tmp_name = (char *)malloc(strlen(node->name) + 3); strcpy(tmp_name, node->name); strcat(tmp_name, "-0"); free(node->name); node->name = tmp_name; /* free the additional output pins */ if (data_port2 == -1) { for (i = 1; i < node->num_output_pins; i++) free_npin(node->output_pins[i]); node->num_output_pins = 1; node->output_pins = realloc(node->output_pins, sizeof(npin_t *) * node->num_output_pins); node->output_port_sizes[0] = 1; } else { for (i = 1; i < (node->num_output_pins/2); i++) free_npin(node->output_pins[i]); node->output_pins[1] = node->output_pins[data_diff1 + 1]; node->output_pins[data_diff1 + 1] = NULL; node->output_pins[1]->pin_node_idx = 1; for (; i < node->num_output_pins; i++) free_npin(node->output_pins[i]); node->num_output_pins = 2; node->output_pins = realloc(node->output_pins, sizeof(npin_t *) * node->num_output_pins); node->output_port_sizes[0] = 1; node->output_port_sizes[1] = 1; } /* Shuffle the input pins on account of removed input pins */ idx = old_idx = 0; node->input_port_sizes[data_port1] = 1; if (data_port2 != -1) node->input_port_sizes[data_port2] = 1; for (i = 0; i < node->num_input_port_sizes; i++) { for (j = 0; j < node->input_port_sizes[i]; j++) { node->input_pins[idx] = node->input_pins[old_idx]; node->input_pins[idx]->pin_node_idx = idx; idx++; old_idx++; } if (i == data_port1) old_idx = old_idx + data_diff1; if (i == data_port2) old_idx = old_idx + data_diff2; } node->num_input_pins = node->num_input_pins - data_diff1; if (data_port2 != -1) node->num_input_pins = node->num_input_pins - data_diff2; node->input_pins = realloc(node->input_pins, sizeof(npin_t *) * node->num_input_pins); dp_memory_list = insert_in_vptr_list(dp_memory_list, node); return; }
/*------------------------------------------------------------------------- * (function: split_sp_memory_width) * * This function works to split the width of a memory into several smaller * memories. *------------------------------------------------------------------------ */ void split_sp_memory_width(nnode_t *node) { int data_port; int i, j, k, idx, old_idx, diff; nnode_t *new_node; oassert(node->type == MEMORY); /* Find which port is the data port on the input! */ idx = 0; data_port = -1; for (i = 0; i < node->num_input_port_sizes; i++) { if (strcmp("data", node->input_pins[idx]->mapping) == 0) data_port = i; idx += node->input_port_sizes[i]; } if (data_port == -1) { error_message(1, 0, -1, "No \"data\" port on single port RAM"); } diff = node->input_port_sizes[data_port]; /* Need to create a new node for every data bit */ for (i = 1; i < node->input_port_sizes[data_port]; i++) { char BUF[10]; new_node = allocate_nnode(); sp_memory_list = insert_in_vptr_list(sp_memory_list, new_node); new_node->name = (char *)malloc(strlen(node->name) + 10); strcpy(new_node->name, node->name); strcat(new_node->name, "-"); sprintf(BUF, "%d", i); strcat(new_node->name, BUF); /* Copy properties from the original node */ new_node->type = node->type; new_node->related_ast_node = node->related_ast_node; new_node->traverse_visited = node->traverse_visited; new_node->node_data = NULL; new_node->num_input_port_sizes = node->num_input_port_sizes; new_node->input_port_sizes = (int *)malloc(node->num_input_port_sizes * sizeof(int)); for (j = 0; j < node->num_input_port_sizes; j++) new_node->input_port_sizes[j] = node->input_port_sizes[j]; new_node->input_port_sizes[data_port] = 1; new_node->num_output_port_sizes = 1; new_node->output_port_sizes = (int *)malloc(sizeof(int)); new_node->output_port_sizes[0] = 1; /* Set the number of input pins and pin entires */ new_node->num_input_pins = node->num_input_pins - diff + 1; new_node->input_pins = (npin_t**)malloc(sizeof(void *) * new_node->num_input_pins); idx = 0; old_idx = 0; for (j = 0; j < new_node->num_input_port_sizes; j++) { if (j == data_port) { new_node->input_pins[idx] = node->input_pins[idx + i]; node->input_pins[idx+i] = NULL; new_node->input_pins[idx]->node = new_node; new_node->input_pins[idx]->pin_node_idx = idx; old_idx = old_idx + node->input_port_sizes[data_port]; idx++; } else { for (k = 0; k < new_node->input_port_sizes[j]; k++) { new_node->input_pins[idx] = copy_input_npin(node->input_pins[old_idx]); new_node->input_pins[idx]->pin_node_idx = idx; new_node->input_pins[idx]->node = new_node; idx++; old_idx++; } } } /* Set the number of output pins and pin entry */ new_node->num_output_pins = 1; new_node->output_pins = (npin_t **)malloc(sizeof(void*)); new_node->output_pins[0] = copy_output_npin(node->output_pins[i]); add_a_driver_pin_to_net(node->output_pins[i]->net, new_node->output_pins[0]); free_npin(node->output_pins[i]); node->output_pins[i] = NULL; new_node->output_pins[0]->pin_node_idx = 0; new_node->output_pins[0]->node = new_node; } /* Now need to clean up the original to do 1 bit output - first bit */ /* Name the node to show first bit! */ { char *new_name = append_string(node->name, "-0"); free(node->name); node->name = new_name; } /* free the additional output pins */ for (i = 1; i < node->num_output_pins; i++) free_npin(node->output_pins[i]); node->num_output_pins = 1; node->output_pins = realloc(node->output_pins, sizeof(npin_t *) * 1); node->output_port_sizes[0] = 1; /* Shuffle the input pins on account of removed input pins */ idx = old_idx = 0; node->input_port_sizes[data_port] = 1; for (i = 0; i < node->num_input_port_sizes; i++) { for (j = 0; j < node->input_port_sizes[i]; j++) { node->input_pins[idx] = node->input_pins[old_idx]; node->input_pins[idx]->pin_node_idx = idx; idx++; old_idx++; } if (i == data_port) old_idx = old_idx + diff - 1; } node->num_input_pins = node->num_input_pins - diff + 1; sp_memory_list = insert_in_vptr_list(sp_memory_list, node); return; }