multipliers.c File Reference

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "types.h"
#include "node_creation_library.h"
#include "multipliers.h"
#include "read_xml_arch_file.h"
#include "util.h"
#include "netlist_utils.h"
#include "globals.h"
Include dependency graph for multipliers.c:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

void instantiate_simple_soft_multiplier (nnode_t *node, short mark, netlist_t *netlist)

Variables

t_model * hard_multipliers = NULL
struct s_linked_vptr * mult_list = NULL
int min_mult = 0
int * mults = NULL

Function Documentation

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

Definition at line 61 of file multipliers.c.

00062 {
00063         int width_a;
00064         int width_b;
00065         int width;
00066         int multiplier_width;
00067         int multiplicand_width;
00068         nnode_t **adders_for_partial_products;
00069         nnode_t ***partial_products;
00070         int multiplicand_offset_index;
00071         int multiplier_offset_index;
00072         int current_index;
00073         int i, j;
00074 
00075         /* need for an carry-ripple-adder for each of the bits of port B. */
00076         /* good question of which is better to put on the bottom of multiplier.  Larger means more smaller adds, or small is 
00077          * less large adds */
00078         oassert(node->num_output_pins > 0);
00079         oassert(node->num_input_pins > 0);
00080         oassert(node->num_input_port_sizes == 2);
00081         oassert(node->num_output_port_sizes == 1);
00082         width_a = node->input_port_sizes[0];
00083         width_b = node->input_port_sizes[1];
00084         width = node->output_port_sizes[0];
00085         multiplicand_width = width_b;
00086         multiplier_width = width_a;
00087         /* offset is related to which multport is chosen as the multiplicand */
00088         multiplicand_offset_index = width_a;
00089         multiplier_offset_index = 0;
00090 
00091         adders_for_partial_products = (nnode_t**)malloc(sizeof(nnode_t*)*multiplicand_width-1);
00092 
00093         /* need to generate partial products for each bit in width B. */
00094         partial_products = (nnode_t***)malloc(sizeof(nnode_t**)*multiplicand_width);
00095 
00096         /* generate the AND partial products */
00097         for (i = 0; i < multiplicand_width; i++)
00098         {
00099                 /* create the memory for each AND gate needed for the levels of partial products */
00100                 partial_products[i] = (nnode_t**)malloc(sizeof(nnode_t*)*multiplier_width);
00101                 
00102                 if (i < multiplicand_width - 1)
00103                 {
00104                         adders_for_partial_products[i] = make_2port_gate(ADD, multiplier_width+1, multiplier_width+1, multiplier_width+1, node, mark);
00105                 }
00106 
00107                 for (j = 0; j < multiplier_width; j++)
00108                 {
00109                         /* create each one of the partial products */
00110                         partial_products[i][j] = make_1port_logic_gate(LOGICAL_AND, 2, node, mark);
00111                 }
00112         }
00113 
00114         /* generate the coneections to the AND gates */
00115         for (i = 0; i < multiplicand_width; i++)
00116         {
00117                 for (j = 0; j < multiplier_width; j++)
00118                 {
00119                         /* hookup the input of B to each AND gate */
00120                         if (j == 0)
00121                         {
00122                                 /* IF - this is the first time we are mapping multiplicand port then can remap */ 
00123                                 remap_pin_to_new_node(node->input_pins[i+multiplicand_offset_index], partial_products[i][j], 0);
00124                         }
00125                         else
00126                         {
00127                                 /* ELSE - this needs to be a new ouput of the multiplicand port */
00128                                 add_a_input_pin_to_node_spot_idx(partial_products[i][j], copy_input_npin(partial_products[i][0]->input_pins[0]), 0);
00129                         }
00130 
00131                         /* hookup the input of the multiplier to each AND gate */
00132                         if (i == 0)
00133                         {
00134                                 /* IF - this is the first time we are mapping multiplier port then can remap */ 
00135                                 remap_pin_to_new_node(node->input_pins[j+multiplier_offset_index], partial_products[i][j], 1);
00136                         }
00137                         else
00138                         {
00139                                 /* ELSE - this needs to be a new ouput of the multiplier port */
00140                                 add_a_input_pin_to_node_spot_idx(partial_products[i][j], copy_input_npin(partial_products[0][j]->input_pins[1]), 1);
00141                         }
00142                 }
00143         }
00144 
00145         /* hookup each of the adders */
00146         for (i = 0; i < multiplicand_width-1; i++) // -1 since the first stage is a combo of partial products while all others are part of tree
00147         {
00148                 for (j = 0; j < multiplier_width+1; j++) // +1 since adders are one greater than multwidth to pass carry
00149                 {
00150                         /* join to port 1 of the add one of the partial products.  */
00151                         if (i == 0)
00152                         {
00153                                 /* IF - this is the first addition row, then adding two sets of partial products and first set is from the c0* */
00154                                 if (j < multiplier_width-1)
00155                                 {
00156                                         /* IF - we just take an element of the first list c[0][j+1]. */
00157                                         connect_nodes(partial_products[i][j+1], 0, adders_for_partial_products[i], j);
00158                                 }
00159                                 else
00160                                 {
00161                                         /* ELSE - this is the last input to the first adder, then we pass in 0 since no carry yet */
00162                                         add_a_input_pin_to_node_spot_idx(adders_for_partial_products[i], get_a_zero_pin(netlist), j);
00163                                 }
00164                         }
00165                         else if (j < multiplier_width)
00166                         {
00167                                 /* ELSE - this is the standard situation when we need to hookup this adder with a previous adder, r[i-1][j+1] */
00168                                 connect_nodes(adders_for_partial_products[i-1], j+1, adders_for_partial_products[i], j);
00169                         }
00170                         else
00171                         {
00172                                 add_a_input_pin_to_node_spot_idx(adders_for_partial_products[i], get_a_zero_pin(netlist), j);
00173                         }
00174                         
00175                         if (j < multiplier_width)
00176                         {
00177                                 /* IF - this is not most significant bit then just add current partial product */
00178                                 connect_nodes(partial_products[i+1][j], 0, adders_for_partial_products[i], j+multiplier_width+1);
00179                         }
00180                         else
00181                         {
00182                                 add_a_input_pin_to_node_spot_idx(adders_for_partial_products[i], get_a_zero_pin(netlist), j+multiplier_width+1);
00183                         }
00184                 }
00185         }
00186 
00187         current_index = 0;
00188         /* hookup the outputs */
00189         for (i = 0; i < width; i++)
00190         {
00191                 if (multiplicand_width == 1)
00192                 {
00193                         oassert(FALSE); // this is undealt with
00194                 }
00195                 else if (i == 0)
00196                 {
00197                         /* IF - this is the LSbit, then we use a pass through from the partial product */
00198                         remap_pin_to_new_node(node->output_pins[i], partial_products[0][0], 0);
00199                 }
00200                 else if (i < multiplicand_width - 1)
00201                 {
00202                         /* ELSE IF - these are the middle values that come from the LSbit of partial adders */
00203                         remap_pin_to_new_node(node->output_pins[i], adders_for_partial_products[i-1], 0);
00204                 }
00205                 else 
00206                 {
00207                         /* ELSE - the final outputs are straight from the outputs of the last adder */
00208                         remap_pin_to_new_node(node->output_pins[i], adders_for_partial_products[multiplicand_width-2], current_index);
00209                         current_index++;
00210                 }
00211         }
00212 
00213         /* soft map the adders if they need to be mapped */
00214         for (i = 0; i < multiplicand_width - 1; i++)
00215         {
00216                 instantiate_add_w_carry(adders_for_partial_products[i], mark, netlist);
00217         }
00218 
00219         /* Cleanup everything */
00220         if (adders_for_partial_products != NULL)
00221         {
00222                 free(adders_for_partial_products);
00223         }
00224         /* generate the AND partial products */
00225         for (i = 0; i < multiplicand_width; i++)
00226         {
00227                 /* create the memory for each AND gate needed for the levels of partial products */
00228                 if (partial_products[i] != NULL)
00229                 {
00230                         free(partial_products[i]);
00231                 }
00232         }
00233         if (partial_products != NULL)
00234         {
00235                 free(partial_products);
00236         }
00237 }

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

t_model* hard_multipliers = NULL

Definition at line 36 of file multipliers.c.

int min_mult = 0

Definition at line 38 of file multipliers.c.

struct s_linked_vptr* mult_list = NULL

Definition at line 37 of file multipliers.c.

int* mults = NULL

Definition at line 39 of file multipliers.c.

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