diff --git a/vpr/src/base/vpr_context.h b/vpr/src/base/vpr_context.h index 487382480..d823c921b 100644 --- a/vpr/src/base/vpr_context.h +++ b/vpr/src/base/vpr_context.h @@ -148,6 +148,11 @@ struct DeviceContext : public Context { /* RRGraph object */ RRGraph rr_graph; + /* Track ids for each rr_node in the rr_graph. + * This is used by drawer for tileable routing resource graph + */ + std::map> rr_node_track_ids; + /* Structures to define the routing architecture of the FPGA. */ std::vector rr_nodes; /* autogenerated in build_rr_graph */ diff --git a/vpr/src/base/vpr_types.h b/vpr/src/base/vpr_types.h index dee5fd7e6..009887d71 100644 --- a/vpr/src/base/vpr_types.h +++ b/vpr/src/base/vpr_types.h @@ -1004,6 +1004,12 @@ struct t_det_routing_arch { enum e_switch_block_type switch_block_type; std::vector switchblocks; + /* Xifan Tang: subtype of switch blocks. + * Sub type and Fs are applied to pass tracks + */ + int subFs; + enum e_switch_block_type switch_block_subtype; + short global_route_switch; short delayless_switch; int wire_to_arch_ipin_switch; diff --git a/vpr/src/route/rr_graph.cpp b/vpr/src/route/rr_graph.cpp index 50f2799d9..b21310ad4 100644 --- a/vpr/src/route/rr_graph.cpp +++ b/vpr/src/route/rr_graph.cpp @@ -41,6 +41,8 @@ #include "rr_graph_obj_util.h" #include "check_rr_graph_obj.h" +#include "tileable_rr_graph_builder.h" + #include "clb2clb_directs.h" //#define VERBOSE @@ -318,33 +320,54 @@ void create_rr_graph(const t_graph_type graph_type, free_rr_graph(); - build_rr_graph(graph_type, - block_types, - grid, - nodes_per_chan, - det_routing_arch->switch_block_type, - det_routing_arch->Fs, - det_routing_arch->switchblocks, - num_arch_switches, - segment_inf, - det_routing_arch->global_route_switch, - det_routing_arch->wire_to_arch_ipin_switch, - det_routing_arch->delayless_switch, - det_routing_arch->R_minW_nmos, - det_routing_arch->R_minW_pmos, - base_cost_type, - trim_empty_channels, - trim_obs_channels, - directs, num_directs, - &det_routing_arch->wire_to_rr_ipin_switch, - Warnings); + if (GRAPH_UNIDIR_TILEABLE != graph_type) { + build_rr_graph(graph_type, + block_types, + grid, + nodes_per_chan, + det_routing_arch->switch_block_type, + det_routing_arch->Fs, + det_routing_arch->switchblocks, + num_arch_switches, + segment_inf, + det_routing_arch->global_route_switch, + det_routing_arch->wire_to_arch_ipin_switch, + det_routing_arch->delayless_switch, + det_routing_arch->R_minW_nmos, + det_routing_arch->R_minW_pmos, + base_cost_type, + trim_empty_channels, + trim_obs_channels, + directs, num_directs, + &det_routing_arch->wire_to_rr_ipin_switch, + Warnings); - if (clock_modeling == DEDICATED_NETWORK) { - ClockRRGraphBuilder::create_and_append_clock_rr_graph(segment_inf, - det_routing_arch->R_minW_nmos, - det_routing_arch->R_minW_pmos, - det_routing_arch->wire_to_rr_ipin_switch, - base_cost_type); + if (clock_modeling == DEDICATED_NETWORK) { + ClockRRGraphBuilder::create_and_append_clock_rr_graph(segment_inf, + det_routing_arch->R_minW_nmos, + det_routing_arch->R_minW_pmos, + det_routing_arch->wire_to_rr_ipin_switch, + base_cost_type); + } + } else { + /* We do not support dedicated network for clocks in tileable rr_graph generation */ + openfpga::build_tileable_unidir_rr_graph(block_types, + grid, + nodes_per_chan, + det_routing_arch->switch_block_type, + det_routing_arch->Fs, + det_routing_arch->switch_block_subtype, + det_routing_arch->subFs, + segment_inf, + det_routing_arch->wire_to_arch_ipin_switch, + det_routing_arch->delayless_switch, + det_routing_arch->R_minW_nmos, + det_routing_arch->R_minW_pmos, + base_cost_type, + directs, num_directs, + &det_routing_arch->wire_to_rr_ipin_switch, + false, /* Do not allow passing tracks to be wired to the same routing channels */ + Warnings); } /* Xifan Tang - Create rr_graph object: load rr_nodes to the object */ diff --git a/vpr/src/tileable_rr_graph/tileable_rr_graph_builder.cpp b/vpr/src/tileable_rr_graph/tileable_rr_graph_builder.cpp index d9f98d895..f103fb545 100644 --- a/vpr/src/tileable_rr_graph/tileable_rr_graph_builder.cpp +++ b/vpr/src/tileable_rr_graph/tileable_rr_graph_builder.cpp @@ -266,6 +266,9 @@ void build_tileable_unidir_rr_graph(const std::vector& typ /* Save the channel widths for the newly constructed graph */ device_ctx.chan_width = chan_width; + /* Save the track ids for tileable routing resource graph */ + device_ctx.rr_node_track_ids = rr_node_track_ids; + /************************************************************************ * Allocate external data structures * a. cost_index diff --git a/vpr/src/tileable_rr_graph/tileable_rr_graph_gsb.cpp b/vpr/src/tileable_rr_graph/tileable_rr_graph_gsb.cpp index cca9e001c..b37265dfb 100755 --- a/vpr/src/tileable_rr_graph/tileable_rr_graph_gsb.cpp +++ b/vpr/src/tileable_rr_graph/tileable_rr_graph_gsb.cpp @@ -1316,4 +1316,94 @@ t_pin2track_map build_gsb_opin_to_track_map(const RRGraph& rr_graph, return opin2track_map; } +/************************************************************************ + * Add all direct clb-pin-to-clb-pin edges to given opin + ***********************************************************************/ +void build_direct_connections_for_one_gsb(RRGraph& rr_graph, + const DeviceGrid& grids, + const vtr::Point& from_grid_coordinate, + const RRSwitchId& delayless_switch, + const std::vector& directs, + const std::vector& clb_to_clb_directs) { + VTR_ASSERT(directs.size() == clb_to_clb_directs.size()); + + const t_grid_tile& from_grid = grids[from_grid_coordinate.x()][from_grid_coordinate.y()]; + t_physical_tile_type_ptr grid_type = from_grid.type; + + /* Iterate through all direct connections */ + for (size_t i = 0; i < directs.size(); ++i) { + /* Bypass unmatched direct clb-to-clb connections */ + if (grid_type != clb_to_clb_directs[i].from_clb_type) { + continue; + } + + /* This opin is specified to connect directly to an ipin, + * now compute which ipin to connect to + */ + vtr::Point to_grid_coordinate(from_grid_coordinate.x() + directs[i].x_offset, + from_grid_coordinate.y() + directs[i].y_offset); + + /* Bypass unmatched direct clb-to-clb connections */ + t_physical_tile_type_ptr to_grid_type = grids[to_grid_coordinate.x()][to_grid_coordinate.y()].type; + /* Check if to_grid if the same grid */ + if (to_grid_type != clb_to_clb_directs[i].to_clb_type) { + continue; + } + + bool swap; + int max_index, min_index; + /* Compute index of opin with regards to given pins */ + if ( clb_to_clb_directs[i].from_clb_pin_start_index + > clb_to_clb_directs[i].from_clb_pin_end_index) { + swap = true; + max_index = clb_to_clb_directs[i].from_clb_pin_start_index; + min_index = clb_to_clb_directs[i].from_clb_pin_end_index; + } else { + swap = false; + min_index = clb_to_clb_directs[i].from_clb_pin_start_index; + max_index = clb_to_clb_directs[i].from_clb_pin_end_index; + } + + /* get every opin in the range */ + for (int opin = min_index; opin <= max_index; ++opin) { + int offset = opin - min_index; + + if ( (to_grid_coordinate.x() < grids.width() - 1) + && (to_grid_coordinate.y() < grids.height() - 1) ) { + int ipin = OPEN; + if ( clb_to_clb_directs[i].to_clb_pin_start_index + > clb_to_clb_directs[i].to_clb_pin_end_index) { + if (true == swap) { + ipin = clb_to_clb_directs[i].to_clb_pin_end_index + offset; + } else { + ipin = clb_to_clb_directs[i].to_clb_pin_start_index - offset; + } + } else { + if(true == swap) { + ipin = clb_to_clb_directs[i].to_clb_pin_end_index - offset; + } else { + ipin = clb_to_clb_directs[i].to_clb_pin_start_index + offset; + } + } + + /* Get the pin index in the rr_graph */ + int from_grid_width_ofs = from_grid.width_offset; + int from_grid_height_ofs = from_grid.height_offset; + int to_grid_width_ofs = grids[to_grid_coordinate.x()][to_grid_coordinate.y()].width_offset; + int to_grid_height_ofs = grids[to_grid_coordinate.x()][to_grid_coordinate.y()].height_offset; + const RRNodeId& opin_node_id = rr_graph.find_node(from_grid_coordinate.x() - from_grid_width_ofs, + from_grid_coordinate.y() - from_grid_height_ofs, + OPIN, opin); + const RRNodeId& ipin_node_id = rr_graph.find_node(to_grid_coordinate.x() - to_grid_width_ofs, + to_grid_coordinate.y() - to_grid_height_ofs, + IPIN, ipin); + /* add edges to the opin_node */ + rr_graph.create_edge(opin_node_id, ipin_node_id, + delayless_switch); + } + } + } +} + + } /* end namespace openfpga */