00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <string.h>
00025 #include "globals.h"
00026 #include "errors.h"
00027 #include "netlist_utils.h"
00028 #include "node_creation_library.h"
00029 #include "memories.h"
00030
00031 struct s_linked_vptr *sp_memory_list;
00032 struct s_linked_vptr *dp_memory_list;
00033 struct s_linked_vptr *split_list;
00034 struct s_linked_vptr *memory_instances = NULL;
00035 struct s_linked_vptr *memory_port_size_list = NULL;
00036 int split_size = 0;
00037
00038 int
00039 get_memory_port_size(char *name)
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 }
00052
00053 void
00054 init_memory_distribution()
00055 {
00056 return;
00057 }
00058
00059 void
00060 report_memory_distribution()
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
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
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 }
00129
00130
00131
00132
00133
00134
00135
00136
00137 void
00138 split_sp_memory_depth(nnode_t *node)
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
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
00190
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
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
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
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;
00237
00238
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
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
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
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 }
00299
00300
00301
00302
00303
00304
00305
00306
00307 void
00308 split_dp_memory_depth(nnode_t *node)
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
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
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
00379 if (logical_size <= split_size) {
00380 dp_memory_list = insert_in_vptr_list(dp_memory_list, node);
00381 return;
00382 }
00383
00384
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
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
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
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
00444 new_mem_node->num_input_pins = node->num_input_pins;
00445
00446
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
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)
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
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])
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
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
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 }
00561
00562
00563
00564
00565
00566
00567
00568
00569 void
00570 split_sp_memory_width(nnode_t *node)
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
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
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
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
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
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
00665
00666
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
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
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 }
00699
00700
00701
00702
00703
00704
00705
00706
00707 void
00708 split_dp_memory_width(nnode_t *node)
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
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
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
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
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
00829 if (data_port2 == -1)
00830 {
00831 new_node->num_output_pins = 1;
00832 new_node->output_pins = (npin_t **)malloc(sizeof(void*));
00833
00834
00835
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
00846
00847
00848
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
00855
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
00864
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
00872 if (data_port2 == -1)
00873 {
00874
00875
00876 node->num_output_pins = 1;
00877 node->output_port_sizes[0] = 1;
00878 }
00879 else
00880 {
00881
00882
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
00887
00888 node->num_output_pins = 2;
00889 node->output_port_sizes[0] = 1;
00890 node->output_port_sizes[1] = 1;
00891 }
00892
00893
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 }
00919
00920
00921
00922
00923
00924
00925
00926
00927 void
00928 iterate_memories(netlist_t *netlist)
00929 {
00930 nnode_t *node;
00931 struct s_linked_vptr *temp;
00932
00933
00934 if (configuration.split_memory_depth != 0)
00935 {
00936
00937
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
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 }
00991
00992
00993
00994
00995
00996
00997
00998 void
00999 clean_memories()
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 }
01007