VPR-6.0

vpr/SRC/base/place_and_route.h File Reference

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  s_fmap_cell

Defines

#define INFINITE   -1
#define NOT_FOUND   0
#define WNEED   1
#define WL   2
#define PROC_TIME   3

Typedefs

typedef struct s_fmap_cell t_fmap_cell

Functions

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)
void init_chan (int cfactor, t_chan_width_dist chan_width_dist)

Define Documentation

#define INFINITE   -1

Definition at line 1 of file place_and_route.h.

#define NOT_FOUND   0

Definition at line 2 of file place_and_route.h.

#define PROC_TIME   3

Definition at line 6 of file place_and_route.h.

#define WL   2

Definition at line 5 of file place_and_route.h.

#define WNEED   1

Definition at line 4 of file place_and_route.h.


Typedef Documentation

typedef struct s_fmap_cell t_fmap_cell

Function Documentation

void init_chan ( int  cfactor,
t_chan_width_dist  chan_width_dist 
)

Assigns widths to channels (in tracks). Minimum one track per channel. io channels are io_rat * maximum in interior tracks wide. The channel distributions read from the architecture file are scaled by cfactor.

Definition at line 699 of file place_and_route.c.

{

    float x, separation, chan_width_io;
    int nio, i;
    t_chan chan_x_dist, chan_y_dist;

    chan_width_io = chan_width_dist.chan_width_io;
    chan_x_dist = chan_width_dist.chan_x_dist;
    chan_y_dist = chan_width_dist.chan_y_dist;

/* io channel widths */

    nio = (int)floor(cfactor * chan_width_io + 0.5);
    if(nio == 0)
        nio = 1;                /* No zero width channels */

    chan_width_x[0] = chan_width_x[ny] = nio;
    chan_width_y[0] = chan_width_y[nx] = nio;

    if(ny > 1)
        {
            separation = 1. / (ny - 2.);        /* Norm. distance between two channels. */
            x = 0.;             /* This avoids div by zero if ny = 2. */
            chan_width_x[1] = (int)floor(cfactor * comp_width(&chan_x_dist, x,
                                                              separation) +
                                         0.5);

            /* No zero width channels */
            chan_width_x[1] = max(chan_width_x[1], 1);

            for(i = 1; i < ny - 1; i++)
                {
                    x = (float)i / ((float)(ny - 2.));
                    chan_width_x[i + 1] =
                        (int)floor(cfactor *
                                   comp_width(&chan_x_dist, x,
                                              separation) + 0.5);
                    chan_width_x[i + 1] = max(chan_width_x[i + 1], 1);
                }
        }

    if(nx > 1)
        {
            separation = 1. / (nx - 2.);        /* Norm. distance between two channels. */
            x = 0.;             /* Avoids div by zero if nx = 2. */
            chan_width_y[1] = (int)floor(cfactor * comp_width(&chan_y_dist, x,
                                                              separation) +
                                         0.5);

            chan_width_y[1] = max(chan_width_y[1], 1);

            for(i = 1; i < nx - 1; i++)
                {
                    x = (float)i / ((float)(nx - 2.));
                    chan_width_y[i + 1] =
                        (int)floor(cfactor *
                                   comp_width(&chan_y_dist, x,
                                              separation) + 0.5);
                    chan_width_y[i + 1] = max(chan_width_y[i + 1], 1);
                }
        }
#ifdef VERBOSE
    printf("\nchan_width_x:\n");
    for(i = 0; i <= ny; i++)
        printf("%d  ", chan_width_x[i]);
    printf("\n\nchan_width_y:\n");
    for(i = 0; i <= nx; i++)
        printf("%d  ", chan_width_y[i]);
    printf("\n\n");
#endif

}

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 
)

This routine controls the overall placement and routing of a circuit.

Definition at line 58 of file place_and_route.c.

{
    char msg[BUFSIZE];
    int width_fac, inet, i;
    boolean success, Fc_clipped;
    float **net_delay, **net_slack;
    struct s_linked_vptr *net_delay_chunk_list_head;
    t_ivec **clb_opins_used_locally;    /* [0..num_blocks-1][0..num_class-1] */
    t_mst_edge **mst = NULL;    /* Make sure mst is never undefined */
    int max_pins_per_clb;
        clock_t begin, end;

        Fc_clipped = FALSE;

    max_pins_per_clb = 0;
    for(i = 0; i < num_types; i++)
        {
            if(type_descriptors[i].num_pins > max_pins_per_clb)
                {
                    max_pins_per_clb = type_descriptors[i].num_pins;
                }
        }

    if(placer_opts.place_freq == PLACE_NEVER)
        {
            /* Read the placement from a file */
            read_place(place_file, net_file, arch_file, nx, ny, num_blocks,
                       block);
            sync_grid_to_blocks(num_blocks, block, nx, ny, grid);
        }
    else
        {
            assert((PLACE_ONCE == placer_opts.place_freq) ||
                   (PLACE_ALWAYS == placer_opts.place_freq));
                begin = clock();
            try_place(placer_opts, annealing_sched, chan_width_dist,
                      router_opts, det_routing_arch, segment_inf,
                      timing_inf, &mst);
            print_place(place_file, net_file, arch_file);
                end = clock();
#ifdef CLOCKS_PER_SEC
                printf("Placement took %g seconds\n", (float)(end - begin) / CLOCKS_PER_SEC);
#else
                printf("Placement took %g seconds\n", (float)(end - begin) / CLK_PER_SEC);
#endif
        }
        begin = clock();
    post_place_sync(num_blocks, block);


    fflush(stdout);

        /* reset mst */
        if(mst)
        {
            for(inet = 0; inet < num_nets; inet++)
                {
                        if(mst[inet]) {
                                free(mst[inet]);
                        }
                }
            free(mst);
        }
        mst = NULL;

        if(!router_opts.doRouting)
        return;

    mst = (t_mst_edge **) my_malloc(sizeof(t_mst_edge *) * num_nets);
    for(inet = 0; inet < num_nets; inet++)
        {
            mst[inet] = get_mst_of_net(inet);
        }

    width_fac = router_opts.fixed_channel_width;

    /* If channel width not fixed, use binary search to find min W */
    if(NO_FIXED_CHANNEL_WIDTH == width_fac)
        {
            binary_search_place_and_route(placer_opts, place_file,
                                          net_file, arch_file, route_file,
                                          router_opts.full_stats, router_opts.verify_binary_search,
                                          annealing_sched, router_opts,
                                          det_routing_arch, segment_inf,
                                          timing_inf,
                                          chan_width_dist, mst, models);
        }
    else
        {
            if(det_routing_arch.directionality == UNI_DIRECTIONAL)
                {
                    if(width_fac % 2 != 0)
                        {
                            printf
                                ("Error: pack_place_and_route.c: given odd chan width (%d) for udsd architecture\n",
                                 width_fac);
                            exit(1);
                        }
                }
            /* Other constraints can be left to rr_graph to check since this is one pass routing */


            /* Allocate the major routing structures. */

            clb_opins_used_locally = alloc_route_structs();

            if(timing_inf.timing_analysis_enabled)
                {
                    net_slack =
                        alloc_and_load_timing_graph(timing_inf);
                    net_delay = alloc_net_delay(&net_delay_chunk_list_head, clb_net, num_nets);
                }
            else
                {
                    net_delay = NULL;   /* Defensive coding. */
                    net_slack = NULL;
                }

            success =
                try_route(width_fac, router_opts, det_routing_arch,
                          segment_inf, timing_inf, net_slack, net_delay,
                          chan_width_dist, clb_opins_used_locally, mst,
                          &Fc_clipped);

            if(Fc_clipped)
                {
                    printf
                        ("Warning: Fc_output was too high and was clipped to full (maximum) connectivity.\n");
                }

            if(success == FALSE)
                {
                    printf
                        ("Circuit is unrouteable with a channel width factor of %d\n\n",
                         width_fac);
                    sprintf(msg,
                            "Routing failed with a channel width factor of %d.  ILLEGAL routing shown.",
                            width_fac);
                }

            else
                {
                    check_route(router_opts.route_type,
                                det_routing_arch.num_switch,
                                clb_opins_used_locally);
                    get_serial_num();

                    printf
                        ("Circuit successfully routed with a channel width factor of %d.\n\n",
                         width_fac);

                        routing_stats(router_opts.full_stats, router_opts.route_type,
                                  det_routing_arch.num_switch, segment_inf,
                                  det_routing_arch.num_segment,
                                  det_routing_arch.R_minW_nmos,
                                  det_routing_arch.R_minW_pmos,
                                  det_routing_arch.directionality,
                                  timing_inf.timing_analysis_enabled,
                                  net_slack, net_delay);

                    print_route(route_file);

#ifdef CREATE_ECHO_FILES
                    /*print_sink_delays("routing_sink_delays.echo"); */
#endif /* CREATE_ECHO_FILES */

                    sprintf(msg,
                            "Routing succeeded with a channel width factor of %d.\n\n",
                            width_fac);
                }

            init_draw_coords(max_pins_per_clb);
            update_screen(MAJOR, msg, ROUTING,
                          timing_inf.timing_analysis_enabled);

            if(timing_inf.timing_analysis_enabled)
                {
                    assert(net_slack);
                        #ifdef CREATE_ECHO_FILES
                                print_timing_graph_as_blif("post_flow_timing_graph.blif", models);
                        #endif

                    free_timing_graph(net_slack);

                    assert(net_delay);
                    free_net_delay(net_delay, &net_delay_chunk_list_head);
                }

            free_route_structs(clb_opins_used_locally);
            fflush(stdout);
        }
        end = clock();
        #ifdef CLOCKS_PER_SEC
                printf("Routing took %g seconds\n", (float)(end - begin) / CLOCKS_PER_SEC);
        #else
                printf("Routing took %g seconds\n", (float)(end - begin) / CLK_PER_SEC);
        #endif

    /*WMF: cleaning up memory usage */
    if(mst)
        {
            for(inet = 0; inet < num_nets; inet++)
                {
                        if(!mst[inet]) {
                                printf("no mst for net %s #%d\n", clb_net[inet].name, inet);
                        }
                    assert(mst[inet]);
                    free(mst[inet]);
                }
            free(mst);
            mst = NULL;
        }
}

Here is the call graph for this function:

Here is the caller graph for this function: