|
VPR-6.0
|
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 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 struct s_fmap_cell t_fmap_cell |
| 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: