static void alloc_routing_structs(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) { int bb_factor; /*calls routines that set up routing resource graph and associated structures*/ /*must set up dummy blocks for the first pass through*/ assign_locations(CLB, 1, 1, CLB, nx, ny); clb_opins_used_locally = alloc_route_structs(subblock_data); free_rr_graph(); build_rr_graph(router_opts.route_type, det_routing_arch, segment_inf, timing_inf, router_opts.base_cost_type); alloc_and_load_rr_node_route_structs(); alloc_timing_driven_route_structs(&pin_criticality, &sink_order, &rt_node_of_sink); bb_factor = nx + ny; /*set it to a huge value*/ init_route_structs(bb_factor); }
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_slack, float **net_delay, t_chan_width_dist chan_width_dist, t_ivec **clb_opins_used_locally) { /* Attempts a routing via an iterated maze router algorithm. Width_fac * * specifies the relative width of the channels, while the members of * * router_opts determine the value of the costs assigned to routing * * resource node, etc. det_routing_arch describes the detailed routing * * architecture (connection and switch boxes) of the FPGA; it is used * * only if a DETAILED routing has been selected. */ boolean success; printf("\nAttempting routing with a width factor (usually maximum channel "); printf("width) of %d.\n",width_fac); /* Set the channel widths */ init_chan (width_fac, chan_width_dist); /* Free any old routing graph, if one exists. */ free_rr_graph (); /* Set up the routing resource graph defined by this FPGA architecture. */ build_rr_graph (router_opts.route_type, det_routing_arch, segment_inf, timing_inf, router_opts.base_cost_type); /* Allocate and load some additional rr_graph information needed only by * * the router. */ alloc_and_load_rr_node_route_structs (); init_route_structs (router_opts.bb_factor); if (router_opts.router_algorithm == BREADTH_FIRST) success = try_breadth_first_route (router_opts, clb_opins_used_locally); else /* TIMING_DRIVEN route */ success = try_timing_driven_route (router_opts, net_slack, net_delay, clb_opins_used_locally); free_rr_node_route_structs (); return (success); }
static void alloc_routing_structs(struct s_router_opts router_opts, struct s_det_routing_arch det_routing_arch, t_segment_inf * segment_inf, t_timing_inf timing_inf) { int bb_factor; int warnings; t_graph_type graph_type; /*calls routines that set up routing resource graph and associated structures */ /*must set up dummy blocks for the first pass through to setup locally used opins */ /* Only one block per tile */ assign_locations(FILL_TYPE, 1, 1, 0, FILL_TYPE, nx, ny, 0); clb_opins_used_locally = alloc_route_structs(); free_rr_graph(); if(router_opts.route_type == GLOBAL) { graph_type = GRAPH_GLOBAL; } else { graph_type = (det_routing_arch.directionality == BI_DIRECTIONAL ? GRAPH_BIDIR : GRAPH_UNIDIR); } build_rr_graph(graph_type, num_types, dummy_type_descriptors, nx, ny, grid, chan_width_x[0], NULL, det_routing_arch.switch_block_type, det_routing_arch.Fs, det_routing_arch.num_segment, det_routing_arch.num_switch, segment_inf, det_routing_arch.global_route_switch, det_routing_arch.delayless_switch, timing_inf, det_routing_arch.wire_to_ipin_switch, router_opts.base_cost_type, &warnings); alloc_and_load_rr_node_route_structs(); alloc_timing_driven_route_structs(&pin_criticality, &sink_order, &rt_node_of_sink); bb_factor = nx + ny; /*set it to a huge value */ init_route_structs(bb_factor); }
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_slack, float **net_delay, t_chan_width_dist chan_width_dist, t_ivec ** fb_opins_used_locally, t_mst_edge ** mst, boolean * Fc_clipped) { /* Attempts a routing via an iterated maze router algorithm. Width_fac * * specifies the relative width of the channels, while the members of * * router_opts determine the value of the costs assigned to routing * * resource node, etc. det_routing_arch describes the detailed routing * * architecture (connection and switch boxes) of the FPGA; it is used * * only if a DETAILED routing has been selected. */ int tmp; boolean success; t_graph_type graph_type; if(router_opts.route_type == GLOBAL) { graph_type = GRAPH_GLOBAL; } else { graph_type = (det_routing_arch.directionality == BI_DIRECTIONAL ? GRAPH_BIDIR : GRAPH_UNIDIR); } /* Set the channel widths */ init_chan(width_fac, chan_width_dist); /* Free any old routing graph, if one exists. */ free_rr_graph(); /* Set up the routing resource graph defined by this FPGA architecture. */ build_rr_graph(graph_type, num_types, type_descriptors, nx, ny, grid, chan_width_x[0], NULL, det_routing_arch.switch_block_type, det_routing_arch.Fs, det_routing_arch.num_segment, det_routing_arch.num_switch, segment_inf, det_routing_arch.global_route_switch, det_routing_arch.delayless_switch, timing_inf, det_routing_arch.wire_to_ipin_switch, router_opts.base_cost_type, &tmp); /* Allocate and load some additional rr_graph information needed only by * * the router. */ alloc_and_load_rr_node_route_structs(); init_route_structs(router_opts.bb_factor); if(router_opts.router_algorithm == BREADTH_FIRST) { printf("Confirming Router Algorithm: BREADTH_FIRST.\n"); success = try_breadth_first_route(router_opts, fb_opins_used_locally, width_fac); } else if(router_opts.router_algorithm == TIMING_DRIVEN) { /* TIMING_DRIVEN route */ printf("Confirming Router Algorithm: TIMING_DRIVEN.\n"); assert(router_opts.route_type != GLOBAL); success = try_timing_driven_route(router_opts, net_slack, net_delay, fb_opins_used_locally); } else { /* Directed Search Routability Driven */ printf("Confirming Router Algorithm: DIRECTED_SEARCH.\n"); success = try_directed_search_route(router_opts, fb_opins_used_locally, width_fac, mst); } free_rr_node_route_structs(); return (success); }