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); }
void vpr_free_all(INOUTP t_arch Arch, INOUTP t_options options, INOUTP t_vpr_setup vpr_setup) { free_rr_graph(); if (vpr_setup.RouterOpts.doRouting) { free_route_structs(); } free_trace_structs(); vpr_free_vpr_data_structures(Arch, options, vpr_setup); if (has_printhandler_pre_vpr == FALSE) { PrintHandlerDelete(); } }
static void free_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) { free_rr_graph(); free_rr_node_route_structs(); free_route_structs(clb_opins_used_locally); free_trace_structs(); free_timing_driven_route_structs(pin_criticality, sink_order, rt_node_of_sink); }
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); }
static void free_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 i; free_rr_graph(); free_rr_node_route_structs(); free_route_structs(); free_trace_structs(); free_timing_driven_route_structs(pin_criticality, sink_order, rt_node_of_sink); if (clb_opins_used_locally != NULL) { for (i = 0; i < num_blocks; i++) { free_ivec_vector(clb_opins_used_locally[i], 0, block[i].type->num_class - 1); } free(clb_opins_used_locally); clb_opins_used_locally = NULL; } }
static void clay_logical_equivalence_handling(const t_arch *arch) { t_trace **saved_ext_rr_trace_head, **saved_ext_rr_trace_tail; t_rr_node *saved_ext_rr_node; int num_ext_rr_node, num_ext_nets; int i, j; for (i = 0; i < num_blocks; i++) { clay_reload_ble_locations(i); } /* Resolve logically equivalent inputs */ saved_ext_rr_trace_head = trace_head; saved_ext_rr_trace_tail = trace_tail; saved_ext_rr_node = rr_node; num_ext_rr_node = num_rr_nodes; num_ext_nets = num_nets; num_rr_nodes = 0; rr_node = NULL; trace_head = NULL; trace_tail = NULL; free_rr_graph(); /* free all data structures associated with rr_graph */ alloc_and_load_cluster_legality_checker(); for (i = 0; i < num_blocks; i++) { /* Regenerate rr_graph (note, can be more runtime efficient but this allows for more code reuse) */ rr_node = block[i].pb->rr_graph; num_rr_nodes = block[i].pb->pb_graph_node->total_pb_pins; free_legalizer_for_cluster(&block[i], TRUE); alloc_and_load_legalizer_for_cluster(&block[i], i, arch); reload_intra_cluster_nets(block[i].pb); reload_ext_net_rr_terminal_cluster(); force_post_place_route_cb_input_pins(i); #ifdef HACK_LUT_PIN_SWAPPING /* Resolve rebalancing of LUT inputs */ clay_lut_input_rebalancing(i, block[i].pb); #endif /* reset rr_graph */ for (j = 0; j < num_rr_nodes; j++) { rr_node[j].occ = 0; rr_node[j].prev_edge = OPEN; rr_node[j].prev_node = OPEN; } if (try_breadth_first_route_cluster() == FALSE) { vpr_printf(TIO_MESSAGE_ERROR, "Failed to resync post routed solution with clustered netlist.\n"); vpr_printf(TIO_MESSAGE_ERROR, "Cannot recover from error.\n"); exit(1); } save_cluster_solution(); reset_legalizer_for_cluster(&block[i]); free_legalizer_for_cluster(&block[i], FALSE); } free_cluster_legality_checker(); trace_head = saved_ext_rr_trace_head; trace_tail = saved_ext_rr_trace_tail; rr_node = saved_ext_rr_node; num_rr_nodes = num_ext_rr_node; num_nets = num_ext_nets; }
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); }