VPR-7.0
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros
place_and_route.c File Reference
#include <assert.h>
#include <stdio.h>
#include <sys/types.h>
#include <time.h>
#include "util.h"
#include "vpr_types.h"
#include "vpr_utils.h"
#include "globals.h"
#include "place_and_route.h"
#include "place.h"
#include "read_place.h"
#include "route_export.h"
#include "draw.h"
#include "stats.h"
#include "check_route.h"
#include "rr_graph.h"
#include "path_delay.h"
#include "net_delay.h"
#include "timing_place.h"
#include "read_xml_arch_file.h"
#include "ReadOptions.h"
#include "route_common.h"
#include "place_macro.h"
#include "verilog_writer.h"
#include "power.h"
+ Include dependency graph for place_and_route.c:

Go to the source code of this file.

Functions

static int binary_search_place_and_route (struct s_placer_opts placer_opts, char *place_file, char *net_file, char *arch_file, char *route_file, boolean full_stats, boolean verify_binary_search, 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, t_model *models, t_direct_inf *directs, int num_directs)
 
static float comp_width (t_chan *chan, float x, float separation)
 
void post_place_sync (INP int L_num_blocks, INOUTP const struct s_block block_list[])
 
void free_pb_data (t_pb *pb)
 
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 init_chan (int cfactor, t_chan_width_dist chan_width_dist)
 

Function Documentation

static int binary_search_place_and_route ( struct s_placer_opts  placer_opts,
char *  place_file,
char *  net_file,
char *  arch_file,
char *  route_file,
boolean  full_stats,
boolean  verify_binary_search,
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,
t_model models,
t_direct_inf directs,
int  num_directs 
)
static

Definition at line 229 of file place_and_route.c.

236  {
237 
238  /* This routine performs a binary search to find the minimum number of *
239  * tracks per channel required to successfully route a circuit, and returns *
240  * that minimum width_fac. */
241 
242  struct s_trace **best_routing; /* Saves the best routing found so far. */
243  int current, low, high, final;
244  int max_pins_per_clb, i;
245  boolean success, prev_success, prev2_success, Fc_clipped = FALSE;
246  char msg[BUFSIZE];
247  float **net_delay = NULL;
248  t_slack * slacks = NULL;
249 
250  t_chunk net_delay_ch = {NULL, 0, NULL};
251 
252  /*struct s_linked_vptr *net_delay_chunk_list_head;*/
253  t_ivec **clb_opins_used_locally, **saved_clb_opins_used_locally;
254 
255  /* [0..num_blocks-1][0..num_class-1] */
256  int attempt_count;
257  int udsd_multiplier;
258  int warnings;
259 
260  t_graph_type graph_type;
261 
262  /* Allocate the major routing structures. */
263 
264  if (router_opts.route_type == GLOBAL) {
265  graph_type = GRAPH_GLOBAL;
266  } else {
267  graph_type = (
268  det_routing_arch.directionality == BI_DIRECTIONAL ?
270  }
271 
272  max_pins_per_clb = 0;
273  for (i = 0; i < num_types; i++) {
274  max_pins_per_clb = std::max(max_pins_per_clb, type_descriptors[i].num_pins);
275  }
276 
277  clb_opins_used_locally = alloc_route_structs();
278  best_routing = alloc_saved_routing(clb_opins_used_locally,
279  &saved_clb_opins_used_locally);
280 
281  slacks = alloc_and_load_timing_graph(timing_inf);
282  net_delay = alloc_net_delay(&net_delay_ch, clb_net, num_nets);
283 
284  /* UDSD by AY Start */
285  if (det_routing_arch.directionality == BI_DIRECTIONAL)
286  udsd_multiplier = 1;
287  else
288  udsd_multiplier = 2;
289  /* UDSD by AY End */
290 
291  if (router_opts.fixed_channel_width != NO_FIXED_CHANNEL_WIDTH) {
292  current = router_opts.fixed_channel_width + 5 * udsd_multiplier;
293  low = router_opts.fixed_channel_width - 1 * udsd_multiplier;
294  } else {
295  current = max_pins_per_clb + max_pins_per_clb % 2; /* Binary search part */
296  low = -1;
297  }
298 
299  /* Constraints must be checked to not break rr_graph generator */
300  if (det_routing_arch.directionality == UNI_DIRECTIONAL) {
301  if (current % 2 != 0) {
302  vpr_printf(TIO_MESSAGE_ERROR, "in pack_place_and_route.c: Tried odd chan width (%d) for udsd architecture.\n",
303  current);
304  exit(1);
305  }
306  }
307 
308  else {
309  if (det_routing_arch.Fs % 3) {
310  vpr_printf(TIO_MESSAGE_ERROR, "Fs must be three in bidirectional mode.\n");
311  exit(1);
312  }
313  }
314 
315  high = -1;
316  final = -1;
317 
318  attempt_count = 0;
319 
320  while (final == -1) {
321 
322  vpr_printf(TIO_MESSAGE_INFO, "Using low: %d, high: %d, current: %d\n", low, high, current);
323  fflush(stdout);
324 
325  /* Check if the channel width is huge to avoid overflow. Assume the *
326  * circuit is unroutable with the current router options if we're *
327  * going to overflow. */
328  if (router_opts.fixed_channel_width != NO_FIXED_CHANNEL_WIDTH) {
329  if (current > router_opts.fixed_channel_width * 4) {
330  vpr_printf(TIO_MESSAGE_ERROR, "This circuit appears to be unroutable with the current router options. Last failed at %d.\n", low);
331  vpr_printf(TIO_MESSAGE_INFO, "Aborting routing procedure.\n");
332  exit(1);
333  }
334  } else {
335  if (current > 1000) {
336  vpr_printf(TIO_MESSAGE_ERROR, "This circuit requires a channel width above 1000, probably is not going to route.\n");
337  vpr_printf(TIO_MESSAGE_INFO, "Aborting routing procedure.\n");
338  exit(1);
339  }
340  }
341 
342  if ((current * 3) < det_routing_arch.Fs) {
343  vpr_printf(TIO_MESSAGE_INFO, "Width factor is now below specified Fs. Stop search.\n");
344  final = high;
345  break;
346  }
347 
348  if (placer_opts.place_freq == PLACE_ALWAYS) {
349  placer_opts.place_chan_width = current;
350  try_place(placer_opts, annealing_sched, chan_width_dist,
351  router_opts, det_routing_arch, segment_inf, timing_inf,
352  directs, num_directs);
353  }
354  success = try_route(current, router_opts, det_routing_arch, segment_inf,
355  timing_inf, net_delay, slacks, chan_width_dist,
356  clb_opins_used_locally, &Fc_clipped, directs, num_directs);
357  attempt_count++;
358  fflush(stdout);
359 #if 1
360  if (success && (Fc_clipped == FALSE)) {
361 #else
362  if (success
363  && (Fc_clipped == FALSE
364  || det_routing_arch.Fc_type == FRACTIONAL))
365  {
366 #endif
367  if (current == high) {
368  /* Can't go any lower */
369  final = current;
370  }
371  high = current;
372 
373  /* If Fc_output is too high, set to full connectivity but warn the user */
374  if (Fc_clipped) {
375  vpr_printf(TIO_MESSAGE_WARNING, "Fc_output was too high and was clipped to full (maximum) connectivity.\n");
376  }
377 
378  /* If we're re-placing constantly, save placement in case it is best. */
379 #if 0
380  if (placer_opts.place_freq == PLACE_ALWAYS)
381  {
382  print_place(place_file, net_file, arch_file);
383  }
384 #endif
385 
386  /* Save routing in case it is best. */
387  save_routing(best_routing, clb_opins_used_locally,
388  saved_clb_opins_used_locally);
389 
390  if ((high - low) <= 1 * udsd_multiplier)
391  final = high;
392 
393  if (low != -1) {
394  current = (high + low) / 2;
395  } else {
396  current = high / 2; /* haven't found lower bound yet */
397  }
398  } else { /* last route not successful */
399  if (success && Fc_clipped) {
400  vpr_printf(TIO_MESSAGE_INFO, "Routing rejected, Fc_output was too high.\n");
401  success = FALSE;
402  }
403  low = current;
404  if (high != -1) {
405 
406  if ((high - low) <= 1 * udsd_multiplier)
407  final = high;
408 
409  current = (high + low) / 2;
410  } else {
411  if (router_opts.fixed_channel_width != NO_FIXED_CHANNEL_WIDTH) {
412  /* FOR Wneed = f(Fs) search */
413  if (low < router_opts.fixed_channel_width + 30) {
414  current = low + 5 * udsd_multiplier;
415  } else {
416  vpr_printf(TIO_MESSAGE_ERROR, "Aborting: Wneed = f(Fs) search found exceedingly large Wneed (at least %d).\n", low);
417  exit(1);
418  }
419  } else {
420  current = low * 2; /* Haven't found upper bound yet */
421  }
422  }
423  }
424  current = current + current % udsd_multiplier;
425  }
426 
427  /* The binary search above occassionally does not find the minimum *
428  * routeable channel width. Sometimes a circuit that will not route *
429  * in 19 channels will route in 18, due to router flukiness. If *
430  * verify_binary_search is set, the code below will ensure that FPGAs *
431  * with channel widths of final-2 and final-3 wil not route *
432  * successfully. If one does route successfully, the router keeps *
433  * trying smaller channel widths until two in a row (e.g. 8 and 9) *
434  * fail. */
435 
436  if (verify_binary_search) {
437 
438  vpr_printf(TIO_MESSAGE_INFO, "\n");
439  vpr_printf(TIO_MESSAGE_INFO, "Verifying that binary search found min channel width...\n");
440 
441  prev_success = TRUE; /* Actually final - 1 failed, but this makes router */
442  /* try final-2 and final-3 even if both fail: safer */
443  prev2_success = TRUE;
444 
445  current = final - 2;
446 
447  while (prev2_success || prev_success) {
448  if ((router_opts.fixed_channel_width != NO_FIXED_CHANNEL_WIDTH)
449  && (current < router_opts.fixed_channel_width)) {
450  break;
451  }
452  fflush(stdout);
453  if (current < 1)
454  break;
455  if (placer_opts.place_freq == PLACE_ALWAYS) {
456  placer_opts.place_chan_width = current;
457  try_place(placer_opts, annealing_sched, chan_width_dist,
458  router_opts, det_routing_arch, segment_inf, timing_inf,
459  directs, num_directs);
460  }
461  success = try_route(current, router_opts, det_routing_arch,
462  segment_inf, timing_inf, net_delay, slacks,
463  chan_width_dist, clb_opins_used_locally, &Fc_clipped, directs, num_directs);
464 
465  if (success && Fc_clipped == FALSE) {
466  final = current;
467  save_routing(best_routing, clb_opins_used_locally,
468  saved_clb_opins_used_locally);
469 
470  if (placer_opts.place_freq == PLACE_ALWAYS) {
471  print_place(place_file, net_file, arch_file);
472  }
473  }
474 
475  prev2_success = prev_success;
476  prev_success = success;
477  current--;
478  if (det_routing_arch.directionality == UNI_DIRECTIONAL) {
479  current--; /* width must be even */
480  }
481  }
482  }
483 
484  /* End binary search verification. */
485  /* Restore the best placement (if necessary), the best routing, and *
486  * * the best channel widths for final drawing and statistics output. */
487  init_chan(final, chan_width_dist);
488 #if 0
489  if (placer_opts.place_freq == PLACE_ALWAYS)
490  {
491  vpr_printf(TIO_MESSAGE_INFO, "Reading best placement back in.\n");
492  placer_opts.place_chan_width = final;
493  read_place(place_file, net_file, arch_file, placer_opts,
494  router_opts, chan_width_dist, det_routing_arch,
495  segment_inf, timing_inf);
496  }
497 #endif
498  free_rr_graph();
499 
500  build_rr_graph(graph_type, num_types, type_descriptors, nx, ny, grid,
501  chan_width_x[0], NULL, det_routing_arch.switch_block_type,
502  det_routing_arch.Fs, det_routing_arch.num_segment,
503  det_routing_arch.num_switch, segment_inf,
504  det_routing_arch.global_route_switch,
505  det_routing_arch.delayless_switch, timing_inf,
506  det_routing_arch.wire_to_ipin_switch, router_opts.base_cost_type,
507  directs, num_directs, FALSE,
508  &warnings);
509 
510  restore_routing(best_routing, clb_opins_used_locally,
511  saved_clb_opins_used_locally);
512  check_route(router_opts.route_type, det_routing_arch.num_switch,
513  clb_opins_used_locally);
514  get_serial_num();
515  if (Fc_clipped) {
516  vpr_printf(TIO_MESSAGE_WARNING, "Best routing Fc_output too high, clipped to full (maximum) connectivity.\n");
517  }
518  vpr_printf(TIO_MESSAGE_INFO, "Best routing used a channel width factor of %d.\n", final);
519 
520  routing_stats(full_stats, router_opts.route_type,
521  det_routing_arch.num_switch, segment_inf,
522  det_routing_arch.num_segment, det_routing_arch.R_minW_nmos,
523  det_routing_arch.R_minW_pmos, det_routing_arch.directionality,
524  timing_inf.timing_analysis_enabled, net_delay, slacks);
525 
526  print_route(route_file);
527 
530  }
531 
532  init_draw_coords(max_pins_per_clb);
533  sprintf(msg, "Routing succeeded with a channel width factor of %d.", final);
535 
536  if (timing_inf.timing_analysis_enabled) {
539  }
540 
542  {
543  verilog_writer();
544  }
545 
546  free_timing_graph(slacks);
547  free_net_delay(net_delay, &net_delay_ch);
548  }
549 
550  for (i = 0; i < num_blocks; i++) {
551  free_ivec_vector(clb_opins_used_locally[i], 0,
552  block[i].type->num_class - 1);
553  }
554  free(clb_opins_used_locally);
555  clb_opins_used_locally = NULL;
556 
557  free_saved_routing(best_routing, saved_clb_opins_used_locally);
558  fflush(stdout);
559 
560  return (final);
561 
562 }
Definition: util.h:57
void update_screen(int priority, char *msg, enum pic_type pic_on_screen_val, boolean crit_path_button_enabled)
Definition: draw.c:156
void free_rr_graph(void)
Definition: rr_graph.c:798
void print_timing_graph_as_blif(const char *fname, t_model *models)
Definition: path_delay.c:3360
void save_routing(struct s_trace **best_routing, t_ivec **clb_opins_used_locally, t_ivec **saved_clb_opins_used_locally)
Definition: route_common.c:99
void read_place(INP const char *place_file, INP const char *arch_file, INP const char *net_file, INP int L_nx, INP int L_ny, INP int L_num_blocks, INOUTP struct s_block block_list[])
Definition: read_place.c:15
short delayless_switch
Definition: vpr_types.h:764
short global_route_switch
Definition: vpr_types.h:763
int fixed_channel_width
Definition: vpr_types.h:704
#define MAJOR
Definition: vpr_types.h:73
static float ** net_delay
enum e_graph_type t_graph_type
Definition: rr_graph.h:11
int * chan_width_x
Definition: globals.c:56
boolean try_route(int width_fac, struct s_router_opts router_opts, struct s_det_routing_arch det_routing_arch, t_segment_inf *segment_inf, t_timing_inf timing_inf, float **net_delay, t_slack *slacks, t_chan_width_dist chan_width_dist, t_ivec **clb_opins_used_locally, boolean *Fc_clipped, t_direct_inf *directs, int num_directs)
Definition: route_common.c:220
boolean timing_analysis_enabled
void free_saved_routing(struct s_trace **best_routing, t_ivec **saved_clb_opins_used_locally)
Definition: route_common.c:771
void get_serial_num(void)
Definition: route_common.c:188
int num_nets
Definition: globals.c:27
#define BUFSIZE
Definition: graphics.c:184
void check_route(enum e_route_type route_type, int num_switch, t_ivec **clb_opins_used_locally)
Definition: check_route.c:27
int num_blocks
Definition: globals.c:30
boolean getEchoEnabled(void)
Definition: ReadOptions.c:67
Definition: util.h:12
static t_ivec ** clb_opins_used_locally
void init_draw_coords(float width_val)
Definition: draw.c:430
enum pfreq place_freq
Definition: vpr_types.h:644
void verilog_writer(void)
enum e_directionality directionality
Definition: vpr_types.h:758
#define max(a, b)
Definition: graphics.c:171
void build_rr_graph(INP t_graph_type graph_type, INP int L_num_types, INP t_type_ptr types, INP int L_nx, INP int L_ny, INP struct s_grid_tile **L_grid, INP int chan_width, INP struct s_chan_width_dist *chan_capacity_inf, INP enum e_switch_block_type sb_type, INP int Fs, INP int num_seg_types, INP int num_switches, INP t_segment_inf *segment_inf, INP int global_route_switch, INP int delayless_switch, INP t_timing_inf timing_inf, INP int wire_to_ipin_switch, INP enum e_base_cost_type base_cost_type, INP t_direct_inf *directs, INP int num_directs, INP boolean ignore_Fc_0, OUTP int *Warnings)
Definition: rr_graph.c:192
struct s_block * block
Definition: globals.c:31
struct s_net * clb_net
Definition: globals.c:28
int nx
Definition: globals.c:46
void init_chan(int cfactor, t_chan_width_dist chan_width_dist)
void free_ivec_vector(struct s_ivec *ivec_vector, int nrmin, int nrmax)
Definition: util.c:498
static t_chunk net_delay_ch
Definition: timing_place.c:15
t_ivec ** alloc_route_structs(void)
Definition: route_common.c:611
void print_route(char *route_file)
boolean isEchoFileEnabled(enum e_echo_files echo_option)
Definition: ReadOptions.c:115
void print_sink_delays(const char *fname)
Definition: timing_place.c:58
void restore_routing(struct s_trace **best_routing, t_ivec **clb_opins_used_locally, t_ivec **saved_clb_opins_used_locally)
Definition: route_common.c:149
void print_place(char *place_file, char *net_file, char *arch_file)
Definition: read_place.c:262
enum e_route_type route_type
Definition: vpr_types.h:703
struct s_grid_tile ** grid
Definition: globals.c:59
void free_net_delay(float **net_delay, t_chunk *chunk_list_ptr)
Definition: net_delay.c:127
Definition: util.h:47
boolean GetPostSynthesisOption(void)
Definition: ReadOptions.c:80
float ** alloc_net_delay(t_chunk *chunk_list_ptr, struct s_net *nets, int n_nets)
Definition: net_delay.c:103
t_slack * alloc_and_load_timing_graph(t_timing_inf timing_inf)
Definition: path_delay.c:239
struct s_trace ** alloc_saved_routing(t_ivec **clb_opins_used_locally, t_ivec ***saved_clb_opins_used_locally_ptr)
Definition: route_common.c:638
enum e_switch_block_type switch_block_type
Definition: vpr_types.h:760
int num_types
Definition: globals.c:37
#define NO_FIXED_CHANNEL_WIDTH
Definition: vpr_types.h:692
struct s_type_descriptor * type_descriptors
Definition: globals.c:38
char * getEchoFileName(enum e_echo_files echo_option)
Definition: ReadOptions.c:122
int place_chan_width
Definition: vpr_types.h:641
int ny
Definition: globals.c:47
messagelogger vpr_printf
Definition: util.c:17
void free_timing_graph(t_slack *slacks)
Definition: path_delay.c:390
short wire_to_ipin_switch
Definition: vpr_types.h:765
enum e_base_cost_type base_cost_type
Definition: vpr_types.h:706
void routing_stats(boolean full_stats, enum e_route_type route_type, int num_switch, t_segment_inf *segment_inf, int num_segment, float R_minW_nmos, float R_minW_pmos, enum e_directionality directionality, boolean timing_analysis_enabled, float **net_delay, t_slack *slacks)
Definition: stats.c:27
void try_place(struct s_placer_opts placer_opts, struct s_annealing_sched annealing_sched, t_chan_width_dist chan_width_dist, 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_direct_inf *directs, int num_directs)
Definition: place.c:310
Definition: util.h:12
static struct s_trace ** best_routing

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static float comp_width ( t_chan chan,
float  x,
float  separation 
)
static

Definition at line 634 of file place_and_route.c.

634  {
635 
636  /* Return the relative channel density. *chan points to a channel *
637  * functional description data structure, and x is the distance *
638  * (between 0 and 1) we are across the chip. separation is the *
639  * distance between two channels, in the 0 to 1 coordinate system. */
640 
641  float val;
642 
643  switch (chan->type) {
644 
645  case UNIFORM:
646  val = chan->peak;
647  break;
648 
649  case GAUSSIAN:
650  val = (x - chan->xpeak) * (x - chan->xpeak)
651  / (2 * chan->width * chan->width);
652  val = chan->peak * exp(-val);
653  val += chan->dc;
654  break;
655 
656  case PULSE:
657  val = (float) fabs((double) (x - chan->xpeak));
658  if (val > chan->width / 2.) {
659  val = 0;
660  } else {
661  val = chan->peak;
662  }
663  val += chan->dc;
664  break;
665 
666  case DELTA:
667  val = x - chan->xpeak;
668  if (val > -separation / 2. && val <= separation / 2.)
669  val = chan->peak;
670  else
671  val = 0.;
672  val += chan->dc;
673  break;
674 
675  default:
676  vpr_printf(TIO_MESSAGE_ERROR, "in comp_width: Unknown channel type %d.\n", chan->type);
677  exit(1);
678  break;
679  }
680 
681  return (val);
682 }
float peak
float dc
float xpeak
float width
enum e_stat type
messagelogger vpr_printf
Definition: util.c:17

+ Here is the caller graph for this function:

void free_pb_data ( t_pb pb)

Definition at line 720 of file place_and_route.c.

720  {
721  int i, j;
722  const t_pb_type *pb_type;
723  t_rr_node *temp;
724 
725  if (pb == NULL || pb->name == NULL) {
726  return;
727  }
728 
729  pb_type = pb->pb_graph_node->pb_type;
730 
731  /* free existing rr graph for pb */
732  if (pb->rr_graph) {
733  temp = rr_node;
734  rr_node = pb->rr_graph;
736  free_rr_graph();
737  rr_node = temp;
738  }
739 
740  if (pb_type->num_modes > 0) {
741  /* Free children of pb */
742  for (i = 0; i < pb_type->modes[pb->mode].num_pb_type_children; i++) {
743  for (j = 0; j < pb_type->modes[pb->mode].pb_type_children[i].num_pb;
744  j++) {
745  if (pb->child_pbs[i]) {
746  free_pb_data(&pb->child_pbs[i][j]);
747  }
748  }
749  }
750  }
751 
752  /* Frees all the pb data structures. */
753  if (pb->name) {
754  free(pb->name);
755  if (pb->child_pbs) {
756  free(pb->child_pbs);
757  }
758  }
759 }
char * name
Definition: vpr_types.h:179
struct s_pb ** child_pbs
Definition: vpr_types.h:185
void free_rr_graph(void)
Definition: rr_graph.c:798
struct s_pb_type * pb_type_children
t_rr_node * rr_node
Definition: globals.c:70
struct s_rr_node * rr_graph
Definition: vpr_types.h:188
t_mode * modes
int num_rr_nodes
Definition: globals.c:69
int num_pb_type_children
struct s_pb_type * pb_type
void free_pb_data(t_pb *pb)
int mode
Definition: vpr_types.h:183
t_pb_graph_node * pb_graph_node
Definition: vpr_types.h:180

+ Here is the call graph for this function:

void init_chan ( int  cfactor,
t_chan_width_dist  chan_width_dist 
)

Definition at line 564 of file place_and_route.c.

564  {
565 
566  /* Assigns widths to channels (in tracks). Minimum one track *
567  * per channel. io channels are io_rat * maximum in interior *
568  * tracks wide. The channel distributions read from the architecture *
569  * file are scaled by cfactor. */
570 
571  float x, separation, chan_width_io;
572  int nio, i;
573  t_chan chan_x_dist, chan_y_dist;
574 
575  chan_width_io = chan_width_dist.chan_width_io;
576  chan_x_dist = chan_width_dist.chan_x_dist;
577  chan_y_dist = chan_width_dist.chan_y_dist;
578 
579  /* io channel widths */
580 
581  nio = (int) floor(cfactor * chan_width_io + 0.5);
582  if (nio == 0)
583  nio = 1; /* No zero width channels */
584 
585  chan_width_x[0] = chan_width_x[ny] = nio;
586  chan_width_y[0] = chan_width_y[nx] = nio;
587 
588  if (ny > 1) {
589  separation = 1. / (ny - 2.); /* Norm. distance between two channels. */
590  x = 0.; /* This avoids div by zero if ny = 2. */
591  chan_width_x[1] = (int) floor(
592  cfactor * comp_width(&chan_x_dist, x, separation) + 0.5);
593 
594  /* No zero width channels */
595  chan_width_x[1] = std::max(chan_width_x[1], 1);
596 
597  for (i = 1; i < ny - 1; i++) {
598  x = (float) i / ((float) (ny - 2.));
599  chan_width_x[i + 1] = (int) floor(
600  cfactor * comp_width(&chan_x_dist, x, separation) + 0.5);
601  chan_width_x[i + 1] = std::max(chan_width_x[i + 1], 1);
602  }
603  }
604 
605  if (nx > 1) {
606  separation = 1. / (nx - 2.); /* Norm. distance between two channels. */
607  x = 0.; /* Avoids div by zero if nx = 2. */
608  chan_width_y[1] = (int) floor(
609  cfactor * comp_width(&chan_y_dist, x, separation) + 0.5);
610 
611  chan_width_y[1] = std::max(chan_width_y[1], 1);
612 
613  for (i = 1; i < nx - 1; i++) {
614  x = (float) i / ((float) (nx - 2.));
615  chan_width_y[i + 1] = (int) floor(
616  cfactor * comp_width(&chan_y_dist, x, separation) + 0.5);
617  chan_width_y[i + 1] = std::max(chan_width_y[i + 1], 1);
618  }
619  }
620 #ifdef VERBOSE
621  vpr_printf(TIO_MESSAGE_INFO, "\n");
622  vpr_printf(TIO_MESSAGE_INFO, "chan_width_x:\n");
623  for (i = 0; i <= ny; i++)
624  vpr_printf(TIO_MESSAGE_INFO, "%d ", chan_width_x[i]);
625  vpr_printf(TIO_MESSAGE_INFO, "\n");
626  vpr_printf(TIO_MESSAGE_INFO, "chan_width_y:\n");
627  for (i = 0; i <= nx; i++)
628  vpr_printf(TIO_MESSAGE_INFO, "%d ", chan_width_y[i]);
629  vpr_printf(TIO_MESSAGE_INFO, "\n");
630 #endif
631 
632 }
int * chan_width_x
Definition: globals.c:56
int * chan_width_y
Definition: globals.c:57
static float comp_width(t_chan *chan, float x, float separation)
#define max(a, b)
Definition: graphics.c:171
int nx
Definition: globals.c:46
int ny
Definition: globals.c:47
messagelogger vpr_printf
Definition: util.c:17

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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 
)

Definition at line 47 of file place_and_route.c.

55  {
56 
57  /* This routine controls the overall placement and routing of a circuit. */
58  char msg[BUFSIZE];
59  int width_fac, i;
60  boolean success, Fc_clipped;
61  float **net_delay = NULL;
62  t_slack * slacks = NULL;
63  t_chunk net_delay_ch = {NULL, 0, NULL};
64 
65  /*struct s_linked_vptr *net_delay_chunk_list_head;*/
66  t_ivec **clb_opins_used_locally = NULL; /* [0..num_blocks-1][0..num_class-1] */
67  int max_pins_per_clb;
68  clock_t begin, end;
69 
70  Fc_clipped = FALSE;
71 
72  max_pins_per_clb = 0;
73  for (i = 0; i < num_types; i++) {
74  if (type_descriptors[i].num_pins > max_pins_per_clb) {
75  max_pins_per_clb = type_descriptors[i].num_pins;
76  }
77  }
78 
79  if (placer_opts.place_freq == PLACE_NEVER) {
80  /* Read the placement from a file */
81  read_place(place_file, net_file, arch_file, nx, ny, num_blocks, block);
83  } else {
84  assert(
85  (PLACE_ONCE == placer_opts.place_freq) || (PLACE_ALWAYS == placer_opts.place_freq));
86  begin = clock();
87  try_place(placer_opts, annealing_sched, chan_width_dist, router_opts,
88  det_routing_arch, segment_inf, timing_inf, directs, num_directs);
89  print_place(place_file, net_file, arch_file);
90  end = clock();
91 #ifdef CLOCKS_PER_SEC
92  vpr_printf(TIO_MESSAGE_INFO, "Placement took %g seconds.\n", (float)(end - begin) / CLOCKS_PER_SEC);
93 #else
94  vpr_printf(TIO_MESSAGE_INFO, "Placement took %g seconds.\n", (float)(end - begin) / CLK_PER_SEC);
95 #endif
96  }
97  begin = clock();
99 
100  fflush(stdout);
101 
102  if (!router_opts.doRouting)
103  return;
104 
105  width_fac = router_opts.fixed_channel_width;
106 
107  /* If channel width not fixed, use binary search to find min W */
108  if (NO_FIXED_CHANNEL_WIDTH == width_fac) {
109  g_solution_inf.channel_width = binary_search_place_and_route(placer_opts, place_file, net_file,
110  arch_file, route_file, router_opts.full_stats,
111  router_opts.verify_binary_search, annealing_sched, router_opts,
112  det_routing_arch, segment_inf, timing_inf, chan_width_dist,
113  models, directs, num_directs);
114  } else {
115  g_solution_inf.channel_width = width_fac;
116  if (det_routing_arch.directionality == UNI_DIRECTIONAL) {
117  if (width_fac % 2 != 0) {
118  vpr_printf(TIO_MESSAGE_ERROR, "in pack_place_and_route.c: Given odd chan width (%d) for udsd architecture.\n",
119  width_fac);
120  exit(1);
121  }
122  }
123  /* Other constraints can be left to rr_graph to check since this is one pass routing */
124 
125  /* Allocate the major routing structures. */
126 
127  clb_opins_used_locally = alloc_route_structs();
128 
129  slacks = alloc_and_load_timing_graph(timing_inf);
130  net_delay = alloc_net_delay(&net_delay_ch, clb_net,
131  num_nets);
132 
133  success = try_route(width_fac, router_opts, det_routing_arch,
134  segment_inf, timing_inf, net_delay, slacks, chan_width_dist,
135  clb_opins_used_locally, &Fc_clipped, directs, num_directs);
136 
137  if (Fc_clipped) {
138  vpr_printf(TIO_MESSAGE_WARNING, "Fc_output was too high and was clipped to full (maximum) connectivity.\n");
139  }
140 
141  if (success == FALSE) {
142  vpr_printf(TIO_MESSAGE_INFO, "Circuit is unrouteable with a channel width factor of %d.\n", width_fac);
143  vpr_printf(TIO_MESSAGE_INFO, "\n");
144  sprintf(msg, "Routing failed with a channel width factor of %d. ILLEGAL routing shown.", width_fac);
145  }
146 
147  else {
148  check_route(router_opts.route_type, det_routing_arch.num_switch, clb_opins_used_locally);
149  get_serial_num();
150 
151  vpr_printf(TIO_MESSAGE_INFO, "Circuit successfully routed with a channel width factor of %d.\n", width_fac);
152  vpr_printf(TIO_MESSAGE_INFO, "\n");
153 
154  routing_stats(router_opts.full_stats, router_opts.route_type,
155  det_routing_arch.num_switch, segment_inf,
156  det_routing_arch.num_segment, det_routing_arch.R_minW_nmos,
157  det_routing_arch.R_minW_pmos,
158  det_routing_arch.directionality,
159  timing_inf.timing_analysis_enabled, net_delay, slacks);
160 
161  print_route(route_file);
162 
165  }
166 
167  sprintf(msg, "Routing succeeded with a channel width factor of %d.\n\n",
168  width_fac);
169 
170 
171  }
172 
173  init_draw_coords(max_pins_per_clb);
175 
176 
177  if (timing_inf.timing_analysis_enabled) {
178  assert(slacks->slack);
179 
182  models);
183  }
184 
186  {
187  verilog_writer();
188  }
189 
190  free_timing_graph(slacks);
191 
192  assert(net_delay);
193  free_net_delay(net_delay, &net_delay_ch);
194  }
195 
196  fflush(stdout);
197  }
198 
199  if (clb_opins_used_locally != NULL) {
200  for (i = 0; i < num_blocks; i++) {
201  free_ivec_vector(clb_opins_used_locally[i], 0,
202  block[i].type->num_class - 1);
203  }
204  free(clb_opins_used_locally);
205  clb_opins_used_locally = NULL;
206  }
207 
208  /* Frees up all the data structure used in vpr_utils. */
211 
212  end = clock();
213 #ifdef CLOCKS_PER_SEC
214  vpr_printf(TIO_MESSAGE_INFO, "Routing took %g seconds.\n", (float) (end - begin) / CLOCKS_PER_SEC);
215 #else
216  vpr_printf(TIO_MESSAGE_INFO, "Routing took %g seconds.\n", (float)(end - begin) / CLK_PER_SEC);
217 #endif
218 
219  /*WMF: cleaning up memory usage */
220 
221  /* if (g_heap_free_head)
222  free(g_heap_free_head);
223  if (g_trace_free_head)
224  free(g_trace_free_head);
225  if (g_linked_f_pointer_free_head)
226  free(g_linked_f_pointer_free_head);*/
227 }
Definition: util.h:57
void update_screen(int priority, char *msg, enum pic_type pic_on_screen_val, boolean crit_path_button_enabled)
Definition: draw.c:156
boolean doRouting
Definition: vpr_types.h:712
void print_timing_graph_as_blif(const char *fname, t_model *models)
Definition: path_delay.c:3360
boolean full_stats
Definition: vpr_types.h:711
void free_port_pin_from_blk_pin(void)
Definition: vpr_utils.c:736
void read_place(INP const char *place_file, INP const char *arch_file, INP const char *net_file, INP int L_nx, INP int L_ny, INP int L_num_blocks, INOUTP struct s_block block_list[])
Definition: read_place.c:15
int fixed_channel_width
Definition: vpr_types.h:704
#define MAJOR
Definition: vpr_types.h:73
static float ** net_delay
boolean try_route(int width_fac, struct s_router_opts router_opts, struct s_det_routing_arch det_routing_arch, t_segment_inf *segment_inf, t_timing_inf timing_inf, float **net_delay, t_slack *slacks, t_chan_width_dist chan_width_dist, t_ivec **clb_opins_used_locally, boolean *Fc_clipped, t_direct_inf *directs, int num_directs)
Definition: route_common.c:220
boolean timing_analysis_enabled
void sync_grid_to_blocks(INP int L_num_blocks, INP const struct s_block block_list[], INP int L_nx, INP int L_ny, INOUTP struct s_grid_tile **L_grid)
Definition: vpr_utils.c:84
void get_serial_num(void)
Definition: route_common.c:188
int num_nets
Definition: globals.c:27
static int binary_search_place_and_route(struct s_placer_opts placer_opts, char *place_file, char *net_file, char *arch_file, char *route_file, boolean full_stats, boolean verify_binary_search, 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, t_model *models, t_direct_inf *directs, int num_directs)
float ** slack
Definition: vpr_types.h:405
#define BUFSIZE
Definition: graphics.c:184
void check_route(enum e_route_type route_type, int num_switch, t_ivec **clb_opins_used_locally)
Definition: check_route.c:27
int num_blocks
Definition: globals.c:30
boolean getEchoEnabled(void)
Definition: ReadOptions.c:67
Definition: util.h:12
int channel_width
Definition: power.h:84
t_solution_inf g_solution_inf
Definition: power.c:64
static t_ivec ** clb_opins_used_locally
void init_draw_coords(float width_val)
Definition: draw.c:430
enum pfreq place_freq
Definition: vpr_types.h:644
void verilog_writer(void)
enum e_directionality directionality
Definition: vpr_types.h:758
struct s_block * block
Definition: globals.c:31
struct s_net * clb_net
Definition: globals.c:28
int nx
Definition: globals.c:46
void free_ivec_vector(struct s_ivec *ivec_vector, int nrmin, int nrmax)
Definition: util.c:498
static t_chunk net_delay_ch
Definition: timing_place.c:15
t_ivec ** alloc_route_structs(void)
Definition: route_common.c:611
void print_route(char *route_file)
boolean isEchoFileEnabled(enum e_echo_files echo_option)
Definition: ReadOptions.c:115
void print_sink_delays(const char *fname)
Definition: timing_place.c:58
void free_blk_pin_from_port_pin(void)
Definition: vpr_utils.c:840
void print_place(char *place_file, char *net_file, char *arch_file)
Definition: read_place.c:262
enum e_route_type route_type
Definition: vpr_types.h:703
struct s_grid_tile ** grid
Definition: globals.c:59
void free_net_delay(float **net_delay, t_chunk *chunk_list_ptr)
Definition: net_delay.c:127
void post_place_sync(INP int L_num_blocks, INOUTP const struct s_block block_list[])
Definition: util.h:47
boolean GetPostSynthesisOption(void)
Definition: ReadOptions.c:80
float ** alloc_net_delay(t_chunk *chunk_list_ptr, struct s_net *nets, int n_nets)
Definition: net_delay.c:103
t_slack * alloc_and_load_timing_graph(t_timing_inf timing_inf)
Definition: path_delay.c:239
int num_types
Definition: globals.c:37
#define NO_FIXED_CHANNEL_WIDTH
Definition: vpr_types.h:692
struct s_type_descriptor * type_descriptors
Definition: globals.c:38
char * getEchoFileName(enum e_echo_files echo_option)
Definition: ReadOptions.c:122
int ny
Definition: globals.c:47
messagelogger vpr_printf
Definition: util.c:17
void free_timing_graph(t_slack *slacks)
Definition: path_delay.c:390
void routing_stats(boolean full_stats, enum e_route_type route_type, int num_switch, t_segment_inf *segment_inf, int num_segment, float R_minW_nmos, float R_minW_pmos, enum e_directionality directionality, boolean timing_analysis_enabled, float **net_delay, t_slack *slacks)
Definition: stats.c:27
void try_place(struct s_placer_opts placer_opts, struct s_annealing_sched annealing_sched, t_chan_width_dist chan_width_dist, 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_direct_inf *directs, int num_directs)
Definition: place.c:310
boolean verify_binary_search
Definition: vpr_types.h:710

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void post_place_sync ( INP int  L_num_blocks,
INOUTP const struct s_block  block_list[] 
)

Definition at line 686 of file place_and_route.c.

687  {
688  int iblk, j, k, inet;
689  t_type_ptr type;
690  int max_num_block_pins;
691 
692  /* Go through each block */
693  for (iblk = 0; iblk < L_num_blocks; ++iblk) {
694  type = block[iblk].type;
695  assert(type->num_pins % type->capacity == 0);
696  max_num_block_pins = type->num_pins / type->capacity;
697  /* Logical location and physical location is offset by z * max_num_block_pins */
698  /* Sync blocks and nets */
699  for (j = 0; j < max_num_block_pins; j++) {
700  inet = block[iblk].nets[j];
701  if (inet != OPEN && block[iblk].z > 0) {
702  assert(
703  block[iblk]. nets[j + block[iblk].z * max_num_block_pins] == OPEN);
704  block[iblk].nets[j + block[iblk].z * max_num_block_pins] =
705  block[iblk].nets[j];
706  block[iblk].nets[j] = OPEN;
707  for (k = 0; k <= clb_net[inet].num_sinks; k++) {
708  if (clb_net[inet].node_block[k] == iblk && clb_net[inet]. node_block_pin[k] == j) {
709  clb_net[inet].node_block_pin[k] = j
710  + block[iblk].z * max_num_block_pins;
711  break;
712  }
713  }
714  assert(k <= clb_net[inet].num_sinks);
715  }
716  }
717  }
718 }
int * node_block_pin
Definition: vpr_types.h:509
t_type_ptr type
Definition: vpr_types.h:561
struct s_block * block
Definition: globals.c:31
struct s_net * clb_net
Definition: globals.c:28
Definition: slre.c:50
int * nets
Definition: vpr_types.h:562
int z
Definition: vpr_types.h:565
int num_sinks
Definition: vpr_types.h:506

+ Here is the caller graph for this function: