memories.h File Reference

This graph shows which files directly or indirectly include this file:

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 Documentation

typedef struct s_memory t_memory

Function Documentation

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 }

Here is the caller graph for this function:

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.

00055 {
00056         return;
00057 }

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

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.

Definition at line 36 of file memories.c.

Generated on Tue Aug 2 10:43:16 2011 for ODIN_II by  doxygen 1.6.3