SRC/place_and_route.c File Reference

#include <stdio.h>
#include <sys/types.h>
#include "util.h"
#include "vpr_types.h"
#include "vpr_utils.h"
#include "globals.h"
#include "place_and_route.h"
#include "mst.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 <assert.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_subblock_data *subblock_data_ptr, t_chan_width_dist chan_width_dist, t_mst_edge **mst)
static float comp_width (t_chan *chan, float x, float separation)
void post_place_sync (IN int num_blocks, INOUT const struct s_block block_list[], INOUT t_subblock_data *subblock_data_ptr)
void free_subblock_data (t_subblock_data *subblock_data_ptr)
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_subblock_data *subblock_data_ptr, t_chan_width_dist chan_width_dist)
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_subblock_data subblock_data_ptr,
t_chan_width_dist  chan_width_dist,
t_mst_edge **  mst 
) [static]

Definition at line 250 of file place_and_route.c.

00265 {
00266 
00267 /* This routine performs a binary search to find the minimum number of      *
00268  * tracks per channel required to successfully route a circuit, and returns *
00269  * that minimum width_fac.                                                  */
00270 
00271     struct s_trace **best_routing;      /* Saves the best routing found so far. */
00272     int current, low, high, final;
00273     int max_pins_per_fb, i;
00274     boolean success, prev_success, prev2_success, Fc_clipped = FALSE;
00275     char msg[BUFSIZE];
00276     float **net_delay, **net_slack;
00277     struct s_linked_vptr *net_delay_chunk_list_head;
00278     int try_w_limit;
00279     t_ivec **fb_opins_used_locally, **saved_clb_opins_used_locally;
00280 
00281     /* [0..num_blocks-1][0..num_class-1] */
00282     int attempt_count;
00283     int udsd_multiplier;
00284     int warnings;
00285 
00286         t_graph_type graph_type;
00287 
00288 /* Allocate the major routing structures. */
00289 
00290         if(router_opts.route_type == GLOBAL) {
00291                 graph_type = GRAPH_GLOBAL;
00292         } else {
00293                 graph_type = (det_routing_arch.directionality ==
00294                     BI_DIRECTIONAL ? GRAPH_BIDIR : GRAPH_UNIDIR);
00295         }
00296 
00297     max_pins_per_fb = 0;
00298     for(i = 0; i < num_types; i++)
00299         {
00300             max_pins_per_fb =
00301                 max(max_pins_per_fb, type_descriptors[i].num_pins);
00302         }
00303 
00304     fb_opins_used_locally = alloc_route_structs(*subblock_data_ptr);
00305     best_routing = alloc_saved_routing(fb_opins_used_locally,
00306                                        &saved_clb_opins_used_locally);
00307 
00308     if(timing_inf.timing_analysis_enabled)
00309         {
00310             net_slack =
00311                 alloc_and_load_timing_graph(timing_inf, *subblock_data_ptr);
00312             net_delay = alloc_net_delay(&net_delay_chunk_list_head);
00313         }
00314     else
00315         {
00316             net_delay = NULL;   /* Defensive coding. */
00317             net_slack = NULL;
00318         }
00319 
00320     /* UDSD by AY Start */
00321     if(det_routing_arch.directionality == BI_DIRECTIONAL)
00322         udsd_multiplier = 1;
00323     else
00324         udsd_multiplier = 2;
00325     /* UDSD by AY End */
00326 
00327     if(router_opts.fixed_channel_width != NO_FIXED_CHANNEL_WIDTH)
00328         {
00329             current = router_opts.fixed_channel_width + 5 * udsd_multiplier;
00330             low = router_opts.fixed_channel_width - 1 * udsd_multiplier;
00331         }
00332     else
00333         {
00334             current = max_pins_per_fb + max_pins_per_fb % 2;    /* Binary search part */
00335             low = -1;
00336         }
00337 
00338     /* Constraints must be checked to not break rr_graph generator */
00339     if(det_routing_arch.directionality == UNI_DIRECTIONAL)
00340         {
00341             if(current % 2 != 0)
00342                 {
00343                     printf
00344                         ("Error: place_and_route.c: tried odd chan width (%d) for udsd architecture\n",
00345                          current);
00346                     exit(1);
00347                 }
00348         }
00349 
00350     else
00351         {
00352             if(det_routing_arch.Fs % 3)
00353                 {
00354                     printf("Fs must be three in bidirectional mode\n");
00355                     exit(1);
00356                 }
00357         }
00358 
00359     high = -1;
00360     final = -1;
00361     try_w_limit = 0;
00362 
00363     attempt_count = 0;
00364 
00365     while(final == -1)
00366         {
00367 
00368             printf("low, high, current %d %d %d\n", low, high, current);
00369             fflush(stdout);
00370 
00371 /* Check if the channel width is huge to avoid overflow.  Assume the *
00372  * circuit is unroutable with the current router options if we're    *
00373  * going to overflow.                                                */
00374             if(router_opts.fixed_channel_width != NO_FIXED_CHANNEL_WIDTH)
00375                 {
00376                     if(current > router_opts.fixed_channel_width * 4)
00377                         {
00378                             printf
00379                                 ("This circuit appears to be unroutable with the current "
00380                                  "router options. Last failed at %d\n", low);
00381                             printf("Aborting routing procedure.\n");
00382                             exit(1);
00383                         }
00384                 }
00385             else
00386                 {
00387                     if(current > 305)
00388                         {
00389                             printf
00390                                 ("This circuit appears to be unroutable with the current "
00391                                  "router options. Last failed at %d\n", low);
00392                             printf("Aborting routing procedure.\n");
00393                             exit(1);
00394                         }
00395                 }
00396 
00397             if((current * 3) < det_routing_arch.Fs)
00398                 {
00399                     printf
00400                         ("width factor is now below specified Fs. Stop search.\n");
00401                     final = high;
00402                     break;
00403                 }
00404 
00405             if(placer_opts.place_freq == PLACE_ALWAYS)
00406                 {
00407                     placer_opts.place_chan_width = current;
00408                     try_place(placer_opts, annealing_sched, chan_width_dist,
00409                               router_opts, det_routing_arch, segment_inf,
00410                               timing_inf, subblock_data_ptr, &mst);
00411                 }
00412             success =
00413                 try_route(current, router_opts, det_routing_arch, segment_inf,
00414                           timing_inf, net_slack, net_delay, chan_width_dist,
00415                           fb_opins_used_locally, mst, &Fc_clipped);
00416             attempt_count++;
00417             fflush(stdout);
00418 #if 1
00419             if(success && (Fc_clipped == FALSE))
00420                 {
00421 #else
00422             if(success
00423                && (Fc_clipped == FALSE
00424                    || det_routing_arch.Fc_type == FRACTIONAL))
00425                 {
00426 #endif
00427                     high = current;
00428 
00429                     /* If Fc_output is too high, set to full connectivity but warn the user */
00430                     if(Fc_clipped)
00431                         {
00432                             printf
00433                                 ("Warning: Fc_output was too high and was clipped to full (maximum) connectivity.\n");
00434                         }
00435 
00436 /* If we're re-placing constantly, save placement in case it is best. */
00437 #if 0
00438                     if(placer_opts.place_freq == PLACE_ALWAYS)
00439                         {
00440                             print_place(place_file, net_file, arch_file);
00441                         }
00442 #endif
00443 
00444                     /* Save routing in case it is best. */
00445                     save_routing(best_routing, fb_opins_used_locally,
00446                                  saved_clb_opins_used_locally);
00447 
00448                     if((high - low) <= 1 * udsd_multiplier)
00449                         final = high;
00450 
00451                     if(low != -1)
00452                         {
00453                             current = (high + low) / 2;
00454                         }
00455                     else
00456                         {
00457                             current = high / 2; /* haven't found lower bound yet */
00458                         }
00459                 }
00460             else
00461                 {               /* last route not successful */
00462                     if(success && Fc_clipped)
00463                         {
00464                             printf
00465                                 ("Routing rejected, Fc_output was too high.\n");
00466                             success = FALSE;
00467                         }
00468                     low = current;
00469                     if(high != -1)
00470                         {
00471 
00472                             if((high - low) <= 1 * udsd_multiplier)
00473                                 final = high;
00474 
00475                             current = (high + low) / 2;
00476                         }
00477                     else
00478                         {
00479                             if(router_opts.fixed_channel_width !=
00480                                NO_FIXED_CHANNEL_WIDTH)
00481                                 {
00482                                     /* FOR Wneed = f(Fs) search */
00483                                     if(low <
00484                                        router_opts.fixed_channel_width + 30)
00485                                         {
00486                                             current =
00487                                                 low + 5 * udsd_multiplier;
00488                                         }
00489                                     else
00490                                         {
00491                                             printf
00492                                                 ("Aborting: Wneed = f(Fs) search found exceedingly large Wneed (at least %d)\n",
00493                                                  low);
00494                                             exit(1);
00495                                         }
00496                                 }
00497                             else
00498                                 {
00499                                     current = low * 2;  /* Haven't found upper bound yet */
00500                                 }
00501                         }
00502                 }
00503             current = current + current % udsd_multiplier;
00504         }
00505 
00506 /* The binary search above occassionally does not find the minimum    *
00507  * routeable channel width.  Sometimes a circuit that will not route  *
00508  * in 19 channels will route in 18, due to router flukiness.  If      *  
00509  * verify_binary_search is set, the code below will ensure that FPGAs *
00510  * with channel widths of final-2 and final-3 wil not route           *  
00511  * successfully.  If one does route successfully, the router keeps    *
00512  * trying smaller channel widths until two in a row (e.g. 8 and 9)    *
00513  * fail.                                                              */
00514 
00515     if(verify_binary_search)
00516         {
00517 
00518             printf
00519                 ("\nVerifying that binary search found min. channel width ...\n");
00520 
00521             prev_success = TRUE;        /* Actually final - 1 failed, but this makes router */
00522             /* try final-2 and final-3 even if both fail: safer */
00523             prev2_success = TRUE;
00524 
00525             current = final - 2;
00526 
00527             while(prev2_success || prev_success)
00528                 {
00529                     if((router_opts.fixed_channel_width !=
00530                         NO_FIXED_CHANNEL_WIDTH)
00531                        && (current < router_opts.fixed_channel_width))
00532                         {
00533                             break;
00534                         }
00535                     fflush(stdout);
00536                     if(current < 1)
00537                         break;
00538                     if(placer_opts.place_freq == PLACE_ALWAYS)
00539                         {
00540                             placer_opts.place_chan_width = current;
00541                             try_place(placer_opts, annealing_sched,
00542                                       chan_width_dist, router_opts,
00543                                       det_routing_arch, segment_inf,
00544                                       timing_inf, subblock_data_ptr, &mst);
00545                         }
00546 
00547                     success =
00548                         try_route(current, router_opts, det_routing_arch,
00549                                   segment_inf, timing_inf, net_slack,
00550                                   net_delay, chan_width_dist,
00551                                   fb_opins_used_locally, mst, &Fc_clipped);
00552 
00553                     if(success && Fc_clipped == FALSE)
00554                         {
00555                             final = current;
00556                             save_routing(best_routing, fb_opins_used_locally,
00557                                          saved_clb_opins_used_locally);
00558 
00559                             if(placer_opts.place_freq == PLACE_ALWAYS)
00560                                 {
00561                                     print_place(place_file, net_file,
00562                                                 arch_file);
00563                                 }
00564                         }
00565 
00566 
00567                     prev2_success = prev_success;
00568                     prev_success = success;
00569                     current--;
00570                         if(det_routing_arch.directionality == UNI_DIRECTIONAL) {
00571                                 current--; /* width must be even */
00572                         }
00573                 }
00574         }
00575 
00576 
00577 
00578     /* End binary search verification. */
00579     /* Restore the best placement (if necessary), the best routing, and  *
00580      * * the best channel widths for final drawing and statistics output.  */
00581     init_chan(final, chan_width_dist);
00582 #if 0
00583     if(placer_opts.place_freq == PLACE_ALWAYS)
00584         {
00585             printf("Reading best placement back in.\n");
00586             placer_opts.place_chan_width = final;
00587             read_place(place_file, net_file, arch_file, placer_opts,
00588                        router_opts, chan_width_dist, det_routing_arch,
00589                        segment_inf, timing_inf, subblock_data_ptr, &mst);
00590         }
00591 #endif
00592     free_rr_graph();
00593 
00594     build_rr_graph(graph_type,
00595                    num_types, type_descriptors, nx, ny, grid,
00596                    chan_width_x[0], NULL,
00597                    det_routing_arch.switch_block_type, det_routing_arch.Fs,
00598                    det_routing_arch.num_segment, det_routing_arch.num_switch, segment_inf,
00599                    det_routing_arch.global_route_switch,
00600                    det_routing_arch.delayless_switch, timing_inf,
00601                    det_routing_arch.wire_to_ipin_switch,
00602                    router_opts.base_cost_type, &warnings);
00603 
00604     restore_routing(best_routing, fb_opins_used_locally,
00605                     saved_clb_opins_used_locally);
00606     check_route(router_opts.route_type, det_routing_arch.num_switch,
00607                 fb_opins_used_locally);
00608     get_serial_num();
00609     if(Fc_clipped)
00610         {
00611             printf
00612                 ("Warning: Best routing Fc_output too high, clipped to full (maximum) connectivity.\n");
00613         }
00614     printf("Best routing used a channel width factor of %d.\n\n", final);
00615 
00616     routing_stats(full_stats, router_opts.route_type,
00617                   det_routing_arch.num_switch, segment_inf,
00618                   det_routing_arch.num_segment,
00619                   det_routing_arch.R_minW_nmos,
00620                   det_routing_arch.R_minW_pmos,
00621                   det_routing_arch.directionality,
00622                   timing_inf.timing_analysis_enabled, net_slack, net_delay,
00623                   *subblock_data_ptr);
00624 
00625     print_route(route_file);
00626 
00627 #ifdef CREATE_ECHO_FILES
00628     /* print_sink_delays("routing_sink_delays.echo"); */
00629 #endif /* CREATE_ECHO_FILES */
00630 
00631     init_draw_coords(max_pins_per_fb);
00632     sprintf(msg, "Routing succeeded with a channel width factor of %d.",
00633             final);
00634     update_screen(MAJOR, msg, ROUTING, timing_inf.timing_analysis_enabled);
00635 
00636     free_subblock_data(subblock_data_ptr);
00637 
00638     if(timing_inf.timing_analysis_enabled)
00639         {
00640             free_timing_graph(net_slack);
00641             free_net_delay(net_delay, &net_delay_chunk_list_head);
00642         }
00643 
00644     free_route_structs(fb_opins_used_locally);
00645     free_saved_routing(best_routing, saved_clb_opins_used_locally);
00646     fflush(stdout);
00647 
00648     return (final);
00649 }

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 735 of file place_and_route.c.

00738 {
00739 
00740 /* Return the relative channel density.  *chan points to a channel   *
00741  * functional description data structure, and x is the distance      *   
00742  * (between 0 and 1) we are across the chip.  separation is the      *   
00743  * distance between two channels, in the 0 to 1 coordinate system.   */
00744 
00745     float val;
00746 
00747     switch (chan->type)
00748         {
00749 
00750         case UNIFORM:
00751             val = chan->peak;
00752             break;
00753 
00754         case GAUSSIAN:
00755             val = (x - chan->xpeak) * (x - chan->xpeak) / (2 * chan->width *
00756                                                            chan->width);
00757             val = chan->peak * exp(-val);
00758             val += chan->dc;
00759             break;
00760 
00761         case PULSE:
00762             val = (float)fabs((double)(x - chan->xpeak));
00763             if(val > chan->width / 2.)
00764                 {
00765                     val = 0;
00766                 }
00767             else
00768                 {
00769                     val = chan->peak;
00770                 }
00771             val += chan->dc;
00772             break;
00773 
00774         case DELTA:
00775             val = x - chan->xpeak;
00776             if(val > -separation / 2. && val <= separation / 2.)
00777                 val = chan->peak;
00778             else
00779                 val = 0.;
00780             val += chan->dc;
00781             break;
00782 
00783         default:
00784             printf("Error in comp_width:  Unknown channel type %d.\n",
00785                    chan->type);
00786             exit(1);
00787             break;
00788         }
00789 
00790     return (val);
00791 }

Here is the caller graph for this function:

void free_subblock_data ( t_subblock_data subblock_data_ptr  ) 

Definition at line 879 of file place_and_route.c.

00880 {
00881         int i, j;
00882 
00883         /* Frees all the subblock data structures.                                 */
00884         for(i = 0; i < num_blocks; i++) {
00885                 if(subblock_data_ptr->subblock_inf[i] != NULL) {
00886                         for(j = 0; j < subblock_data_ptr->num_subblocks_per_block[i]; j++) {
00887                                 free(subblock_data_ptr->subblock_inf[i][j].name);
00888                                 free(subblock_data_ptr->subblock_inf[i][j].outputs);
00889                                 free(subblock_data_ptr->subblock_inf[i][j].inputs);
00890                         }
00891                         free(subblock_data_ptr->subblock_inf[i]);
00892 
00893                 }
00894         }
00895     free(subblock_data_ptr->subblock_inf);
00896     free(subblock_data_ptr->num_subblocks_per_block);
00897 
00898         /* Mark as freed. */
00899     subblock_data_ptr->num_subblocks_per_block = NULL;
00900     subblock_data_ptr->subblock_inf = NULL;
00901 }

Here is the caller graph for this function:

void init_chan ( int  cfactor,
t_chan_width_dist  chan_width_dist 
)

Definition at line 653 of file place_and_route.c.

00655 {
00656 
00657 /* Assigns widths to channels (in tracks).  Minimum one track          * 
00658  * per channel.  io channels are io_rat * maximum in interior          * 
00659  * tracks wide.  The channel distributions read from the architecture  *
00660  * file are scaled by cfactor.                                         */
00661 
00662     float x, separation, chan_width_io;
00663     int nio, i;
00664     t_chan chan_x_dist, chan_y_dist;
00665 
00666     chan_width_io = chan_width_dist.chan_width_io;
00667     chan_x_dist = chan_width_dist.chan_x_dist;
00668     chan_y_dist = chan_width_dist.chan_y_dist;
00669 
00670 /* io channel widths */
00671 
00672     nio = (int)floor(cfactor * chan_width_io + 0.5);
00673     if(nio == 0)
00674         nio = 1;                /* No zero width channels */
00675 
00676     chan_width_x[0] = chan_width_x[ny] = nio;
00677     chan_width_y[0] = chan_width_y[nx] = nio;
00678 
00679     if(ny > 1)
00680         {
00681             separation = 1. / (ny - 2.);        /* Norm. distance between two channels. */
00682             x = 0.;             /* This avoids div by zero if ny = 2. */
00683             chan_width_x[1] = (int)floor(cfactor * comp_width(&chan_x_dist, x,
00684                                                               separation) +
00685                                          0.5);
00686 
00687             /* No zero width channels */
00688             chan_width_x[1] = max(chan_width_x[1], 1);
00689 
00690             for(i = 1; i < ny - 1; i++)
00691                 {
00692                     x = (float)i / ((float)(ny - 2.));
00693                     chan_width_x[i + 1] =
00694                         (int)floor(cfactor *
00695                                    comp_width(&chan_x_dist, x,
00696                                               separation) + 0.5);
00697                     chan_width_x[i + 1] = max(chan_width_x[i + 1], 1);
00698                 }
00699         }
00700 
00701     if(nx > 1)
00702         {
00703             separation = 1. / (nx - 2.);        /* Norm. distance between two channels. */
00704             x = 0.;             /* Avoids div by zero if nx = 2. */
00705             chan_width_y[1] = (int)floor(cfactor * comp_width(&chan_y_dist, x,
00706                                                               separation) +
00707                                          0.5);
00708 
00709             chan_width_y[1] = max(chan_width_y[1], 1);
00710 
00711             for(i = 1; i < nx - 1; i++)
00712                 {
00713                     x = (float)i / ((float)(nx - 2.));
00714                     chan_width_y[i + 1] =
00715                         (int)floor(cfactor *
00716                                    comp_width(&chan_y_dist, x,
00717                                               separation) + 0.5);
00718                     chan_width_y[i + 1] = max(chan_width_y[i + 1], 1);
00719                 }
00720         }
00721 #ifdef VERBOSE
00722     printf("\nchan_width_x:\n");
00723     for(i = 0; i <= ny; i++)
00724         printf("%d  ", chan_width_x[i]);
00725     printf("\n\nchan_width_y:\n");
00726     for(i = 0; i <= nx; i++)
00727         printf("%d  ", chan_width_y[i]);
00728     printf("\n\n");
00729 #endif
00730 
00731 }

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_subblock_data subblock_data_ptr,
t_chan_width_dist  chan_width_dist 
)

Definition at line 56 of file place_and_route.c.

00069 {
00070 
00071 /* This routine controls the overall placement and routing of a circuit. */
00072 
00073     char msg[BUFSIZE];
00074     int width_fac, inet, i;
00075     boolean success, Fc_clipped;
00076     float **net_delay, **net_slack;
00077     struct s_linked_vptr *net_delay_chunk_list_head;
00078     t_ivec **fb_opins_used_locally;     /* [0..num_blocks-1][0..num_class-1] */
00079     t_mst_edge **mst = NULL;    /* Make sure mst is never undefined */
00080     int max_pins_per_fb;
00081 
00082         Fc_clipped = FALSE;
00083 
00084     max_pins_per_fb = 0;
00085     for(i = 0; i < num_types; i++)
00086         {
00087             if(type_descriptors[i].num_pins > max_pins_per_fb)
00088                 {
00089                     max_pins_per_fb = type_descriptors[i].num_pins;
00090                 }
00091         }
00092 
00093     if(placer_opts.place_freq == PLACE_NEVER)
00094         {
00095             /* Read the placement from a file */
00096             read_place(place_file, net_file, arch_file, nx, ny, num_blocks,
00097                        block);
00098             sync_grid_to_blocks(num_blocks, block, nx, ny, grid);
00099         }
00100     else
00101         {
00102             assert((PLACE_ONCE == placer_opts.place_freq) ||
00103                    (PLACE_ALWAYS == placer_opts.place_freq));
00104 
00105             try_place(placer_opts, annealing_sched, chan_width_dist,
00106                       router_opts, det_routing_arch, segment_inf,
00107                       timing_inf, subblock_data_ptr, &mst);
00108             print_place(place_file, net_file, arch_file);
00109         }
00110     post_place_sync(num_blocks, block, subblock_data_ptr);
00111 
00112 
00113     fflush(stdout);
00114     if(operation == PLACE_ONLY)
00115         return;
00116 
00117     width_fac = router_opts.fixed_channel_width;
00118 
00119     /* If channel width not fixed, use binary search to find min W */
00120     if(NO_FIXED_CHANNEL_WIDTH == width_fac)
00121         {
00122             binary_search_place_and_route(placer_opts, place_file,
00123                                           net_file, arch_file, route_file,
00124                                           router_opts.full_stats, router_opts.verify_binary_search,
00125                                           annealing_sched, router_opts,
00126                                           det_routing_arch, segment_inf,
00127                                           timing_inf, subblock_data_ptr,
00128                                           chan_width_dist, mst);
00129         }
00130     else
00131         {
00132             if(det_routing_arch.directionality == UNI_DIRECTIONAL)
00133                 {
00134                     if(width_fac % 2 != 0)
00135                         {
00136                             printf
00137                                 ("Error: place_and_route.c: given odd chan width (%d) for udsd architecture\n",
00138                                  width_fac);
00139                             exit(1);
00140                         }
00141                 }
00142             /* Other constraints can be left to rr_graph to check since this is one pass routing */
00143 
00144 
00145             /* Allocate the major routing structures. */
00146 
00147             fb_opins_used_locally = alloc_route_structs(*subblock_data_ptr);
00148 
00149             if(timing_inf.timing_analysis_enabled)
00150                 {
00151                     net_slack =
00152                         alloc_and_load_timing_graph(timing_inf,
00153                                                     *subblock_data_ptr);
00154                     net_delay = alloc_net_delay(&net_delay_chunk_list_head);
00155                 }
00156             else
00157                 {
00158                     net_delay = NULL;   /* Defensive coding. */
00159                     net_slack = NULL;
00160                 }
00161 
00162             success =
00163                 try_route(width_fac, router_opts, det_routing_arch,
00164                           segment_inf, timing_inf, net_slack, net_delay,
00165                           chan_width_dist, fb_opins_used_locally, mst,
00166                           &Fc_clipped);
00167 
00168             if(Fc_clipped)
00169                 {
00170                     printf
00171                         ("Warning: Fc_output was too high and was clipped to full (maximum) connectivity.\n");
00172                 }
00173 
00174             if(success == FALSE)
00175                 {
00176                     printf
00177                         ("Circuit is unrouteable with a channel width factor of %d\n\n",
00178                          width_fac);
00179                     sprintf(msg,
00180                             "Routing failed with a channel width factor of %d.  ILLEGAL routing shown.",
00181                             width_fac);
00182                 }
00183 
00184             else
00185                 {
00186                     check_route(router_opts.route_type,
00187                                 det_routing_arch.num_switch,
00188                                 fb_opins_used_locally);
00189                     get_serial_num();
00190 
00191                     printf
00192                         ("Circuit successfully routed with a channel width factor of %d.\n\n",
00193                          width_fac);
00194 
00195                         routing_stats(router_opts.full_stats, router_opts.route_type,
00196                                   det_routing_arch.num_switch, segment_inf,
00197                                   det_routing_arch.num_segment,
00198                                   det_routing_arch.R_minW_nmos,
00199                                   det_routing_arch.R_minW_pmos,
00200                                   det_routing_arch.directionality,
00201                                   timing_inf.timing_analysis_enabled,
00202                                   net_slack, net_delay, *subblock_data_ptr);
00203 
00204                     print_route(route_file);
00205 
00206 #ifdef CREATE_ECHO_FILES
00207                     /*print_sink_delays("routing_sink_delays.echo"); */
00208 #endif /* CREATE_ECHO_FILES */
00209 
00210                     sprintf(msg,
00211                             "Routing succeeded with a channel width factor of %d.\n\n",
00212                             width_fac);
00213                 }
00214             free_subblock_data(subblock_data_ptr);
00215 
00216             init_draw_coords(max_pins_per_fb);
00217             update_screen(MAJOR, msg, ROUTING,
00218                           timing_inf.timing_analysis_enabled);
00219 
00220             if(timing_inf.timing_analysis_enabled)
00221                 {
00222                     assert(net_slack);
00223                     free_timing_graph(net_slack);
00224 
00225                     assert(net_delay);
00226                     free_net_delay(net_delay, &net_delay_chunk_list_head);
00227                 }
00228 
00229             free_route_structs(fb_opins_used_locally);
00230             fflush(stdout);
00231         }
00232 
00233     /*WMF: cleaning up memory usage */
00234     if(mst)
00235         {
00236             for(inet = 0; inet < num_nets; inet++)
00237                 {
00238                     assert(mst[inet]);
00239                     free(mst[inet]);
00240                 }
00241             free(mst);
00242             mst = NULL;
00243         }
00244 
00245 }

Here is the call graph for this function:

Here is the caller graph for this function:

void post_place_sync ( IN int  num_blocks,
INOUT const struct s_block  block_list[],
INOUT t_subblock_data subblock_data_ptr 
)

Definition at line 796 of file place_and_route.c.

00799 {
00800     int iblk, j, k, inet;
00801     t_type_ptr type;
00802     int max_num_block_pins;
00803     t_subblock **subblock_inf;
00804 
00805     subblock_inf = subblock_data_ptr->subblock_inf;
00806 
00807 
00808     /* Go through each block */
00809     for(iblk = 0; iblk < num_blocks; ++iblk)
00810         {
00811             type = block[iblk].type;
00812             assert(type->num_pins % type->capacity == 0);
00813             max_num_block_pins = type->num_pins / type->capacity;
00814             /* Logical location and physical location is offset by z * max_num_block_pins */
00815             /* Sync blocks and nets */
00816             for(j = 0; j < max_num_block_pins; j++)
00817                 {
00818                     inet = block[iblk].nets[j];
00819                     if(inet != OPEN && block[iblk].z > 0)
00820                         {
00821                             assert(block[iblk].
00822                                    nets[j +
00823                                         block[iblk].z * max_num_block_pins] ==
00824                                    OPEN);
00825                             block[iblk].nets[j +
00826                                              block[iblk].z *
00827                                              max_num_block_pins] =
00828                                 block[iblk].nets[j];
00829                             block[iblk].nets[j] = OPEN;
00830                             for(k = 0; k < type->num_pins; k++)
00831                                 {
00832                                     if(net[inet].node_block[k] == iblk)
00833                                         {
00834                                             assert(net[inet].
00835                                                    node_block_pin[k] == j);
00836                                             net[inet].node_block_pin[k] =
00837                                                 j +
00838                                                 block[iblk].z *
00839                                                 max_num_block_pins;
00840                                             break;
00841                                         }
00842                                 }
00843                         }
00844                 }
00845 
00846             /* Shift subblock pins to point to synced block pins */
00847             for(j = 0; j < subblock_data_ptr->num_subblocks_per_block[iblk];
00848                 j++)
00849                 {
00850                     for(k = 0; k < type->max_subblock_inputs; k++)
00851                         {
00852                             if(subblock_inf[iblk][j].inputs[k] != OPEN)
00853                                 {
00854                                     subblock_inf[iblk][j].inputs[k] =
00855                                         subblock_inf[iblk][j].inputs[k] +
00856                                         block[iblk].z * max_num_block_pins;
00857                                 }
00858                         }
00859                     for(k = 0; k < type->max_subblock_outputs; k++)
00860                         {
00861                             if(subblock_inf[iblk][j].outputs[k] != OPEN)
00862                                 {
00863                                     subblock_inf[iblk][j].outputs[k] =
00864                                         subblock_inf[iblk][j].outputs[k] +
00865                                         block[iblk].z * max_num_block_pins;
00866                                 }
00867                         }
00868                     if(subblock_inf[iblk][j].clock != OPEN)
00869                         {
00870                             subblock_inf[iblk][j].clock =
00871                                 subblock_inf[iblk][j].clock +
00872                                 block[iblk].z * max_num_block_pins;
00873                         }
00874                 }
00875         }
00876 }

Here is the caller graph for this function:


Generated on Tue Jan 5 15:26:00 2010 for VPR5.0 by  doxygen 1.6.1