partial_map.c File Reference

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include "types.h"
#include "globals.h"
#include "errors.h"
#include "netlist_utils.h"
#include "node_creation_library.h"
#include "odin_util.h"
#include "outputs.h"
#include "partial_map.h"
#include "multipliers.h"
#include "util.h"
#include "hard_blocks.h"
Include dependency graph for partial_map.c:

Go to the source code of this file.

Functions

void depth_first_traversal_to_partial_map (short marker_value, netlist_t *netlist)
void depth_first_traverse_parital_map (nnode_t *node, int traverse_mark_number, netlist_t *netlist)
void partial_map_node (nnode_t *node, short traverse_number, netlist_t *netlist)
void instantiate_not_logic (nnode_t *node, short mark, netlist_t *netlist)
void instantiate_buffer (nnode_t *node, short mark, netlist_t *netlist)
void instantiate_bitwise_logic (nnode_t *node, operation_list op, short mark, netlist_t *netlist)
void instantiate_bitwise_reduction (nnode_t *node, operation_list op, short mark, netlist_t *netlist)
void instantiate_logical_logic (nnode_t *node, operation_list op, short mark, netlist_t *netlist)
void instantiate_EQUAL (nnode_t *node, short type, short mark, netlist_t *netlist)
void instantiate_GE (nnode_t *node, short type, short mark, netlist_t *netlist)
void instantiate_GT (nnode_t *node, short type, short mark, netlist_t *netlist)
void instantiate_shift_left_or_right (nnode_t *node, short type, short mark, netlist_t *netlist)
void instantiate_multi_port_mux (nnode_t *node, short mark, netlist_t *netlist)
void instantiate_add_w_carry (nnode_t *node, short mark, netlist_t *netlist)
void instantiate_unary_sub (nnode_t *node, short mark, netlist_t *netlist)
void instantiate_sub_w_carry (nnode_t *node, short mark, netlist_t *netlist)
void partial_map_top (netlist_t *netlist)

Function Documentation

void depth_first_traversal_to_partial_map ( short  marker_value,
netlist_t netlist 
)

Definition at line 74 of file partial_map.c.

00075 {
00076         int i;
00077 
00078         /* start with the primary input list */
00079         for (i = 0; i < netlist->num_top_input_nodes; i++)
00080         {
00081                 if (netlist->top_input_nodes[i] != NULL)
00082                 {
00083                         depth_first_traverse_parital_map(netlist->top_input_nodes[i], marker_value, netlist);
00084                 }
00085         }
00086         /* now traverse the ground and vcc pins */
00087         depth_first_traverse_parital_map(netlist->gnd_node, marker_value, netlist);
00088         depth_first_traverse_parital_map(netlist->vcc_node, marker_value, netlist);
00089 }

Here is the call graph for this function:

Here is the caller graph for this function:

void depth_first_traverse_parital_map ( nnode_t node,
int  traverse_mark_number,
netlist_t netlist 
)

Definition at line 94 of file partial_map.c.

00095 {
00096         int i, j;
00097         nnode_t *next_node;
00098         nnet_t *next_net;
00099 
00100         if (node->traverse_visited == traverse_mark_number)
00101         {
00102                 return;
00103         }
00104         else
00105         {
00106                 /* ELSE - this is a new node so depth visit it */
00107 
00108                 /* mark that we have visitied this node now */
00109                 node->traverse_visited = traverse_mark_number;
00110 
00111                 for (i = 0; i < node->num_output_pins; i++)
00112                 {
00113                         if (node->output_pins[i]->net == NULL)
00114                                 continue;
00115 
00116                         next_net = node->output_pins[i]->net;
00117                         for (j = 0; j < next_net->num_fanout_pins; j++)
00118                         {
00119                                 if (next_net->fanout_pins[j] == NULL)
00120                                         continue;
00121 
00122                                 next_node = next_net->fanout_pins[j]->node;
00123                                 if (next_node == NULL)
00124                                         continue;
00125 
00126                                 /* recursive call point */
00127                                 depth_first_traverse_parital_map(next_node, traverse_mark_number, netlist);
00128                         }
00129                 }
00130 
00131                 /* POST traverse  map the node since you might delete */
00132                 partial_map_node(node, traverse_mark_number, netlist);
00133         }
00134 }

Here is the call graph for this function:

Here is the caller graph for this function:

void instantiate_add_w_carry ( nnode_t node,
short  mark,
netlist_t netlist 
)

Definition at line 587 of file partial_map.c.

00588 {
00589         int width;
00590         int width_a;
00591         int width_b;
00592         int i;
00593         nnode_t **new_add_cells;
00594         nnode_t **new_carry_cells;
00595 
00596         oassert(node->num_input_pins > 0);
00597         oassert(node->num_input_port_sizes == 2);
00598         width = node->output_port_sizes[0];
00599         width_a = node->input_port_sizes[0];
00600         width_b = node->input_port_sizes[1];
00601 
00602         new_add_cells = (nnode_t**)malloc(sizeof(nnode_t*)*width);
00603         new_carry_cells = (nnode_t**)malloc(sizeof(nnode_t*)*width);
00604 
00605         /* create the adder units and the zero unit */
00606         for (i = 0; i < width; i++)
00607         {
00608                 new_add_cells[i] = make_3port_gate(ADDER_FUNC, 1, 1, 1, 1, node, mark);
00609                 if (i < width - 1)
00610                 {
00611                         new_carry_cells[i] = make_3port_gate(CARRY_FUNC, 1, 1, 1, 1, node, mark);
00612                 }
00613         }
00614 
00615         /* ground first carry in */
00616         add_a_input_pin_to_node_spot_idx(new_add_cells[0], get_a_zero_pin(netlist), 0);
00617         if (i > 1)
00618         {
00619                 add_a_input_pin_to_node_spot_idx(new_carry_cells[0], get_a_zero_pin(netlist), 0);
00620         }
00621 
00622         /* connect inputs */
00623         for(i = 0; i < width; i++)
00624         {
00625                 if (i < width_a)
00626                 {
00627                         /* join the A port up to adder */
00628                         remap_pin_to_new_node(node->input_pins[i], new_add_cells[i], 1);
00629                         if (i < width - 1)
00630                                 add_a_input_pin_to_node_spot_idx(new_carry_cells[i], copy_input_npin(new_add_cells[i]->input_pins[1]), 1);
00631                 }
00632                 else 
00633                 {
00634                         add_a_input_pin_to_node_spot_idx(new_add_cells[i], get_a_zero_pin(netlist), 1);
00635                         if (i < width - 1)
00636                                 add_a_input_pin_to_node_spot_idx(new_carry_cells[i], get_a_zero_pin(netlist), 1);
00637                 }
00638 
00639                 if (i < width_b)
00640                 {
00641                         /* join the B port up to adder */
00642                         remap_pin_to_new_node(node->input_pins[i+width_a], new_add_cells[i], 2);
00643                         if (i < width - 1)
00644                                 add_a_input_pin_to_node_spot_idx(new_carry_cells[i], copy_input_npin(new_add_cells[i]->input_pins[2]), 2);
00645                 }
00646                 else
00647                 {
00648                         add_a_input_pin_to_node_spot_idx(new_add_cells[i], get_a_zero_pin(netlist), 2);
00649                         if (i < width - 1)
00650                                 add_a_input_pin_to_node_spot_idx(new_carry_cells[i], get_a_zero_pin(netlist), 2);
00651                 }
00652 
00653                 /* join that gate to the output */
00654                 remap_pin_to_new_node(node->output_pins[i], new_add_cells[i], 0);
00655         }
00656         
00657         /* connect carry outs with carry ins */
00658         for(i = 1; i < width; i++)
00659         {
00660                 connect_nodes(new_carry_cells[i-1], 0, new_add_cells[i], 0);
00661                 if (i < width - 1)
00662                         connect_nodes(new_carry_cells[i-1], 0, new_carry_cells[i], 0);
00663         }
00664 
00665         free(new_add_cells);
00666         free(new_carry_cells);
00667 }

Here is the call graph for this function:

Here is the caller graph for this function:

void instantiate_bitwise_logic ( nnode_t node,
operation_list  op,
short  mark,
netlist_t netlist 
)

Definition at line 493 of file partial_map.c.

00494 {
00495         int width;
00496         int i;
00497         int port_B_offset;
00498         int width_a;
00499         int width_b;
00500         nnode_t **new_logic_cells;
00501         operation_list cell_op;
00502 
00503         oassert(node->num_input_pins > 0);
00504         oassert(node->num_input_port_sizes == 2);
00505         /* setup the calculations for padding and indexing */
00506         width = node->output_port_sizes[0];
00507         width_a = node->input_port_sizes[0];
00508         width_b = node->input_port_sizes[1];
00509         port_B_offset = width_a;
00510 
00511         switch (op)
00512         {
00513                 case BITWISE_AND:
00514                         cell_op = LOGICAL_AND;
00515                         break;
00516                 case BITWISE_OR:
00517                         cell_op = LOGICAL_OR;
00518                         break;
00519                 case BITWISE_NAND:
00520                         cell_op = LOGICAL_NAND;
00521                         break;
00522                 case BITWISE_NOR:
00523                         cell_op = LOGICAL_NOR;
00524                         break;
00525                 case BITWISE_XNOR:
00526                         cell_op = LOGICAL_XNOR;
00527                         break;
00528                 case BITWISE_XOR:
00529                         cell_op = LOGICAL_XOR;
00530                         break;
00531                 default:
00532                         oassert(FALSE);
00533                         break;
00534         }
00535         new_logic_cells = (nnode_t**)malloc(sizeof(nnode_t*)*width);
00536         for (i = 0; i < width; i++)
00537         {
00538                 /* instantiate the cells */
00539                 new_logic_cells[i] = make_2port_gate(cell_op, 1, 1, 1, node, mark);
00540         }
00541 
00542         /* connect inputs.  In the case that a signal is smaller than the other then zero pad */
00543         for(i = 0; i < width; i++)
00544         {
00545                 /* Joining the inputs to the input 1 of that gate */
00546                 if (i < width_a)
00547                 {
00548                         if (i < width_b)
00549                         {
00550                                 /* IF - this current input will also have a corresponding b_port input then join it to the gate */
00551                                 remap_pin_to_new_node(node->input_pins[i], new_logic_cells[i], 0);
00552                         }
00553                         else
00554                         {
00555                                 /* ELSE - the B input does not exist, so this answer goes right through */
00556                                 add_a_input_pin_to_node_spot_idx(new_logic_cells[i], get_a_zero_pin(netlist), 0);
00557                         }
00558                 }
00559 
00560                 if (i < width_b)
00561                 {
00562                         if (i < width_a)
00563                         {
00564                                 /* IF - this current input will also have a corresponding a_port input then join it to the gate */
00565                                 /* Joining the inputs to the input 2 of that gate */
00566                                 remap_pin_to_new_node(node->input_pins[i+port_B_offset], new_logic_cells[i], 1);
00567                         }
00568                         else
00569                         {
00570                                 /* ELSE - the A input does not exist, so this answer goes right through */
00571                                 add_a_input_pin_to_node_spot_idx(new_logic_cells[i], get_a_zero_pin(netlist), 1);
00572                         }
00573                 }
00574 
00575                 remap_pin_to_new_node(node->output_pins[i], new_logic_cells[i], 0);
00576         }
00577 
00578         free(new_logic_cells);
00579 }

Here is the call graph for this function:

Here is the caller graph for this function:

void instantiate_bitwise_reduction ( nnode_t node,
operation_list  op,
short  mark,
netlist_t netlist 
)

Definition at line 424 of file partial_map.c.

00425 {
00426         int width;
00427         int i;
00428         int width_a;
00429         nnode_t *new_logic_cell;
00430         operation_list cell_op;
00431 
00432         oassert(node->num_input_pins > 0);
00433         oassert(node->num_input_port_sizes == 1);
00434         oassert(node->output_port_sizes[0] == 1);
00435         /* setup the calculations for padding and indexing */
00436         width = node->output_port_sizes[0];
00437         width_a = node->input_port_sizes[0];
00438 
00439         switch (op)
00440         {
00441                 case BITWISE_AND:
00442                 case LOGICAL_AND:
00443                         cell_op = LOGICAL_AND;
00444                         break;
00445                 case BITWISE_OR:
00446                 case LOGICAL_OR:
00447                         cell_op = LOGICAL_OR;
00448                         break;
00449                 case BITWISE_NAND:
00450                 case LOGICAL_NAND:
00451                         cell_op = LOGICAL_NAND;
00452                         break;
00453                 case BITWISE_NOR:
00454                 case LOGICAL_NOR:
00455                         cell_op = LOGICAL_NOR;
00456                         break;
00457                 case BITWISE_XNOR:
00458                 case LOGICAL_XNOR:
00459                         cell_op = LOGICAL_XNOR;
00460                         break;
00461                 case BITWISE_XOR:
00462                 case LOGICAL_XOR:
00463                         cell_op = LOGICAL_XOR;
00464                         break;
00465                 default:
00466                         oassert(FALSE);
00467         }
00468         /* instantiate the cells */
00469         new_logic_cell = make_1port_logic_gate(cell_op, width_a, node, mark);
00470 
00471         /* connect inputs.  In the case that a signal is smaller than the other then zero pad */
00472         for(i = 0; i < width_a; i++)
00473         {
00474                 /* Joining the inputs to the input 1 of that gate */
00475                 if (i < width_a)
00476                 {
00477                         remap_pin_to_new_node(node->input_pins[i], new_logic_cell, i);
00478                 }
00479                 else
00480                 {
00481                         /* ELSE - the B input does not exist, so this answer goes right through */
00482                         add_a_input_pin_to_node_spot_idx(new_logic_cell, get_a_zero_pin(netlist), i);
00483                 }
00484         }
00485 
00486         remap_pin_to_new_node(node->output_pins[0], new_logic_cell, 0);
00487 }

Here is the call graph for this function:

Here is the caller graph for this function:

void instantiate_buffer ( nnode_t node,
short  mark,
netlist_t netlist 
)

Definition at line 340 of file partial_map.c.

00341 {
00342         int width = node->num_input_pins;
00343         int i;
00344 
00345         /* for now we just pass the signals dierectly through */
00346         for (i = 0; i < width; i++)
00347         {
00348                 int idx_2_buffer = node->input_pins[i]->pin_net_idx;
00349 
00350                 /* join all fanouts of the output net with the input pins net */
00351                 join_nets(node->input_pins[i]->net, node->output_pins[i]->net);
00352 
00353                 /* erase the pointer to this buffer */
00354                 node->input_pins[i]->net->fanout_pins[idx_2_buffer] = NULL;
00355         }
00356 }

Here is the call graph for this function:

Here is the caller graph for this function:

void instantiate_EQUAL ( nnode_t node,
short  type,
short  mark,
netlist_t netlist 
)

Definition at line 834 of file partial_map.c.

00835 {
00836         int width_a;
00837         int width_b;
00838         int width_max;
00839         int i;
00840         int port_B_offset;
00841         nnode_t *xnor_gate;
00842         nnode_t *logical_and_gate;
00843 
00844         oassert(node->num_output_pins == 1);
00845         oassert(node->num_input_pins > 0);
00846         oassert(node->num_input_port_sizes == 2);
00847         width_a = node->input_port_sizes[0];
00848         width_b = node->input_port_sizes[1];
00849         width_max = width_a > width_b ? width_a : width_b;
00850         port_B_offset = width_a;
00851 
00852         /* build an xnor bitwise XNOR */
00853         xnor_gate = make_2port_gate(LOGICAL_XNOR, width_a, width_b, width_max, node, mark);
00854         /* build an and bitwise AND */
00855         logical_and_gate = make_1port_logic_gate(LOGICAL_AND, width_max, node, mark);
00856 
00857         /* connect inputs.  In the case that a signal is smaller than the other then zero pad */
00858         for(i = 0; i < width_max; i++)
00859         {
00860                 /* Joining the inputs to the input 1 of that gate */
00861                 if (i < width_a)
00862                 {
00863                         if (i < width_b)
00864                         {
00865                                 /* IF - this current input will also have a corresponding b_port input then join it to the gate */
00866                                 remap_pin_to_new_node(node->input_pins[i], xnor_gate, i);
00867                         }
00868                         else
00869                         {
00870                                 /* ELSE - the B input does not exist, so this answer goes right through */
00871                                 add_a_input_pin_to_node_spot_idx(xnor_gate, get_a_zero_pin(netlist), i);
00872                         }
00873                 }
00874 
00875                 if (i < width_b)
00876                 {
00877                         if (i < width_a)
00878                         {
00879                                 /* IF - this current input will also have a corresponding a_port input then join it to the gate */
00880                                 /* Joining the inputs to the input 2 of that gate */
00881                                 remap_pin_to_new_node(node->input_pins[i+port_B_offset], xnor_gate, i+port_B_offset);
00882                         }
00883                         else
00884                         {
00885                                 /* ELSE - the A input does not exist, so this answer goes right through */
00886                                 add_a_input_pin_to_node_spot_idx(xnor_gate, get_a_zero_pin(netlist), i+port_B_offset);
00887                         }
00888                 }
00889 
00890                 /* hook it up to the logcial AND */
00891                 connect_nodes(xnor_gate, i, logical_and_gate, i);
00892         }
00893 
00894         /* join that gate to the output */
00895         remap_pin_to_new_node(node->output_pins[0], logical_and_gate, 0);
00896 
00897         if (type == LOGICAL_EQUAL)
00898                 instantiate_bitwise_logic(xnor_gate, BITWISE_XNOR, mark, netlist);
00899         else if (type == NOT_EQUAL)
00900                 instantiate_bitwise_logic(xnor_gate, BITWISE_XOR, mark, netlist);
00901         /* Don't need to instantiate a Logic and gate since it is a function itself */
00902 
00903         oassert(logical_and_gate->num_output_pins == 1);
00904 }

Here is the call graph for this function:

Here is the caller graph for this function:

void instantiate_GE ( nnode_t node,
short  type,
short  mark,
netlist_t netlist 
)

Definition at line 1050 of file partial_map.c.

01051 {
01052         int width_a;
01053         int width_b;
01054         int width_max;
01055         int i;
01056         int port_B_offset;
01057         int port_A_offset;
01058         nnode_t *equal;
01059         nnode_t *gt;
01060         nnode_t *logical_or_final_gate;
01061 
01062         oassert(node->num_output_pins == 1);
01063         oassert(node->num_input_pins > 0);
01064         oassert(node->num_input_port_sizes == 2);
01065         oassert(node->input_port_sizes[0] == node->input_port_sizes[1]);
01066         width_a = node->input_port_sizes[0];
01067         width_b = node->input_port_sizes[1];
01068         oassert(width_a == width_b);
01069         width_max = width_a > width_b ? width_a : width_b;
01070 
01071         /* swaps ports A and B */
01072         if (type == GTE)
01073         {
01074                 port_A_offset = 0;
01075                 port_B_offset = width_a;
01076         }
01077         else if (type == LTE)
01078         {
01079                 port_A_offset = width_b;
01080                 port_B_offset = 0;
01081         }
01082 
01083         /* build an xnor bitwise XNOR */
01084         equal = make_2port_gate(LOGICAL_EQUAL, width_a, width_b, 1, node, mark);
01085         gt = make_2port_gate(GT, width_a, width_b, 1, node, mark);
01086         logical_or_final_gate = make_1port_logic_gate(LOGICAL_OR, 2, node, mark);
01087 
01088         /* connect inputs.  In the case that a signal is smaller than the other then zero pad */
01089         for(i = 0; i < width_max; i++)
01090         {
01091                 /* Joining the inputs to the input 1 of that gate */
01092                 if (i < width_a)
01093                 {
01094                         /* IF - this current input will also have a corresponding b_port input then join it to the gate */
01095                         remap_pin_to_new_node(node->input_pins[i+port_A_offset], equal, i+port_A_offset);
01096                         add_a_input_pin_to_node_spot_idx(gt, copy_input_npin(equal->input_pins[i+port_A_offset]), i+port_A_offset);
01097                 }
01098                 else
01099                 {
01100                         /* ELSE - the B input does not exist, so this answer goes right through */
01101                         add_a_input_pin_to_node_spot_idx(equal, get_a_zero_pin(netlist), i+port_A_offset);
01102                         add_a_input_pin_to_node_spot_idx(gt, get_a_zero_pin(netlist), i+port_A_offset);
01103                 }
01104 
01105                 if (i < width_b)
01106                 {
01107                         /* IF - this current input will also have a corresponding a_port input then join it to the gate */
01108                         /* Joining the inputs to the input 2 of that gate */
01109                         remap_pin_to_new_node(node->input_pins[i+port_B_offset], equal, i+port_B_offset);
01110                         add_a_input_pin_to_node_spot_idx(gt, copy_input_npin(equal->input_pins[i+port_B_offset]), i+port_B_offset);
01111                 }
01112                 else
01113                 {
01114                         /* ELSE - the A input does not exist, so this answer goes right through */
01115                         add_a_input_pin_to_node_spot_idx(equal, get_a_zero_pin(netlist), i+port_B_offset);
01116                         add_a_input_pin_to_node_spot_idx(gt, get_a_zero_pin(netlist), i+port_B_offset);
01117                 }
01118         }
01119         connect_nodes(equal, 0, logical_or_final_gate, 0);
01120         connect_nodes(gt, 0, logical_or_final_gate, 1);
01121 
01122         /* join that gate to the output */
01123         remap_pin_to_new_node(node->output_pins[0], logical_or_final_gate, 0);
01124         oassert(logical_or_final_gate->num_output_pins == 1);
01125 
01126         /* make the two intermediate gates */
01127         instantiate_EQUAL(equal, LOGICAL_EQUAL, mark, netlist);
01128         instantiate_GT(gt, GT, mark, netlist);
01129 }

Here is the call graph for this function:

Here is the caller graph for this function:

void instantiate_GT ( nnode_t node,
short  type,
short  mark,
netlist_t netlist 
)

Definition at line 911 of file partial_map.c.

00912 {
00913         int width_a;
00914         int width_b;
00915         int width_max;
00916         int i;
00917         int port_A_offset;
00918         int port_B_offset;
00919         int port_A_index;
00920         int port_B_index;
00921         int index = 0;
00922         nnode_t *xor_gate;
00923         nnode_t *logical_or_gate;
00924         nnode_t **or_cells;
00925         nnode_t **gt_cells;
00926 
00927         oassert(node->num_output_pins == 1);
00928         oassert(node->num_input_pins > 0);
00929         oassert(node->num_input_port_sizes == 2);
00930         oassert(node->input_port_sizes[0] == node->input_port_sizes[1]);
00931         width_a = node->input_port_sizes[0];
00932         width_b = node->input_port_sizes[1];
00933         width_max = width_a > width_b ? width_a : width_b;
00934 
00935         /* swaps ports A and B */
00936         if (type == GT)
00937         {
00938                 port_A_offset = 0;
00939                 port_B_offset = width_a;
00940                 port_A_index = 0;
00941                 port_B_index = width_a-1;
00942         }
00943         else if (type == LT)
00944         {
00945                 port_A_offset = width_b;
00946                 port_B_offset = 0;
00947                 port_A_index = width_b-1;
00948                 port_B_index = 0;
00949         }
00950 
00951         /* xor gate identifies if any bits don't match */
00952         xor_gate = make_2port_gate(LOGICAL_XOR, width_a-1, width_b-1, width_max-1, node, mark);
00953         /* collects all the GT signals and determines if gt */
00954         logical_or_gate = make_1port_logic_gate(LOGICAL_OR, width_max, node, mark);
00955         /* collects a chain if any 1 happens than the GT cells output 0 */
00956         or_cells = (nnode_t**)malloc(sizeof(nnode_t*)*width_max-1);
00957         /* each cell checks if A > B and sends out a 1 if history has no 1s (3rd input) */
00958         gt_cells = (nnode_t**)malloc(sizeof(nnode_t*)*width_max);
00959 
00960         for (i = 0; i < width_max; i++)
00961         {
00962                 gt_cells[i] = make_3port_gate(GT, 1, 1, 1, 1, node, mark);
00963                 if (i < width_max-1)
00964                 {
00965                         or_cells[i] = make_2port_gate(LOGICAL_OR, 1, 1, 1, node, mark);
00966                 }
00967         }
00968 
00969         /* connect inputs.  In the case that a signal is smaller than the other then zero pad */
00970         for(i = 0; i < width_max; i++)
00971         {
00972                 /* Joining the inputs to the input 1 of that gate */
00973                 if (i < width_a)
00974                 {
00975                         /* IF - this current input will also have a corresponding b_port input then join it to the gate */
00976                         remap_pin_to_new_node(node->input_pins[i+port_A_offset], gt_cells[i], 0);
00977                         if (i > 0)
00978                                 add_a_input_pin_to_node_spot_idx(xor_gate, copy_input_npin(gt_cells[i]->input_pins[0]), index+port_A_index);
00979                 }
00980                 else
00981                 {
00982                         /* ELSE - the B input does not exist, so this answer goes right through */
00983                         add_a_input_pin_to_node_spot_idx(gt_cells[i], get_a_zero_pin(netlist), 0);
00984                         if (i > 0)
00985                                 add_a_input_pin_to_node_spot_idx(xor_gate, get_a_zero_pin(netlist), index+port_A_index);
00986                 }
00987 
00988                 if (i < width_b)
00989                 {
00990                         /* IF - this current input will also have a corresponding a_port input then join it to the gate */
00991                         /* Joining the inputs to the input 2 of that gate */
00992                         remap_pin_to_new_node(node->input_pins[i+port_B_offset], gt_cells[i], 1);
00993                         if (i > 0)
00994                                 add_a_input_pin_to_node_spot_idx(xor_gate, copy_input_npin(gt_cells[i]->input_pins[1]), index+port_B_index);
00995                 }
00996                 else
00997                 {
00998                         /* ELSE - the A input does not exist, so this answer goes right through */
00999                         add_a_input_pin_to_node_spot_idx(gt_cells[i], get_a_zero_pin(netlist), 1);
01000                         if (i > 0)
01001                                 add_a_input_pin_to_node_spot_idx(xor_gate, get_a_zero_pin(netlist), index+port_B_index);
01002                 }
01003 
01004                 if (i < width_max-1)
01005                 {
01006                         /* number of OR gates */
01007                         if (i < width_max-2)
01008                         {
01009                                 /* connect the msb or to the next lower bit */
01010                                 connect_nodes(or_cells[i+1], 0, or_cells[i], 1);
01011                         }
01012                         else
01013                         {
01014                                 /* deal with the first greater than test which autom gets a zero */
01015                                 add_a_input_pin_to_node_spot_idx(or_cells[i], get_a_zero_pin(netlist), 1);
01016                         }
01017 
01018                         /* get all the equals with the or gates */
01019                         connect_nodes(xor_gate, i, or_cells[i], 0);
01020                         connect_nodes(or_cells[i], 0, gt_cells[i], 2);
01021                         
01022                 }
01023                 else
01024                 {
01025                         /* deal with the first greater than test which autom gets a zero */
01026                         add_a_input_pin_to_node_spot_idx(gt_cells[i], get_a_zero_pin(netlist), 2);
01027                 }
01028 
01029                 /* hook it up to the logcial AND */
01030                 connect_nodes(gt_cells[i], 0, logical_or_gate, i);
01031 
01032                 if (i > 0)
01033                 {
01034                         index++;
01035                 }
01036         }
01037 
01038         /* join that gate to the output */
01039         remap_pin_to_new_node(node->output_pins[0], logical_or_gate, 0);
01040         oassert(logical_or_gate->num_output_pins == 1);
01041 
01042         instantiate_bitwise_logic(xor_gate, BITWISE_XOR, mark, netlist);
01043 }

Here is the call graph for this function:

Here is the caller graph for this function:

void instantiate_logical_logic ( nnode_t node,
operation_list  op,
short  mark,
netlist_t netlist 
)

Definition at line 361 of file partial_map.c.

00362 {
00363         int i;
00364         int port_B_offset;
00365         int width_a;
00366         int width_b;
00367         nnode_t *new_logic_cell;
00368         nnode_t *reduction1;
00369         nnode_t *reduction2;
00370 
00371         oassert(node->num_input_pins > 0);
00372         oassert(node->num_input_port_sizes == 2);
00373         oassert(node->num_output_pins == 1);
00374         /* setup the calculations for padding and indexing */
00375         width_a = node->input_port_sizes[0];
00376         width_b = node->input_port_sizes[1];
00377         port_B_offset = width_a;
00378 
00379         /* instantiate the cells */
00380         new_logic_cell = make_1port_logic_gate(op, 2, node, mark);
00381         reduction1 = make_1port_logic_gate(BITWISE_OR, width_a, node, mark);
00382         reduction2 = make_1port_logic_gate(BITWISE_OR, width_b, node, mark);
00383 
00384         /* connect inputs.  In the case that a signal is smaller than the other then zero pad */
00385         for(i = 0; i < width_a; i++)
00386         {
00387                 /* Joining the inputs to the input 1 of that gate */
00388                 if (i < width_a)
00389                 {
00390                         remap_pin_to_new_node(node->input_pins[i], reduction1, i);
00391                 }
00392                 else
00393                 {
00394                         /* ELSE - the B input does not exist, so this answer goes right through */
00395                         add_a_input_pin_to_node_spot_idx(reduction1, get_a_zero_pin(netlist), i);
00396                 }
00397         }
00398         for(i = 0; i < width_b; i++)
00399         {
00400                 /* Joining the inputs to the input 1 of that gate */
00401                 if (i < width_b)
00402                 {
00403                         remap_pin_to_new_node(node->input_pins[i+port_B_offset], reduction2, i);
00404                 }
00405                 else
00406                 {
00407                         /* ELSE - the B input does not exist, so this answer goes right through */
00408                         add_a_input_pin_to_node_spot_idx(reduction2, get_a_zero_pin(netlist), i);
00409                 }
00410         }
00411 
00412         connect_nodes(reduction1, 0, new_logic_cell, 0);
00413         connect_nodes(reduction2, 0, new_logic_cell, 1);
00414 
00415         instantiate_bitwise_reduction(reduction1, BITWISE_OR, mark, netlist);
00416         instantiate_bitwise_reduction(reduction2, BITWISE_OR, mark, netlist);
00417 
00418         remap_pin_to_new_node(node->output_pins[0], new_logic_cell, 0);
00419 }

Here is the call graph for this function:

Here is the caller graph for this function:

void instantiate_multi_port_mux ( nnode_t node,
short  mark,
netlist_t netlist 
)

Definition at line 263 of file partial_map.c.

00264 {
00265         int i, j;
00266         int width_of_one_hot_logic;
00267         int num_ports;
00268         int port_offset;
00269         nnode_t **muxes;
00270         
00271         /* setup the calculations for padding and indexing */
00272         width_of_one_hot_logic = node->input_port_sizes[0];
00273         num_ports = node->num_input_port_sizes;
00274         port_offset = node->input_port_sizes[1];
00275 
00276         muxes = (nnode_t**)malloc(sizeof(nnode_t*)*(num_ports-1));
00277         for(i = 0; i < num_ports-1; i++)
00278         {
00279                 muxes[i] = make_2port_gate(MUX_2, width_of_one_hot_logic, width_of_one_hot_logic, 1, node, mark);
00280         }
00281 
00282         for(j = 0; j < num_ports - 1; j++)
00283         {
00284                 if (j == 0)
00285                 {
00286                         for(i = 0; i < width_of_one_hot_logic; i++)
00287                         {
00288                                 /* map the inputs to the muxt */
00289                                 remap_pin_to_new_node(node->input_pins[i+(j+1)*port_offset], muxes[j], width_of_one_hot_logic+i);
00290                                 /* map the one hot logic control */
00291                                 remap_pin_to_new_node(node->input_pins[i], muxes[j], i);
00292                         }
00293                 }
00294                 else
00295                 {
00296                         for(i = 0; i < width_of_one_hot_logic; i++)
00297                         {
00298                                 /* map the inputs to the muxt */
00299                                 remap_pin_to_new_node(node->input_pins[i+(j+1)*port_offset], muxes[j], width_of_one_hot_logic+i);
00300                                 /* map the one hot logic control */
00301                                 add_a_input_pin_to_node_spot_idx(muxes[j], copy_input_npin(muxes[0]->input_pins[i]), i);
00302                         }
00303                 }
00304                 /* now hookup outputs */
00305                 remap_pin_to_new_node(node->output_pins[j], muxes[j], 0);
00306         }
00307 }

Here is the call graph for this function:

Here is the caller graph for this function:

void instantiate_not_logic ( nnode_t node,
short  mark,
netlist_t netlist 
)

Definition at line 312 of file partial_map.c.

00313 {
00314         int width = node->num_input_pins;
00315         nnode_t **new_not_cells;
00316         int i;
00317 
00318         new_not_cells = (nnode_t**)malloc(sizeof(nnode_t*)*width);
00319 
00320         for (i = 0; i < width; i++)
00321         {
00322                 new_not_cells[i] = make_not_gate(node, mark);
00323         }
00324 
00325         /* connect inputs and outputs */
00326         for(i = 0; i < width; i++)
00327         {
00328                 /* Joining the inputs to the new soft NOT GATES */
00329                 remap_pin_to_new_node(node->input_pins[i], new_not_cells[i], 0);
00330                 remap_pin_to_new_node(node->output_pins[i], new_not_cells[i], 0);
00331         }
00332 
00333         free(new_not_cells);
00334 }

Here is the call graph for this function:

Here is the caller graph for this function:

void instantiate_shift_left_or_right ( nnode_t node,
short  type,
short  mark,
netlist_t netlist 
)

Definition at line 1135 of file partial_map.c.

01136 {
01137         /* these variables are used in an attempt so that I don't need if cases.  Probably a bad idea, but fun */
01138         int width;
01139         int i;
01140         int shift_size;
01141         nnode_t *buf_node;
01142 
01143         width = node->input_port_sizes[0];
01144 
01145         if (node->related_ast_node->children[1]->type == NUMBERS)
01146         {
01147                 /* record the size of the shift */
01148                 shift_size = node->related_ast_node->children[1]->types.number.value;
01149         }
01150         else
01151         {
01152                 error_message(NETLIST_ERROR, node->related_ast_node->line_number, node->related_ast_node->file_number, "Odin only supports constant shifts at present\n");
01153         }       
01154 
01155         buf_node = make_1port_gate(BUF_NODE, width, width, node, mark);
01156 
01157         if (type == SL) 
01158         {
01159                 /* IF shift left */
01160 
01161                 /* connect inputs to outputs */
01162                 for(i = 0; i < width - shift_size; i++)
01163                 {
01164                         // connect higher output pin to lower input pin
01165                         remap_pin_to_new_node(node->input_pins[i], buf_node, i+shift_size);
01166                 }
01167         
01168                 /* connect ZERO to outputs that don't have inputs connected */
01169                 for(i = 0; i < shift_size; i++)
01170                 {
01171                         // connect 0 to lower outputs
01172                         add_a_input_pin_to_node_spot_idx(buf_node, get_a_zero_pin(netlist), i);
01173                 }
01174         
01175                 for(i = width-1; i >= width-shift_size; i--)
01176                 {
01177                         /* demap the node from the net */
01178                         int idx_2_buffer = node->input_pins[i]->pin_net_idx;
01179                         node->input_pins[i]->net->fanout_pins[idx_2_buffer] = NULL;
01180                 }
01181         }
01182         else
01183         {
01184                 /* ELSE shift right */
01185 
01186                 /* connect inputs to outputs */
01187                 for(i = width - 1; i >= shift_size; i--)
01188                 {
01189                         // connect higher input pin to lower output pin
01190                         remap_pin_to_new_node(node->input_pins[i], buf_node, i-shift_size);
01191                 }
01192         
01193                 /* connect ZERO to outputs that don't have inputs connected */
01194                 for(i = width - 1; i >= width - shift_size; i--)
01195                 {
01196                         // connect 0 to lower outputs
01197                         add_a_input_pin_to_node_spot_idx(buf_node, get_a_zero_pin(netlist), i);
01198                 }
01199                 for(i = 0; i < shift_size; i++)
01200                 {
01201                         /* demap the node from the net */
01202                         int idx_2_buffer = node->input_pins[i]->pin_net_idx;
01203                         node->input_pins[i]->net->fanout_pins[idx_2_buffer] = NULL;
01204                 }
01205         }
01206 
01207         for(i = 0; i < width; i++)
01208         {
01209                 remap_pin_to_new_node(node->output_pins[i], buf_node, i);
01210         }
01211         /* instantiate the buffer */
01212         instantiate_buffer(buf_node, mark, netlist);
01213 }

Here is the call graph for this function:

Here is the caller graph for this function:

void instantiate_sub_w_carry ( nnode_t node,
short  mark,
netlist_t netlist 
)

Definition at line 674 of file partial_map.c.

00675 {
00676         int width;
00677         int width_a;
00678         int width_b;
00679         int i;
00680         nnode_t **new_add_cells;
00681         nnode_t **new_carry_cells;
00682         nnode_t **new_not_cells;
00683 
00684         oassert(node->num_input_pins > 0);
00685         oassert(node->num_input_port_sizes == 2);
00686         width = node->output_port_sizes[0];
00687         width_a = node->input_port_sizes[0];
00688         width_b = node->input_port_sizes[1];
00689 
00690         new_add_cells = (nnode_t**)malloc(sizeof(nnode_t*)*width);
00691         new_carry_cells = (nnode_t**)malloc(sizeof(nnode_t*)*width);
00692         new_not_cells = (nnode_t**)malloc(sizeof(nnode_t*)*width);
00693 
00694         /* create the adder units and the zero unit */
00695         for (i = 0; i < width; i++)
00696         {
00697                 new_add_cells[i] = make_3port_gate(ADDER_FUNC, 1, 1, 1, 1, node, mark);
00698                 new_not_cells[i] = make_not_gate(node, mark);
00699                 if (i < width - 1)
00700                 {
00701                         new_carry_cells[i] = make_3port_gate(CARRY_FUNC, 1, 1, 1, 1, node, mark);
00702                 }
00703         }
00704 
00705         /* ground first carry in .  Note the one constant is inputted to start 2's complement */
00706         add_a_input_pin_to_node_spot_idx(new_add_cells[0], get_a_one_pin(netlist), 0);
00707         if (i > 1)
00708         {
00709                 add_a_input_pin_to_node_spot_idx(new_carry_cells[0], get_a_one_pin(netlist), 0);
00710         }
00711 
00712         /* connect inputs */
00713         for(i = 0; i < width; i++)
00714         {
00715                 if (i < width_a)
00716                 {
00717                         /* join the A port up to adder */
00718                         remap_pin_to_new_node(node->input_pins[i], new_add_cells[i], 1);
00719                         if (i < width - 1)
00720                                 add_a_input_pin_to_node_spot_idx(new_carry_cells[i], copy_input_npin(new_add_cells[i]->input_pins[1]), 1);
00721                 }
00722                 else
00723                 {
00724                         add_a_input_pin_to_node_spot_idx(new_add_cells[i], get_a_zero_pin(netlist), 1);
00725                         if (i < width - 1)
00726                                 add_a_input_pin_to_node_spot_idx(new_carry_cells[i], get_a_zero_pin(netlist), 1);
00727                 }
00728 
00729                 if (i < width_b)
00730                 {
00731                         /* join the B port up to adder */
00732                         remap_pin_to_new_node(node->input_pins[i+width_a], new_not_cells[i], 0);
00733                 }
00734                 else 
00735                 {
00736                         add_a_input_pin_to_node_spot_idx(new_not_cells[i], get_a_zero_pin(netlist), 0);
00737                 }
00738 
00739                 /* now hookup not to adder parts */
00740                 connect_nodes(new_not_cells[i], 0, new_add_cells[i], 2);
00741                 if (i < width - 1)
00742                         connect_nodes(new_not_cells[i], 0, new_carry_cells[i], 2);
00743 
00744                 /* join that gate to the output */
00745                 remap_pin_to_new_node(node->output_pins[i], new_add_cells[i], 0);
00746         }
00747         
00748         /* connect carry outs with carry ins */
00749         for(i = 1; i < width; i++)
00750         {
00751                 connect_nodes(new_carry_cells[i-1], 0, new_add_cells[i], 0);
00752                 if (i < width - 1)
00753                         connect_nodes(new_carry_cells[i-1], 0, new_carry_cells[i], 0);
00754         }
00755 
00756         free(new_add_cells);
00757         free(new_carry_cells);
00758 }

Here is the call graph for this function:

Here is the caller graph for this function:

void instantiate_unary_sub ( nnode_t node,
short  mark,
netlist_t netlist 
)

Definition at line 764 of file partial_map.c.

00765 {
00766         int width;
00767         int width_a;
00768         int i;
00769         nnode_t **new_add_cells;
00770         nnode_t **new_carry_cells;
00771         nnode_t **new_not_cells;
00772 
00773         oassert(node->num_input_pins > 0);
00774         oassert(node->num_input_port_sizes == 1);
00775         width = node->output_port_sizes[0];
00776         width_a = node->input_port_sizes[0];
00777 
00778         new_add_cells = (nnode_t**)malloc(sizeof(nnode_t*)*width);
00779         new_carry_cells = (nnode_t**)malloc(sizeof(nnode_t*)*width);
00780         new_not_cells = (nnode_t**)malloc(sizeof(nnode_t*)*width);
00781 
00782         /* create the adder units and the zero unit */
00783         for (i = 0; i < width; i++)
00784         {
00785                 new_add_cells[i] = make_3port_gate(ADDER_FUNC, 1, 1, 1, 1, node, mark);
00786                 new_not_cells[i] = make_not_gate(node, mark);
00787                 if (i < width - 1)
00788                 {
00789                         new_carry_cells[i] = make_3port_gate(CARRY_FUNC, 1, 1, 1, 1, node, mark);
00790                 }
00791         }
00792 
00793         /* ground first carry in .  Note the one constant is inputted to start 2's complement */
00794         add_a_input_pin_to_node_spot_idx(new_add_cells[0], get_a_one_pin(netlist), 0);
00795         if (i > 1)
00796         {
00797                 add_a_input_pin_to_node_spot_idx(new_carry_cells[0], get_a_one_pin(netlist), 0);
00798         }
00799 
00800         /* connect inputs */
00801         for(i = 0; i < width; i++)
00802         {
00803                 /* join the A port up to adder */
00804                 remap_pin_to_new_node(node->input_pins[i], new_not_cells[i], 0);
00805                 connect_nodes(new_not_cells[i], 0, new_add_cells[i], 1);
00806                 if (i < width - 1)
00807                         connect_nodes(new_not_cells[i], 0, new_carry_cells[i], 1);
00808 
00809                 add_a_input_pin_to_node_spot_idx(new_add_cells[i], get_a_zero_pin(netlist), 2);
00810                 if (i < width - 1)
00811                         add_a_input_pin_to_node_spot_idx(new_carry_cells[i], get_a_zero_pin(netlist), 2);
00812 
00813                 /* join that gate to the output */
00814                 remap_pin_to_new_node(node->output_pins[i], new_add_cells[i], 0);
00815         }
00816         
00817         /* connect carry outs with carry ins */
00818         for(i = 1; i < width; i++)
00819         {
00820                 connect_nodes(new_carry_cells[i-1], 0, new_add_cells[i], 0);
00821                 if (i < width - 1)
00822                         connect_nodes(new_carry_cells[i-1], 0, new_carry_cells[i], 0);
00823         }
00824 
00825         free(new_add_cells);
00826         free(new_carry_cells);
00827 }

Here is the call graph for this function:

Here is the caller graph for this function:

void partial_map_node ( nnode_t node,
short  traverse_number,
netlist_t netlist 
)

Definition at line 139 of file partial_map.c.

00140 {
00141         switch (node->type) 
00142         {
00143                 case BITWISE_NOT:
00144                         instantiate_not_logic(node, traverse_number, netlist);
00145                         break;
00146                 case BUF_NODE:
00147                         instantiate_buffer(node, traverse_number, netlist);
00148                         break;
00149 
00150                 case BITWISE_AND:
00151                 case BITWISE_OR:
00152                 case BITWISE_NAND:
00153                 case BITWISE_NOR:
00154                 case BITWISE_XNOR:
00155                 case BITWISE_XOR:
00156                         if (node->num_input_port_sizes == 2)
00157                         {
00158                                 instantiate_bitwise_logic(node, node->type, traverse_number, netlist);
00159                         }
00160                         else if (node->num_input_port_sizes == 1)
00161                         {
00162                                 instantiate_bitwise_reduction(node, node->type, traverse_number, netlist);
00163                         }
00164                         else    
00165                                 oassert(FALSE);
00166                         break;
00167 
00168                 case LOGICAL_OR:
00169                 case LOGICAL_AND:
00170                 case LOGICAL_NOR:
00171                 case LOGICAL_NAND:
00172                 case LOGICAL_XOR:
00173                 case LOGICAL_XNOR:
00174                         if (node->num_input_port_sizes == 2)
00175                         {
00176                                 instantiate_logical_logic(node, node->type, traverse_number, netlist);
00177                         }
00178                         break;
00179 
00180                 case LOGICAL_NOT:
00181                         /* don't need to do anything since this is a reduction */
00182                         break;
00183 
00184                 case ADD:
00185                         instantiate_add_w_carry(node, traverse_number, netlist);
00186                         break;
00187                 case MINUS:
00188                         if (node->num_input_port_sizes == 2)
00189                         {
00190                                 instantiate_sub_w_carry(node, traverse_number, netlist);
00191                         }
00192                         else if (node->num_input_port_sizes == 1)
00193                         {
00194                                 instantiate_unary_sub(node, traverse_number, netlist);
00195                         }
00196                         else
00197                                 oassert(FALSE);
00198                         break;
00199                 case LOGICAL_EQUAL:
00200                 case NOT_EQUAL:
00201                         instantiate_EQUAL(node, node->type, traverse_number, netlist);
00202                         break;
00203                 case GTE:
00204                 case LTE:
00205                         instantiate_GE(node, node->type, traverse_number, netlist);
00206                         break;
00207                 case GT:
00208                 case LT:
00209                         instantiate_GT(node, node->type, traverse_number, netlist);
00210                         break;
00211                 case SL:
00212                 case SR:
00213                         instantiate_shift_left_or_right(node, node->type, traverse_number, netlist);
00214                         break;
00215                 case MULTI_PORT_MUX:
00216                         instantiate_multi_port_mux(node, traverse_number, netlist);
00217                         break;
00218                 case MULTIPLY:
00219                         if (hard_multipliers != NULL)
00220                         {
00221 #ifdef VPR6
00222                                 if ((node->input_port_sizes[0] * node->input_port_sizes[1]) > min_mult)
00223                                         instantiate_hard_multiplier(node, traverse_number, netlist);
00224 #endif
00225                         }
00226                         else
00227                                 instantiate_simple_soft_multiplier(node, traverse_number, netlist);
00228                         break;
00229                 
00230                 case MEMORY:
00231                 case HARD_IP:
00232 #ifdef VPR6
00233                         instantiate_hard_block(node, traverse_number, netlist);
00234 #endif
00235                         break;
00236 
00237                 case ADDER_FUNC:
00238                 case CARRY_FUNC:
00239                 case MUX_2:
00240                 case INPUT_NODE:
00241                 case CLOCK_NODE:
00242                 case OUTPUT_NODE:
00243                 case GND_NODE:
00244                 case VCC_NODE:
00245                 case FF_NODE:
00246                         /* some nodes already in the form that is mapable */
00247                         break;
00248 
00249                 case CASE_EQUAL:
00250                 case CASE_NOT_EQUAL:
00251                 case DIVIDE:
00252                 case MODULO:
00253                 default:
00254                         oassert(FALSE);
00255                         break;
00256         }
00257 }

Here is the call graph for this function:

Here is the caller graph for this function:

void partial_map_top ( netlist_t netlist  ) 

Definition at line 61 of file partial_map.c.

00062 {
00063         /* depending on the output target choose how to do partial mapping */
00064         if (strcmp(configuration.output_type, "blif") == 0)
00065         {
00066                 /* do the partial map without any larger structures identified */
00067                 depth_first_traversal_to_partial_map(PARTIAL_MAP_TRAVERSE_VALUE, netlist);      
00068         }
00069 }

Here is the call graph for this function:

Here is the caller graph for this function:

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