Skip to content

Commit

Permalink
Merge pull request #2264 from verilog-to-routing/place_3d
Browse files Browse the repository at this point in the history
Place 3d
  • Loading branch information
vaughnbetz committed Jun 29, 2023
2 parents 203029e + 13e219b commit 83dc3c4
Show file tree
Hide file tree
Showing 127 changed files with 4,233 additions and 2,822 deletions.
24 changes: 15 additions & 9 deletions libs/libarchfpga/src/device_grid.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class DeviceGrid {
* @brief Return the number of instances of the specified tile type on the specified layer. If the layer_num is -1, return the total number of instances of the specified tile type on all layers.
* @note This function should be used if count_instances() is called in the constructor.
*/
size_t num_instances(t_physical_tile_type_ptr type, int layer_num = 0) const;
size_t num_instances(t_physical_tile_type_ptr type, int layer_num) const;

/**
* @brief Returns the block types which limits the device size (may be empty if
Expand All @@ -59,23 +59,23 @@ class DeviceGrid {
std::vector<t_logical_block_type_ptr> limiting_resources() const { return limiting_resources_; }

///@brief Return the t_physical_tile_type_ptr at the specified location
inline t_physical_tile_type_ptr get_physical_type(size_t x, size_t y, int layer_num = 0) const {
return grid_[layer_num][x][y].type;
inline t_physical_tile_type_ptr get_physical_type(const t_physical_tile_loc& tile_loc) const {
return grid_[tile_loc.layer_num][tile_loc.x][tile_loc.y].type;
}

///@brief Return the width offset of the tile at the specified location. The root location of the tile is where width_offset and height_offset are 0.
inline int get_width_offset(size_t x, size_t y, int layer_num = 0) const {
return grid_[layer_num][x][y].width_offset;
inline int get_width_offset(const t_physical_tile_loc& tile_loc) const {
return grid_[tile_loc.layer_num][tile_loc.x][tile_loc.y].width_offset;
}

///@brief Return the height offset of the tile at the specified location. The root location of the tile is where width_offset and height_offset are 0
inline int get_height_offset(size_t x, size_t y, int layer_num = 0) const {
return grid_[layer_num][x][y].height_offset;
inline int get_height_offset(const t_physical_tile_loc& tile_loc) const {
return grid_[tile_loc.layer_num][tile_loc.x][tile_loc.y].height_offset;
}

///@brief Return the metadata of the tile at the specified location
inline const t_metadata_dict* get_metadata(size_t x, size_t y, int layer_num = 0) const {
return grid_[layer_num][x][y].meta;
inline const t_metadata_dict* get_metadata(const t_physical_tile_loc& tile_loc) const {
return grid_[tile_loc.layer_num][tile_loc.x][tile_loc.y].meta;
}

///@brief Given t_grid_tile, return the x coordinate of the tile on the given layer - Used by serializer functions
Expand All @@ -94,6 +94,12 @@ class DeviceGrid {
return diff % grid_.dim_size(2);
}

///@brief Given t_grid_tile, return the layer number of the tile - Used by serializer functions
inline int get_grid_loc_layer(const t_grid_tile*& grid_loc) const {
int layer_num = std::floor(static_cast<int>(grid_loc - &grid_.get(0)) / (width() * height()));
return layer_num;
}

///@brief Return the nth t_grid_tile on the given layer of the flattened grid - Used by serializer functions
inline const t_grid_tile* get_grid_locs_grid_loc(int n) const {
return &grid_.get(n);
Expand Down
25 changes: 25 additions & 0 deletions libs/libarchfpga/src/physical_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -814,6 +814,31 @@ struct t_physical_pin {
}
};

/**
* @brief Describes The location of a physical tile
* @param layer_num The die number of the physical tile. If the FPGA only has one die, or the physical tile is located
* on the base die, layer_num is equal to zero. If it is one the die above base die, it is one, etc.
* @param x The x location of the physical tile on the given die
* @param y The y location of the physical tile on the given die
*/
struct t_physical_tile_loc {
int x = OPEN;
int y = OPEN;
int layer_num = OPEN;

t_physical_tile_loc() = default;

t_physical_tile_loc(int x_val, int y_val, int layer_num_val)
: x(x_val)
, y(y_val)
, layer_num(layer_num_val) {}

// Returns true if this type location layer_num/x/y is not equal to OPEN
operator bool() const {
return !(x == OPEN || y == OPEN || layer_num == OPEN);
}
};

/** Describes I/O and clock ports of a physical tile type
*
* It corresponds to <port/> tags in the FPGA architecture description
Expand Down
8 changes: 4 additions & 4 deletions libs/librrgraph/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,14 @@ add_custom_target(
COMMAND ${CMAKE_COMMAND} -E make_directory rr_graph_generate
COMMAND ${CMAKE_COMMAND} -E chdir rr_graph_generate git clone https://github.com/duck2/uxsdcxx
COMMAND python3 -mpip install --user -r rr_graph_generate/uxsdcxx/requirements.txt
COMMAND ${CMAKE_COMMAND} -E chdir rr_graph_generate python3 uxsdcxx/uxsdcxx.py ${CMAKE_CURRENT_SOURCE_DIR}/src/base/rr_graph.xsd
COMMAND ${CMAKE_COMMAND} -E chdir rr_graph_generate python3 uxsdcxx/uxsdcap.py ${CMAKE_CURRENT_SOURCE_DIR}/src/base/rr_graph.xsd
COMMAND ${CMAKE_COMMAND} -E chdir rr_graph_generate python3 uxsdcxx/uxsdcxx.py ${CMAKE_CURRENT_SOURCE_DIR}/src/io/rr_graph.xsd
COMMAND ${CMAKE_COMMAND} -E chdir rr_graph_generate python3 uxsdcxx/uxsdcap.py ${CMAKE_CURRENT_SOURCE_DIR}/src/io/rr_graph.xsd
COMMAND ${CMAKE_COMMAND} -E copy
rr_graph_generate/rr_graph_uxsdcxx.h
rr_graph_generate/rr_graph_uxsdcxx_capnp.h
rr_graph_generate/rr_graph_uxsdcxx_interface.h
${CMAKE_CURRENT_SOURCE_DIR}/src/base/gen
${CMAKE_CURRENT_SOURCE_DIR}/src/io/gen
COMMAND ${CMAKE_COMMAND} -E copy rr_graph_generate/rr_graph_uxsdcxx.capnp ${CMAKE_CURRENT_SOURCE_DIR}/../libvtrcapnproto/gen
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/src/base/rr_graph.xsd
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/src/io/rr_graph.xsd
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)
22 changes: 17 additions & 5 deletions libs/librrgraph/src/base/check_rr_graph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -234,9 +234,11 @@ void check_rr_graph(const RRGraphView& rr_graph,
size_t inode = (size_t)rr_node;
t_rr_type rr_type = rr_graph.node_type(rr_node);
int ptc_num = rr_graph.node_ptc_num(rr_node);
int layer_num = rr_graph.node_layer(rr_node);
int xlow = rr_graph.node_xlow(rr_node);
int ylow = rr_graph.node_ylow(rr_node);
t_physical_tile_type_ptr type = grid.get_physical_type(xlow, ylow);

t_physical_tile_type_ptr type = grid.get_physical_type({xlow, ylow, layer_num});

if (rr_type == IPIN || rr_type == OPIN) {
// #TODO: No edges are added for internal pins. However, they need to be checked somehow!
Expand Down Expand Up @@ -273,7 +275,9 @@ void check_rr_graph(const RRGraphView& rr_graph,
if (!is_chain && !is_fringe && !is_wire) {
if (rr_graph.node_type(rr_node) == IPIN || rr_graph.node_type(rr_node) == OPIN) {
if (has_adjacent_channel(rr_graph, grid, node)) {
auto block_type = grid.get_physical_type(rr_graph.node_xlow(rr_node), rr_graph.node_ylow(rr_node));
auto block_type = grid.get_physical_type({rr_graph.node_xlow(rr_node),
rr_graph.node_ylow(rr_node),
rr_graph.node_layer(rr_node)});
std::string pin_name = block_type_pin_index_to_name(block_type, rr_graph.node_pin_num(rr_node), is_flat);
/* Print error messages for all the sides that a node may appear */
for (const e_side& node_side : SIDES) {
Expand Down Expand Up @@ -312,7 +316,9 @@ static bool rr_node_is_global_clb_ipin(const RRGraphView& rr_graph, const Device
int ipin;
t_physical_tile_type_ptr type;

type = grid.get_physical_type(rr_graph.node_xlow(inode), rr_graph.node_ylow(inode));
type = grid.get_physical_type({rr_graph.node_xlow(inode),
rr_graph.node_ylow(inode),
rr_graph.node_layer(inode)});

if (rr_graph.node_type(inode) != IPIN)
return (false);
Expand All @@ -335,7 +341,7 @@ void check_rr_node(const RRGraphView& rr_graph,

//Make sure over-flow doesn't happen
VTR_ASSERT(inode >= 0);
int xlow, ylow, xhigh, yhigh, ptc_num, capacity;
int xlow, ylow, xhigh, yhigh, layer_num, ptc_num, capacity;
t_rr_type rr_type;
t_physical_tile_type_ptr type;
int nodes_per_chan, tracks_per_node;
Expand All @@ -348,6 +354,7 @@ void check_rr_node(const RRGraphView& rr_graph,
xhigh = rr_graph.node_xhigh(rr_node);
ylow = rr_graph.node_ylow(rr_node);
yhigh = rr_graph.node_yhigh(rr_node);
layer_num = rr_graph.node_layer(rr_node);
ptc_num = rr_graph.node_ptc_num(rr_node);
capacity = rr_graph.node_capacity(rr_node);
cost_index = rr_graph.node_cost_index(rr_node);
Expand All @@ -363,6 +370,11 @@ void check_rr_node(const RRGraphView& rr_graph,
"in check_rr_node: rr endpoints (%d,%d) and (%d,%d) are out of range.\n", xlow, ylow, xhigh, yhigh);
}

if (layer_num < 0 || layer_num > int(grid.get_num_layers()) - 1) {
VPR_FATAL_ERROR(VPR_ERROR_ROUTE,
"in check_rr_node: rr endpoints layer_num (%d) is out of range.\n", layer_num);
}

if (ptc_num < 0) {
VPR_ERROR(VPR_ERROR_ROUTE,
"in check_rr_node: inode %d (type %d) had a ptc_num of %d.\n", inode, rr_type, ptc_num);
Expand All @@ -374,7 +386,7 @@ void check_rr_node(const RRGraphView& rr_graph,
}

/* Check that the segment is within the array and such. */
type = grid.get_physical_type(xlow, ylow);
type = grid.get_physical_type({xlow, ylow, layer_num});

switch (rr_type) {
case SOURCE:
Expand Down
7 changes: 4 additions & 3 deletions libs/librrgraph/src/base/rr_graph_builder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,26 +28,27 @@ MetadataStorage<std::tuple<int, int, short>>& RRGraphBuilder::rr_edge_metadata()
void RRGraphBuilder::add_node_to_all_locs(RRNodeId node) {
t_rr_type node_type = node_storage_.node_type(node);
short node_ptc_num = node_storage_.node_ptc_num(node);
short node_layer = node_storage_.node_layer(node);
for (int ix = node_storage_.node_xlow(node); ix <= node_storage_.node_xhigh(node); ix++) {
for (int iy = node_storage_.node_ylow(node); iy <= node_storage_.node_yhigh(node); iy++) {
switch (node_type) {
case SOURCE:
case SINK:
case CHANY:
node_lookup_.add_node(node, ix, iy, node_type, node_ptc_num, SIDES[0]);
node_lookup_.add_node(node,node_layer, ix, iy, node_type, node_ptc_num, SIDES[0]);
break;
case CHANX:
/* Currently need to swap x and y for CHANX because of chan, seg convention
* TODO: Once the builders is reworked for use consistent (x, y) convention,
* the following swapping can be removed
*/
node_lookup_.add_node(node, iy, ix, node_type, node_ptc_num, SIDES[0]);
node_lookup_.add_node(node,node_layer, iy, ix, node_type, node_ptc_num, SIDES[0]);
break;
case OPIN:
case IPIN:
for (const e_side& side : SIDES) {
if (node_storage_.is_node_on_specific_side(node, side)) {
node_lookup_.add_node(node, ix, iy, node_type, node_ptc_num, side);
node_lookup_.add_node(node,node_layer, ix, iy, node_type, node_ptc_num, side);
}
}
break;
Expand Down
10 changes: 10 additions & 0 deletions libs/librrgraph/src/base/rr_graph_builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,11 @@ class RRGraphBuilder {
node_storage_.set_node_coordinates(id, x1, y1, x2, y2);
}

/** @brief Set the node layer (specifies which die the node is located at) */
inline void set_node_layer(RRNodeId id, short layer){
node_storage_.set_node_layer(id,layer);
}

/** @brief The ptc_num carries different meanings for different node types
* (true in VPR RRG that is currently supported, may not be true in customized RRG)
* CHANX or CHANY: the track id in routing channels
Expand All @@ -179,6 +184,11 @@ class RRGraphBuilder {
node_storage_.set_node_ptc_num(id, new_ptc_num);
}

/** @brief set the layer number at which RRNodeId is located at */
inline void set_node_layer(RRNodeId id, int layer){
node_storage_.set_node_layer(id, layer);
}

/** @brief set_node_pin_num() is designed for logic blocks, which are IPIN and OPIN nodes */
inline void set_node_pin_num(RRNodeId id, int new_pin_num) {
node_storage_.set_node_pin_num(id, new_pin_num);
Expand Down
6 changes: 6 additions & 0 deletions libs/librrgraph/src/base/rr_graph_storage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -624,6 +624,10 @@ const char* t_rr_graph_storage::node_side_string(RRNodeId id) const {
return SIDE_STRING[NUM_SIDES];
}

void t_rr_graph_storage::set_node_layer(RRNodeId id, short layer) {
node_layer_[id] = layer;
}

void t_rr_graph_storage::set_node_ptc_num(RRNodeId id, int new_ptc_num) {
node_ptc_[id].ptc_.pin_num = new_ptc_num; //TODO: eventually remove
}
Expand Down Expand Up @@ -777,6 +781,7 @@ int t_rr_graph_view::node_class_num(RRNodeId id) const {
return get_node_class_num(node_storage_, node_ptc_, id);
}


t_rr_graph_view t_rr_graph_storage::view() const {
VTR_ASSERT(partitioned_);
VTR_ASSERT(node_storage_.size() == node_fan_in_.size());
Expand All @@ -785,6 +790,7 @@ t_rr_graph_view t_rr_graph_storage::view() const {
vtr::make_const_array_view_id(node_ptc_),
vtr::make_const_array_view_id(node_first_edge_),
vtr::make_const_array_view_id(node_fan_in_),
vtr::make_const_array_view_id(node_layer_),
vtr::make_const_array_view_id(edge_src_node_),
vtr::make_const_array_view_id(edge_dest_node_),
vtr::make_const_array_view_id(edge_switch_));
Expand Down
30 changes: 30 additions & 0 deletions libs/librrgraph/src/base/rr_graph_storage.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ struct alignas(16) t_rr_node_data {
} dir_side_;

uint16_t capacity_ = 0;

};

// t_rr_node_data is a key data structure, so fail at compile time if the
Expand Down Expand Up @@ -226,6 +227,14 @@ class t_rr_graph_storage {
return node_fan_in_[id];
}

/* Find the layer number that RRNodeId is located at.
* it is zero if the FPGA only has one die.
* The layer number start from the base die (base die: 0, the die above it: 1, etc.)
* */
short node_layer(RRNodeId id) const{
return node_layer_[id];
}

// This prefetechs hot RR node data required for optimization.
//
// Note: This is optional, but may lower time spent on memory stalls in
Expand Down Expand Up @@ -393,6 +402,7 @@ class t_rr_graph_storage {
make_room_in_vector(&node_storage_, size_t(elem_position));
node_ptc_.reserve(node_storage_.capacity());
node_ptc_.resize(node_storage_.size());
node_layer_.resize(node_storage_.size());
}

// Reserve storage for RR nodes.
Expand All @@ -401,6 +411,7 @@ class t_rr_graph_storage {
VTR_ASSERT(!edges_read_);
node_storage_.reserve(size);
node_ptc_.reserve(size);
node_layer_.reserve(size);
}

// Resize node storage to accomidate size RR nodes.
Expand All @@ -409,6 +420,7 @@ class t_rr_graph_storage {
VTR_ASSERT(!edges_read_);
node_storage_.resize(size);
node_ptc_.resize(size);
node_layer_.resize(size);
}

// Number of RR nodes that can be accessed.
Expand All @@ -429,6 +441,7 @@ class t_rr_graph_storage {
node_ptc_.clear();
node_first_edge_.clear();
node_fan_in_.clear();
node_layer_.clear();
seen_edge_.clear();
edge_src_node_.clear();
edge_dest_node_.clear();
Expand All @@ -448,6 +461,7 @@ class t_rr_graph_storage {
node_ptc_.shrink_to_fit();
node_first_edge_.shrink_to_fit();
node_fan_in_.shrink_to_fit();
node_layer_.shrink_to_fit();
seen_edge_.shrink_to_fit();
edge_src_node_.shrink_to_fit();
edge_dest_node_.shrink_to_fit();
Expand All @@ -461,6 +475,7 @@ class t_rr_graph_storage {
VTR_ASSERT(!edges_read_);
node_storage_.emplace_back();
node_ptc_.emplace_back();
node_layer_.emplace_back();
}

// Given `order`, a vector mapping each RRNodeId to a new one (old -> new),
Expand All @@ -479,6 +494,7 @@ class t_rr_graph_storage {

void set_node_type(RRNodeId id, t_rr_type new_type);
void set_node_coordinates(RRNodeId id, short x1, short y1, short x2, short y2);
void set_node_layer(RRNodeId id, short layer);
void set_node_cost_index(RRNodeId, RRIndexedDataId new_cost_index);
void set_node_rc_index(RRNodeId, NodeRCIndex new_rc_index);
void set_node_capacity(RRNodeId, short new_capacity);
Expand Down Expand Up @@ -670,6 +686,12 @@ class t_rr_graph_storage {
// Fan in counts for each RR node.
vtr::vector<RRNodeId, t_edge_size> node_fan_in_;

// Layer number that each RR node is located at
// Layer number refers to the die that the node belongs to. The layer number of base die is zero and die above it one, etc.
// This data is also considered as a hot data since it is used in inner loop of router, but since it didn't fit nicely into t_rr_node_data due to alignment issues, we had to store it
// in a separate vector.
vtr::vector<RRNodeId, short> node_layer_;

// Edge storage.
vtr::vector<RREdgeId, RRNodeId> edge_src_node_;
vtr::vector<RREdgeId, RRNodeId> edge_dest_node_;
Expand Down Expand Up @@ -721,13 +743,15 @@ class t_rr_graph_view {
const vtr::array_view_id<RRNodeId, const t_rr_node_ptc_data> node_ptc,
const vtr::array_view_id<RRNodeId, const RREdgeId> node_first_edge,
const vtr::array_view_id<RRNodeId, const t_edge_size> node_fan_in,
const vtr::array_view_id<RRNodeId, const short> node_layer,
const vtr::array_view_id<RREdgeId, const RRNodeId> edge_src_node,
const vtr::array_view_id<RREdgeId, const RRNodeId> edge_dest_node,
const vtr::array_view_id<RREdgeId, const short> edge_switch)
: node_storage_(node_storage)
, node_ptc_(node_ptc)
, node_first_edge_(node_first_edge)
, node_fan_in_(node_fan_in)
, node_layer_(node_layer)
, edge_src_node_(edge_src_node)
, edge_dest_node_(edge_dest_node)
, edge_switch_(edge_switch) {}
Expand Down Expand Up @@ -784,6 +808,11 @@ class t_rr_graph_view {
return node_fan_in_[id];
}

/* Retrieve layer(die) number that RRNodeId is located at */
short node_layer(RRNodeId id) const{
return node_layer_[id];
}

// This prefetechs hot RR node data required for optimization.
//
// Note: This is optional, but may lower time spent on memory stalls in
Expand Down Expand Up @@ -824,6 +853,7 @@ class t_rr_graph_view {
vtr::array_view_id<RRNodeId, const t_rr_node_ptc_data> node_ptc_;
vtr::array_view_id<RRNodeId, const RREdgeId> node_first_edge_;
vtr::array_view_id<RRNodeId, const t_edge_size> node_fan_in_;
vtr::array_view_id<RRNodeId, const short> node_layer_;
vtr::array_view_id<RREdgeId, const RRNodeId> edge_src_node_;
vtr::array_view_id<RREdgeId, const RRNodeId> edge_dest_node_;
vtr::array_view_id<RREdgeId, const short> edge_switch_;
Expand Down

0 comments on commit 83dc3c4

Please sign in to comment.