#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"
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 |
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 }
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.