adapt rr_graph builder utilized functions and move rr_graph utils from openfpga to vpr
This commit is contained in:
parent
524798799c
commit
4b7d2221d1
|
@ -5,6 +5,9 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include "chan_node_details.h"
|
#include "chan_node_details.h"
|
||||||
|
|
||||||
|
/* begin namespace openfpga */
|
||||||
|
namespace openfpga {
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Constructors
|
* Constructors
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
@ -290,3 +293,4 @@ bool ChanNodeDetails::validate_track_id(const size_t& track_id) const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} /* end namespace openfpga */
|
||||||
|
|
|
@ -1,3 +1,12 @@
|
||||||
|
#ifndef CHAN_NODE_DETAILS_H
|
||||||
|
#define CHAN_NODE_DETAILS_H
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* Include header files that are required by function declaration
|
||||||
|
*******************************************************************/
|
||||||
|
#include <vector>
|
||||||
|
#include "vpr_types.h"
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* This file contains a class to model the details of routing node
|
* This file contains a class to model the details of routing node
|
||||||
* in a channel:
|
* in a channel:
|
||||||
|
@ -7,22 +16,8 @@
|
||||||
* 4. potentail track_id(ptc_num) of each segment
|
* 4. potentail track_id(ptc_num) of each segment
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
||||||
/* IMPORTANT:
|
/* begin namespace openfpga */
|
||||||
* The following preprocessing flags are added to
|
namespace openfpga {
|
||||||
* avoid compilation error when this headers are included in more than 1 times
|
|
||||||
*/
|
|
||||||
#ifndef CHAN_NODE_DETAILS_H
|
|
||||||
#define CHAN_NODE_DETAILS_H
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Notes in include header files in a head file
|
|
||||||
* Only include the neccessary header files
|
|
||||||
* that is required by the data types in the function/class declarations!
|
|
||||||
*/
|
|
||||||
/* Header files should be included in a sequence */
|
|
||||||
/* Standard header files required go first */
|
|
||||||
#include <vector>
|
|
||||||
#include "vpr_types.h"
|
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* ChanNodeDetails records segment length, directionality and starting of routing tracks
|
* ChanNodeDetails records segment length, directionality and starting of routing tracks
|
||||||
|
@ -33,7 +28,6 @@
|
||||||
* +---------------------------------+
|
* +---------------------------------+
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
class ChanNodeDetails {
|
class ChanNodeDetails {
|
||||||
public : /* Constructor */
|
public : /* Constructor */
|
||||||
ChanNodeDetails(const ChanNodeDetails&); /* Duplication */
|
ChanNodeDetails(const ChanNodeDetails&); /* Duplication */
|
||||||
|
@ -76,5 +70,6 @@ class ChanNodeDetails {
|
||||||
std::vector<bool> track_end_; /* flag to identify if this is the ending point of the track */
|
std::vector<bool> track_end_; /* flag to identify if this is the ending point of the track */
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
} /* end namespace openfpga */
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,289 @@
|
||||||
|
/************************************************************************
|
||||||
|
* This file contains most utilized functions for rr_graph builders
|
||||||
|
***********************************************************************/
|
||||||
|
#include <vector>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
/* Headers from vtrutil library */
|
||||||
|
#include "vtr_assert.h"
|
||||||
|
#include "vtr_log.h"
|
||||||
|
|
||||||
|
#include "vpr_utils.h"
|
||||||
|
|
||||||
|
#include "rr_graph_builder_utils.h"
|
||||||
|
|
||||||
|
/* begin namespace openfpga */
|
||||||
|
namespace openfpga {
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
* Get the class index of a grid pin
|
||||||
|
***********************************************************************/
|
||||||
|
int get_grid_pin_class_index(const t_grid_tile& cur_grid,
|
||||||
|
const int pin_index) {
|
||||||
|
/* check */
|
||||||
|
VTR_ASSERT(pin_index < cur_grid.type->num_pins);
|
||||||
|
return cur_grid.type->pin_class[pin_index];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Deteremine the side of a io grid */
|
||||||
|
e_side determine_io_grid_pin_side(const vtr::Point<size_t>& device_size,
|
||||||
|
const vtr::Point<size_t>& grid_coordinate) {
|
||||||
|
/* TOP side IO of FPGA */
|
||||||
|
if (device_size.y() == grid_coordinate.y()) {
|
||||||
|
return BOTTOM; /* Such I/O has only Bottom side pins */
|
||||||
|
} else if (device_size.x() == grid_coordinate.x()) { /* RIGHT side IO of FPGA */
|
||||||
|
return LEFT; /* Such I/O has only Left side pins */
|
||||||
|
} else if (0 == grid_coordinate.y()) { /* BOTTOM side IO of FPGA */
|
||||||
|
return TOP; /* Such I/O has only Top side pins */
|
||||||
|
} else if (0 == grid_coordinate.x()) { /* LEFT side IO of FPGA */
|
||||||
|
return RIGHT; /* Such I/O has only Right side pins */
|
||||||
|
} else {
|
||||||
|
VTR_LOGF_ERROR(__FILE__, __LINE__,
|
||||||
|
"I/O Grid is in the center part of FPGA! Currently unsupported!\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
* Get a list of pin_index for a grid (either OPIN or IPIN)
|
||||||
|
* For IO_TYPE, only one side will be used, we consider one side of pins
|
||||||
|
* For others, we consider all the sides
|
||||||
|
***********************************************************************/
|
||||||
|
std::vector<int> get_grid_side_pins(const t_grid_tile& cur_grid,
|
||||||
|
const e_pin_type& pin_type,
|
||||||
|
const e_side& pin_side,
|
||||||
|
const int& pin_width,
|
||||||
|
const int& pin_height) {
|
||||||
|
std::vector<int> pin_list;
|
||||||
|
/* Make sure a clear start */
|
||||||
|
pin_list.clear();
|
||||||
|
|
||||||
|
for (int ipin = 0; ipin < cur_grid.type->num_pins; ++ipin) {
|
||||||
|
int class_id = cur_grid.type->pin_class[ipin];
|
||||||
|
if ( (1 == cur_grid.type->pinloc[pin_width][pin_height][pin_side][ipin])
|
||||||
|
&& (pin_type == cur_grid.type->class_inf[class_id].type) ) {
|
||||||
|
pin_list.push_back(ipin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return pin_list;
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
* Get the number of pins for a grid (either OPIN or IPIN)
|
||||||
|
* For IO_TYPE, only one side will be used, we consider one side of pins
|
||||||
|
* For others, we consider all the sides
|
||||||
|
***********************************************************************/
|
||||||
|
size_t get_grid_num_pins(const t_grid_tile& cur_grid,
|
||||||
|
const e_pin_type& pin_type,
|
||||||
|
const e_side& io_side) {
|
||||||
|
size_t num_pins = 0;
|
||||||
|
|
||||||
|
/* For IO_TYPE sides */
|
||||||
|
for (const e_side& side : {TOP, RIGHT, BOTTOM, LEFT}) {
|
||||||
|
/* skip unwanted sides */
|
||||||
|
if ( (true == is_io_type(cur_grid.type))
|
||||||
|
&& (side != io_side) ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* Get pin list */
|
||||||
|
for (int width = 0; width < cur_grid.type->width; ++width) {
|
||||||
|
for (int height = 0; height < cur_grid.type->height; ++height) {
|
||||||
|
std::vector<int> pin_list = get_grid_side_pins(cur_grid, pin_type, side, width, height);
|
||||||
|
num_pins += pin_list.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return num_pins;
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
* Get the number of pins for a grid (either OPIN or IPIN)
|
||||||
|
* For IO_TYPE, only one side will be used, we consider one side of pins
|
||||||
|
* For others, we consider all the sides
|
||||||
|
***********************************************************************/
|
||||||
|
size_t get_grid_num_classes(const t_grid_tile& cur_grid,
|
||||||
|
const e_pin_type& pin_type) {
|
||||||
|
size_t num_classes = 0;
|
||||||
|
|
||||||
|
for (int iclass = 0; iclass < cur_grid.type->num_class; ++iclass) {
|
||||||
|
/* Bypass unmatched pin_type */
|
||||||
|
if (pin_type != cur_grid.type->class_inf[iclass].type) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
num_classes++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return num_classes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
* Get the track_id of a routing track w.r.t its coordinator
|
||||||
|
* In tileable routing architecture, the track_id changes SB by SB.
|
||||||
|
* Therefore the track_ids are stored in a vector, indexed by the relative coordinator
|
||||||
|
* based on the starting point of the track
|
||||||
|
* For routing tracks in INC_DIRECTION
|
||||||
|
* (xlow, ylow) should be the starting point
|
||||||
|
*
|
||||||
|
* (xlow, ylow) (xhigh, yhigh)
|
||||||
|
* track_id[0] -------------------------------> track_id[xhigh - xlow + yhigh - ylow]
|
||||||
|
*
|
||||||
|
* For routing tracks in DEC_DIRECTION
|
||||||
|
* (xhigh, yhigh) should be the starting point
|
||||||
|
*
|
||||||
|
* (xlow, ylow) (xhigh, yhigh)
|
||||||
|
* track_id[0] <------------------------------- track_id[xhigh - xlow + yhigh - ylow]
|
||||||
|
*
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
short get_rr_node_actual_track_id(const RRGraph& rr_graph,
|
||||||
|
const RRNodeId& track_rr_node,
|
||||||
|
const vtr::Point<size_t>& coord,
|
||||||
|
const vtr::vector<RRNodeId, std::vector<size_t>>& tileable_rr_graph_node_track_ids) {
|
||||||
|
vtr::Point<size_t> low_coord(rr_graph.node_xlow(track_rr_node), rr_graph.node_ylow(track_rr_node));
|
||||||
|
size_t offset = (int)abs((int)coord.x() - (int)low_coord.x() + (int)coord.y() - (int)low_coord.y());
|
||||||
|
return tileable_rr_graph_node_track_ids[track_rr_node][offset];
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
* Get the ptc of a routing track in the channel where it ends
|
||||||
|
* For routing tracks in INC_DIRECTION
|
||||||
|
* the ptc is the last of track_ids
|
||||||
|
*
|
||||||
|
* For routing tracks in DEC_DIRECTION
|
||||||
|
* the ptc is the first of track_ids
|
||||||
|
***********************************************************************/
|
||||||
|
short get_track_rr_node_end_track_id(const RRGraph& rr_graph,
|
||||||
|
const RRNodeId& track_rr_node,
|
||||||
|
const vtr::vector<RRNodeId, std::vector<size_t>>& tileable_rr_graph_node_track_ids) {
|
||||||
|
/* Make sure we have CHANX or CHANY */
|
||||||
|
VTR_ASSERT( (CHANX == rr_graph.node_type(track_rr_node))
|
||||||
|
|| (CHANY == rr_graph.node_type(track_rr_node)) );
|
||||||
|
|
||||||
|
if (INC_DIRECTION == rr_graph.node_direction(track_rr_node)) {
|
||||||
|
return tileable_rr_graph_node_track_ids[track_rr_node].back();
|
||||||
|
}
|
||||||
|
|
||||||
|
VTR_ASSERT(DEC_DIRECTION == rr_graph.node_direction(track_rr_node));
|
||||||
|
return tileable_rr_graph_node_track_ids[track_rr_node].front();
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
* Find the number of nodes in the same class
|
||||||
|
* in a routing resource graph
|
||||||
|
************************************************************************/
|
||||||
|
short find_rr_graph_num_nodes(const RRGraph& rr_graph,
|
||||||
|
const std::vector<t_rr_type>& node_types) {
|
||||||
|
short counter = 0;
|
||||||
|
|
||||||
|
for (const RRNodeId& node : rr_graph.nodes()) {
|
||||||
|
/* Bypass the nodes not in the class */
|
||||||
|
if (node_types.end() == std::find(node_types.begin(), node_types.end(), rr_graph.node_type(node))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
counter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
* Find the maximum fan-in for a given class of nodes
|
||||||
|
* in a routing resource graph
|
||||||
|
************************************************************************/
|
||||||
|
short find_rr_graph_max_fan_in(const RRGraph& rr_graph,
|
||||||
|
const std::vector<t_rr_type>& node_types) {
|
||||||
|
short max_fan_in = 0;
|
||||||
|
|
||||||
|
for (const RRNodeId& node : rr_graph.nodes()) {
|
||||||
|
/* Bypass the nodes not in the class */
|
||||||
|
if (node_types.end() == std::find(node_types.begin(), node_types.end(), rr_graph.node_type(node))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
max_fan_in = std::max(rr_graph.node_fan_in(node), max_fan_in);
|
||||||
|
}
|
||||||
|
|
||||||
|
return max_fan_in;
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
* Find the minimum fan-in for a given class of nodes
|
||||||
|
* in a routing resource graph
|
||||||
|
************************************************************************/
|
||||||
|
short find_rr_graph_min_fan_in(const RRGraph& rr_graph,
|
||||||
|
const std::vector<t_rr_type>& node_types) {
|
||||||
|
short min_fan_in = 0;
|
||||||
|
|
||||||
|
for (const RRNodeId& node : rr_graph.nodes()) {
|
||||||
|
/* Bypass the nodes not in the class */
|
||||||
|
if (node_types.end() == std::find(node_types.begin(), node_types.end(), rr_graph.node_type(node))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
min_fan_in = std::min(rr_graph.node_fan_in(node), min_fan_in);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return min_fan_in;
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
* Find the average fan-in for a given class of nodes
|
||||||
|
* in a routing resource graph
|
||||||
|
************************************************************************/
|
||||||
|
short find_rr_graph_average_fan_in(const RRGraph& rr_graph,
|
||||||
|
const std::vector<t_rr_type>& node_types) {
|
||||||
|
/* Get the maximum SB mux size */
|
||||||
|
size_t sum = 0;
|
||||||
|
size_t counter = 0;
|
||||||
|
|
||||||
|
for (const RRNodeId& node : rr_graph.nodes()) {
|
||||||
|
/* Bypass the nodes not in the class */
|
||||||
|
if (node_types.end() == std::find(node_types.begin(), node_types.end(), rr_graph.node_type(node))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
sum += rr_graph.node_fan_in(node);
|
||||||
|
counter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sum / counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
* Print statistics of multiplexers in a routing resource graph
|
||||||
|
************************************************************************/
|
||||||
|
void print_rr_graph_mux_stats(const RRGraph& rr_graph) {
|
||||||
|
|
||||||
|
/* Print MUX size distribution */
|
||||||
|
std::vector<t_rr_type> sb_node_types;
|
||||||
|
sb_node_types.push_back(CHANX);
|
||||||
|
sb_node_types.push_back(CHANY);
|
||||||
|
|
||||||
|
/* Print statistics */
|
||||||
|
VTR_LOG("------------------------------------------------\n");
|
||||||
|
VTR_LOG("Total No. of Switch Block multiplexer size: %d\n",
|
||||||
|
find_rr_graph_num_nodes(rr_graph, sb_node_types));
|
||||||
|
VTR_LOG("Maximum Switch Block multiplexer size: %d\n",
|
||||||
|
find_rr_graph_max_fan_in(rr_graph, sb_node_types));
|
||||||
|
VTR_LOG("Minimum Switch Block multiplexer size: %d\n",
|
||||||
|
find_rr_graph_min_fan_in(rr_graph, sb_node_types));
|
||||||
|
VTR_LOG("Average Switch Block multiplexer size: %lu\n",
|
||||||
|
find_rr_graph_average_fan_in(rr_graph, sb_node_types));
|
||||||
|
VTR_LOG("------------------------------------------------\n");
|
||||||
|
|
||||||
|
/* Get the maximum CB mux size */
|
||||||
|
std::vector<t_rr_type> cb_node_types(1, IPIN);
|
||||||
|
|
||||||
|
VTR_LOG("------------------------------------------------\n");
|
||||||
|
VTR_LOG("Total No. of Connection Block Multiplexer size: %d\n",
|
||||||
|
find_rr_graph_num_nodes(rr_graph, cb_node_types));
|
||||||
|
VTR_LOG("Maximum Connection Block Multiplexer size: %d\n",
|
||||||
|
find_rr_graph_max_fan_in(rr_graph, cb_node_types));
|
||||||
|
VTR_LOG("Minimum Connection Block Multiplexer size: %d\n",
|
||||||
|
find_rr_graph_min_fan_in(rr_graph, cb_node_types));
|
||||||
|
VTR_LOG("Average Connection Block Multiplexer size: %lu\n",
|
||||||
|
find_rr_graph_average_fan_in(rr_graph, cb_node_types));
|
||||||
|
VTR_LOG("------------------------------------------------\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* end namespace openfpga */
|
|
@ -0,0 +1,69 @@
|
||||||
|
#ifndef RR_GRAPH_BUILDER_UTILS_H
|
||||||
|
#define RR_GRAPH_BUILDER_UTILS_H
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* Include header files that are required by function declaration
|
||||||
|
*******************************************************************/
|
||||||
|
#include "device_grid.h"
|
||||||
|
#include "rr_graph_obj.h"
|
||||||
|
#include "vtr_geometry.h"
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* Function declaration
|
||||||
|
*******************************************************************/
|
||||||
|
|
||||||
|
/* begin namespace openfpga */
|
||||||
|
namespace openfpga {
|
||||||
|
|
||||||
|
int get_grid_pin_class_index(const t_grid_tile& cur_grid,
|
||||||
|
const int pin_index);
|
||||||
|
|
||||||
|
e_side determine_io_grid_pin_side(const vtr::Point<size_t>& device_size,
|
||||||
|
const vtr::Point<size_t>& grid_coordinate);
|
||||||
|
|
||||||
|
std::vector<int> get_grid_side_pins(const t_grid_tile& cur_grid,
|
||||||
|
const e_pin_type& pin_type,
|
||||||
|
const e_side& pin_side,
|
||||||
|
const int& pin_width,
|
||||||
|
const int& pin_height);
|
||||||
|
|
||||||
|
size_t get_grid_num_pins(const t_grid_tile& cur_grid,
|
||||||
|
const e_pin_type& pin_type,
|
||||||
|
const e_side& io_side);
|
||||||
|
|
||||||
|
size_t get_grid_num_classes(const t_grid_tile& cur_grid,
|
||||||
|
const e_pin_type& pin_type);
|
||||||
|
|
||||||
|
short get_rr_node_actual_track_id(const RRGraph& rr_graph,
|
||||||
|
const RRNodeId& track_rr_node,
|
||||||
|
const vtr::Point<size_t>& coord,
|
||||||
|
const vtr::vector<RRNodeId, std::vector<size_t>>& tileable_rr_graph_node_track_ids);
|
||||||
|
|
||||||
|
vtr::Point<size_t> get_track_rr_node_start_coordinator(const RRGraph& rr_graph,
|
||||||
|
const RRNodeId& track_rr_node);
|
||||||
|
|
||||||
|
vtr::Point<size_t> get_track_rr_node_end_coordinator(const RRGraph& rr_graph,
|
||||||
|
const RRNodeId& track_rr_node);
|
||||||
|
|
||||||
|
short get_track_rr_node_end_track_id(const RRGraph& rr_graph,
|
||||||
|
const RRNodeId& track_rr_node,
|
||||||
|
const vtr::vector<RRNodeId, std::vector<size_t>>& tileable_rr_graph_node_track_ids);
|
||||||
|
|
||||||
|
short find_rr_graph_num_nodes(const RRGraph& rr_graph,
|
||||||
|
const std::vector<t_rr_type>& node_types);
|
||||||
|
|
||||||
|
short find_rr_graph_max_fan_in(const RRGraph& rr_graph,
|
||||||
|
const std::vector<t_rr_type>& node_types);
|
||||||
|
|
||||||
|
short find_rr_graph_min_fan_in(const RRGraph& rr_graph,
|
||||||
|
const std::vector<t_rr_type>& node_types);
|
||||||
|
|
||||||
|
short find_rr_graph_average_fan_in(const RRGraph& rr_graph,
|
||||||
|
const std::vector<t_rr_type>& node_types);
|
||||||
|
|
||||||
|
void print_rr_graph_mux_stats(const RRGraph& rr_graph);
|
||||||
|
|
||||||
|
} /* end namespace openfpga */
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue