diff --git a/vpr/src/tileable_rr_graph/tileable_rr_graph_edge_builder.cpp b/vpr/src/tileable_rr_graph/tileable_rr_graph_edge_builder.cpp new file mode 100644 index 000000000..185e4923b --- /dev/null +++ b/vpr/src/tileable_rr_graph/tileable_rr_graph_edge_builder.cpp @@ -0,0 +1,169 @@ +/************************************************************************ + * This file contains functions that are used to build edges + * between nodes of a tileable routing resource graph + ***********************************************************************/ +#include + +/* Headers from vtrutil library */ +#include "vtr_assert.h" +#include "vtr_log.h" +#include "vtr_time.h" + +#include "vpr_utils.h" + +#include "rr_graph_builder_utils.h" +#include "tileable_rr_graph_gsb.h" +#include "tileable_rr_graph_edge_builder.h" + +/* begin namespace openfpga */ +namespace openfpga { + +/************************************************************************ + * Build the edges for all the SOURCE and SINKs nodes: + * 1. create edges between SOURCE and OPINs + ***********************************************************************/ +static +void build_rr_graph_edges_for_source_nodes(RRGraph& rr_graph, + const vtr::vector& rr_node_driver_switches, + const DeviceGrid& grids) { + for (const RRNodeId& node : rr_graph.nodes()) { + /* Bypass all the non OPIN nodes */ + if (OPIN != rr_graph.node_type(node)) { + continue; + } + /* Now, we have an OPIN node, we get the source node index */ + short xlow = rr_graph.node_xlow(node); + short ylow = rr_graph.node_ylow(node); + short src_node_class_num = get_grid_pin_class_index(grids[xlow][ylow], + rr_graph.node_pin_num(node)); + + /* Create edges between SOURCE and OPINs */ + const RRNodeId& src_node = rr_graph.find_node(xlow - grids[xlow][ylow].width_offset, + ylow - grids[xlow][ylow].height_offset, + SOURCE, src_node_class_num); + VTR_ASSERT(true == rr_graph.valid_node_id(src_node)); + + /* add edges to the src_node */ + rr_graph.create_edge(src_node, node, rr_node_driver_switches[node]); + } +} + +/************************************************************************ + * Build the edges for all the SINKs nodes: + * 1. create edges between IPINs and SINKs + ***********************************************************************/ +static +void build_rr_graph_edges_for_sink_nodes(RRGraph& rr_graph, + const vtr::vector& rr_node_driver_switches, + const DeviceGrid& grids) { + for (const RRNodeId& node : rr_graph.nodes()) { + /* Bypass all the non IPIN nodes */ + if (IPIN != rr_graph.node_type(node)) { + continue; + } + /* Now, we have an OPIN node, we get the source node index */ + short xlow = rr_graph.node_xlow(node); + short ylow = rr_graph.node_ylow(node); + short sink_node_class_num = get_grid_pin_class_index(grids[xlow][ylow], + rr_graph.node_pin_num(node)); + /* 1. create edges between IPINs and SINKs */ + const RRNodeId& sink_node = rr_graph.find_node(xlow - grids[xlow][ylow].width_offset, + ylow - grids[xlow][ylow].height_offset, + SINK, sink_node_class_num); + VTR_ASSERT(true == rr_graph.valid_node_id(sink_node)); + + /* add edges to connect the IPIN node to SINK nodes */ + rr_graph.create_edge(node, sink_node, rr_node_driver_switches[sink_node]); + } +} + +/************************************************************************ + * Build the edges of each rr_node tile by tile: + * We classify rr_nodes into a general switch block (GSB) data structure + * where we create edges to each rr_nodes in the GSB with respect to + * Fc_in and Fc_out, switch block patterns + * For each GSB: + * 1. create edges between CHANX | CHANY and IPINs (connections inside connection blocks) + * 2. create edges between OPINs, CHANX and CHANY (connections inside switch blocks) + * 3. create edges between OPINs and IPINs (direct-connections) + ***********************************************************************/ +void build_rr_graph_edges(RRGraph& rr_graph, + const vtr::vector& rr_node_driver_switches, + const DeviceGrid& grids, + const vtr::Point& device_chan_width, + const std::vector& segment_inf, + int** Fc_in, int** Fc_out, + const e_switch_block_type& sb_type, const int& Fs, + const e_switch_block_type& sb_subtype, const int& subFs, + const bool& wire_opposite_side) { + + /* Create edges for SOURCE and SINK nodes for a tileable rr_graph */ + build_rr_graph_edges_for_source_nodes(rr_graph, rr_node_driver_switches, grids); + build_rr_graph_edges_for_sink_nodes(rr_graph, rr_node_driver_switches, grids); + + vtr::Point gsb_range(grids.width() - 2, grids.height() - 2); + + /* Go Switch Block by Switch Block */ + for (size_t ix = 0; ix <= gsb_range.x(); ++ix) { + for (size_t iy = 0; iy <= gsb_range.y(); ++iy) { + //vpr_printf(TIO_MESSAGE_INFO, "Building edges for GSB[%lu][%lu]\n", ix, iy); + + vtr::Point gsb_coord(ix, iy); + /* Create a GSB object */ + const RRGSB& rr_gsb = build_one_tileable_rr_gsb(grids, rr_graph, + device_chan_width, segment_inf, + gsb_coord); + + /* adapt the track_to_ipin_lookup for the GSB nodes */ + t_track2pin_map track2ipin_map; /* [0..track_gsb_side][0..num_tracks][ipin_indices] */ + track2ipin_map = build_gsb_track_to_ipin_map(rr_graph, rr_gsb, grids, segment_inf, Fc_in); + + /* adapt the opin_to_track_map for the GSB nodes */ + t_pin2track_map opin2track_map; /* [0..gsb_side][0..num_opin_node][track_indices] */ + opin2track_map = build_gsb_opin_to_track_map(rr_graph, rr_gsb, grids, segment_inf, Fc_out); + + /* adapt the switch_block_conn for the GSB nodes */ + t_track2track_map sb_conn; /* [0..from_gsb_side][0..chan_width-1][track_indices] */ + sb_conn = build_gsb_track_to_track_map(rr_graph, rr_gsb, + sb_type, Fs, sb_subtype, subFs, wire_opposite_side, + segment_inf); + + /* Build edges for a GSB */ + build_edges_for_one_tileable_rr_gsb(rr_graph, rr_gsb, + track2ipin_map, opin2track_map, + sb_conn, rr_node_driver_switches); + /* Finish this GSB, go to the next*/ + } + } +} + +/************************************************************************ + * Build direct edges for Grids * + ***********************************************************************/ +void build_rr_graph_direct_connections(RRGraph& rr_graph, + const DeviceGrid& grids, + const RRSwitchId& delayless_switch, + const std::vector& directs, + const std::vector& clb_to_clb_directs) { + for (size_t ix = 0; ix < grids.width(); ++ix) { + for (size_t iy = 0; iy < grids.height(); ++iy) { + /* Skip EMPTY tiles */ + if (true == is_empty_type(grids[ix][iy].type)) { + continue; + } + /* Skip height > 1 or width > 1 tiles (mostly heterogeneous blocks) */ + if ( (0 < grids[ix][iy].width_offset) + || (0 < grids[ix][iy].height_offset) ) { + continue; + } + vtr::Point from_grid_coordinate(ix, iy); + build_direct_connections_for_one_gsb(rr_graph, + grids, + from_grid_coordinate, + delayless_switch, + directs, clb_to_clb_directs); + } + } +} + +} /* end namespace openfpga */ diff --git a/vpr/src/tileable_rr_graph/tileable_rr_graph_edge_builder.h b/vpr/src/tileable_rr_graph/tileable_rr_graph_edge_builder.h new file mode 100644 index 000000000..34c2ced24 --- /dev/null +++ b/vpr/src/tileable_rr_graph/tileable_rr_graph_edge_builder.h @@ -0,0 +1,42 @@ +#ifndef TILEABLE_RR_GRAPH_EDGE_BUILDER_H +#define TILEABLE_RR_GRAPH_EDGE_BUILDER_H + +/******************************************************************** + * Include header files that are required by function declaration + *******************************************************************/ +#include + +/* Headers from vtrutil library */ +#include "vtr_geometry.h" + +#include "physical_types.h" +#include "device_grid.h" +#include "rr_graph_obj.h" +#include "clb2clb_directs.h" + +/******************************************************************** + * Function declaration + *******************************************************************/ + +/* begin namespace openfpga */ +namespace openfpga { + +void build_rr_graph_edges(RRGraph& rr_graph, + const vtr::vector& rr_node_driver_switches, + const DeviceGrid& grids, + const vtr::Point& device_chan_width, + const std::vector& segment_inf, + int** Fc_in, int** Fc_out, + const e_switch_block_type& sb_type, const int& Fs, + const e_switch_block_type& sb_subtype, const int& subFs, + const bool& wire_opposite_side); + +void build_rr_graph_direct_connections(RRGraph& rr_graph, + const DeviceGrid& grids, + const RRSwitchId& delayless_switch, + const std::vector& directs, + const std::vector& clb_to_clb_directs); + +} /* end namespace openfpga */ + +#endif 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 9cbc69dff..e2bf6e4ce 100755 --- a/vpr/src/tileable_rr_graph/tileable_rr_graph_gsb.cpp +++ b/vpr/src/tileable_rr_graph/tileable_rr_graph_gsb.cpp @@ -620,7 +620,7 @@ RRChan build_one_tileable_rr_chan(const vtr::Point& chan_coordinate, ***********************************************************************/ RRGSB build_one_tileable_rr_gsb(const DeviceGrid& grids, const RRGraph& rr_graph, - const std::vector& device_chan_width, + const vtr::Point& device_chan_width, const std::vector& segment_inf, const vtr::Point& gsb_coordinate) { /* Create an object to return */ @@ -650,9 +650,9 @@ RRGSB build_one_tileable_rr_gsb(const DeviceGrid& grids, /* Build a segment details, where we need the segment ids for building rr_chan * We do not care starting and ending points here, so set chan_side as NUM_SIDES */ - ChanNodeDetails chanx_details = build_unidir_chan_node_details(device_chan_width[0], grids.width() - 1, + ChanNodeDetails chanx_details = build_unidir_chan_node_details(device_chan_width.x(), grids.width() - 1, false, false, segment_inf); - ChanNodeDetails chany_details = build_unidir_chan_node_details(device_chan_width[1], grids.height() - 1, + ChanNodeDetails chany_details = build_unidir_chan_node_details(device_chan_width.y(), grids.height() - 1, false, false, segment_inf); switch (side) { @@ -907,7 +907,7 @@ void build_edges_for_one_tileable_rr_gsb(RRGraph& rr_graph, const t_track2pin_map& track2ipin_map, const t_pin2track_map& opin2track_map, const t_track2track_map& track2track_map, - const vtr::vector rr_node_driver_switches) { + const vtr::vector& rr_node_driver_switches) { /* Walk through each sides */ for (size_t side = 0; side < rr_gsb.get_num_sides(); ++side) { diff --git a/vpr/src/tileable_rr_graph/tileable_rr_graph_gsb.h b/vpr/src/tileable_rr_graph/tileable_rr_graph_gsb.h index 170249f74..7c7568fb9 100755 --- a/vpr/src/tileable_rr_graph/tileable_rr_graph_gsb.h +++ b/vpr/src/tileable_rr_graph/tileable_rr_graph_gsb.h @@ -44,7 +44,7 @@ t_track2track_map build_gsb_track_to_track_map(const RRGraph& rr_graph, RRGSB build_one_tileable_rr_gsb(const DeviceGrid& grids, const RRGraph& rr_graph, - const std::vector& device_chan_width, + const vtr::Point& device_chan_width, const std::vector& segment_inf, const vtr::Point& gsb_coordinate); @@ -53,7 +53,7 @@ void build_edges_for_one_tileable_rr_gsb(RRGraph& rr_graph, const t_track2pin_map& track2ipin_map, const t_pin2track_map& opin2track_map, const t_track2track_map& track2track_map, - const vtr::vector rr_node_driver_switches); + const vtr::vector& rr_node_driver_switches); t_track2pin_map build_gsb_track_to_ipin_map(const RRGraph& rr_graph, const RRGSB& rr_gsb,