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
00076
00077
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
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
00094 partial_products = (nnode_t***)malloc(sizeof(nnode_t**)*multiplicand_width);
00095
00096
00097 for (i = 0; i < multiplicand_width; i++)
00098 {
00099
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
00110 partial_products[i][j] = make_1port_logic_gate(LOGICAL_AND, 2, node, mark);
00111 }
00112 }
00113
00114
00115 for (i = 0; i < multiplicand_width; i++)
00116 {
00117 for (j = 0; j < multiplier_width; j++)
00118 {
00119
00120 if (j == 0)
00121 {
00122
00123 remap_pin_to_new_node(node->input_pins[i+multiplicand_offset_index], partial_products[i][j], 0);
00124 }
00125 else
00126 {
00127
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
00132 if (i == 0)
00133 {
00134
00135 remap_pin_to_new_node(node->input_pins[j+multiplier_offset_index], partial_products[i][j], 1);
00136 }
00137 else
00138 {
00139
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
00146 for (i = 0; i < multiplicand_width-1; i++)
00147 {
00148 for (j = 0; j < multiplier_width+1; j++)
00149 {
00150
00151 if (i == 0)
00152 {
00153
00154 if (j < multiplier_width-1)
00155 {
00156
00157 connect_nodes(partial_products[i][j+1], 0, adders_for_partial_products[i], j);
00158 }
00159 else
00160 {
00161
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
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
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
00189 for (i = 0; i < width; i++)
00190 {
00191 if (multiplicand_width == 1)
00192 {
00193 oassert(FALSE);
00194 }
00195 else if (i == 0)
00196 {
00197
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
00203 remap_pin_to_new_node(node->output_pins[i], adders_for_partial_products[i-1], 0);
00204 }
00205 else
00206 {
00207
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
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
00220 if (adders_for_partial_products != NULL)
00221 {
00222 free(adders_for_partial_products);
00223 }
00224
00225 for (i = 0; i < multiplicand_width; i++)
00226 {
00227
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 }