adapt tileable rr_graph edge builder to rr_graph object
This commit is contained in:
parent
328488f357
commit
8d350ee22f
|
@ -0,0 +1,169 @@
|
||||||
|
/************************************************************************
|
||||||
|
* This file contains functions that are used to build edges
|
||||||
|
* between nodes of a tileable routing resource graph
|
||||||
|
***********************************************************************/
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
/* 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<RRNodeId, RRSwitchId>& 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<RRNodeId, RRSwitchId>& 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<RRNodeId, RRSwitchId>& rr_node_driver_switches,
|
||||||
|
const DeviceGrid& grids,
|
||||||
|
const vtr::Point<size_t>& device_chan_width,
|
||||||
|
const std::vector<t_segment_inf>& 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<size_t> 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<size_t> 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<t_direct_inf>& directs,
|
||||||
|
const std::vector<t_clb_to_clb_directs>& 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<size_t> 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 */
|
|
@ -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 <vector>
|
||||||
|
|
||||||
|
/* 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<RRNodeId, RRSwitchId>& rr_node_driver_switches,
|
||||||
|
const DeviceGrid& grids,
|
||||||
|
const vtr::Point<size_t>& device_chan_width,
|
||||||
|
const std::vector<t_segment_inf>& 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<t_direct_inf>& directs,
|
||||||
|
const std::vector<t_clb_to_clb_directs>& clb_to_clb_directs);
|
||||||
|
|
||||||
|
} /* end namespace openfpga */
|
||||||
|
|
||||||
|
#endif
|
|
@ -620,7 +620,7 @@ RRChan build_one_tileable_rr_chan(const vtr::Point<size_t>& chan_coordinate,
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
RRGSB build_one_tileable_rr_gsb(const DeviceGrid& grids,
|
RRGSB build_one_tileable_rr_gsb(const DeviceGrid& grids,
|
||||||
const RRGraph& rr_graph,
|
const RRGraph& rr_graph,
|
||||||
const std::vector<size_t>& device_chan_width,
|
const vtr::Point<size_t>& device_chan_width,
|
||||||
const std::vector<t_segment_inf>& segment_inf,
|
const std::vector<t_segment_inf>& segment_inf,
|
||||||
const vtr::Point<size_t>& gsb_coordinate) {
|
const vtr::Point<size_t>& gsb_coordinate) {
|
||||||
/* Create an object to return */
|
/* 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
|
/* 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
|
* 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);
|
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);
|
false, false, segment_inf);
|
||||||
|
|
||||||
switch (side) {
|
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_track2pin_map& track2ipin_map,
|
||||||
const t_pin2track_map& opin2track_map,
|
const t_pin2track_map& opin2track_map,
|
||||||
const t_track2track_map& track2track_map,
|
const t_track2track_map& track2track_map,
|
||||||
const vtr::vector<RRNodeId, RRSwitchId> rr_node_driver_switches) {
|
const vtr::vector<RRNodeId, RRSwitchId>& rr_node_driver_switches) {
|
||||||
|
|
||||||
/* Walk through each sides */
|
/* Walk through each sides */
|
||||||
for (size_t side = 0; side < rr_gsb.get_num_sides(); ++side) {
|
for (size_t side = 0; side < rr_gsb.get_num_sides(); ++side) {
|
||||||
|
|
|
@ -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,
|
RRGSB build_one_tileable_rr_gsb(const DeviceGrid& grids,
|
||||||
const RRGraph& rr_graph,
|
const RRGraph& rr_graph,
|
||||||
const std::vector<size_t>& device_chan_width,
|
const vtr::Point<size_t>& device_chan_width,
|
||||||
const std::vector<t_segment_inf>& segment_inf,
|
const std::vector<t_segment_inf>& segment_inf,
|
||||||
const vtr::Point<size_t>& gsb_coordinate);
|
const vtr::Point<size_t>& 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_track2pin_map& track2ipin_map,
|
||||||
const t_pin2track_map& opin2track_map,
|
const t_pin2track_map& opin2track_map,
|
||||||
const t_track2track_map& track2track_map,
|
const t_track2track_map& track2track_map,
|
||||||
const vtr::vector<RRNodeId, RRSwitchId> rr_node_driver_switches);
|
const vtr::vector<RRNodeId, RRSwitchId>& rr_node_driver_switches);
|
||||||
|
|
||||||
t_track2pin_map build_gsb_track_to_ipin_map(const RRGraph& rr_graph,
|
t_track2pin_map build_gsb_track_to_ipin_map(const RRGraph& rr_graph,
|
||||||
const RRGSB& rr_gsb,
|
const RRGSB& rr_gsb,
|
||||||
|
|
Loading…
Reference in New Issue