Go to the source code of this file.
Data Structures | |
struct | s_memory |
struct | s_memory_port_sizes |
Typedefs | |
typedef struct s_memory | t_memory |
typedef struct s_memory_port_sizes | t_memory_port_sizes |
Functions | |
void | init_memory_distribution () |
void | report_memory_distribution () |
int | get_memory_port_size (char *name) |
void | split_sp_memory_depth (nnode_t *node) |
void | split_dp_memory_depth (nnode_t *node) |
void | split_sp_memory_width (nnode_t *node) |
void | split_dp_memory_width (nnode_t *node) |
void | iterate_memories (netlist_t *netlist) |
void | clean_memories () |
Variables | |
struct s_linked_vptr * | sp_memory_list |
struct s_linked_vptr * | dp_memory_list |
struct s_linked_vptr * | memory_instances |
struct s_linked_vptr * | memory_port_size_list |
int | split_size |
typedef struct s_memory_port_sizes t_memory_port_sizes |
void clean_memories | ( | ) |
Definition at line 999 of file memories.c.
01000 { 01001 while (sp_memory_list != NULL) 01002 sp_memory_list = delete_in_vptr_list(sp_memory_list); 01003 while (dp_memory_list != NULL) 01004 dp_memory_list = delete_in_vptr_list(dp_memory_list); 01005 return; 01006 }
int get_memory_port_size | ( | char * | name | ) |
Definition at line 39 of file memories.c.
00040 { 00041 struct s_linked_vptr *mpl; 00042 00043 mpl = memory_port_size_list; 00044 while (mpl != NULL) 00045 { 00046 if (strcmp(((t_memory_port_sizes *)mpl->data_vptr)->name, name) == 0) 00047 return ((t_memory_port_sizes *)mpl->data_vptr)->size; 00048 mpl = mpl->next; 00049 } 00050 return -1; 00051 }
void init_memory_distribution | ( | ) |
Definition at line 54 of file memories.c.
void iterate_memories | ( | netlist_t * | netlist | ) |
Definition at line 928 of file memories.c.
00929 { 00930 nnode_t *node; 00931 struct s_linked_vptr *temp; 00932 00933 /* Split it up on depth */ 00934 if (configuration.split_memory_depth != 0) 00935 { 00936 /* Jason Luu: HACK detected: split_size should NOT come from configuration.split_memory_depth, 00937 it should come from the maximum model size for the port, IMPORTANT TODO!!!! */ 00938 split_size = configuration.split_memory_depth; 00939 00940 temp = sp_memory_list; 00941 sp_memory_list = NULL; 00942 while (temp != NULL) 00943 { 00944 node = (nnode_t *)temp->data_vptr; 00945 oassert(node != NULL); 00946 oassert(node->type == MEMORY); 00947 temp = delete_in_vptr_list(temp); 00948 split_sp_memory_depth(node); 00949 } 00950 00951 temp = dp_memory_list; 00952 dp_memory_list = NULL; 00953 while (temp != NULL) 00954 { 00955 node = (nnode_t *)temp->data_vptr; 00956 oassert(node != NULL); 00957 oassert(node->type == MEMORY); 00958 temp = delete_in_vptr_list(temp); 00959 split_dp_memory_depth(node); 00960 } 00961 } 00962 00963 /* Split memory up on width */ 00964 if (configuration.split_memory_width == 1) 00965 { 00966 temp = sp_memory_list; 00967 sp_memory_list = NULL; 00968 while (temp != NULL) 00969 { 00970 node = (nnode_t *)temp->data_vptr; 00971 oassert(node != NULL); 00972 oassert(node->type == MEMORY); 00973 temp = delete_in_vptr_list(temp); 00974 split_sp_memory_width(node); 00975 } 00976 00977 temp = dp_memory_list; 00978 dp_memory_list = NULL; 00979 while (temp != NULL) 00980 { 00981 node = (nnode_t *)temp->data_vptr; 00982 oassert(node != NULL); 00983 oassert(node->type == MEMORY); 00984 temp = delete_in_vptr_list(temp); 00985 split_dp_memory_width(node); 00986 } 00987 } 00988 00989 return; 00990 }
void report_memory_distribution | ( | ) |
Definition at line 60 of file memories.c.
00061 { 00062 nnode_t *node; 00063 struct s_linked_vptr *temp; 00064 int i, idx, width, depth; 00065 00066 if ((sp_memory_list == NULL) && (dp_memory_list == NULL)) 00067 return; 00068 printf("\nHard Logical Memory Distribution\n"); 00069 printf("============================\n"); 00070 00071 temp = sp_memory_list; 00072 while (temp != NULL) 00073 { 00074 node = (nnode_t *)temp->data_vptr; 00075 oassert(node != NULL); 00076 oassert(node->type == MEMORY); 00077 00078 /* Need to find the addr and data1 ports */ 00079 idx = 0; 00080 for (i = 0; i < node->num_input_port_sizes; i++) 00081 { 00082 if (strcmp("addr", node->input_pins[idx]->mapping) == 0) 00083 { 00084 depth = node->input_port_sizes[i]; 00085 } 00086 else if (strcmp("data", node->input_pins[idx]->mapping) == 0) 00087 { 00088 width = node->input_port_sizes[i]; 00089 } 00090 idx += node->input_port_sizes[i]; 00091 } 00092 00093 printf("SPRAM: %d width %d depth\n", width, depth); 00094 temp = temp->next; 00095 } 00096 00097 temp = dp_memory_list; 00098 while (temp != NULL) 00099 { 00100 node = (nnode_t *)temp->data_vptr; 00101 oassert(node != NULL); 00102 oassert(node->type == MEMORY); 00103 00104 /* Need to find the addr and data1 ports */ 00105 idx = 0; 00106 for (i = 0; i < node->num_input_port_sizes; i++) 00107 { 00108 if (strcmp("addr", node->input_pins[idx]->mapping) == 0) 00109 { 00110 depth = node->input_port_sizes[i]; 00111 } else if (strcmp("addr1", node->input_pins[idx]->mapping) == 0) 00112 { 00113 depth = node->input_port_sizes[i]; 00114 } 00115 else if (strcmp("data1", node->input_pins[idx]->mapping) == 0) 00116 { 00117 width = node->input_port_sizes[i]; 00118 } 00119 idx += node->input_port_sizes[i]; 00120 } 00121 00122 printf("DPRAM: %d width %d depth\n", width, depth); 00123 temp = temp->next; 00124 } 00125 00126 printf("\n"); 00127 return; 00128 }
void split_dp_memory_depth | ( | nnode_t * | node | ) |
Definition at line 308 of file memories.c.
00309 { 00310 int addr1_port = -1; 00311 int addr2_port = -1; 00312 int we1_port = -1; 00313 int we2_port = -1; 00314 int clk_port = -1; 00315 int logical_size; 00316 int i, j, idx, addr1_pin_idx, we1_pin_idx, addr2_pin_idx, we2_pin_idx; 00317 nnode_t *new_mem_node; 00318 nnode_t *and1_node, *not1_node, *ff1_node, *mux1_node; 00319 nnode_t *and2_node, *not2_node, *ff2_node, *mux2_node; 00320 npin_t *addr1_pin = NULL; 00321 npin_t *addr2_pin = NULL; 00322 npin_t *we1_pin = NULL; 00323 npin_t *we2_pin = NULL; 00324 npin_t *twe_pin, *taddr_pin, *clk_pin, *tdout_pin; 00325 00326 oassert(node->type == MEMORY); 00327 00328 /* Find which ports are the addr1 and addr2 ports */ 00329 idx = 0; 00330 for (i = 0; i < node->num_input_port_sizes; i++) 00331 { 00332 if (strcmp("addr1", node->input_pins[idx]->mapping) == 0) 00333 { 00334 addr1_port = i; 00335 addr1_pin_idx = idx; 00336 addr1_pin = node->input_pins[idx]; 00337 } 00338 else if (strcmp("addr2", node->input_pins[idx]->mapping) == 0) 00339 { 00340 addr2_port = i; 00341 addr2_pin_idx = idx; 00342 addr2_pin = node->input_pins[idx]; 00343 } 00344 else if (strcmp("we1", node->input_pins[idx]->mapping) == 0) 00345 { 00346 we1_port = i; 00347 we1_pin = node->input_pins[idx]; 00348 we1_pin_idx = idx; 00349 } 00350 else if (strcmp("we2", node->input_pins[idx]->mapping) == 0) 00351 { 00352 we2_port = i; 00353 we2_pin = node->input_pins[idx]; 00354 we2_pin_idx = idx; 00355 } 00356 else if (strcmp("clk", node->input_pins[idx]->mapping) == 0) 00357 { 00358 clk_port = i; 00359 clk_pin = node->input_pins[idx]; 00360 } 00361 idx += node->input_port_sizes[i]; 00362 } 00363 00364 if (addr1_port == -1) 00365 { 00366 error_message(1, 0, -1, "No \"addr1\" port on dual port RAM"); 00367 } 00368 00369 00370 /* Jason Luu HACK: Logical memory depth determination messed up, forced to use this method */ 00371 for(i = 0; i < node->input_port_sizes[addr1_port]; i++) 00372 { 00373 if(strcmp(node->input_pins[addr1_pin_idx + i]->name, "top^ZERO_PAD_ZERO") == 0) 00374 break; 00375 } 00376 logical_size = i; 00377 00378 /* Check that the memory needs to be split */ 00379 if (logical_size <= split_size) { 00380 dp_memory_list = insert_in_vptr_list(dp_memory_list, node); 00381 return; 00382 } 00383 00384 /* Let's remove the address1 line from the memory */ 00385 for (i = addr1_pin_idx; i < node->num_input_pins - 1; i++) 00386 { 00387 node->input_pins[i] = node->input_pins[i+1]; 00388 node->input_pins[i]->pin_node_idx--; 00389 } 00390 node->input_port_sizes[addr1_port]--; 00391 node->num_input_pins--; 00392 if ((we1_port != -1) && (we1_pin_idx >= addr1_pin_idx)) 00393 we1_pin_idx--; 00394 if ((we2_port != -1) && (we2_pin_idx >= addr1_pin_idx)) 00395 we2_pin_idx--; 00396 if ((addr2_port != -1) && (addr2_pin_idx >= addr1_pin_idx)) 00397 addr2_pin_idx--; 00398 00399 /* Let's remove the address2 line from the memory */ 00400 if (addr2_port != -1) 00401 { 00402 for (i = addr2_pin_idx; i < node->num_input_pins - 1; i++) 00403 { 00404 node->input_pins[i] = node->input_pins[i+1]; 00405 node->input_pins[i]->pin_node_idx--; 00406 } 00407 node->input_port_sizes[addr2_port]--; 00408 node->num_input_pins--; 00409 if ((we1_port != -1) && (we1_pin_idx >= addr2_pin_idx)) 00410 we1_pin_idx--; 00411 if ((we2_port != -1) && (we2_pin_idx >= addr2_pin_idx)) 00412 we2_pin_idx--; 00413 if (addr1_pin_idx >= addr2_pin_idx) 00414 addr1_pin_idx--; 00415 } 00416 00417 /* Create the new memory node */ 00418 new_mem_node = allocate_nnode(); 00419 new_mem_node->name = (char *)malloc(strlen(node->name) + 10); 00420 strcpy(new_mem_node->name, node->name); 00421 strcat(new_mem_node->name, "__H"); 00422 node->name = (char *)realloc(node->name, strlen(node->name) + 10); 00423 strcat(node->name,"__S"); 00424 00425 /* Copy properties from the original memory node */ 00426 new_mem_node->type = node->type; 00427 new_mem_node->related_ast_node = node->related_ast_node; 00428 new_mem_node->traverse_visited = node->traverse_visited; 00429 new_mem_node->node_data = NULL; 00430 00431 new_mem_node->num_output_pins = node->num_output_pins; 00432 new_mem_node->num_output_port_sizes = node->num_output_port_sizes; 00433 new_mem_node->output_pins = (struct npin_t_t **)malloc(sizeof(struct npin_t_t **) * new_mem_node->num_output_pins); 00434 for (i = 0; i < new_mem_node->num_output_pins; i++) 00435 new_mem_node->output_pins[i] = NULL; 00436 new_mem_node->output_port_sizes = (int *)malloc(sizeof(int) * new_mem_node->num_output_port_sizes); 00437 for (i = 0; i < new_mem_node->num_output_port_sizes; i++) 00438 new_mem_node->output_port_sizes[i] = node->output_port_sizes[i]; 00439 new_mem_node->num_input_port_sizes = node->num_input_port_sizes; 00440 new_mem_node->input_port_sizes = (int *)malloc(node->num_input_port_sizes * sizeof(int)); 00441 new_mem_node->input_pins = (struct npin_t_t **)malloc(node->num_input_pins * sizeof(struct npin_t_t **)); 00442 00443 /* KEN - IS THIS AN ERROR? */ 00444 new_mem_node->num_input_pins = node->num_input_pins; // jluu yes -1; is an error, removed 00445 00446 /* Copy over the pin sizes for the new memory */ 00447 for (j = 0; j < new_mem_node->num_input_port_sizes; j++) 00448 { 00449 new_mem_node->input_port_sizes[j] = node->input_port_sizes[j]; 00450 } 00451 00452 /* Copy over the pins for the new memory */ 00453 for (j = 0; j < node->num_input_pins; j++) 00454 { 00455 new_mem_node->input_pins[j] = copy_input_npin(node->input_pins[j]); 00456 } 00457 00458 if (we1_pin != NULL) 00459 { 00460 and1_node = make_2port_gate(LOGICAL_AND, 1, 1, 1, node, node->traverse_visited); 00461 twe_pin = copy_input_npin(we1_pin); 00462 add_a_input_pin_to_node_spot_idx(and1_node, twe_pin, 1); 00463 taddr_pin = copy_input_npin(addr1_pin); 00464 add_a_input_pin_to_node_spot_idx(and1_node, taddr_pin, 0); 00465 connect_nodes(and1_node, 0, node, we1_pin_idx); 00466 node->input_pins[we1_pin_idx]->mapping = we1_pin->mapping; 00467 } 00468 00469 if (we2_pin != NULL) 00470 { 00471 and2_node = make_2port_gate(LOGICAL_AND, 1, 1, 1, node, node->traverse_visited); 00472 twe_pin = copy_input_npin(we2_pin); 00473 add_a_input_pin_to_node_spot_idx(and2_node, twe_pin, 1); 00474 taddr_pin = copy_input_npin(addr2_pin); 00475 add_a_input_pin_to_node_spot_idx(and2_node, taddr_pin, 0); 00476 connect_nodes(and2_node, 0, node, we2_pin_idx); 00477 node->input_pins[we2_pin_idx]->mapping = we2_pin->mapping; 00478 } 00479 00480 if (we1_pin != NULL) 00481 { 00482 taddr_pin = copy_input_npin(addr1_pin); 00483 not1_node = make_not_gate_with_input(taddr_pin, new_mem_node, new_mem_node->traverse_visited); 00484 and1_node = make_2port_gate(LOGICAL_AND, 1, 1, 1, new_mem_node, new_mem_node->traverse_visited); 00485 connect_nodes(not1_node, 0, and1_node, 0); 00486 add_a_input_pin_to_node_spot_idx(and1_node, we1_pin, 1); 00487 connect_nodes(and1_node, 0, new_mem_node, we1_pin_idx); 00488 new_mem_node->input_pins[we1_pin_idx]->mapping = we1_pin->mapping; 00489 } 00490 00491 if (we2_pin != NULL) 00492 { 00493 taddr_pin = copy_input_npin(addr2_pin); 00494 not2_node = make_not_gate_with_input(taddr_pin, new_mem_node, new_mem_node->traverse_visited); 00495 and2_node = make_2port_gate(LOGICAL_AND, 1, 1, 1, new_mem_node, new_mem_node->traverse_visited); 00496 connect_nodes(not2_node, 0, and2_node, 0); 00497 add_a_input_pin_to_node_spot_idx(and2_node, we2_pin, 1); 00498 connect_nodes(and2_node, 0, new_mem_node, we2_pin_idx); 00499 new_mem_node->input_pins[we2_pin_idx]->mapping = we2_pin->mapping; 00500 } 00501 00502 if (node->num_output_pins > 0) /* There is an "out1" output */ 00503 { 00504 ff1_node = make_2port_gate(FF_NODE, 1, 1, 1, node, node->traverse_visited); 00505 add_a_input_pin_to_node_spot_idx(ff1_node, addr1_pin, 0); 00506 add_a_input_pin_to_node_spot_idx(ff1_node, copy_input_npin(clk_pin), 1); 00507 00508 /* Copy over the output pins for the new memory */ 00509 for (j = 0; j < node->output_port_sizes[0]; j++) 00510 { 00511 mux1_node = make_2port_gate(MULTI_PORT_MUX, 2, 2, 1, node, node->traverse_visited); 00512 connect_nodes(ff1_node, 0, mux1_node, 0); 00513 not1_node = make_not_gate(node, node->traverse_visited); 00514 connect_nodes(ff1_node, 0, not1_node, 0); 00515 connect_nodes(not1_node, 0, mux1_node, 1); 00516 tdout_pin = node->output_pins[j]; 00517 remap_pin_to_new_node(tdout_pin, mux1_node, 0); 00518 connect_nodes(node, j, mux1_node, 3); 00519 node->output_pins[j]->mapping = tdout_pin->mapping; 00520 connect_nodes(new_mem_node, j, mux1_node, 2); 00521 new_mem_node->output_pins[j]->mapping = tdout_pin->mapping; 00522 tdout_pin->mapping = NULL; 00523 } 00524 } 00525 00526 if (node->num_output_pins > node->output_port_sizes[0]) /* There is an "out2" output */ 00527 { 00528 ff2_node = make_2port_gate(FF_NODE, 1, 1, 1, node, node->traverse_visited); 00529 add_a_input_pin_to_node_spot_idx(ff2_node, addr2_pin, 0); 00530 add_a_input_pin_to_node_spot_idx(ff2_node, copy_input_npin(clk_pin), 1); 00531 00532 /* Copy over the output pins for the new memory */ 00533 for (j = 0; j < node->output_port_sizes[0]; j++) 00534 { 00535 mux2_node = make_2port_gate(MULTI_PORT_MUX, 2, 2, 1, node, node->traverse_visited); 00536 connect_nodes(ff2_node, 0, mux2_node, 0); 00537 not2_node = make_not_gate(node, node->traverse_visited); 00538 connect_nodes(ff2_node, 0, not2_node, 0); 00539 connect_nodes(not2_node, 0, mux2_node, 1); 00540 tdout_pin = node->output_pins[node->output_port_sizes[0] + j]; 00541 remap_pin_to_new_node(tdout_pin, mux2_node, 0); 00542 connect_nodes(node, node->output_port_sizes[0] + j, mux2_node, 3); 00543 node->output_pins[node->output_port_sizes[0] + j]->mapping = tdout_pin->mapping; 00544 connect_nodes(new_mem_node, node->output_port_sizes[0] + j, mux2_node, 2); 00545 new_mem_node->output_pins[node->output_port_sizes[0] + j]->mapping = tdout_pin->mapping; 00546 tdout_pin->mapping = NULL; 00547 } 00548 } 00549 00550 /* must recurse on new memory if it's too small */ 00551 if (logical_size <= split_size) { 00552 dp_memory_list = insert_in_vptr_list(dp_memory_list, new_mem_node); 00553 dp_memory_list = insert_in_vptr_list(dp_memory_list, node); 00554 } else { 00555 split_dp_memory_depth(node); 00556 split_dp_memory_depth(new_mem_node); 00557 } 00558 00559 return; 00560 }
void split_dp_memory_width | ( | nnode_t * | node | ) |
Definition at line 708 of file memories.c.
00709 { 00710 int data_port1, data_port2; 00711 int i, j, k, idx, old_idx, data_diff1, data_diff2; 00712 nnode_t *new_node; 00713 char *tmp_name; 00714 nnet_t *data1_net, *data2_net; 00715 00716 oassert(node->type == MEMORY); 00717 00718 /* Find which port is the data port on the input! */ 00719 idx = 0; 00720 data_port1 = -1; 00721 data_port2 = -1; 00722 data_diff1 = 0; 00723 data_diff2 = 0; 00724 data1_net = node->output_pins[0]->net; 00725 if (node->num_output_port_sizes > 1) 00726 data2_net = node->output_pins[node->output_port_sizes[0]]->net; 00727 for (i = 0; i < node->num_input_port_sizes; i++) 00728 { 00729 if (strcmp("data1", node->input_pins[idx]->mapping) == 0) 00730 { 00731 data_port1 = i; 00732 data_diff1 = node->input_port_sizes[data_port1] - 1; 00733 } 00734 if (strcmp("data2", node->input_pins[idx]->mapping) == 0) 00735 { 00736 data_port2 = i; 00737 data_diff2 = node->input_port_sizes[data_port2] - 1; 00738 } 00739 idx += node->input_port_sizes[i]; 00740 } 00741 00742 if (data_port1 == -1) 00743 { 00744 error_message(1, 0, -1, "No \"data1\" port on dual port RAM"); 00745 return; 00746 } 00747 00748 /* Need to create a new node for every data bit */ 00749 for (i = 1; i < node->input_port_sizes[data_port1]; i++) 00750 { 00751 char BUF[10]; 00752 new_node = allocate_nnode(); 00753 dp_memory_list = insert_in_vptr_list(dp_memory_list, new_node); 00754 new_node->name = (char *)malloc(strlen(node->name) + 10); 00755 strcpy(new_node->name, node->name); 00756 strcat(new_node->name, "-"); 00757 sprintf(BUF, "%d", i); 00758 strcat(new_node->name, BUF); 00759 00760 /* Copy properties from the original node */ 00761 new_node->type = node->type; 00762 new_node->related_ast_node = node->related_ast_node; 00763 new_node->traverse_visited = node->traverse_visited; 00764 new_node->node_data = NULL; 00765 00766 new_node->num_input_port_sizes = node->num_input_port_sizes; 00767 new_node->input_port_sizes = (int *)malloc(node->num_input_port_sizes * sizeof(int)); 00768 for (j = 0; j < node->num_input_port_sizes; j++) 00769 new_node->input_port_sizes[j] = node->input_port_sizes[j]; 00770 00771 new_node->input_port_sizes[data_port1] = 1; 00772 if (data_port2 != -1) 00773 new_node->input_port_sizes[data_port2] = 1; 00774 00775 if (data_port2 == -1) 00776 { 00777 new_node->num_output_port_sizes = 1; 00778 new_node->output_port_sizes = (int *)malloc(sizeof(int)); 00779 } 00780 else 00781 { 00782 new_node->num_output_port_sizes = 2; 00783 new_node->output_port_sizes = (int *)malloc(sizeof(int)*2); 00784 new_node->output_port_sizes[1] = 1; 00785 } 00786 new_node->output_port_sizes[0] = 1; 00787 00788 /* Set the number of input pins and pin entires */ 00789 new_node->num_input_pins = node->num_input_pins - data_diff1 - data_diff2; 00790 new_node->input_pins = (npin_t**)malloc(sizeof(void *) * new_node->num_input_pins); 00791 00792 00793 idx = 0; 00794 old_idx = 0; 00795 for (j = 0; j < new_node->num_input_port_sizes; j++) 00796 { 00797 if (j == data_port1) 00798 { 00799 new_node->input_pins[idx] = node->input_pins[old_idx + i]; 00800 node->input_pins[old_idx+i] = NULL; 00801 new_node->input_pins[idx]->node = new_node; 00802 new_node->input_pins[idx]->pin_node_idx = idx; 00803 old_idx = old_idx + node->input_port_sizes[data_port1]; 00804 idx++; 00805 } 00806 else if (j == data_port2) 00807 { 00808 new_node->input_pins[idx] = node->input_pins[old_idx + i]; 00809 node->input_pins[old_idx+i] = NULL; 00810 new_node->input_pins[idx]->node = new_node; 00811 new_node->input_pins[idx]->pin_node_idx = idx; 00812 old_idx = old_idx + node->input_port_sizes[data_port2]; 00813 idx++; 00814 } 00815 else 00816 { 00817 for (k = 0; k < new_node->input_port_sizes[j]; k++) 00818 { 00819 new_node->input_pins[idx] = copy_input_npin(node->input_pins[old_idx]); 00820 new_node->input_pins[idx]->pin_node_idx = idx; 00821 new_node->input_pins[idx]->node = new_node; 00822 idx++; 00823 old_idx++; 00824 } 00825 } 00826 } 00827 00828 /* Set the number of output pins and pin entry */ 00829 if (data_port2 == -1) 00830 { 00831 new_node->num_output_pins = 1; 00832 new_node->output_pins = (npin_t **)malloc(sizeof(void*)); 00833 // new_node->output_pins[0] = copy_output_npin(node->output_pins[i]); 00834 // add_a_driver_pin_to_net(data1_net, new_node->output_pins[0]); 00835 // free_npin(node->output_pins[i]); 00836 new_node->output_pins[0] = node->output_pins[i]; 00837 node->output_pins[i] = NULL; 00838 new_node->output_pins[0]->pin_node_idx = 0; 00839 new_node->output_pins[0]->node = new_node; 00840 } 00841 else 00842 { 00843 new_node->num_output_pins = 2; 00844 new_node->output_pins = (npin_t **)malloc(sizeof(void*)*2); 00845 // new_node->output_pins[0] = copy_output_npin(node->output_pins[i]); 00846 // new_node->output_pins[1] = copy_output_npin(node->output_pins[i+data_diff1+1]); 00847 // add_a_driver_pin_to_net(data1_net, new_node->output_pins[0]); 00848 // free_npin(node->output_pins[i]); 00849 new_node->output_pins[0] = node->output_pins[i]; 00850 node->output_pins[i] = NULL; 00851 new_node->output_pins[0]->pin_node_idx = 0; 00852 new_node->output_pins[0]->node = new_node; 00853 00854 // add_a_driver_pin_to_net(data2_net, new_node->output_pins[1]); 00855 // free_npin(node->output_pins[i+data_diff1+1]); 00856 new_node->output_pins[1] = node->output_pins[i+data_diff1+1]; 00857 node->output_pins[i+data_diff1+1] = NULL; 00858 new_node->output_pins[1]->pin_node_idx = 1; 00859 new_node->output_pins[1]->node = new_node; 00860 } 00861 } 00862 00863 /* Now need to clean up the original to do 1 bit output - first bit */ 00864 /* Name the node to show first bit! */ 00865 tmp_name = (char *)malloc(strlen(node->name) + 3); 00866 strcpy(tmp_name, node->name); 00867 strcat(tmp_name, "-0"); 00868 free(node->name); 00869 node->name = tmp_name; 00870 00871 /* free the additional output pins */ 00872 if (data_port2 == -1) 00873 { 00874 // for (i = 1; i < node->num_output_pins; i++) 00875 // free_npin(node->output_pins[i]); 00876 node->num_output_pins = 1; 00877 node->output_port_sizes[0] = 1; 00878 } 00879 else 00880 { 00881 // for (i = 1; i < (node->num_output_pins/2); i++) 00882 // free_npin(node->output_pins[i]); 00883 node->output_pins[1] = node->output_pins[data_diff1 + 1]; 00884 node->output_pins[data_diff1 + 1] = NULL; 00885 node->output_pins[1]->pin_node_idx = 1; 00886 // for (; i < node->num_output_pins; i++) 00887 // free_npin(node->output_pins[i]); 00888 node->num_output_pins = 2; 00889 node->output_port_sizes[0] = 1; 00890 node->output_port_sizes[1] = 1; 00891 } 00892 00893 /* Shuffle the input pins on account of removed input pins */ 00894 idx = old_idx = 0; 00895 node->input_port_sizes[data_port1] = 1; 00896 if (data_port2 != -1) 00897 node->input_port_sizes[data_port2] = 1; 00898 for (i = 0; i < node->num_input_port_sizes; i++) 00899 { 00900 for (j = 0; j < node->input_port_sizes[i]; j++) 00901 { 00902 node->input_pins[idx] = node->input_pins[old_idx]; 00903 node->input_pins[idx]->pin_node_idx = idx; 00904 idx++; 00905 old_idx++; 00906 } 00907 if (i == data_port1) 00908 old_idx = old_idx + data_diff1; 00909 if (i == data_port2) 00910 old_idx = old_idx + data_diff2; 00911 } 00912 node->num_input_pins = node->num_input_pins - data_diff1; 00913 if (data_port2 != -1) 00914 node->num_input_pins = node->num_input_pins - data_diff2; 00915 dp_memory_list = insert_in_vptr_list(dp_memory_list, node); 00916 00917 return; 00918 }
void split_sp_memory_depth | ( | nnode_t * | node | ) |
Definition at line 138 of file memories.c.
00139 { 00140 int addr_port = -1; 00141 int we_port = -1; 00142 int clk_port = -1; 00143 int logical_size; 00144 int i, j, idx, addr_pin_idx, we_pin_idx; 00145 nnode_t *new_mem_node; 00146 nnode_t *and_node, *not_node, *ff_node, *mux_node; 00147 npin_t *addr_pin = NULL; 00148 npin_t *we_pin = NULL; 00149 npin_t *twe_pin, *taddr_pin, *clk_pin, *tdout_pin; 00150 00151 oassert(node->type == MEMORY); 00152 00153 /* Find which port is the addr port */ 00154 idx = 0; 00155 for (i = 0; i < node->num_input_port_sizes; i++) 00156 { 00157 if (strcmp("addr", node->input_pins[idx]->mapping) == 0) 00158 { 00159 addr_port = i; 00160 addr_pin_idx = idx; 00161 addr_pin = node->input_pins[idx]; 00162 } 00163 else if (strcmp("we", node->input_pins[idx]->mapping) == 0) 00164 { 00165 we_port = i; 00166 we_pin = node->input_pins[idx]; 00167 we_pin_idx = idx; 00168 } 00169 else if (strcmp("clk", node->input_pins[idx]->mapping) == 0) 00170 { 00171 clk_port = i; 00172 clk_pin = node->input_pins[idx]; 00173 } 00174 idx += node->input_port_sizes[i]; 00175 } 00176 if (addr_port == -1) 00177 { 00178 error_message(1, 0, -1, "No \"addr\" port on single port RAM"); 00179 } 00180 if (we_port == -1) 00181 { 00182 error_message(1, 0, -1, "No \"we\" port on single port RAM"); 00183 } 00184 if (clk_port == -1) 00185 { 00186 error_message(1, 0, -1, "No \"clk\" port on single port RAM"); 00187 } 00188 00189 /* Check that the memory needs to be split */ 00190 /* Jason Luu HACK: Logical memory depth determination messed up, forced to use this method */ 00191 for(i = 0; i < node->input_port_sizes[addr_port]; i++) 00192 { 00193 if(strcmp(node->input_pins[addr_pin_idx + i]->name, "top^ZERO_PAD_ZERO") == 0) 00194 break; 00195 } 00196 logical_size = i; 00197 if (logical_size <= split_size) { 00198 sp_memory_list = insert_in_vptr_list(sp_memory_list, node); 00199 return; 00200 } 00201 00202 /* Let's remove the address line from the memory */ 00203 for (i = addr_pin_idx; i < node->num_input_pins - 1; i++) 00204 { 00205 node->input_pins[i] = node->input_pins[i+1]; 00206 node->input_pins[i]->pin_node_idx--; 00207 } 00208 node->input_port_sizes[addr_port]--; 00209 node->num_input_pins--; 00210 if (we_pin_idx >= addr_pin_idx) 00211 we_pin_idx--; 00212 00213 /* Create the new memory node */ 00214 new_mem_node = allocate_nnode(); 00215 new_mem_node->name = (char *)malloc(strlen(node->name) + 10); 00216 strcpy(new_mem_node->name, node->name); 00217 strcat(new_mem_node->name, "__H"); 00218 node->name = (char *)realloc(node->name, strlen(node->name) + 10); 00219 strcat(node->name,"__S"); 00220 00221 /* Copy properties from the original memory node */ 00222 new_mem_node->type = node->type; 00223 new_mem_node->related_ast_node = node->related_ast_node; 00224 new_mem_node->traverse_visited = node->traverse_visited; 00225 new_mem_node->node_data = NULL; 00226 new_mem_node->num_output_pins = node->num_output_pins; 00227 new_mem_node->output_pins = (struct npin_t_t **)malloc(node->num_output_pins * sizeof(struct npin_t_t **)); 00228 new_mem_node->output_port_sizes = (int *)malloc(sizeof(int)); 00229 new_mem_node->output_port_sizes[0] = node->output_port_sizes[0]; 00230 for (i = 0; i < new_mem_node->num_output_pins; i++) 00231 new_mem_node->output_pins[i] = NULL; 00232 00233 new_mem_node->num_input_port_sizes = node->num_input_port_sizes; 00234 new_mem_node->input_port_sizes = (int *)malloc(node->num_input_port_sizes * sizeof(int)); 00235 new_mem_node->input_pins = (struct npin_t_t **)malloc(node->num_input_pins * sizeof(struct npin_t_t **)); 00236 new_mem_node->num_input_pins = node->num_input_pins; //- 1; 00237 00238 /* Copy over the pin sizes for the new memory */ 00239 for (j = 0; j < new_mem_node->num_input_port_sizes; j++) 00240 { 00241 new_mem_node->input_port_sizes[j] = node->input_port_sizes[j]; 00242 } 00243 00244 /* Copy over the pins for the new memory */ 00245 for (j = 0; j < node->num_input_pins; j++) 00246 { 00247 new_mem_node->input_pins[j] = copy_input_npin(node->input_pins[j]); 00248 } 00249 00250 and_node = make_2port_gate(LOGICAL_AND, 1, 1, 1, node, node->traverse_visited); 00251 twe_pin = copy_input_npin(we_pin); 00252 add_a_input_pin_to_node_spot_idx(and_node, twe_pin, 1); 00253 taddr_pin = copy_input_npin(addr_pin); 00254 add_a_input_pin_to_node_spot_idx(and_node, taddr_pin, 0); 00255 connect_nodes(and_node, 0, node, we_pin_idx); 00256 node->input_pins[we_pin_idx]->mapping = we_pin->mapping; 00257 00258 taddr_pin = copy_input_npin(addr_pin); 00259 not_node = make_not_gate_with_input(taddr_pin, new_mem_node, new_mem_node->traverse_visited); 00260 and_node = make_2port_gate(LOGICAL_AND, 1, 1, 1, new_mem_node, new_mem_node->traverse_visited); 00261 connect_nodes(not_node, 0, and_node, 0); 00262 add_a_input_pin_to_node_spot_idx(and_node, we_pin, 1); 00263 connect_nodes(and_node, 0, new_mem_node, we_pin_idx); 00264 new_mem_node->input_pins[we_pin_idx]->mapping = we_pin->mapping; 00265 00266 ff_node = make_2port_gate(FF_NODE, 1, 1, 1, node, node->traverse_visited); 00267 add_a_input_pin_to_node_spot_idx(ff_node, addr_pin, 0); 00268 add_a_input_pin_to_node_spot_idx(ff_node, copy_input_npin(clk_pin), 1); 00269 00270 00271 /* Copy over the output pins for the new memory */ 00272 for (j = 0; j < node->num_output_pins; j++) 00273 { 00274 mux_node = make_2port_gate(MULTI_PORT_MUX, 2, 2, 1, node, node->traverse_visited); 00275 connect_nodes(ff_node, 0, mux_node, 0); 00276 not_node = make_not_gate(node, node->traverse_visited); 00277 connect_nodes(ff_node, 0, not_node, 0); 00278 connect_nodes(not_node, 0, mux_node, 1); 00279 tdout_pin = node->output_pins[j]; 00280 remap_pin_to_new_node(tdout_pin, mux_node, 0); 00281 connect_nodes(node, j, mux_node, 3); 00282 node->output_pins[j]->mapping = tdout_pin->mapping; 00283 connect_nodes(new_mem_node, j, mux_node, 2); 00284 new_mem_node->output_pins[j]->mapping = tdout_pin->mapping; 00285 tdout_pin->mapping = NULL; 00286 } 00287 00288 /* must recurse on new memory if it's too small */ 00289 if (logical_size <= split_size) { 00290 sp_memory_list = insert_in_vptr_list(sp_memory_list, new_mem_node); 00291 sp_memory_list = insert_in_vptr_list(sp_memory_list, node); 00292 } else { 00293 split_sp_memory_depth(node); 00294 split_sp_memory_depth(new_mem_node); 00295 } 00296 00297 return; 00298 }
void split_sp_memory_width | ( | nnode_t * | node | ) |
Definition at line 570 of file memories.c.
00571 { 00572 int data_port; 00573 int i, j, k, idx, old_idx, diff; 00574 nnode_t *new_node; 00575 char *tmp_name; 00576 00577 oassert(node->type == MEMORY); 00578 00579 /* Find which port is the data port on the input! */ 00580 idx = 0; 00581 data_port = -1; 00582 for (i = 0; i < node->num_input_port_sizes; i++) 00583 { 00584 if (strcmp("data", node->input_pins[idx]->mapping) == 0) 00585 data_port = i; 00586 idx += node->input_port_sizes[i]; 00587 } 00588 if (data_port == -1) 00589 { 00590 error_message(1, 0, -1, "No \"data\" port on single port RAM"); 00591 } 00592 00593 diff = node->input_port_sizes[data_port]; 00594 00595 /* Need to create a new node for every data bit */ 00596 for (i = 1; i < node->input_port_sizes[data_port]; i++) 00597 { 00598 char BUF[10]; 00599 new_node = allocate_nnode(); 00600 sp_memory_list = insert_in_vptr_list(sp_memory_list, new_node); 00601 new_node->name = (char *)malloc(strlen(node->name) + 10); 00602 strcpy(new_node->name, node->name); 00603 strcat(new_node->name, "-"); 00604 sprintf(BUF, "%d", i); 00605 strcat(new_node->name, BUF); 00606 00607 /* Copy properties from the original node */ 00608 new_node->type = node->type; 00609 new_node->related_ast_node = node->related_ast_node; 00610 new_node->traverse_visited = node->traverse_visited; 00611 new_node->node_data = NULL; 00612 00613 new_node->num_input_port_sizes = node->num_input_port_sizes; 00614 new_node->input_port_sizes = (int *)malloc(node->num_input_port_sizes * sizeof(int)); 00615 for (j = 0; j < node->num_input_port_sizes; j++) 00616 new_node->input_port_sizes[j] = node->input_port_sizes[j]; 00617 00618 new_node->input_port_sizes[data_port] = 1; 00619 new_node->num_output_port_sizes = 1; 00620 new_node->output_port_sizes = (int *)malloc(sizeof(int)); 00621 new_node->output_port_sizes[0] = 1; 00622 00623 /* Set the number of input pins and pin entires */ 00624 new_node->num_input_pins = node->num_input_pins - diff + 1; 00625 new_node->input_pins = (npin_t**)malloc(sizeof(void *) * new_node->num_input_pins); 00626 00627 idx = 0; 00628 old_idx = 0; 00629 for (j = 0; j < new_node->num_input_port_sizes; j++) 00630 { 00631 if (j == data_port) 00632 { 00633 new_node->input_pins[idx] = node->input_pins[idx + i]; 00634 node->input_pins[idx+i] = NULL; 00635 new_node->input_pins[idx]->node = new_node; 00636 new_node->input_pins[idx]->pin_node_idx = idx; 00637 old_idx = old_idx + node->input_port_sizes[data_port]; 00638 idx++; 00639 } 00640 else 00641 { 00642 for (k = 0; k < new_node->input_port_sizes[j]; k++) 00643 { 00644 new_node->input_pins[idx] = copy_input_npin(node->input_pins[old_idx]); 00645 new_node->input_pins[idx]->pin_node_idx = idx; 00646 new_node->input_pins[idx]->node = new_node; 00647 idx++; 00648 old_idx++; 00649 } 00650 } 00651 } 00652 00653 /* Set the number of output pins and pin entry */ 00654 new_node->num_output_pins = 1; 00655 new_node->output_pins = (npin_t **)malloc(sizeof(void*)); 00656 new_node->output_pins[0] = copy_output_npin(node->output_pins[i]); 00657 add_a_driver_pin_to_net(node->output_pins[i]->net, new_node->output_pins[0]); 00658 free_npin(node->output_pins[i]); 00659 node->output_pins[i] = NULL; 00660 new_node->output_pins[0]->pin_node_idx = 0; 00661 new_node->output_pins[0]->node = new_node; 00662 } 00663 00664 /* Now need to clean up the original to do 1 bit output - first bit */ 00665 00666 /* Name the node to show first bit! */ 00667 tmp_name = (char *)malloc(strlen(node->name) + 3); 00668 strcpy(tmp_name, node->name); 00669 strcat(tmp_name, "-0"); 00670 free(node->name); 00671 node->name = tmp_name; 00672 00673 /* free the additional output pins */ 00674 for (i = 1; i < node->num_output_pins; i++) 00675 free_npin(node->output_pins[i]); 00676 node->num_output_pins = 1; 00677 node->output_port_sizes[0] = 1; 00678 00679 /* Shuffle the input pins on account of removed input pins */ 00680 idx = old_idx = 0; 00681 node->input_port_sizes[data_port] = 1; 00682 for (i = 0; i < node->num_input_port_sizes; i++) 00683 { 00684 for (j = 0; j < node->input_port_sizes[i]; j++) 00685 { 00686 node->input_pins[idx] = node->input_pins[old_idx]; 00687 node->input_pins[idx]->pin_node_idx = idx; 00688 idx++; 00689 old_idx++; 00690 } 00691 if (i == data_port) 00692 old_idx = old_idx + diff - 1; 00693 } 00694 node->num_input_pins = node->num_input_pins - diff + 1; 00695 sp_memory_list = insert_in_vptr_list(sp_memory_list, node); 00696 00697 return; 00698 }
struct s_linked_vptr* dp_memory_list |
Definition at line 32 of file memories.c.
struct s_linked_vptr* memory_instances |
Definition at line 34 of file memories.c.
struct s_linked_vptr* memory_port_size_list |
Definition at line 35 of file memories.c.
struct s_linked_vptr* sp_memory_list |
Definition at line 31 of file memories.c.
int split_size |
Definition at line 36 of file memories.c.