00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <stdlib.h>
00025 #include <stdio.h>
00026 #include <string.h>
00027 #include "types.h"
00028 #include "node_creation_library.h"
00029 #include "multipliers.h"
00030 #include "netlist_utils.h"
00031 #include "partial_map.h"
00032 #include "util.h"
00033 #include "read_xml_arch_file.h"
00034 #include "globals.h"
00035
00036 t_model *hard_multipliers = NULL;
00037 struct s_linked_vptr *mult_list = NULL;
00038 int min_mult = 0;
00039 int *mults = NULL;
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061 void instantiate_simple_soft_multiplier(nnode_t *node, short mark, netlist_t *netlist)
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 }
00238
00239 #ifdef VPR6
00240
00241
00242
00243 void init_mult_distribution()
00244 {
00245 int i, j;
00246
00247 oassert(hard_multipliers != NULL);
00248 mults = (int *)malloc(sizeof(int) * (hard_multipliers->inputs->size + 1) * (1 + hard_multipliers->inputs->next->size));
00249 for (i = 0; i <= hard_multipliers->inputs->size; i++)
00250 for (j = 0; j <= hard_multipliers->inputs->next->size; j++)
00251 mults[i * hard_multipliers->inputs->size + j] = 0;
00252 return;
00253 }
00254
00255
00256
00257
00258 void record_mult_distribution(nnode_t *node)
00259 {
00260 int a, b;
00261
00262
00263 oassert(hard_multipliers != NULL);
00264 oassert(node != NULL);
00265
00266 a = node->input_port_sizes[0];
00267 b = node->input_port_sizes[1];
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296 mults[a * hard_multipliers->inputs->size + b] += 1;
00297 return;
00298 }
00299
00300
00301
00302
00303 void report_mult_distribution()
00304 {
00305 int i, j;
00306 int total = 0;
00307
00308 if(hard_multipliers == NULL)
00309 return;
00310
00311 printf("\nHard Multiplier Distribution\n");
00312 printf("============================\n");
00313 for (i = 0; i <= hard_multipliers->inputs->size; i++)
00314 {
00315 for (j = 1; j <= hard_multipliers->inputs->next->size; j++)
00316 {
00317 if (mults[i * hard_multipliers->inputs->size + j] != 0)
00318 {
00319 total += mults[i * hard_multipliers->inputs->size + j];
00320 printf("%d X %d => %d\n", i, j, mults[i * hard_multipliers->inputs->size + j]);
00321 }
00322 }
00323 }
00324 printf("\n");
00325 printf("\nTotal # of multipliers = %d\n", total);
00326 return;
00327 }
00328
00329
00330
00331
00332 void find_hard_multipliers()
00333 {
00334 hard_multipliers = Arch.models;
00335 min_mult = configuration.min_hard_multiplier;
00336 while (hard_multipliers != NULL)
00337 {
00338 if (strcmp(hard_multipliers->name, "multiply") == 0)
00339 {
00340 init_mult_distribution();
00341 return;
00342 }
00343 else
00344 {
00345 hard_multipliers = hard_multipliers->next;
00346 }
00347 }
00348
00349 return;
00350 }
00351
00352
00353
00354
00355 void declare_hard_multiplier(nnode_t *node)
00356 {
00357 t_multiplier *tmp;
00358 int width_a, width_b, width, swap;
00359
00360
00361 if (hard_multipliers == NULL)
00362 {
00363 printf(ERRTAG "Instantiating multiplier where multipliers do not exist\n");
00364 }
00365 tmp = (t_multiplier *)hard_multipliers->instances;
00366 width_a = node->input_port_sizes[0];
00367 width_b = node->input_port_sizes[1];
00368 width = node->output_port_sizes[0];
00369 if (width_a < width_b)
00370 {
00371 swap = width_b;
00372 width_b = width_a;
00373 width_a = swap;
00374 }
00375 while (tmp != NULL)
00376 {
00377 if ((tmp->size_a == width_a) && (tmp->size_b == width_b) && (tmp->size_out == width))
00378 return;
00379 else
00380 tmp = tmp->next;
00381 }
00382
00383
00384 tmp = (t_multiplier *)malloc(sizeof(t_multiplier));
00385 tmp->next = (t_multiplier *)hard_multipliers->instances;
00386 hard_multipliers->instances = tmp;
00387 tmp->size_a = width_a;
00388 tmp->size_b = width_b;
00389 tmp->size_out = width;
00390 return;
00391 }
00392
00393
00394
00395
00396 void instantiate_hard_multiplier(nnode_t *node, short mark, netlist_t *netlist)
00397 {
00398 char *new_name;
00399 int len, sanity, i;
00400
00401 declare_hard_multiplier(node);
00402
00403
00404 len = strlen(node->name);
00405 len = len + 20;
00406 new_name = (char*)malloc(len);
00407
00408
00409 if (node->input_port_sizes[0] > node->input_port_sizes[1])
00410 sanity = sprintf(new_name, "%s_%d_%d_%d", node->name, node->input_port_sizes[0], node->input_port_sizes[1], node->output_port_sizes[0]);
00411 else
00412 sanity = sprintf(new_name, "%s_%d_%d_%d", node->name, node->input_port_sizes[1], node->input_port_sizes[0], node->output_port_sizes[0]);
00413
00414 if (len <= sanity)
00415 oassert(FALSE);
00416
00417
00418 for (i = 0; i < node->num_output_pins; i++)
00419 {
00420 if (node->output_pins[i]->name != NULL)
00421 {
00422 free(node->output_pins[i]->name);
00423 }
00424 len = strlen(node->name) + 6;
00425 new_name = (char*)malloc(len);
00426 sprintf(new_name, "%s[%d]", node->name, node->output_pins[i]->pin_node_idx);
00427 node->output_pins[i]->name = new_name;
00428 }
00429 free(node->name);
00430 node->name = new_name;
00431 node->traverse_visited = mark;
00432 return;
00433 }
00434
00435
00436
00437
00438
00439 void add_the_blackbox_for_mults(FILE *out)
00440 {
00441 int i;
00442 int count;
00443 int hard_mult_inputs;
00444 t_multiplier *muls;
00445 t_model_ports *ports;
00446 char buffer[MAX_BUF];
00447 char *pa, *pb, *po;
00448
00449
00450 if (hard_multipliers == NULL)
00451 return;
00452
00453
00454 ports = hard_multipliers->inputs;
00455 pb = ports->name;
00456 ports = ports->next;
00457 pa = ports->name;
00458 po = hard_multipliers->outputs->name;
00459
00460
00461 muls = (t_multiplier *)(hard_multipliers->instances);
00462 if (muls == NULL)
00463 return;
00464
00465
00466 while (muls != NULL)
00467 {
00468
00469 if (configuration.fixed_hard_multiplier != 0)
00470 count = fprintf(out, ".model multiply\n");
00471 else
00472 count = fprintf(out, ".model mult_%d_%d_%d\n", muls->size_a, muls->size_b, muls->size_out);
00473
00474
00475 count = count + fprintf(out, ".inputs");
00476 hard_mult_inputs = muls->size_a + muls->size_b;
00477 for (i = 0; i < hard_mult_inputs; i++)
00478 {
00479 if (i < muls->size_a)
00480 {
00481 count = count + sprintf(buffer, " %s[%d]", pa, i);
00482 if (count > 78)
00483 count = fprintf(out, " \\\n%s", buffer) - 3;
00484 else
00485 fprintf(out, "%s", buffer);
00486 }
00487 else
00488 {
00489 count = count + sprintf(buffer, " %s[%d]", pb, i - muls->size_a);
00490 if (count > 78)
00491 count = fprintf(out, " \\\n %s", buffer) - 3;
00492 else
00493 fprintf(out, " %s", buffer);
00494 }
00495 }
00496 fprintf(out, "\n");
00497
00498
00499 count = fprintf(out, ".outputs");
00500 for (i = 0; i < muls->size_out; i++)
00501 {
00502 count = count + sprintf(buffer, " %s[%d]", po, i);
00503 if (count > 78)
00504 {
00505 fprintf(out, " \\\n%s", buffer);
00506 count = strlen(buffer);
00507 }
00508 else
00509 fprintf(out, "%s", buffer);
00510 }
00511 fprintf(out, "\n");
00512 fprintf(out, ".blackbox\n");
00513 fprintf(out, ".end\n");
00514 fprintf(out, "\n");
00515
00516 muls = muls->next;
00517 }
00518 }
00519
00520
00521
00522
00523 void define_mult_function(nnode_t *node, short type, FILE *out)
00524 {
00525 int i, j;
00526 int count;
00527 char buffer[MAX_BUF];
00528
00529 count = fprintf(out, "\n.subckt");
00530 count--;
00531 oassert(node->input_port_sizes[0] > 0);
00532 oassert(node->input_port_sizes[1] > 0);
00533 oassert(node->output_port_sizes[0] > 0);
00534
00535 if (configuration.fixed_hard_multiplier != 0)
00536 {
00537 count += fprintf(out, " multiply");
00538 }
00539 else
00540 {
00541 if (node->input_port_sizes[0] > node->input_port_sizes[1])
00542 {
00543 count += fprintf(out, " mult_%d_%d_%d", node->input_port_sizes[0],
00544 node->input_port_sizes[1], node->output_port_sizes[0]);
00545 }
00546 else
00547 {
00548 count += fprintf(out, " mult_%d_%d_%d", node->input_port_sizes[1],
00549 node->input_port_sizes[0], node->output_port_sizes[0]);
00550 }
00551 }
00552
00553 for (i = 0; i < node->num_input_pins; i++)
00554 {
00555 if (i < node->input_port_sizes[0])
00556 {
00557 if (node->input_pins[i]->net->driver_pin->name == NULL)
00558 j = sprintf(buffer, " %s[%d]=%s", hard_multipliers->inputs->next->name, i, node->input_pins[i]->net->driver_pin->node->name);
00559 else
00560 j = sprintf(buffer, " %s[%d]=%s", hard_multipliers->inputs->next->name, i, node->input_pins[i]->net->driver_pin->name);
00561 }
00562 else
00563 {
00564 if (node->input_pins[i]->net->driver_pin->name == NULL)
00565 j = sprintf(buffer, " %s[%d]=%s", hard_multipliers->inputs->name, i - node->input_port_sizes[0], node->input_pins[i]->net->driver_pin->node->name);
00566 else
00567 j = sprintf(buffer, " %s[%d]=%s", hard_multipliers->inputs->name, i - node->input_port_sizes[0], node->input_pins[i]->net->driver_pin->name);
00568 }
00569
00570 if (count + j > 79)
00571 {
00572 fprintf(out, "\\\n");
00573 count = 0;
00574 }
00575 count += fprintf(out, "%s", buffer);
00576 }
00577
00578 for (i = 0; i < node->num_output_pins; i++)
00579 {
00580
00581 j = sprintf(buffer, " %s[%d]=%s", hard_multipliers->outputs->name, i, node->output_pins[i]->name);
00582
00583
00584
00585 if (count + j > 79)
00586 {
00587 fprintf(out, "\\\n");
00588 count = 0;
00589 }
00590 count += fprintf(out, "%s", buffer);
00591 }
00592
00593 fprintf(out, "\n\n");
00594 return;
00595 }
00596
00597
00598
00599
00600
00601
00602
00603 void init_split_multiplier(nnode_t *node, nnode_t *ptr, int offa, int a, int offb, int b)
00604 {
00605 int i;
00606
00607
00608 ptr->type = node->type;
00609 ptr->related_ast_node = node->related_ast_node;
00610 ptr->traverse_visited = node->traverse_visited;
00611 ptr->node_data = NULL;
00612
00613
00614 ptr->num_input_port_sizes = 2;
00615 ptr->input_port_sizes = (int *)malloc(2 * sizeof(int));
00616 ptr->input_port_sizes[0] = a;
00617 ptr->input_port_sizes[1] = b;
00618 ptr->num_output_port_sizes = 1;
00619 ptr->output_port_sizes = (int *)malloc(sizeof(int));
00620 ptr->output_port_sizes[0] = a + b;
00621
00622
00623 ptr->num_input_pins = a + b;
00624 ptr->input_pins = (npin_t**)malloc(sizeof(void *) * (a + b));
00625 for (i = 0; i < a; i++)
00626 {
00627 ptr->input_pins[i] = node->input_pins[i+offa];
00628 ptr->input_pins[i]->node = ptr;
00629 }
00630 for (i = 0; i < b; i++)
00631 {
00632 ptr->input_pins[i+a] = node->input_pins[i + offa + a + offb];
00633 ptr->input_pins[i+a]->node = ptr;
00634 }
00635
00636
00637 ptr->num_output_pins = a + b;
00638 ptr->output_pins = (npin_t**)malloc(sizeof(void *) * (a + b));
00639 for (i = 0; i < a + b; i++)
00640 ptr->output_pins[i] = NULL;
00641
00642 return;
00643 }
00644
00645
00646
00647
00648
00649
00650
00651 void init_cascade_adder(nnode_t *node, nnode_t *a, int b)
00652 {
00653 int i, size;
00654
00655 node->type = ADD;
00656 node->related_ast_node = a->related_ast_node;
00657 node->traverse_visited = a->traverse_visited;
00658 node->node_data = NULL;
00659
00660
00661 size = a->output_port_sizes[0];
00662 size = (size < b) ? b : size;
00663
00664
00665 node->num_input_port_sizes = 2;
00666 node->input_port_sizes = (int *)malloc(2 * sizeof(int));
00667 node->input_port_sizes[0] = a->output_port_sizes[0];
00668 node->input_port_sizes[1] = b;
00669 node->num_output_port_sizes = 1;
00670 node->output_port_sizes = (int *)malloc(sizeof(int));
00671 node->output_port_sizes[0] = size;
00672
00673
00674 node->num_input_pins = a->output_port_sizes[0] + b;
00675 node->input_pins = (npin_t**)malloc(sizeof(void *) *
00676 (a->output_port_sizes[0] + b));
00677 for (i = 0; i < a->output_port_sizes[0] + b; i++)
00678 node->input_pins[i] = NULL;
00679
00680
00681 node->num_output_pins = size;
00682 node->output_pins = (npin_t**)malloc(sizeof(void *) * size);
00683 for (i = 0; i < size; i++)
00684 node->output_pins[i] = NULL;
00685 return;
00686 }
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713 void split_multiplier(nnode_t *node, int a0, int b0, int a1, int b1)
00714 {
00715 nnode_t *a0b0, *a0b1, *a1b0, *a1b1, *addsmall, *addbig;
00716 int i, size;
00717
00718
00719 oassert(node->input_port_sizes[0] == (a0 + a1));
00720 oassert(node->input_port_sizes[1] == (b0 + b1));
00721
00722
00723 a0b0 = (nnode_t *)my_malloc_struct(sizeof(nnode_t));
00724 a0b0->name = (char *)malloc(strlen(node->name) + 3);
00725 strcpy(a0b0->name, node->name);
00726 strcat(a0b0->name, "-0");
00727 init_split_multiplier(node, a0b0, 0, a0, 0, b0);
00728 mult_list = insert_in_vptr_list(mult_list, a0b0);
00729
00730
00731 a1b1 = (nnode_t *)my_malloc_struct(sizeof(nnode_t));
00732 a1b1->name = (char *)malloc(strlen(node->name) + 3);
00733 strcpy(a1b1->name, node->name);
00734 strcat(a1b1->name, "-3");
00735 init_split_multiplier(node, a1b1, a0, a1, b0, b1);
00736 mult_list = insert_in_vptr_list(mult_list, a1b1);
00737
00738
00739 a0b1 = (nnode_t *)my_malloc_struct(sizeof(nnode_t));
00740 a0b1->name = (char *)malloc(strlen(node->name) + 3);
00741 strcpy(a0b1->name, node->name);
00742 strcat(a0b1->name, "-1");
00743 init_split_multiplier(node, a0b1, 0, a0, b0, b1);
00744 mult_list = insert_in_vptr_list(mult_list, a0b1);
00745
00746
00747 a1b0 = (nnode_t *)my_malloc_struct(sizeof(nnode_t));
00748 a1b0->name = (char *)malloc(strlen(node->name) + 3);
00749 strcpy(a1b0->name, node->name);
00750 strcat(a1b0->name, "-2");
00751 init_split_multiplier(node, a1b0, a0, a1, 0, b0);
00752 mult_list = insert_in_vptr_list(mult_list, a1b0);
00753
00754
00755 addsmall = (nnode_t *)my_malloc_struct(sizeof(nnode_t));
00756 addsmall->name = (char *)malloc(strlen(node->name) + 6);
00757 strcpy(addsmall->name, node->name);
00758 strcat(addsmall->name, "-add0");
00759 init_cascade_adder(addsmall, a1b0, a0b1->output_port_sizes[0]);
00760
00761
00762 addbig = (nnode_t *)my_malloc_struct(sizeof(nnode_t));
00763 addbig->name = (char *)malloc(strlen(node->name) + 6);
00764 strcpy(addbig->name, node->name);
00765 strcat(addbig->name, "-add1");
00766 init_cascade_adder(addbig, addsmall,
00767 a0b0->output_port_sizes[0] + a1b1->output_port_sizes[0]);
00768
00769
00770 for (i = 0; i < a0b1->output_port_sizes[0]; i++)
00771 connect_nodes(a0b1, i, addsmall, i);
00772 for (i = 0; i < a1b0->output_port_sizes[0]; i++)
00773 connect_nodes(a1b0, i, addsmall, i+a0b1->output_port_sizes[0]);
00774
00775
00776 size = addsmall->output_port_sizes[0];
00777 for (i = 0; i < size; i++)
00778 connect_nodes(addsmall, i, addbig, i);
00779 for (i = 0; i < a1b1->output_port_sizes[0]; i++)
00780 connect_nodes(a1b1, i, addbig, i + size);
00781 size = size + a1b1->output_port_sizes[0];
00782 for (i = 0; i < a0b0->output_port_sizes[0]; i++)
00783 connect_nodes(a0b0, i, addbig, i + size);
00784
00785
00786 for (i = 0; i < addbig->num_output_pins; i++)
00787 remap_pin_to_new_node(node->output_pins[i], addbig, i);
00788
00789
00790 free(node->name);
00791 free(node->input_port_sizes);
00792 free(node->output_port_sizes);
00793
00794
00795 free(node->input_pins);
00796 free(node->output_pins);
00797 free(node);
00798
00799 return;
00800 }
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819 void split_multiplier_a(nnode_t *node, int a0, int a1, int b)
00820 {
00821 nnode_t *a0b, *a1b, *addsmall;
00822 int i;
00823
00824
00825 oassert(node->input_port_sizes[0] == (a0 + a1));
00826 oassert(node->input_port_sizes[1] == b);
00827
00828
00829 a0b = (nnode_t *)my_malloc_struct(sizeof(nnode_t));
00830 a0b->name = (char *)malloc(strlen(node->name) + 3);
00831 strcpy(a0b->name, node->name);
00832 strcat(a0b->name, "-0");
00833 init_split_multiplier(node, a0b, 0, a0, 0, b);
00834 mult_list = insert_in_vptr_list(mult_list, a0b);
00835
00836
00837 a1b = (nnode_t *)my_malloc_struct(sizeof(nnode_t));
00838 a1b->name = (char *)malloc(strlen(node->name) + 3);
00839 strcpy(a1b->name, node->name);
00840 strcat(a1b->name, "-1");
00841 init_split_multiplier(node, a1b, a0, a1, 0, b);
00842 mult_list = insert_in_vptr_list(mult_list, a1b);
00843
00844
00845 addsmall = (nnode_t *)my_malloc_struct(sizeof(nnode_t));
00846 addsmall->name = (char *)malloc(strlen(node->name) + 6);
00847 strcpy(addsmall->name, node->name);
00848 strcat(addsmall->name, "-add0");
00849 init_cascade_adder(addsmall, a1b, a1 + b);
00850
00851
00852 for (i = 0; i < a0b->output_port_sizes[0]; i++)
00853 connect_nodes(a0b, i, addsmall, i);
00854 for (i = a0b->output_port_sizes[0]; i < b+a1; i++)
00855 connect_nodes(a0b, a0b->output_port_sizes[0]-1, addsmall, i);
00856 for (i = b+a1; i < (2 * (a1 + b)); i++)
00857 connect_nodes(a1b, i-(b+a1), addsmall, i);
00858
00859
00860 for (i = 0; i < a0; i++)
00861 {
00862 remap_pin_to_new_node(node->output_pins[i], a0b, i);
00863 }
00864 for (i = a0; i < node->num_output_pins; i++)
00865 remap_pin_to_new_node(node->output_pins[i], addsmall, i-a0);
00866
00867
00868 free(node->name);
00869 free(node->input_port_sizes);
00870 free(node->output_port_sizes);
00871
00872
00873 free(node->input_pins);
00874 free(node->output_pins);
00875 free(node);
00876 return;
00877 }
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896 void split_multiplier_b(nnode_t *node, int a, int b1, int b0)
00897 {
00898 nnode_t *ab0, *ab1, *addsmall;
00899 int i;
00900
00901
00902 oassert(node->input_port_sizes[0] == a);
00903 oassert(node->input_port_sizes[1] == (b0 + b1));
00904
00905
00906 ab0 = (nnode_t *)my_malloc_struct(sizeof(nnode_t));
00907 ab0->name = (char *)malloc(strlen(node->name) + 3);
00908 strcpy(ab0->name, node->name);
00909 strcat(ab0->name, "-0");
00910 init_split_multiplier(node, ab0, 0, a, 0, b0);
00911 mult_list = insert_in_vptr_list(mult_list, ab0);
00912
00913
00914 ab1 = (nnode_t *)my_malloc_struct(sizeof(nnode_t));
00915 ab1->name = (char *)malloc(strlen(node->name) + 3);
00916 strcpy(ab1->name, node->name);
00917 strcat(ab1->name, "-1");
00918 init_split_multiplier(node, ab1, 0, a, b0, b1);
00919 mult_list = insert_in_vptr_list(mult_list, ab1);
00920
00921
00922 addsmall = (nnode_t *)my_malloc_struct(sizeof(nnode_t));
00923 addsmall->name = (char *)malloc(strlen(node->name) + 6);
00924 strcpy(addsmall->name, node->name);
00925 strcat(addsmall->name, "-add0");
00926 init_cascade_adder(addsmall, ab1, a + b1);
00927
00928
00929 for (i = b0; i < ab0->output_port_sizes[0]; i++)
00930 connect_nodes(ab0, i, addsmall, i-b0);
00931 for (i = ab0->output_port_sizes[0] - b0; i < a+b1; i++)
00932 connect_nodes(ab0, ab0->output_port_sizes[0]-1, addsmall, i);
00933 for (i = b1+a; i < (2 * (a + b1)); i++)
00934 connect_nodes(ab1, i-(b1+a), addsmall, i);
00935
00936
00937 for (i = 0; i < b0; i++)
00938 {
00939 remap_pin_to_new_node(node->output_pins[i], ab0, i);
00940 }
00941 for (i = b0; i < node->num_output_pins; i++)
00942 remap_pin_to_new_node(node->output_pins[i], addsmall, i-b0);
00943
00944
00945 free(node->name);
00946 free(node->input_port_sizes);
00947 free(node->output_port_sizes);
00948
00949
00950 free(node->input_pins);
00951 free(node->output_pins);
00952 free(node);
00953 return;
00954 }
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964 void pad_multiplier(nnode_t *node, netlist_t *netlist)
00965 {
00966 int diffa, diffb, diffout, i;
00967 int sizea, sizeb, sizeout;
00968 struct s_linked_vptr *plist = NULL;
00969 t_pb_type *physical = NULL;
00970 int testa, testb;
00971
00972 oassert(node->type == MULTIPLY);
00973 oassert(hard_multipliers != NULL);
00974
00975 sizea = node->input_port_sizes[0];
00976 sizeb = node->input_port_sizes[1];
00977 sizeout = node->output_port_sizes[0];
00978 record_mult_distribution(node);
00979
00980
00981 diffa = hard_multipliers->inputs->size - sizea;
00982 diffb = hard_multipliers->inputs->next->size - sizeb;
00983 diffout = hard_multipliers->outputs->size - sizeout;
00984
00985 if (configuration.fracture_hard_multiplier == 1)
00986 {
00987 plist = hard_multipliers->pb_types;
00988 while ((diffa + diffb != 0) && (plist != NULL))
00989 {
00990 physical = (t_pb_type *)(plist->data_vptr);
00991 plist = plist->next;
00992 testa = physical->ports[0].num_pins;
00993 testb = physical->ports[1].num_pins;
00994 if ((testa >= sizea) && (testb >= sizeb) &&
00995 ((testa - sizea + testb - sizeb) < (diffa + diffb)))
00996 {
00997 diffa = testa - sizea;
00998 diffb = testb - sizeb;
00999 diffout = physical->ports[2].num_pins - sizeout;
01000 }
01001 }
01002 }
01003
01004
01005 if ((diffa != 0) || (diffb != 0))
01006 {
01007 allocate_more_node_input_pins(node, diffa + diffb);
01008
01009
01010 if (diffa != 0)
01011 {
01012 for (i = 1; i <= sizeb; i++)
01013 {
01014 move_a_input_pin(node, sizea + sizeb - i, node->num_input_pins - diffb - i);
01015 }
01016
01017
01018 for (i = 0; i < diffa; i++)
01019 {
01020 add_a_input_pin_to_node_spot_idx(node, get_a_zero_pin(netlist), i + sizea);
01021 }
01022
01023 node->input_port_sizes[0] = sizea + diffa;
01024 }
01025
01026 if (diffb != 0)
01027 {
01028
01029 for (i = 1; i <= diffb; i++)
01030 {
01031 add_a_input_pin_to_node_spot_idx(node, get_a_zero_pin(netlist), node->num_input_pins - i);
01032 }
01033
01034 node->input_port_sizes[1] = sizeb + diffb;
01035 }
01036 }
01037
01038
01039 if (diffout != 0)
01040 {
01041 allocate_more_node_output_pins(node, diffout);
01042 for (i = 0; i < diffout; i++)
01043 add_a_output_pin_to_node_spot_idx(node, copy_output_npin(node->output_pins[0]), i + sizeout);
01044 node->output_port_sizes[0] = sizeout + diffout;
01045 }
01046
01047 return;
01048 }
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059 void iterate_multipliers(netlist_t *netlist)
01060 {
01061 int sizea, sizeb, sizeout, swap;
01062 int mula, mulb, mulout;
01063 int a0, a1, b0, b1;
01064 nnode_t *node;
01065
01066
01067 if (hard_multipliers == NULL)
01068 return;
01069
01070 sizea = hard_multipliers->inputs->size;
01071 sizeb = hard_multipliers->inputs->next->size;
01072 sizeout = hard_multipliers->outputs->size;
01073 if (sizea < sizeb)
01074 {
01075 swap = sizea;
01076 sizea = sizeb;
01077 sizeb = swap;
01078 }
01079
01080 while (mult_list != NULL)
01081 {
01082 node = (nnode_t *)mult_list->data_vptr;
01083 mult_list = delete_in_vptr_list(mult_list);
01084
01085 oassert(node != NULL);
01086
01087 if (node->type == HARD_IP)
01088 node->type = MULTIPLY;
01089
01090 oassert(node->type == MULTIPLY);
01091
01092 mulout = node->output_port_sizes[0];
01093 mula = node->input_port_sizes[0];
01094 mulb = node->input_port_sizes[1];
01095 if (mula < mulb)
01096 {
01097 swap = sizea;
01098 sizea = sizeb;
01099 sizeb = swap;
01100 }
01101
01102
01103 if ((mula > sizea) && (mulb > sizeb))
01104 {
01105 a1 = sizea;
01106 a0 = mula - sizea;
01107 b1 = sizeb;
01108 b0 = mulb - sizeb;
01109 printf("KEN: splitting into %d %d | %d %d\n", a0, a1, b0, b1);
01110 split_multiplier(node, a0, b0, a1, b1);
01111 }
01112 else if (mula > sizea)
01113 {
01114 a1 = sizea;
01115 a0 = mula - sizea;
01116 printf("KEN: splitting into %d %d | %d\n", a0, a1, mulb);
01117 split_multiplier_a(node, a0, a1, mulb);
01118 }
01119 else if (mulb > sizeb)
01120 {
01121 b1 = sizeb;
01122 b0 = mulb - sizeb;
01123 printf("KEN: splitting into %d | %d %d\n", mula, b0, b1);
01124 split_multiplier_b(node, mula, b0, b1);
01125 }
01126 else if ((sizea >= min_mult) && (sizeb >= min_mult) &&
01127 (configuration.fixed_hard_multiplier != 0))
01128 {
01129
01130 pad_multiplier(node, netlist);
01131 }
01132 }
01133 return;
01134 }
01135
01136
01137
01138
01139
01140
01141
01142 void clean_multipliers()
01143 {
01144 while (mult_list != NULL)
01145 mult_list = delete_in_vptr_list(mult_list);
01146 return;
01147 }
01148 #endif