VPR-7.0
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros
vpr_api.c
Go to the documentation of this file.
1 /**
2  General API for VPR
3  Other software tools should generally call just the functions defined here
4  For advanced/power users, you can call functions defined elsewhere in VPR or modify the data structures directly at your discretion but be aware that doing so can break the correctness of VPR
5 
6  Author: Jason Luu
7  June 21, 2012
8  */
9 
10 #include <stdio.h>
11 #include <string.h>
12 #include <assert.h>
13 #include <time.h>
14 
15 #include "util.h"
16 #include "vpr_types.h"
17 #include "vpr_utils.h"
18 #include "globals.h"
19 #include "graphics.h"
20 #include "read_netlist.h"
21 #include "check_netlist.h"
22 #include "print_netlist.h"
23 #include "read_blif.h"
24 #include "draw.h"
25 #include "place_and_route.h"
26 #include "pack.h"
27 #include "SetupGrid.h"
28 #include "stats.h"
29 #include "path_delay.h"
30 #include "OptionTokens.h"
31 #include "ReadOptions.h"
32 #include "read_xml_arch_file.h"
33 #include "SetupVPR.h"
34 #include "rr_graph.h"
35 #include "pb_type_graph.h"
36 #include "ReadOptions.h"
37 #include "route_common.h"
38 #include "timing_place_lookup.h"
39 #include "cluster_legality.h"
40 #include "route_export.h"
41 #include "vpr_api.h"
42 #include "read_sdc.h"
43 #include "power.h"
44 
45 /* Local subroutines */
46 static void free_pb_type(t_pb_type *pb_type);
47 static void free_complex_block_types(void);
48 
49 static void free_arch(t_arch* Arch);
50 static void free_options(t_options *options);
51 static void free_circuit(void);
52 
54 
55 /* For resync of clustered netlist to the post-route solution. This function adds local nets to cluster */
56 static void reload_intra_cluster_nets(t_pb *pb);
58 static t_trace *expand_routing_trace(t_trace *trace, int ivpack_net);
59 static void print_complete_net_trace(t_trace* trace, const char *file_name);
60 static void resync_post_route_netlist();
61 static void clay_logical_equivalence_handling(const t_arch *arch);
62 static void clay_lut_input_rebalancing(int iblock, t_pb *pb);
63 static void clay_reload_ble_locations(int iblock);
64 static void resync_pb_graph_nodes_in_pb(t_pb_graph_node *pb_graph_node,
65  t_pb *pb);
66 
67 /* Local subroutines end */
68 
69 /* Display general VPR information */
70 void vpr_print_title(void) {
71  vpr_printf(TIO_MESSAGE_INFO, "\n");
72  vpr_printf(TIO_MESSAGE_INFO, "VPR FPGA Placement and Routing.\n");
73  vpr_printf(TIO_MESSAGE_INFO, "Version: Version " VPR_VERSION "\n");
74  vpr_printf(TIO_MESSAGE_INFO, "Compiled: " __DATE__ ".\n");
75  vpr_printf(TIO_MESSAGE_INFO, "University of Toronto\n");
76  vpr_printf(TIO_MESSAGE_INFO, "vpr@eecg.utoronto.ca\n");
77  vpr_printf(TIO_MESSAGE_INFO, "This is free open source code under MIT license.\n");
78  vpr_printf(TIO_MESSAGE_INFO, "\n");
79 }
80 
81 /* Display help screen */
82 void vpr_print_usage(void) {
83  vpr_printf(TIO_MESSAGE_INFO,
84  "Usage: vpr fpga_architecture.xml circuit_name [Options ...]\n");
85  vpr_printf(TIO_MESSAGE_INFO, "\n");
86  vpr_printf(TIO_MESSAGE_INFO,
87  "General Options: [--nodisp] [--auto <int>] [--pack]\n");
88  vpr_printf(TIO_MESSAGE_INFO,
89  "\t[--place] [--route] [--timing_analyze_only_with_net_delay <float>]\n");
90  vpr_printf(TIO_MESSAGE_INFO,
91  "\t[--fast] [--full_stats] [--timing_analysis on | off] [--outfile_prefix <string>]\n");
92  vpr_printf(TIO_MESSAGE_INFO,
93  "\t[--blif_file <string>][--net_file <string>][--place_file <string>]\n");
94  vpr_printf(TIO_MESSAGE_INFO,
95  "\t[--route_file <string>][--sdc_file <string>][--echo_file on | off]\n");
96  vpr_printf(TIO_MESSAGE_INFO, "\n");
97  vpr_printf(TIO_MESSAGE_INFO, "Packer Options:\n");
98  /* vpr_printf(TIO_MESSAGE_INFO, "\t[-global_clocks on|off]\n");
99  vpr_printf(TIO_MESSAGE_INFO, "\t[-hill_climbing on|off]\n");
100  vpr_printf(TIO_MESSAGE_INFO, "\t[-sweep_hanging_nets_and_inputs on|off]\n"); */
101  vpr_printf(TIO_MESSAGE_INFO, "\t[--timing_driven_clustering on|off]\n");
102  vpr_printf(TIO_MESSAGE_INFO,
103  "\t[--cluster_seed_type timing|max_inputs] [--alpha_clustering <float>] [--beta_clustering <float>]\n");
104  /* vpr_printf(TIO_MESSAGE_INFO, "\t[-recompute_timing_after <int>] [-cluster_block_delay <float>]\n"); */
105  vpr_printf(TIO_MESSAGE_INFO, "\t[--allow_unrelated_clustering on|off]\n");
106  /* vpr_printf(TIO_MESSAGE_INFO, "\t[-allow_early_exit on|off]\n");
107  vpr_printf(TIO_MESSAGE_INFO, "\t[-intra_cluster_net_delay <float>] \n");
108  vpr_printf(TIO_MESSAGE_INFO, "\t[-inter_cluster_net_delay <float>] \n"); */
109  vpr_printf(TIO_MESSAGE_INFO,
110  "\t[--connection_driven_clustering on|off] \n");
111  vpr_printf(TIO_MESSAGE_INFO, "\n");
112  vpr_printf(TIO_MESSAGE_INFO, "Placer Options:\n");
113  vpr_printf(TIO_MESSAGE_INFO,
114  "\t[--place_algorithm bounding_box | net_timing_driven | path_timing_driven]\n");
115  vpr_printf(TIO_MESSAGE_INFO, "\t[--init_t <float>] [--exit_t <float>]\n");
116  vpr_printf(TIO_MESSAGE_INFO,
117  "\t[--alpha_t <float>] [--inner_num <float>] [--seed <int>]\n");
118  vpr_printf(TIO_MESSAGE_INFO, "\t[--place_cost_exp <float>]\n");
119  vpr_printf(TIO_MESSAGE_INFO, "\t[--place_chan_width <int>] \n");
120  vpr_printf(TIO_MESSAGE_INFO, "\t[--fix_pins random | <file.pads>]\n");
121  vpr_printf(TIO_MESSAGE_INFO, "\t[--enable_timing_computations on | off]\n");
122  vpr_printf(TIO_MESSAGE_INFO, "\t[--block_dist <int>]\n");
123  vpr_printf(TIO_MESSAGE_INFO, "\n");
124  vpr_printf(TIO_MESSAGE_INFO,
125  "Placement Options Valid Only for Timing-Driven Placement:\n");
126  vpr_printf(TIO_MESSAGE_INFO, "\t[--timing_tradeoff <float>]\n");
127  vpr_printf(TIO_MESSAGE_INFO, "\t[--recompute_crit_iter <int>]\n");
128  vpr_printf(TIO_MESSAGE_INFO, "\t[--inner_loop_recompute_divider <int>]\n");
129  vpr_printf(TIO_MESSAGE_INFO, "\t[--td_place_exp_first <float>]\n");
130  vpr_printf(TIO_MESSAGE_INFO, "\t[--td_place_exp_last <float>]\n");
131  vpr_printf(TIO_MESSAGE_INFO, "\n");
132  vpr_printf(TIO_MESSAGE_INFO,
133  "Router Options: [-max_router_iterations <int>] [-bb_factor <int>]\n");
134  vpr_printf(TIO_MESSAGE_INFO,
135  "\t[--initial_pres_fac <float>] [--pres_fac_mult <float>]\n");
136  vpr_printf(TIO_MESSAGE_INFO,
137  "\t[--acc_fac <float>] [--first_iter_pres_fac <float>]\n");
138  vpr_printf(TIO_MESSAGE_INFO,
139  "\t[--bend_cost <float>] [--route_type global | detailed]\n");
140  vpr_printf(TIO_MESSAGE_INFO,
141  "\t[--verify_binary_search] [--route_chan_width <int>]\n");
142  vpr_printf(TIO_MESSAGE_INFO,
143  "\t[--router_algorithm breadth_first | timing_driven]\n");
144  vpr_printf(TIO_MESSAGE_INFO,
145  "\t[--base_cost_type intrinsic_delay | delay_normalized | demand_only]\n");
146  vpr_printf(TIO_MESSAGE_INFO, "\n");
147  vpr_printf(TIO_MESSAGE_INFO,
148  "Routing options valid only for timing-driven routing:\n");
149  vpr_printf(TIO_MESSAGE_INFO,
150  "\t[--astar_fac <float>] [--max_criticality <float>]\n");
151  vpr_printf(TIO_MESSAGE_INFO, "\t[--criticality_exp <float>]\n");
152  vpr_printf(TIO_MESSAGE_INFO, "\n");
153 }
154 
155 /* Initialize VPR
156  1. Read Options
157  2. Read Arch
158  3. Read Circuit
159  4. Sanity check all three
160  */
161 void vpr_init(INP int argc, INP char **argv, OUTP t_options *options,
162  OUTP t_vpr_setup *vpr_setup, OUTP t_arch *arch) {
163  char* pszLogFileName = "vpr_stdout.log";
164  unsigned char enableTimeStamps = 1;
165  unsigned long maxWarningCount = 100000;
166  unsigned long maxErrorCount = 1000;
167 
168  if (PrintHandlerExists() == 1) {
170  } else {
172  }
174  PrintHandlerNew(pszLogFileName);
175  PrintHandlerInit(enableTimeStamps, maxWarningCount, maxErrorCount);
176  }
177 
178  /* Print title message */
179  vpr_print_title();
180 
181  /* Print usage message if no args */
182  if (argc < 3) {
183  vpr_print_usage();
184  exit(1);
185  }
186 
187  memset(options, 0, sizeof(t_options));
188  memset(vpr_setup, 0, sizeof(t_vpr_setup));
189  memset(arch, 0, sizeof(t_arch));
190 
191  /* Read in user options */
192  ReadOptions(argc, argv, options);
193  /* Timing option priorities */
194  vpr_setup->TimingEnabled = IsTimingEnabled(options);
195  /* Determine whether echo is on or off */
196  setEchoEnabled(IsEchoEnabled(options));
198  vpr_setup->constant_net_delay = options->constant_net_delay;
199 
200  /* Read in arch and circuit */
201  SetupVPR(options, vpr_setup->TimingEnabled, TRUE, &vpr_setup->FileNameOpts,
202  arch, &vpr_setup->Operation, &vpr_setup->user_models,
203  &vpr_setup->library_models, &vpr_setup->PackerOpts,
204  &vpr_setup->PlacerOpts, &vpr_setup->AnnealSched,
205  &vpr_setup->RouterOpts, &vpr_setup->RoutingArch,
206  &vpr_setup->Segments, &vpr_setup->Timing, &vpr_setup->ShowGraphics,
207  &vpr_setup->GraphPause, &vpr_setup->PowerOpts);
208 
209  /* Check inputs are reasonable */
210  CheckOptions(*options, vpr_setup->TimingEnabled);
211  CheckArch(*arch, vpr_setup->TimingEnabled);
212 
213  /* Verify settings don't conflict or otherwise not make sense */
214  CheckSetup(vpr_setup->Operation, vpr_setup->PlacerOpts,
215  vpr_setup->AnnealSched, vpr_setup->RouterOpts,
216  vpr_setup->RoutingArch, vpr_setup->Segments, vpr_setup->Timing,
217  arch->Chans);
218 
219  /* flush any messages to user still in stdout that hasn't gotten displayed */
220  fflush(stdout);
221 
222  /* Read blif file and sweep unused components */
223  read_and_process_blif(vpr_setup->PackerOpts.blif_file_name,
224  vpr_setup->PackerOpts.sweep_hanging_nets_and_inputs,
225  vpr_setup->user_models, vpr_setup->library_models,
226  vpr_setup->PowerOpts.do_power, vpr_setup->FileNameOpts.ActFile);
227  fflush(stdout);
228 
229  ShowSetup(*options, *vpr_setup);
230 }
231 
232 /*
233  * Sets globals: nx, ny
234  * Allocs globals: chan_width_x, chan_width_y, grid
235  * Depends on num_clbs, pins_per_clb */
237  int *num_instances_type, *num_blocks_type;
238  int i;
239  int current, high, low;
240  boolean fit;
241 
242  /* Read in netlist file for placement and routing */
243  if (vpr_setup.FileNameOpts.NetFile) {
244  read_netlist(vpr_setup.FileNameOpts.NetFile, &Arch, &num_blocks, &block,
245  &num_nets, &clb_net);
246  /* This is done so that all blocks have subblocks and can be treated the same */
247  check_netlist();
248  }
249 
250  /* Output the current settings to console. */
252 
253  if (vpr_setup.Operation == TIMING_ANALYSIS_ONLY) {
254  do_constant_net_delay_timing_analysis(vpr_setup.Timing,
255  vpr_setup.constant_net_delay);
256  } else {
257  current = nint((float)sqrt((float)num_blocks)); /* current is the value of the smaller side of the FPGA */
258  low = 1;
259  high = -1;
260 
261  num_instances_type = (int*) my_calloc(num_types, sizeof(int));
262  num_blocks_type = (int*) my_calloc(num_types, sizeof(int));
263 
264  for (i = 0; i < num_blocks; i++) {
265  num_blocks_type[block[i].type->index]++;
266  }
267 
268  if (Arch.clb_grid.IsAuto) {
269  /* Auto-size FPGA, perform a binary search */
270  while (high == -1 || low < high) {
271  /* Generate grid */
272  if (Arch.clb_grid.Aspect >= 1.0) {
273  ny = current;
274  nx = nint(current * Arch.clb_grid.Aspect);
275  } else {
276  nx = current;
277  ny = nint(current / Arch.clb_grid.Aspect);
278  }
279 #if DEBUG
280  vpr_printf(TIO_MESSAGE_INFO,
281  "Auto-sizing FPGA at x = %d y = %d\n", nx, ny);
282 #endif
283  alloc_and_load_grid(num_instances_type);
284  freeGrid();
285 
286  /* Test if netlist fits in grid */
287  fit = TRUE;
288  for (i = 0; i < num_types; i++) {
289  if (num_blocks_type[i] > num_instances_type[i]) {
290  fit = FALSE;
291  break;
292  }
293  }
294 
295  /* get next value */
296  if (!fit) {
297  /* increase size of max */
298  if (high == -1) {
299  current = current * 2;
300  if (current > MAX_SHORT) {
301  vpr_printf(TIO_MESSAGE_ERROR,
302  "FPGA required is too large for current architecture settings.\n");
303  exit(1);
304  }
305  } else {
306  if (low == current)
307  current++;
308  low = current;
309  current = low + ((high - low) / 2);
310  }
311  } else {
312  high = current;
313  current = low + ((high - low) / 2);
314  }
315  }
316  /* Generate grid */
317  if (Arch.clb_grid.Aspect >= 1.0) {
318  ny = current;
319  nx = nint(current * Arch.clb_grid.Aspect);
320  } else {
321  nx = current;
322  ny = nint(current / Arch.clb_grid.Aspect);
323  }
324  alloc_and_load_grid(num_instances_type);
325  vpr_printf(TIO_MESSAGE_INFO, "FPGA auto-sized to x = %d y = %d\n",
326  nx, ny);
327  } else {
328  nx = Arch.clb_grid.W;
329  ny = Arch.clb_grid.H;
330  alloc_and_load_grid(num_instances_type);
331  }
332 
333  vpr_printf(TIO_MESSAGE_INFO,
334  "The circuit will be mapped into a %d x %d array of clbs.\n",
335  nx, ny);
336 
337  /* Test if netlist fits in grid */
338  fit = TRUE;
339  for (i = 0; i < num_types; i++) {
340  if (num_blocks_type[i] > num_instances_type[i]) {
341  fit = FALSE;
342  break;
343  }
344  }
345  if (!fit) {
346  vpr_printf(TIO_MESSAGE_ERROR,
347  "Not enough physical locations for type %s, number of blocks is %d but number of locations is %d.\n",
348  type_descriptors[i].name, num_blocks_type[i],
349  num_instances_type[i]);
350  exit(1);
351  }
352 
353  vpr_printf(TIO_MESSAGE_INFO, "\n");
354  vpr_printf(TIO_MESSAGE_INFO, "Resource usage...\n");
355  for (i = 0; i < num_types; i++) {
356  vpr_printf(TIO_MESSAGE_INFO,
357  "\tNetlist %d\tblocks of type: %s\n",
358  num_blocks_type[i], type_descriptors[i].name);
359  vpr_printf(TIO_MESSAGE_INFO,
360  "\tArchitecture %d\tblocks of type: %s\n",
361  num_instances_type[i], type_descriptors[i].name);
362  }
363  vpr_printf(TIO_MESSAGE_INFO, "\n");
364  chan_width_x = (int *) my_malloc((ny + 1) * sizeof(int));
365  chan_width_y = (int *) my_malloc((nx + 1) * sizeof(int));
366 
367  free(num_blocks_type);
368  free(num_instances_type);
369  }
370 }
371 
372 void vpr_pack(INP t_vpr_setup vpr_setup, INP t_arch arch) {
373  clock_t begin, end;
374  float inter_cluster_delay = UNDEFINED, Tdel_opin_switch, Tdel_wire_switch,
375  Tdel_wtoi_switch, R_opin_switch, R_wire_switch, R_wtoi_switch,
376  Cout_opin_switch, Cout_wire_switch, Cout_wtoi_switch,
377  opin_switch_del, wire_switch_del, wtoi_switch_del, Rmetal, Cmetal,
378  first_wire_seg_delay, second_wire_seg_delay;
379  begin = clock();
380  vpr_printf(TIO_MESSAGE_INFO, "Initialize packing.\n");
381 
382  /* If needed, estimate inter-cluster delay. Assume the average routing hop goes out of
383  a block through an opin switch to a length-4 wire, then through a wire switch to another
384  length-4 wire, then through a wire-to-ipin-switch into another block. */
385 
386  if (vpr_setup.PackerOpts.timing_driven
387  && vpr_setup.PackerOpts.auto_compute_inter_cluster_net_delay) {
388  opin_switch_del = get_switch_info(arch.Segments[0].opin_switch,
389  Tdel_opin_switch, R_opin_switch, Cout_opin_switch);
390  wire_switch_del = get_switch_info(arch.Segments[0].wire_switch,
391  Tdel_wire_switch, R_wire_switch, Cout_wire_switch);
392  wtoi_switch_del = get_switch_info(
393  vpr_setup.RoutingArch.wire_to_ipin_switch, Tdel_wtoi_switch,
394  R_wtoi_switch, Cout_wtoi_switch); /* wire-to-ipin switch */
395  Rmetal = arch.Segments[0].Rmetal;
396  Cmetal = arch.Segments[0].Cmetal;
397 
398  /* The delay of a wire with its driving switch is the switch delay plus the
399  product of the equivalent resistance and capacitance experienced by the wire. */
400 
401 #define WIRE_SEGMENT_LENGTH 4
402  first_wire_seg_delay = opin_switch_del
403  + (R_opin_switch + Rmetal * WIRE_SEGMENT_LENGTH / 2)
404  * (Cout_opin_switch + Cmetal * WIRE_SEGMENT_LENGTH);
405  second_wire_seg_delay = wire_switch_del
406  + (R_wire_switch + Rmetal * WIRE_SEGMENT_LENGTH / 2)
407  * (Cout_wire_switch + Cmetal * WIRE_SEGMENT_LENGTH);
408  inter_cluster_delay = 4
409  * (first_wire_seg_delay + second_wire_seg_delay
410  + wtoi_switch_del); /* multiply by 4 to get a more conservative estimate */
411  }
412 
413  try_pack(&vpr_setup.PackerOpts, &arch, vpr_setup.user_models,
414  vpr_setup.library_models, vpr_setup.Timing, inter_cluster_delay);
415  end = clock();
416 #ifdef CLOCKS_PER_SEC
417  vpr_printf(TIO_MESSAGE_INFO, "Packing took %g seconds.\n",
418  (float) (end - begin) / CLOCKS_PER_SEC);
419  vpr_printf(TIO_MESSAGE_INFO, "Packing completed.\n");
420 #else
421  vpr_printf(TIO_MESSAGE_INFO, "Packing took %g seconds.\n", (float)(end - begin) / CLK_PER_SEC);
422 #endif
423  fflush(stdout);
424 }
425 
427  /* Startup X graphics */
428  set_graphics_state(vpr_setup.ShowGraphics, vpr_setup.GraphPause,
429  vpr_setup.RouterOpts.route_type);
430  if (vpr_setup.ShowGraphics) {
431  init_graphics("VPR: Versatile Place and Route for FPGAs", WHITE);
433  }
434 
435  /* Do placement and routing */
436  place_and_route(vpr_setup.Operation, vpr_setup.PlacerOpts,
437  vpr_setup.FileNameOpts.PlaceFile, vpr_setup.FileNameOpts.NetFile,
438  vpr_setup.FileNameOpts.ArchFile, vpr_setup.FileNameOpts.RouteFile,
439  vpr_setup.AnnealSched, vpr_setup.RouterOpts, vpr_setup.RoutingArch,
440  vpr_setup.Segments, vpr_setup.Timing, arch.Chans, arch.models,
441  arch.Directs, arch.num_directs);
442 
443  fflush(stdout);
444 
445  /* Close down X Display */
446  if (vpr_setup.ShowGraphics)
447  close_graphics();
449 }
450 
451 /* Free architecture data structures */
452 void free_arch(t_arch* Arch) {
453  int i;
454  t_model *model, *prev;
455  t_model_ports *port, *prev_port;
456  struct s_linked_vptr *vptr, *vptr_prev;
457 
458  freeGrid();
459  free(chan_width_x);
460  chan_width_x = NULL;
461  free(chan_width_y);
462  chan_width_y = NULL;
463 
464  for (i = 0; i < Arch->num_switches; i++) {
465  if (Arch->Switches->name != NULL) {
466  free(Arch->Switches[i].name);
467  }
468  }
469  free(Arch->Switches);
470  free(switch_inf);
471  for (i = 0; i < Arch->num_segments; i++) {
472  if (Arch->Segments->cb != NULL) {
473  free(Arch->Segments[i].cb);
474  }
475  if (Arch->Segments->sb != NULL) {
476  free(Arch->Segments[i].sb);
477  }
478  }
479  free(Arch->Segments);
480  model = Arch->models;
481  while (model) {
482  port = model->inputs;
483  while (port) {
484  prev_port = port;
485  port = port->next;
486  free(prev_port->name);
487  free(prev_port);
488  }
489  port = model->outputs;
490  while (port) {
491  prev_port = port;
492  port = port->next;
493  free(prev_port->name);
494  free(prev_port);
495  }
496  vptr = model->pb_types;
497  while (vptr) {
498  vptr_prev = vptr;
499  vptr = vptr->next;
500  free(vptr_prev);
501  }
502  prev = model;
503 
504  model = model->next;
505  if (prev->instances)
506  free(prev->instances);
507  free(prev->name);
508  free(prev);
509  }
510 
511  for (i = 0; i < 4; i++) {
512  vptr = Arch->model_library[i].pb_types;
513  while (vptr) {
514  vptr_prev = vptr;
515  vptr = vptr->next;
516  free(vptr_prev);
517  }
518  }
519 
520  for (i = 0; i < Arch->num_directs; i++) {
521  free(Arch->Directs[i].name);
522  free(Arch->Directs[i].from_pin);
523  free(Arch->Directs[i].to_pin);
524  }
525  free(Arch->Directs);
526 
527  free(Arch->model_library[0].name);
528  free(Arch->model_library[0].outputs->name);
529  free(Arch->model_library[0].outputs);
530  free(Arch->model_library[1].inputs->name);
531  free(Arch->model_library[1].inputs);
532  free(Arch->model_library[1].name);
533  free(Arch->model_library[2].name);
534  free(Arch->model_library[2].inputs[0].name);
535  free(Arch->model_library[2].inputs[1].name);
536  free(Arch->model_library[2].inputs);
537  free(Arch->model_library[2].outputs->name);
538  free(Arch->model_library[2].outputs);
539  free(Arch->model_library[3].name);
540  free(Arch->model_library[3].inputs->name);
541  free(Arch->model_library[3].inputs);
542  free(Arch->model_library[3].outputs->name);
543  free(Arch->model_library[3].outputs);
544  free(Arch->model_library);
545 
546  if (Arch->clocks) {
547  free(Arch->clocks->clock_inf);
548  }
549 
552 }
553 
554 void free_options(t_options *options) {
555  free(options->ArchFile);
556  free(options->CircuitName);
557  if (options->ActFile)
558  free(options->ActFile);
559  if (options->BlifFile)
560  free(options->BlifFile);
561  if (options->NetFile)
562  free(options->NetFile);
563  if (options->PlaceFile)
564  free(options->PlaceFile);
565  if (options->PowerFile)
566  free(options->PowerFile);
567  if (options->CmosTechFile)
568  free(options->CmosTechFile);
569  if (options->RouteFile)
570  free(options->RouteFile);
571  if (options->out_file_prefix)
572  free(options->out_file_prefix);
573  if (options->PinFile)
574  free(options->PinFile);
575 }
576 
577 static void free_complex_block_types(void) {
578  int i, j, k, m;
579 
581 
582  for (i = 0; i < num_types; i++) {
583  if (&type_descriptors[i] == EMPTY_TYPE) {
584  continue;
585  }
586  free(type_descriptors[i].name);
587  for (j = 0; j < type_descriptors[i].height; j++) {
588  for (k = 0; k < 4; k++) {
589  for (m = 0;
591  m++) {
592  if (type_descriptors[i].pin_loc_assignments[j][k][m])
593  free(type_descriptors[i].pin_loc_assignments[j][k][m]);
594  }
595  free(type_descriptors[i].pinloc[j][k]);
596  free(type_descriptors[i].pin_loc_assignments[j][k]);
597  }
598  free(type_descriptors[i].pinloc[j]);
599  free(type_descriptors[i].pin_loc_assignments[j]);
600  free(type_descriptors[i].num_pin_loc_assignments[j]);
601  }
602  for (j = 0; j < type_descriptors[i].num_class; j++) {
603  free(type_descriptors[i].class_inf[j].pinlist);
604  }
605  free(type_descriptors[i].pinloc);
606  free(type_descriptors[i].pin_loc_assignments);
607  free(type_descriptors[i].num_pin_loc_assignments);
608  free(type_descriptors[i].pin_height);
609  free(type_descriptors[i].class_inf);
610  free(type_descriptors[i].is_global_pin);
611  free(type_descriptors[i].pin_class);
612  free(type_descriptors[i].grid_loc_def);
613  free(type_descriptors[i].is_Fc_frac);
614  free(type_descriptors[i].is_Fc_full_flex);
615  free(type_descriptors[i].Fc);
616  free_pb_type(type_descriptors[i].pb_type);
617  free(type_descriptors[i].pb_type);
618  }
619  free(type_descriptors);
620 }
621 
622 static void free_pb_type(t_pb_type *pb_type) {
623  int i, j, k, m;
624 
625  free(pb_type->name);
626  if (pb_type->blif_model)
627  free(pb_type->blif_model);
628 
629  for (i = 0; i < pb_type->num_modes; i++) {
630  for (j = 0; j < pb_type->modes[i].num_pb_type_children; j++) {
631  free_pb_type(&pb_type->modes[i].pb_type_children[j]);
632  }
633  free(pb_type->modes[i].pb_type_children);
634  free(pb_type->modes[i].name);
635  for (j = 0; j < pb_type->modes[i].num_interconnect; j++) {
636  free(pb_type->modes[i].interconnect[j].input_string);
637  free(pb_type->modes[i].interconnect[j].output_string);
638  free(pb_type->modes[i].interconnect[j].name);
639 
640  for (k = 0; k < pb_type->modes[i].interconnect[j].num_annotations;
641  k++) {
642  if (pb_type->modes[i].interconnect[j].annotations[k].clock)
643  free(
644  pb_type->modes[i].interconnect[j].annotations[k].clock);
645  if (pb_type->modes[i].interconnect[j].annotations[k].input_pins) {
646  free(
647  pb_type->modes[i].interconnect[j].annotations[k].input_pins);
648  }
649  if (pb_type->modes[i].interconnect[j].annotations[k].output_pins) {
650  free(
651  pb_type->modes[i].interconnect[j].annotations[k].output_pins);
652  }
653  for (m = 0;
654  m
656  m++) {
657  free(
658  pb_type->modes[i].interconnect[j].annotations[k].value[m]);
659  }
660  free(pb_type->modes[i].interconnect[j].annotations[k].prop);
661  free(pb_type->modes[i].interconnect[j].annotations[k].value);
662  }
663  free(pb_type->modes[i].interconnect[j].annotations);
664  if (pb_type->modes[i].interconnect[j].interconnect_power)
665  free(pb_type->modes[i].interconnect[j].interconnect_power);
666  }
667  if (pb_type->modes[i].interconnect)
668  free(pb_type->modes[i].interconnect);
669  if (pb_type->modes[i].mode_power)
670  free(pb_type->modes[i].mode_power);
671  }
672  if (pb_type->modes)
673  free(pb_type->modes);
674 
675  for (i = 0; i < pb_type->num_annotations; i++) {
676  for (j = 0; j < pb_type->annotations[i].num_value_prop_pairs; j++) {
677  free(pb_type->annotations[i].value[j]);
678  }
679  free(pb_type->annotations[i].value);
680  free(pb_type->annotations[i].prop);
681  if (pb_type->annotations[i].input_pins) {
682  free(pb_type->annotations[i].input_pins);
683  }
684  if (pb_type->annotations[i].output_pins) {
685  free(pb_type->annotations[i].output_pins);
686  }
687  if (pb_type->annotations[i].clock) {
688  free(pb_type->annotations[i].clock);
689  }
690  }
691  if (pb_type->num_annotations > 0) {
692  free(pb_type->annotations);
693  }
694 
695  if (pb_type->pb_type_power) {
696  free(pb_type->pb_type_power);
697  }
698 
699  for (i = 0; i < pb_type->num_ports; i++) {
700  free(pb_type->ports[i].name);
701  if (pb_type->ports[i].port_class) {
702  free(pb_type->ports[i].port_class);
703  }
704  if (pb_type->ports[i].port_power) {
705  free(pb_type->ports[i].port_power);
706  }
707  }
708  free(pb_type->ports);
709 }
710 
711 void free_circuit() {
712  int i;
713  struct s_linked_vptr *p_io_removed;
714 
715  /* Free netlist reference tables for nets */
720 
721  /* Free logical blocks and nets */
722  if (logical_block != NULL) {
725  }
726 
727  if (clb_net != NULL) {
728  for (i = 0; i < num_nets; i++) {
729  free(clb_net[i].name);
730  free(clb_net[i].node_block);
731  free(clb_net[i].node_block_pin);
732  free(clb_net[i].node_block_port);
733  }
734  }
735  free(clb_net);
736  clb_net = NULL;
737 
738  if (block != NULL) {
739  for (i = 0; i < num_blocks; i++) {
740  if (block[i].pb != NULL) {
741  free_cb(block[i].pb);
742  free(block[i].pb);
743  }
744  free(block[i].nets);
745  free(block[i].name);
746  }
747  }
748  free(block);
749  block = NULL;
750 
751  free(blif_circuit_name);
752  free(default_output_name);
753  blif_circuit_name = NULL;
754 
755  p_io_removed = circuit_p_io_removed;
756  while (p_io_removed != NULL) {
757  circuit_p_io_removed = p_io_removed->next;
758  free(p_io_removed->data_vptr);
759  free(p_io_removed);
760  p_io_removed = circuit_p_io_removed;
761  }
762 }
763 
765  INOUTP t_vpr_setup vpr_setup) {
766 
767  if (vpr_setup.Timing.SDCFile != NULL) {
768  free(vpr_setup.Timing.SDCFile);
769  vpr_setup.Timing.SDCFile = NULL;
770  }
771 
772  free_options(&options);
773  free_circuit();
774  free_arch(&Arch);
779 }
780 
782  INOUTP t_vpr_setup vpr_setup) {
783  free_rr_graph();
784  if (vpr_setup.RouterOpts.doRouting) {
786  }
788  vpr_free_vpr_data_structures(Arch, options, vpr_setup);
790  PrintHandlerDelete();
791  }
792 }
793 
794 /****************************************************************************************************
795  * Advanced functions
796  * Used when you need fine-grained control over VPR that the main VPR operations do not enable
797  ****************************************************************************************************/
798 /* Read in user options */
799 void vpr_read_options(INP int argc, INP char **argv, OUTP t_options * options) {
800  ReadOptions(argc, argv, options);
801 }
802 
803 /* Read in arch and circuit */
804 void vpr_setup_vpr(INP t_options *Options, INP boolean TimingEnabled,
805  INP boolean readArchFile, OUTP struct s_file_name_opts *FileNameOpts,
806  INOUTP t_arch * Arch, OUTP enum e_operation *Operation,
807  OUTP t_model ** user_models, OUTP t_model ** library_models,
808  OUTP struct s_packer_opts *PackerOpts,
809  OUTP struct s_placer_opts *PlacerOpts,
810  OUTP struct s_annealing_sched *AnnealSched,
811  OUTP struct s_router_opts *RouterOpts,
812  OUTP struct s_det_routing_arch *RoutingArch,
813  OUTP t_segment_inf ** Segments, OUTP t_timing_inf * Timing,
814  OUTP boolean * ShowGraphics, OUTP int *GraphPause,
815  t_power_opts * PowerOpts) {
816  SetupVPR(Options, TimingEnabled, readArchFile, FileNameOpts, Arch,
817  Operation, user_models, library_models, PackerOpts, PlacerOpts,
818  AnnealSched, RouterOpts, RoutingArch, Segments, Timing,
819  ShowGraphics, GraphPause, PowerOpts);
820 }
821 /* Check inputs are reasonable */
822 void vpr_check_options(INP t_options Options, INP boolean TimingEnabled) {
823  CheckOptions(Options, TimingEnabled);
824 }
825 void vpr_check_arch(INP t_arch Arch, INP boolean TimingEnabled) {
826  CheckArch(Arch, TimingEnabled);
827 }
828 /* Verify settings don't conflict or otherwise not make sense */
829 void vpr_check_setup(INP enum e_operation Operation,
830  INP struct s_placer_opts PlacerOpts,
831  INP struct s_annealing_sched AnnealSched,
832  INP struct s_router_opts RouterOpts,
833  INP struct s_det_routing_arch RoutingArch, INP t_segment_inf * Segments,
834  INP t_timing_inf Timing, INP t_chan_width_dist Chans) {
835  CheckSetup(Operation, PlacerOpts, AnnealSched, RouterOpts, RoutingArch,
836  Segments, Timing, Chans);
837 }
838 /* Read blif file and sweep unused components */
839 void vpr_read_and_process_blif(INP char *blif_file,
840  INP boolean sweep_hanging_nets_and_inputs, INP t_model *user_models,
841  INP t_model *library_models, boolean read_activity_file,
842  char * activity_file) {
843  read_and_process_blif(blif_file, sweep_hanging_nets_and_inputs, user_models,
844  library_models, read_activity_file, activity_file);
845 }
846 /* Show current setup */
847 void vpr_show_setup(INP t_options options, INP t_vpr_setup vpr_setup) {
848  ShowSetup(options, vpr_setup);
849 }
850 
851 /* Output file names management */
852 void vpr_alloc_and_load_output_file_names(const char* default_name) {
853  alloc_and_load_output_file_names(default_name);
854 }
855 void vpr_set_output_file_name(enum e_output_files ename, const char *name,
856  const char* default_name) {
857  setOutputFileName(ename, name, default_name);
858 }
860  return getOutputFileName(ename);
861 }
862 
863 /* logical equivalence scrambles the packed netlist indices with the actual indices, need to resync then re-output clustered netlist, this code assumes I'm dealing with a TI CLAY v1 architecture */
864 /* Returns a trace array [0..num_logical_nets-1] with the final routing of the circuit from the logical_block netlist, index of the trace array corresponds to the index of a vpack_net */
866  INP const t_arch *arch) {
867  t_trace *trace;
868 
869  /* Map post-routed traces to clb_nets and block */
871 
872  /* Resolve logically equivalent inputs */
874 
875  /* Finalize traceback */
880  }
881  return trace;
882 }
883 
884 /* reload intra cluster nets to complex block */
885 static void reload_intra_cluster_nets(t_pb *pb) {
886  int i, j;
887  const t_pb_type* pb_type;
888  pb_type = pb->pb_graph_node->pb_type;
889  if (pb_type->blif_model != NULL) {
891  pb->pb_graph_node);
892  } else if (pb->child_pbs != NULL) {
893  set_pb_graph_mode(pb->pb_graph_node, pb->mode, 1);
894  for (i = 0; i < pb_type->modes[pb->mode].num_pb_type_children; i++) {
895  for (j = 0; j < pb_type->modes[pb->mode].pb_type_children[i].num_pb;
896  j++) {
897  if (pb->child_pbs[i] != NULL) {
898  if (pb->child_pbs[i][j].name != NULL) {
900  }
901  }
902  }
903  }
904  }
905 }
906 
907 /* Determine trace from logical_block output to logical_block inputs
908  Algorithm traverses intra-block routing, goes to inter-block routing, then returns to intra-block routing
909  */
911  int i;
912  int iblock;
913  t_trace* final_routing_trace;
914  t_pb_graph_pin *pin;
915 
916  final_routing_trace = (t_trace*) my_calloc(num_logical_nets,
917  sizeof(t_trace));
918  for (i = 0; i < num_logical_nets; i++) {
920 
921  final_routing_trace[i].iblock = iblock;
922  final_routing_trace[i].iswitch = OPEN;
923  final_routing_trace[i].index = OPEN;
924  final_routing_trace[i].next = NULL;
925 
927  if (!pin)
928  continue;
929  final_routing_trace[i].index = pin->pin_count_in_cluster;
930 
931  expand_routing_trace(&final_routing_trace[i], i);
932  }
933 
934  return final_routing_trace;
935 }
936 
937 /* Given a routing trace, expand until full trace is complete
938  returns pointer to last terminal trace
939  */
940 static t_trace *expand_routing_trace(t_trace *trace, int ivpack_net) {
941  int i, iblock, inode, ipin, inet;
942  int gridx, gridy;
943  t_trace *current, *new_trace, *inter_cb_trace;
944  t_rr_node *local_rr_graph;
945  boolean success;
946  t_pb_graph_pin *pb_graph_pin;
947 
948  iblock = trace->iblock;
949  inode = trace->index;
950  local_rr_graph = block[iblock].pb->rr_graph;
951  current = trace;
952 
953  if (local_rr_graph[inode].pb_graph_pin->num_output_edges == 0) {
954  if (local_rr_graph[inode].pb_graph_pin->port->type == OUT_PORT) {
955  /* connection to outside cb */
956  if (vpack_net[ivpack_net].is_global) {
957  inet = vpack_to_clb_net_mapping[ivpack_net];
958  if (inet != OPEN) {
959  for (ipin = 1; ipin <= clb_net[inet].num_sinks; ipin++) {
960  pb_graph_pin = get_pb_graph_node_pin_from_clb_net(inet,
961  ipin);
962  new_trace = (t_trace*) my_calloc(1, sizeof(t_trace));
963  new_trace->iblock = clb_net[inet].node_block[ipin];
964  new_trace->index = pb_graph_pin->pin_count_in_cluster;
965  new_trace->iswitch = OPEN;
966  new_trace->num_siblings = 0;
967  new_trace->next = NULL;
968  current->next = new_trace;
969  current = expand_routing_trace(new_trace, ivpack_net);
970  }
971  }
972  } else {
973  inter_cb_trace =
975  if (inter_cb_trace != NULL) {
976  inter_cb_trace = inter_cb_trace->next; /* skip source and go right to opin */
977  }
978  while (inter_cb_trace != NULL) {
979  /* continue traversing inter cb trace */
980  if (rr_node[inter_cb_trace->index].type != SINK) {
981  new_trace = (t_trace*) my_calloc(1, sizeof(t_trace));
982  new_trace->iblock = OPEN;
983  new_trace->index = inter_cb_trace->index;
984  new_trace->iswitch = inter_cb_trace->iswitch;
985  new_trace->num_siblings = 0;
986  new_trace->next = NULL;
987  current->next = new_trace;
988  if (rr_node[inter_cb_trace->index].type == IPIN) {
989  current = current->next;
990  gridx = rr_node[new_trace->index].xlow;
991  gridy = rr_node[new_trace->index].ylow;
992  gridy = gridy - grid[gridx][gridy].offset;
993  new_trace = (t_trace*) my_calloc(1,
994  sizeof(t_trace));
995  new_trace->iblock =
996  grid[gridx][gridy].blocks[rr_node[inter_cb_trace->index].z];
997  new_trace->index =
999  new_trace->iswitch = OPEN;
1000  new_trace->num_siblings = 0;
1001  new_trace->next = NULL;
1002  current->next = new_trace;
1003  current = expand_routing_trace(new_trace,
1004  ivpack_net);
1005  } else {
1006  current = current->next;
1007  }
1008  }
1009  inter_cb_trace = inter_cb_trace->next;
1010  }
1011  }
1012  }
1013  } else {
1014  /* connection to another intra-cluster pin */
1015  current = trace;
1016  success = FALSE;
1017  for (i = 0; i < local_rr_graph[inode].num_edges; i++) {
1018  if (local_rr_graph[local_rr_graph[inode].edges[i]].prev_node
1019  == inode) {
1020  if (success == FALSE) {
1021  success = TRUE;
1022  } else {
1023  current->next = (t_trace*) my_calloc(1, sizeof(t_trace));
1024  current = current->next;
1025  current->iblock = trace->iblock;
1026  current->index = trace->index;
1027  current->iswitch = trace->iswitch;
1028  current->next = NULL;
1029  }
1030  new_trace = (t_trace*) my_calloc(1, sizeof(t_trace));
1031  new_trace->iblock = trace->iblock;
1032  new_trace->index = local_rr_graph[inode].edges[i];
1033  new_trace->iswitch = OPEN;
1034  new_trace->num_siblings = 0;
1035  new_trace->next = NULL;
1036  current->next = new_trace;
1037  current = expand_routing_trace(new_trace, ivpack_net);
1038  }
1039  }
1040  assert(success);
1041  }
1042  return current;
1043 }
1044 
1045 static void print_complete_net_trace(t_trace* trace, const char *file_name) {
1046  FILE *fp;
1047  int iblock, inode, iprev_block;
1048  t_trace *current;
1049  t_rr_node *local_rr_graph;
1050  const char *name_type[] = { "SOURCE", "SINK", "IPIN", "OPIN", "CHANX",
1051  "CHANY", "INTRA_CLUSTER_EDGE" };
1052  int i;
1053 
1054  fp = my_fopen(file_name, "w", 0);
1055 
1056  for (i = 0; i < num_logical_nets; i++) {
1057  current = &trace[i];
1058  iprev_block = OPEN;
1059 
1060  fprintf(fp, "Net %s (%d)\n\n", vpack_net[i].name, i);
1061  while (current != NULL) {
1062  iblock = current->iblock;
1063  inode = current->index;
1064  if (iblock != OPEN) {
1065  if (iprev_block != iblock) {
1066  iprev_block = iblock;
1067  fprintf(fp, "Block %s (%d) (%d, %d, %d):\n",
1068  block[iblock].name, iblock, block[iblock].x,
1069  block[iblock].y, block[iblock].z);
1070  }
1071  local_rr_graph = block[iblock].pb->rr_graph;
1072  fprintf(fp, "\tNode:\t%d\t%s[%d].%s[%d]", inode,
1073  local_rr_graph[inode].pb_graph_pin->parent_node->pb_type->name,
1074  local_rr_graph[inode].pb_graph_pin->parent_node->placement_index,
1075  local_rr_graph[inode].pb_graph_pin->port->name,
1076  local_rr_graph[inode].pb_graph_pin->pin_number);
1077  } else {
1078  fprintf(fp, "Node:\t%d\t%6s (%d,%d) ", inode,
1079  name_type[(int) rr_node[inode].type],
1080  rr_node[inode].xlow, rr_node[inode].ylow);
1081 
1082  if ((rr_node[inode].xlow != rr_node[inode].xhigh)
1083  || (rr_node[inode].ylow != rr_node[inode].yhigh))
1084  fprintf(fp, "to (%d,%d) ", rr_node[inode].xhigh,
1085  rr_node[inode].yhigh);
1086 
1087  switch (rr_node[inode].type) {
1088 
1089  case IPIN:
1090  case OPIN:
1091  if (grid[rr_node[inode].xlow][rr_node[inode].ylow].type
1092  == IO_TYPE) {
1093  fprintf(fp, " Pad: ");
1094  } else { /* IO Pad. */
1095  fprintf(fp, " Pin: ");
1096  }
1097  break;
1098 
1099  case CHANX:
1100  case CHANY:
1101  fprintf(fp, " Track: ");
1102  break;
1103 
1104  case SOURCE:
1105  case SINK:
1106  if (grid[rr_node[inode].xlow][rr_node[inode].ylow].type
1107  == IO_TYPE) {
1108  fprintf(fp, " Pad: ");
1109  } else { /* IO Pad. */
1110  fprintf(fp, " Class: ");
1111  }
1112  break;
1113 
1114  default:
1115  vpr_printf(TIO_MESSAGE_ERROR,
1116  "in print_route: Unexpected traceback element type: %d (%s).\n",
1117  rr_node[inode].type,
1118  name_type[rr_node[inode].type]);
1119  exit(1);
1120  break;
1121  }
1122 
1123  fprintf(fp, "%d ", rr_node[inode].ptc_num);
1124 
1125  /* Uncomment line below if you're debugging and want to see the switch types *
1126  * used in the routing. */
1127  /* fprintf (fp, "Switch: %d", tptr->iswitch); */
1128 
1129  fprintf(fp, "\n");
1130  }
1131  current = current->next;
1132  }
1133  fprintf(fp, "\n");
1134  }
1135  fclose(fp);
1136 }
1137 
1139  int i, j, iblock;
1140  int gridx, gridy;
1141  t_trace *trace;
1142  for (i = 0; i < num_blocks; i++) {
1143  for (j = 0; j < block[i].type->num_pins; j++) {
1144  if (block[i].nets[j] != OPEN
1145  && clb_net[block[i].nets[j]].is_global == FALSE)
1146  block[i].nets[j] = OPEN;
1147  }
1148  }
1149  for (i = 0; i < num_nets; i++) {
1150  if (clb_net[i].is_global == TRUE)
1151  continue;
1152  j = 0;
1153  trace = trace_head[i];
1154  while (trace != NULL) {
1155  if (rr_node[trace->index].type == OPIN && j == 0) {
1156  gridx = rr_node[trace->index].xlow;
1157  gridy = rr_node[trace->index].ylow;
1158  gridy = gridy - grid[gridx][gridy].offset;
1159  iblock = grid[gridx][gridy].blocks[rr_node[trace->index].z];
1160  assert(clb_net[i].node_block[j] == iblock);
1161  clb_net[i].node_block_pin[j] = rr_node[trace->index].ptc_num;
1162  block[iblock].nets[rr_node[trace->index].ptc_num] = i;
1163  j++;
1164  } else if (rr_node[trace->index].type == IPIN) {
1165  gridx = rr_node[trace->index].xlow;
1166  gridy = rr_node[trace->index].ylow;
1167  gridy = gridy - grid[gridx][gridy].offset;
1168  iblock = grid[gridx][gridy].blocks[rr_node[trace->index].z];
1169  clb_net[i].node_block[j] = iblock;
1170  clb_net[i].node_block_pin[j] = rr_node[trace->index].ptc_num;
1171  block[iblock].nets[rr_node[trace->index].ptc_num] = i;
1172  j++;
1173  }
1174  trace = trace->next;
1175  }
1176  assert(j == clb_net[i].num_sinks + 1);
1177  }
1178 }
1179 
1180 static void clay_logical_equivalence_handling(const t_arch *arch) {
1181  t_trace **saved_ext_rr_trace_head, **saved_ext_rr_trace_tail;
1182  t_rr_node *saved_ext_rr_node;
1183  int num_ext_rr_node, num_ext_nets;
1184  int i, j;
1185 
1186  for (i = 0; i < num_blocks; i++) {
1188  }
1189 
1190  /* Resolve logically equivalent inputs */
1191  saved_ext_rr_trace_head = trace_head;
1192  saved_ext_rr_trace_tail = trace_tail;
1193  saved_ext_rr_node = rr_node;
1194  num_ext_rr_node = num_rr_nodes;
1195  num_ext_nets = num_nets;
1196  num_rr_nodes = 0;
1197  rr_node = NULL;
1198  trace_head = NULL;
1199  trace_tail = NULL;
1200  free_rr_graph(); /* free all data structures associated with rr_graph */
1201 
1203  for (i = 0; i < num_blocks; i++) {
1204  /* Regenerate rr_graph (note, can be more runtime efficient but this allows for more code reuse)
1205  */
1206  rr_node = block[i].pb->rr_graph;
1213 #ifdef HACK_LUT_PIN_SWAPPING
1214  /* Resolve rebalancing of LUT inputs */
1216 #endif
1217 
1218  /* reset rr_graph */
1219  for (j = 0; j < num_rr_nodes; j++) {
1220  rr_node[j].occ = 0;
1221  rr_node[j].prev_edge = OPEN;
1222  rr_node[j].prev_node = OPEN;
1223  }
1225  vpr_printf(TIO_MESSAGE_ERROR,
1226  "Failed to resync post routed solution with clustered netlist.\n");
1227  vpr_printf(TIO_MESSAGE_ERROR, "Cannot recover from error.\n");
1228  exit(1);
1229  }
1233  }
1235 
1236  trace_head = saved_ext_rr_trace_head;
1237  trace_tail = saved_ext_rr_trace_tail;
1238  rr_node = saved_ext_rr_node;
1239  num_rr_nodes = num_ext_rr_node;
1240  num_nets = num_ext_nets;
1241 }
1242 
1243 /* Force router to use the LUT inputs designated by the timing engine post the LUT input rebalancing optimization */
1244 static void clay_lut_input_rebalancing(int iblock, t_pb *pb) {
1245  int i, j;
1246  t_rr_node *local_rr_graph;
1247  t_pb_graph_node *lut_wrapper, *lut;
1248  int lut_size;
1249  int *lut_pin_remap;
1250  int snode, input;
1251  t_pb_graph_node *pb_graph_node;
1252 
1253  if (pb->name != NULL) {
1254  pb_graph_node = pb->pb_graph_node;
1255  if (pb_graph_node->pb_type->blif_model != NULL) {
1256  lut_pin_remap = pb->lut_pin_remap;
1257  if (lut_pin_remap != NULL) {
1258  local_rr_graph = block[iblock].pb->rr_graph;
1259  lut = pb->pb_graph_node;
1260  lut_wrapper = lut->parent_pb_graph_node;
1261 
1262  /* Ensure that this is actually a LUT */
1263  assert(
1264  lut->num_input_ports == 1 && lut_wrapper->num_input_ports == 1);
1265  assert(
1266  lut->num_input_pins[0] == lut_wrapper->num_input_pins[0]);
1267  assert(
1268  lut->num_output_ports == 1 && lut_wrapper->num_output_ports == 1);
1269  assert(
1270  lut->num_output_pins[0] == 1 && lut_wrapper->num_output_pins[0] == 1);
1271 
1272  lut_size = lut->num_input_pins[0];
1273  for (i = 0; i < lut_size; i++) {
1274  snode = lut_wrapper->input_pins[0][i].pin_count_in_cluster;
1275  free(local_rr_graph[snode].edges);
1276  local_rr_graph[snode].edges = NULL;
1277  local_rr_graph[snode].num_edges = 0;
1278  }
1279  for (i = 0; i < lut_size; i++) {
1280  input = lut_pin_remap[i];
1281  if (input != OPEN) {
1282  snode =
1283  lut_wrapper->input_pins[0][i].pin_count_in_cluster;
1284  assert(local_rr_graph[snode].num_edges == 0);
1285  local_rr_graph[snode].num_edges = 1;
1286  local_rr_graph[snode].edges = (int*) my_malloc(
1287  sizeof(int));
1288  local_rr_graph[snode].edges[0] =
1289  lut->input_pins[0][input].pin_count_in_cluster;
1290  }
1291  }
1292  }
1293  } else if (pb->child_pbs != NULL) {
1294  for (i = 0;
1295  i
1296  < pb_graph_node->pb_type->modes[pb->mode].num_pb_type_children;
1297  i++) {
1298  if (pb->child_pbs[i] != NULL) {
1299  for (j = 0;
1300  j
1301  < pb_graph_node->pb_type->modes[pb->mode].pb_type_children[i].num_pb;
1302  j++) {
1304  &pb->child_pbs[i][j]);
1305  }
1306  }
1307  }
1308  }
1309  }
1310 }
1311 
1312 /* Swaps BLEs to match output logical equivalence solution from routing solution
1313  Assumes classical cluster with full crossbar and BLEs, each BLE is a single LUT+FF pair
1314  */
1315 static void clay_reload_ble_locations(int iblock) {
1316  int i, mode, ipin, new_loc;
1317  t_pb_graph_node *pb_graph_node;
1318  t_pb_graph_pin *pb_graph_pin;
1319  const t_pb_type *pb_type;
1320  t_trace *trace;
1321  t_rr_node *local_rr_graph;
1322  int inet, ivpack_net;
1323 
1324  if (block[iblock].type == IO_TYPE) {
1325  return;
1326  }
1327 
1328  pb_graph_node = block[iblock].pb->pb_graph_node;
1329  pb_type = pb_graph_node->pb_type;
1330  mode = block[iblock].pb->mode;
1331  local_rr_graph = block[iblock].pb->rr_graph;
1332 
1333  assert(block[iblock].pb->mode == 0);
1334  assert(pb_type->modes[mode].num_pb_type_children == 1);
1335  assert(pb_type->modes[mode].pb_type_children[0].num_output_pins == 1);
1336 
1337  t_pb** temp;
1338  temp = (t_pb**) my_calloc(1, sizeof(t_pb*));
1339  temp[0] = (t_pb*) my_calloc(pb_type->modes[mode].pb_type_children[0].num_pb,
1340  sizeof(t_pb));
1341 
1342  /* determine new location for BLEs that route out of cluster */
1343  for (i = 0; i < pb_type->modes[mode].pb_type_children[0].num_pb; i++) {
1344  if (block[iblock].pb->child_pbs[0][i].name != NULL) {
1345  ivpack_net =
1346  local_rr_graph[pb_graph_node->child_pb_graph_nodes[mode][0][i].output_pins[0][0].pin_count_in_cluster].net_num;
1347  inet = vpack_to_clb_net_mapping[ivpack_net];
1348  if (inet != OPEN) {
1349  ipin = OPEN;
1350  trace = trace_head[inet];
1351  while (trace) {
1352  if (rr_node[trace->index].type == OPIN) {
1353  ipin = rr_node[trace->index].ptc_num;
1354  break;
1355  }
1356  trace = trace->next;
1357  }
1358  assert(ipin);
1359  pb_graph_pin = get_pb_graph_node_pin_from_block_pin(iblock,
1360  ipin);
1361  new_loc = pb_graph_pin->pin_number;
1362  assert(temp[0][new_loc].name == NULL);
1363  temp[0][new_loc] = block[iblock].pb->child_pbs[0][i];
1364  }
1365  }
1366  }
1367 
1368  /* determine new location for BLEs that do not route out of cluster */
1369  new_loc = 0;
1370  for (i = 0; i < pb_type->modes[mode].pb_type_children[0].num_pb; i++) {
1371  if (block[iblock].pb->child_pbs[0][i].name != NULL) {
1372  ivpack_net =
1373  local_rr_graph[pb_graph_node->child_pb_graph_nodes[mode][0][i].output_pins[0][0].pin_count_in_cluster].net_num;
1374  inet = vpack_to_clb_net_mapping[ivpack_net];
1375  if (inet == OPEN) {
1376  while (temp[0][new_loc].name != NULL) {
1377  new_loc++;
1378  }
1379  temp[0][new_loc] = block[iblock].pb->child_pbs[0][i];
1380  }
1381  }
1382  }
1383 
1384  free(block[iblock].pb->child_pbs);
1385  block[iblock].pb->child_pbs = temp;
1386  resync_pb_graph_nodes_in_pb(block[iblock].pb->pb_graph_node,
1387  block[iblock].pb);
1388 }
1389 
1391  t_pb *pb) {
1392  int i, j;
1393 
1394  if (pb->name == NULL) {
1395  return;
1396  }
1397 
1398  assert(
1399  strcmp(pb->pb_graph_node->pb_type->name, pb_graph_node->pb_type->name) == 0);
1400 
1401  pb->pb_graph_node = pb_graph_node;
1402  if (pb->child_pbs != NULL) {
1403  for (i = 0;
1404  i < pb_graph_node->pb_type->modes[pb->mode].num_pb_type_children;
1405  i++) {
1406  if (pb->child_pbs[i] != NULL) {
1407  for (j = 0;
1408  j
1409  < pb_graph_node->pb_type->modes[pb->mode].pb_type_children[i].num_pb;
1410  j++) {
1412  &pb_graph_node->child_pb_graph_nodes[pb->mode][i][j],
1413  &pb->child_pbs[i][j]);
1414  }
1415  }
1416  }
1417  }
1418 }
1419 
1420 /* This function performs power estimation, and must be called
1421  * after packing, placement AND routing. Currently, this
1422  * will not work when running a partial flow (ex. only routing).
1423  */
1424 void vpr_power_estimation(t_vpr_setup vpr_setup, t_arch Arch) {
1425  e_power_ret_code power_ret_code;
1426  boolean power_error;
1427 
1428  /* Ensure we are only using 1 clock */
1429  assert(count_netlist_clocks() == 1);
1430 
1431  /* Get the critical path of this clock */
1433  assert(g_solution_inf.T_crit > 0.);
1434 
1435  vpr_printf(TIO_MESSAGE_INFO, "\n\nPower Estimation:\n");
1436  vpr_printf(TIO_MESSAGE_INFO, "-----------------\n");
1437 
1438  vpr_printf(TIO_MESSAGE_INFO, "Initializing power module\n");
1439 
1440  /* Initialize the power module */
1441  power_error = power_init(vpr_setup.FileNameOpts.PowerFile,
1442  vpr_setup.FileNameOpts.CmosTechFile, &Arch, &vpr_setup.RoutingArch);
1443  if (power_error) {
1444  vpr_printf(TIO_MESSAGE_ERROR, "Power initialization failed.\n");
1445  }
1446 
1447  if (!power_error) {
1448  float power_runtime_s;
1449 
1450  vpr_printf(TIO_MESSAGE_INFO, "Running power estimation\n");
1451 
1452  /* Run power estimation */
1453  power_ret_code = power_total(&power_runtime_s, vpr_setup, &Arch,
1454  &vpr_setup.RoutingArch);
1455 
1456  /* Check for errors/warnings */
1457  if (power_ret_code == POWER_RET_CODE_ERRORS) {
1458  vpr_printf(TIO_MESSAGE_ERROR,
1459  "Power estimation failed. See power output for error details.\n");
1460  } else if (power_ret_code == POWER_RET_CODE_WARNINGS) {
1461  vpr_printf(TIO_MESSAGE_WARNING,
1462  "Power estimation completed with warnings. See power output for more details.\n");
1463  } else if (power_ret_code == POWER_RET_CODE_SUCCESS) {
1464  }
1465  vpr_printf(TIO_MESSAGE_INFO, "Power estimation took %g seconds\n",
1466  power_runtime_s);
1467  }
1468 
1469  /* Uninitialize power module */
1470  if (!power_error) {
1471  vpr_printf(TIO_MESSAGE_INFO, "Uninitializing power module\n");
1472  power_error = power_uninit();
1473  if (power_error) {
1474  vpr_printf(TIO_MESSAGE_ERROR, "Power uninitialization failed.\n");
1475  } else {
1476 
1477  }
1478  }
1479  vpr_printf(TIO_MESSAGE_INFO, "\n");
1480 }
int * node_block_pin
Definition: vpr_types.h:509
void setEchoEnabled(boolean echo_enabled)
Definition: ReadOptions.c:71
void free_logical_blocks(void)
short num_edges
Definition: vpr_types.h:901
void printClusteredNetlistStats(void)
Definition: ShowSetup.c:50
char * name
Definition: vpr_types.h:179
t_clock_network * clock_inf
t_interconnect * interconnect
int index
Definition: vpr_types.h:866
char * CmosTechFile
Definition: vpr_types.h:584
FILE * my_fopen(const char *fname, const char *flag, int prompt)
Definition: util.c:54
int num_siblings
Definition: vpr_types.h:869
int * edges
Definition: vpr_types.h:903
t_port_power * port_power
struct s_pb ** child_pbs
Definition: vpr_types.h:185
void vpr_setup_vpr(INP t_options *Options, INP boolean TimingEnabled, INP boolean readArchFile, OUTP struct s_file_name_opts *FileNameOpts, INOUTP t_arch *Arch, OUTP enum e_operation *Operation, OUTP t_model **user_models, OUTP t_model **library_models, OUTP struct s_packer_opts *PackerOpts, OUTP struct s_placer_opts *PlacerOpts, OUTP struct s_annealing_sched *AnnealSched, OUTP struct s_router_opts *RouterOpts, OUTP struct s_det_routing_arch *RoutingArch, OUTP t_segment_inf **Segments, OUTP t_timing_inf *Timing, OUTP boolean *ShowGraphics, OUTP int *GraphPause, t_power_opts *PowerOpts)
Definition: vpr_api.c:804
void free_rr_graph(void)
Definition: rr_graph.c:798
char * name
void close_graphics(void)
Definition: graphics.c:2417
void freeGrid()
Definition: SetupGrid.c:130
struct s_trace ** trace_tail
Definition: globals.c:65
struct s_pb_type * pb_type_children
#define WIRE_SEGMENT_LENGTH
void free_cluster_legality_checker(void)
void vpr_free_vpr_data_structures(INOUTP t_arch Arch, INOUTP t_options options, INOUTP t_vpr_setup vpr_setup)
Definition: vpr_api.c:764
struct s_linked_vptr * circuit_p_io_removed
Definition: globals.c:90
t_rr_node * rr_node
Definition: globals.c:70
boolean IsPostSynthesisEnabled(INP t_options *Options)
Definition: ReadOptions.c:88
int net_num
Definition: vpr_types.h:917
struct s_pb_graph_node * parent_pb_graph_node
void free_legalizer_for_cluster(INP t_block *clb, boolean free_local_rr_graph)
void vpr_check_options(INP t_options Options, INP boolean TimingEnabled)
Definition: vpr_api.c:822
t_direct_inf * Directs
void * instances
Definition: logic_types.h:37
short ptc_num
Definition: vpr_types.h:895
void vpr_print_usage(void)
Definition: vpr_api.c:82
struct s_rr_node * rr_graph
Definition: vpr_types.h:188
t_type_ptr EMPTY_TYPE
Definition: globals.c:41
t_pb_graph_pin * get_pb_graph_node_pin_from_clb_net(int inet, int ipin)
Definition: vpr_utils.c:391
t_model * model_library
int * clb_to_vpack_net_mapping
Definition: globals.c:33
short iswitch
Definition: vpr_types.h:867
#define nint(a)
Definition: util.h:24
static void free_arch(t_arch *Arch)
Definition: vpr_api.c:452
#define VPR_VERSION
Definition: arch_types.h:16
t_mode * modes
void vpr_read_options(INP int argc, INP char **argv, OUTP t_options *options)
Definition: vpr_api.c:799
float get_switch_info(short switch_index, float &Tdel_switch, float &R_switch, float &Cout_switch)
Definition: pack.c:107
t_model * models
float get_critical_path_delay(void)
Definition: path_delay.c:3060
short ylow
Definition: vpr_types.h:892
int num_interconnect
void free_chunk_memory_trace(void)
boolean power_init(char *power_out_filepath, char *cmos_tech_behavior_filepath, t_arch *arch, t_det_routing_arch *routing_arch)
Definition: power.c:1270
void vpr_show_setup(INP t_options options, INP t_vpr_setup vpr_setup)
Definition: vpr_api.c:847
void vpr_check_arch(INP t_arch Arch, INP boolean TimingEnabled)
Definition: vpr_api.c:825
boolean IsTimingEnabled(INP t_options *Options)
Definition: ReadOptions.c:47
boolean IsEchoEnabled(INP t_options *Options)
Definition: ReadOptions.c:58
static t_trace * alloc_and_load_final_routing_trace()
Definition: vpr_api.c:910
char * CmosTechFile
Definition: ReadOptions.h:18
int * chan_width_x
Definition: globals.c:56
int prev_node
Definition: vpr_types.h:915
char * NetFile
Definition: ReadOptions.h:12
char * ArchFile
Definition: ReadOptions.h:9
char * PlaceFile
Definition: ReadOptions.h:13
void check_netlist()
Definition: check_netlist.c:37
void * my_calloc(size_t nelem, size_t size)
Definition: util.c:132
struct s_model_ports * next
Definition: logic_types.h:28
t_pb_type_power * pb_type_power
void free_trace_structs(void)
Definition: route_common.c:733
void free_cb(t_pb *pb)
Definition: vpr_utils.c:508
enum PORTS type
int num_nets
Definition: globals.c:27
int * lut_pin_remap
Definition: vpr_types.h:197
int * node_block
Definition: vpr_types.h:507
void CheckOptions(INP t_options Options, INP boolean TimingEnabled)
Definition: CheckOptions.c:12
void ReadOptions(INP int argc, INP char **argv, OUTP t_options *Options)
Definition: ReadOptions.c:239
void reload_ext_net_rr_terminal_cluster(void)
int * chan_width_y
Definition: globals.c:57
int num_logical_nets
Definition: globals.c:17
void force_post_place_route_cb_input_pins(int iblock)
char * blif_model
t_pb_graph_pin ** output_pins
void vpr_init_pre_place_and_route(INP t_vpr_setup vpr_setup, INP t_arch Arch)
Definition: vpr_api.c:236
t_type_ptr type
Definition: vpr_types.h:561
#define MAX_SHORT
Definition: vpr_types.h:75
static void reload_intra_cluster_nets(t_pb *pb)
Definition: vpr_api.c:885
void reset_legalizer_for_cluster(t_block *clb)
#define INOUTP
Definition: util.h:21
int num_blocks
Definition: globals.c:30
char * blif_circuit_name
Definition: globals.c:21
void vpr_alloc_and_load_output_file_names(const char *default_name)
Definition: vpr_api.c:852
struct s_file_name_opts FileNameOpts
Definition: vpr_types.h:1034
static void free_circuit(void)
Definition: vpr_api.c:711
#define UNDEFINED
Definition: vpr_types.h:103
boolean getEchoEnabled(void)
Definition: ReadOptions.c:67
char * name
Definition: vpr_types.h:560
int count_netlist_clocks(void)
Definition: stats.c:449
void free_output_file_names()
Definition: ReadOptions.c:221
static const char * name_type[]
Definition: draw.c:87
Definition: util.h:12
boolean power_uninit(void)
Definition: power.c:1326
void alloc_and_load_grid(INOUTP int *num_instances_type)
Definition: SetupGrid.c:22
t_solution_inf g_solution_inf
Definition: power.c:64
boolean try_breadth_first_route_cluster(void)
char * PowerFile
Definition: ReadOptions.h:17
void SetupVPR(INP t_options *Options, INP boolean TimingEnabled, INP boolean readArchFile, OUTP struct s_file_name_opts *FileNameOpts, INOUTP t_arch *Arch, OUTP enum e_operation *Operation, OUTP t_model **user_models, OUTP t_model **library_models, OUTP struct s_packer_opts *PackerOpts, OUTP struct s_placer_opts *PlacerOpts, OUTP struct s_annealing_sched *AnnealSched, OUTP struct s_router_opts *RouterOpts, OUTP struct s_det_routing_arch *RoutingArch, OUTP t_segment_inf **Segments, OUTP t_timing_inf *Timing, OUTP boolean *ShowGraphics, OUTP int *GraphPause, t_power_opts *PowerOpts)
Definition: SetupVPR.c:38
void init_graphics(const char *window_name, int cindex)
Definition: graphics.c:1003
t_pin_to_pin_annotation * annotations
void set_pb_graph_mode(t_pb_graph_node *pb_graph_node, int mode, int isOn)
int num_annotations
char * BlifFile
Definition: ReadOptions.h:15
static void clay_logical_equivalence_handling(const t_arch *arch)
Definition: vpr_api.c:1180
void CheckArch(INP t_arch Arch, INP boolean TimingEnabled)
Definition: CheckArch.c:17
struct s_trace * next
Definition: vpr_types.h:870
static void * my_malloc(int ibytes)
Definition: graphics.c:499
void do_constant_net_delay_timing_analysis(t_timing_inf timing_inf, float constant_net_delay_value)
Definition: path_delay.c:2636
boolean * is_global
void vpr_pack(INP t_vpr_setup vpr_setup, INP t_arch arch)
Definition: vpr_api.c:372
t_clock_arch * clocks
int * vpack_to_clb_net_mapping
Definition: globals.c:34
struct s_model * next
Definition: logic_types.h:40
void vpr_set_output_file_name(enum e_output_files ename, const char *name, const char *default_name)
Definition: vpr_api.c:855
struct s_block * block
Definition: globals.c:31
void vpr_read_and_process_blif(INP char *blif_file, INP boolean sweep_hanging_nets_and_inputs, INP t_model *user_models, INP t_model *library_models, boolean read_activity_file, char *activity_file)
Definition: vpr_api.c:839
void free_draw_structs(void)
Definition: draw.c:400
e_operation
Definition: vpr_types.h:468
struct s_net * clb_net
Definition: globals.c:28
#define INP
Definition: util.h:19
int num_rr_nodes
Definition: globals.c:69
int nx
Definition: globals.c:46
void vpr_free_all(INOUTP t_arch Arch, INOUTP t_options options, INOUTP t_vpr_setup vpr_setup)
Definition: vpr_api.c:781
char * name
static void resync_post_route_netlist()
Definition: vpr_api.c:1138
t_trace * vpr_resync_post_route_netlist_to_TI_CLAY_v1_architecture(INP const t_arch *arch)
Definition: vpr_api.c:865
char * default_output_name
Definition: globals.c:22
struct s_pb_graph_node * parent_node
int logical_block
Definition: vpr_types.h:181
struct s_trace ** trace_head
Definition: globals.c:64
void read_and_process_blif(char *blif_file, boolean sweep_hanging_nets_and_inputs, t_model *user_models, t_model *library_models, boolean read_activity_file, char *activity_file)
Definition: read_blif.c:1765
t_model_ports * inputs
Definition: logic_types.h:35
char * ActFile
Definition: ReadOptions.h:16
struct s_switch_inf * switch_inf
Definition: globals.c:83
struct s_switch_inf * Switches
void setOutputFileName(enum e_output_files ename, const char *name, const char *default_name)
Definition: ReadOptions.c:186
t_model_ports * outputs
Definition: logic_types.h:36
boolean isEchoFileEnabled(enum e_echo_files echo_option)
Definition: ReadOptions.c:115
static void print_complete_net_trace(t_trace *trace, const char *file_name)
Definition: vpr_api.c:1045
void free_sdc_related_structs(void)
Definition: read_sdc.c:1280
struct s_linked_vptr * pb_types
Definition: logic_types.h:39
static boolean has_printhandler_pre_vpr
Definition: vpr_api.c:53
t_pin_to_pin_annotation * annotations
t_segment_inf * Segments
void vpr_print_title(void)
Definition: vpr_api.c:70
struct s_pb_graph_node *** child_pb_graph_nodes
struct s_linked_vptr * next
Definition: util.h:36
int num_pb_type_children
void ShowSetup(INP t_options options, INP t_vpr_setup vpr_setup)
Definition: ShowSetup.c:22
struct s_grid_tile ** grid
Definition: globals.c:59
char * CircuitName
Definition: ReadOptions.h:11
float T_crit
Definition: power.h:83
static char * model
Definition: read_blif.c:45
void * data_vptr
Definition: util.h:35
e_output_files
Definition: ReadOptions.h:137
static void free_complex_block_types(void)
Definition: vpr_api.c:577
int iblock
Definition: vpr_types.h:868
int * blocks
Definition: vpr_types.h:525
char * PowerFile
Definition: vpr_types.h:583
char * getOutputFileName(enum e_output_files ename)
Definition: ReadOptions.c:196
struct s_pb_type * pb_type
static void free_pb_type(t_pb_type *pb_type)
Definition: vpr_api.c:622
void free_timing_stats(void)
Definition: path_delay.c:427
int num_types
Definition: globals.c:37
char * name
Definition: logic_types.h:34
int ** num_pin_loc_assignments
t_type_ptr IO_TYPE
Definition: globals.c:40
void vpr_power_estimation(t_vpr_setup vpr_setup, t_arch Arch)
Definition: vpr_api.c:1424
void set_graphics_state(boolean show_graphics_val, int gr_automode_val, enum e_route_type route_type)
Definition: draw.c:144
void free_all_pb_graph_nodes(void)
static t_trace * expand_routing_trace(t_trace *trace, int ivpack_net)
Definition: vpr_api.c:940
void CheckSetup(INP enum e_operation Operation, INP struct s_placer_opts PlacerOpts, INP struct s_annealing_sched AnnealSched, INP struct s_router_opts RouterOpts, INP struct s_det_routing_arch RoutingArch, INP t_segment_inf *Segments, INP t_timing_inf Timing, INP t_chan_width_dist Chans)
Definition: CheckSetup.c:9
t_pb_graph_pin * pb_graph_pin
Definition: vpr_types.h:918
void setup_intracluster_routing_for_logical_block(INP int iblock, INP t_pb_graph_node *primitive)
struct s_det_routing_arch RoutingArch
Definition: vpr_types.h:1042
t_port * ports
void SetPostSynthesisOption(boolean post_synthesis_enabled)
Definition: ReadOptions.c:84
short xlow
Definition: vpr_types.h:890
void read_netlist(INP const char *net_file, INP const t_arch *arch, OUTP int *L_num_blocks, OUTP struct s_block *block_list[], OUTP int *L_num_nets, OUTP struct s_net *net_list[])
Definition: read_netlist.c:72
e_power_ret_code
Definition: power.h:42
Definition: slre.c:50
int * nets
Definition: vpr_types.h:562
void free_echo_file_info()
Definition: ReadOptions.c:171
char * PinFile
Definition: ReadOptions.h:58
void alloc_draw_structs(void)
Definition: draw.c:376
t_pb * pb
Definition: vpr_types.h:567
int num_segments
char * RouteFile
Definition: ReadOptions.h:14
static void resync_pb_graph_nodes_in_pb(t_pb_graph_node *pb_graph_node, t_pb *pb)
Definition: vpr_api.c:1390
struct s_type_descriptor * type_descriptors
Definition: globals.c:38
struct s_net * vpack_net
Definition: globals.c:19
char * getEchoFileName(enum e_echo_files echo_option)
Definition: ReadOptions.c:122
#define OUTP
Definition: util.h:20
int prev_edge
Definition: vpr_types.h:916
int mode
Definition: vpr_types.h:183
void vpr_check_setup(INP enum e_operation Operation, INP struct s_placer_opts PlacerOpts, INP struct s_annealing_sched AnnealSched, INP struct s_router_opts RouterOpts, INP struct s_det_routing_arch RoutingArch, INP t_segment_inf *Segments, INP t_timing_inf Timing, INP t_chan_width_dist Chans)
Definition: vpr_api.c:829
int num_output_pins
int num_switches
static void free_options(t_options *options)
Definition: vpr_api.c:554
void alloc_and_load_legalizer_for_cluster(INP t_block *clb, INP int clb_index, INP const t_arch *arch)
int ny
Definition: globals.c:47
void free_route_structs()
Definition: route_common.c:750
char * out_file_prefix
Definition: ReadOptions.h:19
void alloc_and_load_output_file_names(const char *default_name)
Definition: ReadOptions.c:200
t_mode_power * mode_power
void save_cluster_solution(void)
messagelogger vpr_printf
Definition: util.c:17
static void clay_lut_input_rebalancing(int iblock, t_pb *pb)
Definition: vpr_api.c:1244
t_pb_graph_node * pb_graph_node
Definition: vpr_types.h:180
char * port_class
int num_sinks
Definition: vpr_types.h:506
void place_and_route(enum e_operation operation, struct s_placer_opts placer_opts, char *place_file, char *net_file, char *arch_file, char *route_file, struct s_annealing_sched annealing_sched, struct s_router_opts router_opts, struct s_det_routing_arch det_routing_arch, t_segment_inf *segment_inf, t_timing_inf timing_inf, t_chan_width_dist chan_width_dist, struct s_model *models, t_direct_inf *directs, int num_directs)
void vpr_init(INP int argc, INP char **argv, OUTP t_options *options, OUTP t_vpr_setup *vpr_setup, OUTP t_arch *arch)
Definition: vpr_api.c:161
char * vpr_get_output_file_name(enum e_output_files ename)
Definition: vpr_api.c:859
t_interconnect_power * interconnect_power
void alloc_and_load_cluster_legality_checker(void)
static void clay_reload_ble_locations(int iblock)
Definition: vpr_api.c:1315
t_pb_graph_pin * get_pb_graph_node_pin_from_block_pin(int iblock, int ipin)
Definition: vpr_utils.c:403
short occ
Definition: vpr_types.h:898
t_rr_type type
Definition: vpr_types.h:902
void free_logical_nets(void)
t_pb_graph_pin ** input_pins
struct s_logical_block * logical_block
Definition: globals.c:20
int num_directs
Definition: util.h:12
e_power_ret_code power_total(float *run_time_s, t_vpr_setup vpr_setup, t_arch *arch, t_det_routing_arch *routing_arch)
Definition: power.c:1695
t_pb_graph_pin * get_pb_graph_node_pin_from_vpack_net(int inet, int ipin)
Definition: vpr_utils.c:343
void try_pack(INP struct s_packer_opts *packer_opts, INP const t_arch *arch, INP t_model *user_models, INP t_model *library_models, t_timing_inf timing_inf, float interc_delay)
Definition: pack.c:20
void vpr_place_and_route(INP t_vpr_setup vpr_setup, INP t_arch arch)
Definition: vpr_api.c:426