Merge branch 'refactoring' into dev
This commit is contained in:
commit
3e3a523926
|
@ -1,8 +1,11 @@
|
|||
/************************************************************************
|
||||
* This file contains member functions for class ChanNodeDetails
|
||||
***********************************************************************/
|
||||
#include <cassert>
|
||||
#include <algorithm>
|
||||
|
||||
/* Headers from vtrutil library */
|
||||
#include "vtr_assert.h"
|
||||
|
||||
#include "chan_node_details.h"
|
||||
|
||||
/* begin namespace openfpga */
|
||||
|
@ -33,12 +36,12 @@ ChanNodeDetails::ChanNodeDetails() {
|
|||
* Accessors
|
||||
***********************************************************************/
|
||||
size_t ChanNodeDetails::get_chan_width() const {
|
||||
assert(validate_chan_width());
|
||||
VTR_ASSERT(validate_chan_width());
|
||||
return track_node_ids_.size();
|
||||
}
|
||||
|
||||
size_t ChanNodeDetails::get_track_node_id(const size_t& track_id) const {
|
||||
assert(validate_track_id(track_id));
|
||||
VTR_ASSERT(validate_track_id(track_id));
|
||||
return track_node_ids_[track_id];
|
||||
}
|
||||
|
||||
|
@ -52,27 +55,27 @@ std::vector<size_t> ChanNodeDetails::get_track_node_ids() const {
|
|||
}
|
||||
|
||||
e_direction ChanNodeDetails::get_track_direction(const size_t& track_id) const {
|
||||
assert(validate_track_id(track_id));
|
||||
VTR_ASSERT(validate_track_id(track_id));
|
||||
return track_direction_[track_id];
|
||||
}
|
||||
|
||||
size_t ChanNodeDetails::get_track_segment_length(const size_t& track_id) const {
|
||||
assert(validate_track_id(track_id));
|
||||
VTR_ASSERT(validate_track_id(track_id));
|
||||
return seg_length_[track_id];
|
||||
}
|
||||
|
||||
size_t ChanNodeDetails::get_track_segment_id(const size_t& track_id) const {
|
||||
assert(validate_track_id(track_id));
|
||||
VTR_ASSERT(validate_track_id(track_id));
|
||||
return seg_ids_[track_id];
|
||||
}
|
||||
|
||||
bool ChanNodeDetails::is_track_start(const size_t& track_id) const {
|
||||
assert(validate_track_id(track_id));
|
||||
VTR_ASSERT(validate_track_id(track_id));
|
||||
return track_start_[track_id];
|
||||
}
|
||||
|
||||
bool ChanNodeDetails::is_track_end(const size_t& track_id) const {
|
||||
assert(validate_track_id(track_id));
|
||||
VTR_ASSERT(validate_track_id(track_id));
|
||||
return track_end_[track_id];
|
||||
}
|
||||
|
||||
|
@ -81,9 +84,9 @@ bool ChanNodeDetails::is_track_end(const size_t& track_id) const {
|
|||
* A group size is the number of such nodes between the starting points (include the 1st starting point)
|
||||
*/
|
||||
std::vector<size_t> ChanNodeDetails::get_seg_group(const size_t& track_id) const {
|
||||
assert(validate_chan_width());
|
||||
assert(validate_track_id(track_id));
|
||||
assert(is_track_start(track_id));
|
||||
VTR_ASSERT(validate_chan_width());
|
||||
VTR_ASSERT(validate_track_id(track_id));
|
||||
VTR_ASSERT(is_track_start(track_id));
|
||||
|
||||
std::vector<size_t> group;
|
||||
/* Make sure a clean start */
|
||||
|
@ -115,7 +118,7 @@ std::vector<size_t> ChanNodeDetails::get_seg_group_node_id(const std::vector<siz
|
|||
group.clear();
|
||||
|
||||
for (size_t id = 0; id < seg_group.size(); ++id) {
|
||||
assert(validate_track_id(seg_group[id]));
|
||||
VTR_ASSERT(validate_track_id(seg_group[id]));
|
||||
group.push_back(get_track_node_id(seg_group[id]));
|
||||
}
|
||||
|
||||
|
@ -182,14 +185,14 @@ void ChanNodeDetails::add_track(const size_t& track_node_id, const e_direction&
|
|||
|
||||
/* Update the node_id of a given track */
|
||||
void ChanNodeDetails::set_track_node_id(const size_t& track_index, const size_t& track_node_id) {
|
||||
assert(validate_track_id(track_index));
|
||||
VTR_ASSERT(validate_track_id(track_index));
|
||||
track_node_ids_[track_index] = track_node_id;
|
||||
}
|
||||
|
||||
/* Update the node_ids from a vector */
|
||||
void ChanNodeDetails::set_track_node_ids(const std::vector<size_t>& track_node_ids) {
|
||||
/* the size of vector should match chan_width */
|
||||
assert ( get_chan_width() == track_node_ids.size() );
|
||||
VTR_ASSERT ( get_chan_width() == track_node_ids.size() );
|
||||
for (size_t inode = 0; inode < track_node_ids.size(); ++inode) {
|
||||
track_node_ids_[inode] = track_node_ids[inode];
|
||||
}
|
||||
|
@ -227,7 +230,7 @@ void ChanNodeDetails::rotate_track_node_id(const size_t& offset, const e_directi
|
|||
/* Rotate the node_ids by groups
|
||||
* A group begins from a track_start and ends before another track_start
|
||||
*/
|
||||
assert(validate_chan_width());
|
||||
VTR_ASSERT(validate_chan_width());
|
||||
for (size_t itrack = 0; itrack < get_chan_width(); ++itrack) {
|
||||
/* Bypass non-start segment */
|
||||
if (false == is_track_start(itrack) ) {
|
||||
|
|
|
@ -7,8 +7,14 @@
|
|||
#include "vtr_log.h"
|
||||
#include "vtr_geometry.h"
|
||||
|
||||
/* Headers from openfpgautil library */
|
||||
#include "openfpga_side_manager.h"
|
||||
|
||||
#include "vpr_types.h"
|
||||
#include "vpr_utils.h"
|
||||
|
||||
#include "rr_node.h"
|
||||
|
||||
#include "rr_graph_builder_utils.h"
|
||||
#include "tileable_chan_details_builder.h"
|
||||
#include "tileable_rr_graph_node_builder.h"
|
||||
|
@ -311,10 +317,11 @@ std::vector<size_t> estimate_num_rr_nodes(const DeviceGrid& grids,
|
|||
*
|
||||
* Note: ensure that there are NO nodes in the rr_graph
|
||||
***********************************************************************/
|
||||
void alloc_rr_graph_nodes(RRGraph& rr_graph,
|
||||
const DeviceGrid& grids,
|
||||
const vtr::Point<size_t>& chan_width,
|
||||
const std::vector<t_segment_inf>& segment_infs) {
|
||||
void alloc_tileable_rr_graph_nodes(RRGraph& rr_graph,
|
||||
vtr::vector<RRNodeId, RRSwitchId>& rr_node_driver_switches,
|
||||
const DeviceGrid& grids,
|
||||
const vtr::Point<size_t>& chan_width,
|
||||
const std::vector<t_segment_inf>& segment_infs) {
|
||||
VTR_ASSERT(0 == rr_graph.nodes().size());
|
||||
|
||||
std::vector<size_t> num_rr_nodes_per_type = estimate_num_rr_nodes(grids, chan_width, segment_infs);
|
||||
|
@ -327,14 +334,424 @@ void alloc_rr_graph_nodes(RRGraph& rr_graph,
|
|||
|
||||
rr_graph.reserve_nodes(num_nodes);
|
||||
|
||||
/* Add nodes by types */
|
||||
for (const t_rr_type& node_type : {SOURCE, SINK, IPIN, OPIN, CHANX, CHANY}) {
|
||||
for (size_t inode = 0; inode < num_rr_nodes_per_type[size_t(node_type)]; ++inode) {
|
||||
rr_graph.create_node(node_type);
|
||||
rr_node_driver_switches.reserve(num_nodes);
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Configure OPIN rr_nodes for this grid
|
||||
* coordinates: xlow, ylow, xhigh, yhigh,
|
||||
* features: capacity, ptc_num (pin_num),
|
||||
*
|
||||
* Note: this function should be applied ONLY to grid with 0 width offset and 0 height offset!!!
|
||||
***********************************************************************/
|
||||
static
|
||||
void load_one_grid_opin_nodes_basic_info(RRGraph& rr_graph,
|
||||
vtr::vector<RRNodeId, RRSwitchId>& rr_node_driver_switches,
|
||||
const vtr::Point<size_t>& grid_coordinate,
|
||||
const t_grid_tile& cur_grid,
|
||||
const e_side& io_side,
|
||||
const RRSwitchId& delayless_switch) {
|
||||
SideManager io_side_manager(io_side);
|
||||
|
||||
/* Walk through the width height of each grid,
|
||||
* get pins and configure the rr_nodes
|
||||
*/
|
||||
for (int width = 0; width < cur_grid.type->width; ++width) {
|
||||
for (int height = 0; height < cur_grid.type->height; ++height) {
|
||||
/* Walk through sides */
|
||||
for (size_t side = 0; side < NUM_SIDES; ++side) {
|
||||
SideManager side_manager(side);
|
||||
/* skip unwanted sides */
|
||||
if ( (true == is_io_type(cur_grid.type))
|
||||
&& (side != io_side_manager.to_size_t()) ) {
|
||||
continue;
|
||||
}
|
||||
/* Find OPINs */
|
||||
/* Configure pins by pins */
|
||||
std::vector<int> opin_list = get_grid_side_pins(cur_grid, DRIVER, side_manager.get_side(),
|
||||
width, height);
|
||||
for (const int& pin_num : opin_list) {
|
||||
/* Create a new node and fill information */
|
||||
const RRNodeId& node = rr_graph.create_node(OPIN);
|
||||
|
||||
/* node bounding box */
|
||||
rr_graph.set_node_bounding_box(node, vtr::Rect<short>(grid_coordinate.x() + width,
|
||||
grid_coordinate.x() + width,
|
||||
grid_coordinate.y() + height,
|
||||
grid_coordinate.y() + height));
|
||||
rr_graph.set_node_side(node, side_manager.get_side());
|
||||
rr_graph.set_node_pin_num(node, pin_num);
|
||||
|
||||
rr_graph.set_node_capacity(node, 1);
|
||||
|
||||
/* cost index is a FIXED value for OPIN */
|
||||
rr_graph.set_node_cost_index(node, OPIN_COST_INDEX);
|
||||
|
||||
/* Switch info */
|
||||
VTR_ASSERT(size_t(node) == rr_node_driver_switches.size());
|
||||
rr_node_driver_switches.push_back(delayless_switch);
|
||||
|
||||
/* RC data */
|
||||
rr_graph.set_node_rc_data_index(node, find_create_rr_rc_data(0., 0.));
|
||||
|
||||
} /* End of loading OPIN rr_nodes */
|
||||
} /* End of side enumeration */
|
||||
} /* End of height enumeration */
|
||||
} /* End of width enumeration */
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Configure IPIN rr_nodes for this grid
|
||||
* coordinates: xlow, ylow, xhigh, yhigh,
|
||||
* features: capacity, ptc_num (pin_num),
|
||||
*
|
||||
* Note: this function should be applied ONLY to grid with 0 width offset and 0 height offset!!!
|
||||
***********************************************************************/
|
||||
static
|
||||
void load_one_grid_ipin_nodes_basic_info(RRGraph& rr_graph,
|
||||
vtr::vector<RRNodeId, RRSwitchId>& rr_node_driver_switches,
|
||||
const vtr::Point<size_t>& grid_coordinate,
|
||||
const t_grid_tile& cur_grid,
|
||||
const e_side& io_side,
|
||||
const RRSwitchId& wire_to_ipin_switch) {
|
||||
SideManager io_side_manager(io_side);
|
||||
|
||||
/* Walk through the width and height of each grid,
|
||||
* get pins and configure the rr_nodes
|
||||
*/
|
||||
for (int width = 0; width < cur_grid.type->width; ++width) {
|
||||
for (int height = 0; height < cur_grid.type->height; ++height) {
|
||||
/* Walk through sides */
|
||||
for (size_t side = 0; side < NUM_SIDES; ++side) {
|
||||
SideManager side_manager(side);
|
||||
/* skip unwanted sides */
|
||||
if ( (true == is_io_type(cur_grid.type))
|
||||
&& (side != io_side_manager.to_size_t()) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Find IPINs */
|
||||
/* Configure pins by pins */
|
||||
std::vector<int> ipin_list = get_grid_side_pins(cur_grid, RECEIVER, side_manager.get_side(), width, height);
|
||||
for (const int& pin_num : ipin_list) {
|
||||
/* Create a new node and fill information */
|
||||
const RRNodeId& node = rr_graph.create_node(IPIN);
|
||||
|
||||
/* node bounding box */
|
||||
rr_graph.set_node_bounding_box(node, vtr::Rect<short>(grid_coordinate.x() + width,
|
||||
grid_coordinate.x() + width,
|
||||
grid_coordinate.y() + height,
|
||||
grid_coordinate.y() + height));
|
||||
rr_graph.set_node_side(node, side_manager.get_side());
|
||||
rr_graph.set_node_pin_num(node, pin_num);
|
||||
|
||||
rr_graph.set_node_capacity(node, 1);
|
||||
|
||||
/* cost index is a FIXED value for OPIN */
|
||||
rr_graph.set_node_cost_index(node, IPIN_COST_INDEX);
|
||||
|
||||
/* Switch info */
|
||||
VTR_ASSERT(size_t(node) == rr_node_driver_switches.size());
|
||||
rr_node_driver_switches.push_back(wire_to_ipin_switch);
|
||||
|
||||
/* RC data */
|
||||
rr_graph.set_node_rc_data_index(node, find_create_rr_rc_data(0., 0.));
|
||||
|
||||
} /* End of loading IPIN rr_nodes */
|
||||
} /* End of side enumeration */
|
||||
} /* End of height enumeration */
|
||||
} /* End of width enumeration */
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Configure SOURCE rr_nodes for this grid
|
||||
* coordinates: xlow, ylow, xhigh, yhigh,
|
||||
* features: capacity, ptc_num (pin_num),
|
||||
*
|
||||
* Note: this function should be applied ONLY to grid with 0 width offset and 0 height offset!!!
|
||||
***********************************************************************/
|
||||
static
|
||||
void load_one_grid_source_nodes_basic_info(RRGraph& rr_graph,
|
||||
vtr::vector<RRNodeId, RRSwitchId>& rr_node_driver_switches,
|
||||
const vtr::Point<size_t>& grid_coordinate,
|
||||
const t_grid_tile& cur_grid,
|
||||
const e_side& io_side,
|
||||
const RRSwitchId& delayless_switch) {
|
||||
SideManager io_side_manager(io_side);
|
||||
|
||||
/* Set a SOURCE rr_node for each DRIVER class */
|
||||
for (int iclass = 0; iclass < cur_grid.type->num_class; ++iclass) {
|
||||
/* Set a SINK rr_node for the OPIN */
|
||||
if (DRIVER != cur_grid.type->class_inf[iclass].type) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Create a new node and fill information */
|
||||
const RRNodeId& node = rr_graph.create_node(SOURCE);
|
||||
|
||||
/* node bounding box */
|
||||
rr_graph.set_node_bounding_box(node, vtr::Rect<short>(grid_coordinate.x(),
|
||||
grid_coordinate.x(),
|
||||
grid_coordinate.y(),
|
||||
grid_coordinate.y()));
|
||||
rr_graph.set_node_class_num(node, iclass);
|
||||
|
||||
rr_graph.set_node_capacity(node, 1);
|
||||
|
||||
/* The capacity should be the number of pins in this class*/
|
||||
rr_graph.set_node_capacity(node, cur_grid.type->class_inf[iclass].num_pins);
|
||||
|
||||
/* cost index is a FIXED value for SOURCE */
|
||||
rr_graph.set_node_cost_index(node, SOURCE_COST_INDEX);
|
||||
|
||||
/* Switch info */
|
||||
VTR_ASSERT(size_t(node) == rr_node_driver_switches.size());
|
||||
rr_node_driver_switches.push_back(delayless_switch);
|
||||
|
||||
/* RC data */
|
||||
rr_graph.set_node_rc_data_index(node, find_create_rr_rc_data(0., 0.));
|
||||
|
||||
} /* End of class enumeration */
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Configure SINK rr_nodes for this grid
|
||||
* coordinates: xlow, ylow, xhigh, yhigh,
|
||||
* features: capacity, ptc_num (pin_num),
|
||||
*
|
||||
* Note: this function should be applied ONLY to grid with 0 width offset and 0 height offset!!!
|
||||
***********************************************************************/
|
||||
static
|
||||
void load_one_grid_sink_nodes_basic_info(RRGraph& rr_graph,
|
||||
vtr::vector<RRNodeId, RRSwitchId>& rr_node_driver_switches,
|
||||
const vtr::Point<size_t>& grid_coordinate,
|
||||
const t_grid_tile& cur_grid,
|
||||
const e_side& io_side,
|
||||
const RRSwitchId& delayless_switch) {
|
||||
SideManager io_side_manager(io_side);
|
||||
|
||||
/* Set a SINK rr_node for each RECEIVER class */
|
||||
for (int iclass = 0; iclass < cur_grid.type->num_class; ++iclass) {
|
||||
/* Set a SINK rr_node for the OPIN */
|
||||
if (RECEIVER != cur_grid.type->class_inf[iclass].type) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Create a new node and fill information */
|
||||
const RRNodeId& node = rr_graph.create_node(SINK);
|
||||
|
||||
/* node bounding box */
|
||||
rr_graph.set_node_bounding_box(node, vtr::Rect<short>(grid_coordinate.x(),
|
||||
grid_coordinate.x(),
|
||||
grid_coordinate.y(),
|
||||
grid_coordinate.y()));
|
||||
rr_graph.set_node_class_num(node, iclass);
|
||||
|
||||
rr_graph.set_node_capacity(node, 1);
|
||||
|
||||
/* The capacity should be the number of pins in this class*/
|
||||
rr_graph.set_node_capacity(node, cur_grid.type->class_inf[iclass].num_pins);
|
||||
|
||||
/* cost index is a FIXED value for SINK */
|
||||
rr_graph.set_node_cost_index(node, SINK_COST_INDEX);
|
||||
|
||||
/* Switch info */
|
||||
VTR_ASSERT(size_t(node) == rr_node_driver_switches.size());
|
||||
rr_node_driver_switches.push_back(delayless_switch);
|
||||
|
||||
/* RC data */
|
||||
rr_graph.set_node_rc_data_index(node, find_create_rr_rc_data(0., 0.));
|
||||
|
||||
} /* End of class enumeration */
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Create all the rr_nodes for grids
|
||||
***********************************************************************/
|
||||
static
|
||||
void load_grid_nodes_basic_info(RRGraph& rr_graph,
|
||||
vtr::vector<RRNodeId, RRSwitchId>& rr_node_driver_switches,
|
||||
const DeviceGrid& grids,
|
||||
const RRSwitchId& wire_to_ipin_switch,
|
||||
const RRSwitchId& delayless_switch) {
|
||||
|
||||
for (size_t iy = 0; iy < grids.height(); ++iy) {
|
||||
for (size_t ix = 0; ix < grids.width(); ++ix) {
|
||||
/* Skip EMPTY tiles */
|
||||
if (true == is_empty_type(grids[ix][iy].type)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* We only build rr_nodes for grids with width_offset = 0 and height_offset = 0 */
|
||||
if ( (0 < grids[ix][iy].width_offset)
|
||||
|| (0 < grids[ix][iy].height_offset) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
vtr::Point<size_t> grid_coordinate(ix, iy);
|
||||
enum e_side io_side = NUM_SIDES;
|
||||
|
||||
/* If this is the block on borders, we consider IO side */
|
||||
if (true == is_io_type(grids[ix][iy].type)) {
|
||||
vtr::Point<size_t> io_device_size(grids.width() - 1, grids.height() - 1);
|
||||
io_side = determine_io_grid_pin_side(io_device_size, grid_coordinate);
|
||||
}
|
||||
|
||||
/* Configure source rr_nodes for this grid */
|
||||
load_one_grid_source_nodes_basic_info(rr_graph,
|
||||
rr_node_driver_switches,
|
||||
grid_coordinate,
|
||||
grids[ix][iy],
|
||||
io_side,
|
||||
delayless_switch);
|
||||
|
||||
/* Configure sink rr_nodes for this grid */
|
||||
load_one_grid_sink_nodes_basic_info(rr_graph,
|
||||
rr_node_driver_switches,
|
||||
grid_coordinate,
|
||||
grids[ix][iy],
|
||||
io_side,
|
||||
delayless_switch);
|
||||
|
||||
/* Configure opin rr_nodes for this grid */
|
||||
load_one_grid_opin_nodes_basic_info(rr_graph,
|
||||
rr_node_driver_switches,
|
||||
grid_coordinate,
|
||||
grids[ix][iy],
|
||||
io_side,
|
||||
delayless_switch);
|
||||
|
||||
/* Configure ipin rr_nodes for this grid */
|
||||
load_one_grid_ipin_nodes_basic_info(rr_graph,
|
||||
rr_node_driver_switches,
|
||||
grid_coordinate,
|
||||
grids[ix][iy],
|
||||
io_side,
|
||||
wire_to_ipin_switch);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Initialize the basic information of routing track rr_nodes
|
||||
* coordinates: xlow, ylow, xhigh, yhigh,
|
||||
* features: capacity, track_ids, ptc_num, direction
|
||||
***********************************************************************/
|
||||
static
|
||||
void load_one_chan_rr_nodes_basic_info(RRGraph& rr_graph,
|
||||
vtr::vector<RRNodeId, RRSwitchId>& rr_node_driver_switches,
|
||||
std::map<RRNodeId, std::vector<size_t>>& rr_node_track_ids,
|
||||
const vtr::Point<size_t>& chan_coordinate,
|
||||
const t_rr_type& chan_type,
|
||||
ChanNodeDetails& chan_details,
|
||||
const std::vector<t_segment_inf>& segment_infs,
|
||||
const int& cost_index_offset) {
|
||||
/* Check each node_id(potential ptc_num) in the channel :
|
||||
* If this is a starting point, we set a new rr_node with xlow/ylow, ptc_num
|
||||
* If this is a ending point, we set xhigh/yhigh and track_ids
|
||||
* For other nodes, we set changes in track_ids
|
||||
*/
|
||||
for (size_t itrack = 0; itrack < chan_details.get_chan_width(); ++itrack) {
|
||||
/* For INC direction, a starting point requires a new chan rr_node */
|
||||
if ( ( (true == chan_details.is_track_start(itrack))
|
||||
&& (INC_DIRECTION == chan_details.get_track_direction(itrack)) )
|
||||
/* For DEC direction, an ending point requires a new chan rr_node */
|
||||
||
|
||||
( (true == chan_details.is_track_end(itrack))
|
||||
&& (DEC_DIRECTION == chan_details.get_track_direction(itrack)) ) ) {
|
||||
|
||||
/* Create a new chan rr_node */
|
||||
const RRNodeId& node = rr_graph.create_node(chan_type);
|
||||
|
||||
rr_graph.set_node_xlow(node, chan_coordinate.x());
|
||||
rr_graph.set_node_ylow(node, chan_coordinate.y());
|
||||
|
||||
rr_graph.set_node_direction(node, chan_details.get_track_direction(itrack));
|
||||
rr_graph.set_node_track_num(node, itrack);
|
||||
rr_node_track_ids[node].push_back(itrack);
|
||||
|
||||
rr_graph.set_node_capacity(node, 1);
|
||||
|
||||
/* assign switch id */
|
||||
size_t seg_id = chan_details.get_track_segment_id(itrack);
|
||||
VTR_ASSERT(size_t(node) == rr_node_driver_switches.size());
|
||||
rr_node_driver_switches.push_back(RRSwitchId(segment_infs[seg_id].arch_opin_switch));
|
||||
|
||||
/* Update chan_details with node_id */
|
||||
chan_details.set_track_node_id(itrack, size_t(node));
|
||||
|
||||
/* cost index depends on the segment index */
|
||||
rr_graph.set_node_cost_index(node, cost_index_offset + seg_id);
|
||||
/* Finish here, go to next */
|
||||
}
|
||||
|
||||
/* For INC direction, an ending point requires an update on xhigh and yhigh */
|
||||
if ( ( (true == chan_details.is_track_end(itrack))
|
||||
&& (INC_DIRECTION == chan_details.get_track_direction(itrack)) )
|
||||
||
|
||||
/* For DEC direction, an starting point requires an update on xlow and ylow */
|
||||
( (true == chan_details.is_track_start(itrack))
|
||||
&& (DEC_DIRECTION == chan_details.get_track_direction(itrack)) ) ) {
|
||||
|
||||
/* Get the node_id */
|
||||
const RRNodeId& rr_node_id = RRNodeId(chan_details.get_track_node_id(itrack));
|
||||
|
||||
/* Do a quick check, make sure we do not mistakenly modify other nodes */
|
||||
VTR_ASSERT(chan_type == rr_graph.node_type(rr_node_id));
|
||||
VTR_ASSERT(chan_details.get_track_direction(itrack) == rr_graph.node_direction(rr_node_id));
|
||||
|
||||
/* set xhigh/yhigh and push changes to track_ids */
|
||||
rr_graph.set_node_xhigh(rr_node_id, chan_coordinate.x());
|
||||
rr_graph.set_node_yhigh(rr_node_id, chan_coordinate.y());
|
||||
|
||||
/* Do not update track_ids for length-1 wires, they should have only 1 track_id */
|
||||
if ( (rr_graph.node_xhigh(rr_node_id) > rr_graph.node_xlow(rr_node_id))
|
||||
|| (rr_graph.node_yhigh(rr_node_id) > rr_graph.node_ylow(rr_node_id)) ) {
|
||||
rr_node_track_ids[rr_node_id].push_back(itrack);
|
||||
}
|
||||
/* Finish here, go to next */
|
||||
}
|
||||
|
||||
/* Finish processing starting and ending tracks */
|
||||
if ( (true == chan_details.is_track_start(itrack))
|
||||
|| (true == chan_details.is_track_end(itrack)) ) {
|
||||
/* Finish here, go to next */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* For other nodes, we get the node_id and just update track_ids */
|
||||
/* Ensure those nodes are neither starting nor ending points */
|
||||
VTR_ASSERT( (false == chan_details.is_track_start(itrack))
|
||||
&& (false == chan_details.is_track_end(itrack)) );
|
||||
|
||||
/* Get the node_id */
|
||||
const RRNodeId& rr_node_id = RRNodeId(chan_details.get_track_node_id(itrack));
|
||||
|
||||
/* Do a quick check, make sure we do not mistakenly modify other nodes */
|
||||
VTR_ASSERT(chan_type == rr_graph.node_type(rr_node_id));
|
||||
VTR_ASSERT(chan_details.get_track_direction(itrack) == rr_graph.node_direction(rr_node_id));
|
||||
|
||||
/* Update track_ids */
|
||||
rr_node_track_ids[rr_node_id].push_back(itrack);
|
||||
/* Finish here, go to next */
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Create all the rr_nodes covering both grids and routing channels
|
||||
***********************************************************************/
|
||||
void create_tileable_rr_graph_nodes(RRGraph& rr_graph,
|
||||
vtr::vector<RRNodeId, RRSwitchId>& rr_node_driver_switches,
|
||||
const DeviceGrid& grids,
|
||||
const RRSwitchId& wire_to_ipin_switch,
|
||||
const RRSwitchId& delayless_switch) {
|
||||
load_grid_nodes_basic_info(rr_graph,
|
||||
rr_node_driver_switches,
|
||||
grids,
|
||||
wire_to_ipin_switch,
|
||||
delayless_switch);
|
||||
|
||||
VTR_ASSERT(num_nodes == rr_graph.nodes().size());
|
||||
}
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
|
|
@ -21,10 +21,17 @@
|
|||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
void alloc_rr_graph_nodes(RRGraph& rr_graph,
|
||||
const DeviceGrid& grids,
|
||||
const vtr::Point<size_t>& chan_width,
|
||||
const std::vector<t_segment_inf>& segment_infs);
|
||||
void alloc_tileable_rr_graph_nodes(RRGraph& rr_graph,
|
||||
vtr::vector<RRNodeId, RRSwitchId>& driver_switches,
|
||||
const DeviceGrid& grids,
|
||||
const vtr::Point<size_t>& chan_width,
|
||||
const std::vector<t_segment_inf>& segment_infs);
|
||||
|
||||
void create_tileable_rr_graph_nodes(RRGraph& rr_graph,
|
||||
vtr::vector<RRNodeId, RRSwitchId>& rr_node_driver_switches,
|
||||
const DeviceGrid& grids,
|
||||
const RRSwitchId& wire_to_ipin_switch,
|
||||
const RRSwitchId& delayless_switch);
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
||||
|
|
Loading…
Reference in New Issue