Skip to content

Commit 44962a0

Browse files
Merge branch 'master' into stratix_10_arch_updates
2 parents 8bfe793 + 2a38759 commit 44962a0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+1101
-927
lines changed

doc/src/vpr/command_line_usage.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -840,6 +840,18 @@ If any of init_t, exit_t or alpha_t is specified, the user schedule, with a fixe
840840

841841
**Default:** ``1.0``
842842

843+
.. option:: --anneal_auto_init_t_estimator {cost_variance, equilibrium}
844+
845+
Controls which estimation method is used when selecting the starting temperature
846+
for the automatic annealing schedule.
847+
848+
The options for estimators are:
849+
850+
* ``cost_variance``: Estimates the initial temperature using the variance of cost after a set of trial swaps. The initial temperature is set to a value proportional to the variance.
851+
* ``equilibrium``: Estimates the initial temperature by trying to predict the equilibrium temperature for the initial placement (i.e. the temperature that would result in no change in cost).
852+
853+
**Default** ``cost_variance``
854+
843855
.. option:: --init_t <float>
844856

845857
The starting temperature of the anneal for the manual annealing schedule.

doc/src/vtr/get_vtr.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ How to Cite
99
Citations are important in academia, as they ensure contributors receive credit for their efforts.
1010
Therefore please use the following paper as a general citation whenever you use VTR:
1111

12-
M. A. Elgammal, A. Mohaghegh, S. G. Shahrouz, F. Mahmoudi, F. Koşar, K. Talaei, J. Fife, D. Khadivi, K. E. Murray, A. Boutros, K.B. Kent, J. Goeders, V. Betz "VTR 9: Open-Source CAD for Fabric and Beyond FPGA Architecture Exploration" ACM TRETS, 2024
12+
M. A. Elgammal, A. Mohaghegh, S. G. Shahrouz, F. Mahmoudi, F. Koşar, K. Talaei, J. Fife, D. Khadivi, K. E. Murray, A. Boutros, K.B. Kent, J. Goeders, V. Betz "VTR 9: Open-Source CAD for Fabric and Beyond FPGA Architecture Exploration" ACM TRETS, 2025
1313

1414
Bibtex:
1515

libs/libarchfpga/src/device_grid.h

Lines changed: 65 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,9 @@ class DeviceGrid {
3232
const std::string& name() const { return name_; }
3333

3434
///@brief Return the number of layers(number of dies)
35-
inline int get_num_layers() const {
36-
return (int)grid_.dim_size(0);
35+
inline size_t get_num_layers() const {
36+
return grid_.dim_size(0);
3737
}
38-
3938
///@brief Return the width of the grid at the specified layer
4039
size_t width() const { return grid_.dim_size(1); }
4140
///@brief Return the height of the grid at the specified layer
@@ -54,7 +53,8 @@ class DeviceGrid {
5453
void clear();
5554

5655
/**
57-
* @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.
56+
* @brief Return the number of instances of the specified tile type on the specified layer.
57+
* If the layer_num is -1, return the total number of instances of the specified tile type on all layers.
5858
* @note This function should be used if count_instances() is called in the constructor.
5959
*/
6060
size_t num_instances(t_physical_tile_type_ptr type, int layer_num) const;
@@ -84,6 +84,15 @@ class DeviceGrid {
8484
return get_width_offset(tile_loc) == 0 && get_height_offset(tile_loc) == 0;
8585
}
8686

87+
///@brief Given a location, return the root location (bottom-left corner) of the tile instance
88+
inline t_physical_tile_loc get_root_location(const t_physical_tile_loc& tile_loc) const {
89+
t_physical_tile_loc root_loc;
90+
root_loc.layer_num = tile_loc.layer_num;
91+
root_loc.x = tile_loc.x - get_width_offset(tile_loc);
92+
root_loc.y = tile_loc.y - get_height_offset(tile_loc);
93+
return root_loc;
94+
}
95+
8796
///@brief Returns a rectangle which represents the bounding box of the tile at the given location.
8897
inline vtr::Rect<int> get_tile_bb(const t_physical_tile_loc& tile_loc) const {
8998
t_physical_tile_type_ptr tile_type = get_physical_type(tile_loc);
@@ -96,6 +105,58 @@ class DeviceGrid {
96105
return {{tile_xlow, tile_ylow}, {tile_xhigh, tile_yhigh}};
97106
}
98107

108+
// Forward const-iterator over (layer, x, y)
109+
class loc_const_iterator {
110+
public:
111+
using value_type = t_physical_tile_loc;
112+
using difference_type = std::ptrdiff_t;
113+
using iterator_category = std::forward_iterator_tag;
114+
115+
loc_const_iterator(const DeviceGrid* g, size_t layer, size_t x, size_t y)
116+
: g_(g) {
117+
loc_.layer_num = static_cast<int>(layer);
118+
loc_.x = static_cast<int>(x);
119+
loc_.y = static_cast<int>(y);
120+
}
121+
122+
value_type operator*() const { return loc_; }
123+
124+
// pre-increment
125+
loc_const_iterator& operator++() {
126+
// advance y, then x, then layer
127+
++loc_.y;
128+
if (loc_.y >= static_cast<int>(g_->height())) {
129+
loc_.y = 0;
130+
++loc_.x;
131+
if (loc_.x >= static_cast<int>(g_->width())) {
132+
loc_.x = 0;
133+
++loc_.layer_num;
134+
}
135+
}
136+
return *this;
137+
}
138+
139+
bool operator==(const loc_const_iterator& o) const {
140+
return loc_.x == o.loc_.x
141+
&& loc_.y == o.loc_.y
142+
&& loc_.layer_num == o.loc_.layer_num
143+
&& g_ == o.g_;
144+
}
145+
bool operator!=(const loc_const_iterator& o) const { return !(*this == o); }
146+
147+
private:
148+
const DeviceGrid* g_ = nullptr;
149+
t_physical_tile_loc loc_{0, 0, 0};
150+
};
151+
152+
/// Iterate every (layer, x, y) location
153+
inline auto all_locations() const {
154+
return vtr::make_range(
155+
loc_const_iterator(this, /*layer*/ 0, /*x*/ 0, /*y*/ 0),
156+
loc_const_iterator(this, /*layer*/ get_num_layers(), /*x*/ 0, /*y*/ 0) // end sentinel
157+
);
158+
}
159+
99160
///@brief Return the metadata of the tile at the specified location
100161
inline const t_metadata_dict* get_metadata(const t_physical_tile_loc& tile_loc) const {
101162
return grid_[tile_loc.layer_num][tile_loc.x][tile_loc.y].meta;

libs/libarchfpga/src/physical_types_util.cpp

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,6 @@ static std::vector<int> get_pb_pin_src_pins(t_physical_tile_type_ptr physical_ty
7878
const t_pb_graph_pin* pin);
7979

8080
/**
81-
*
8281
* @param physical_type physical tile which pin belongs to
8382
* @param sub_tile sub_tile in which physical tile located
8483
* @param logical_block logical block mapped to the sub_tile
@@ -108,20 +107,12 @@ static t_pb_graph_pin* get_mutable_tile_pin_pb_pin(t_physical_tile_type* physica
108107
int pin_physical_num);
109108

110109
/**
111-
*
112-
* @param physical_tile
113-
* @param class_physical_num
114110
* @return A vector containing all of the parent pb_graph_nodes and the pb_graph_node of the class_physical_num itself
115111
*/
116112
static std::vector<const t_pb_graph_node*> get_sink_hierarchical_parents(t_physical_tile_type_ptr physical_tile,
117113
int class_physical_num);
118114

119115
/**
120-
*
121-
* @param physical_tile
122-
* @param pin_physcial_num
123-
* @param ref_sink_num
124-
* @param sink_grp
125116
* @return Return zero if the ref_sink_num is not reachable by pin_physical_num, otherwise return the number sinks in sink_grp
126117
* reachable by pin_physical_num
127118
*/
@@ -618,21 +609,21 @@ bool is_opin(int ipin, t_physical_tile_type_ptr type) {
618609
return false;
619610
}
620611

621-
bool is_pin_conencted_to_layer(t_physical_tile_type_ptr type, int ipin, int from_layer, int to_layer, int num_of_avail_layer) {
622-
if (type->is_empty()) { //if type is empty, there is no pins
612+
bool is_pin_conencted_to_layer(t_physical_tile_type_ptr type, int ipin, int from_layer, int to_layer, unsigned num_of_avail_layer) {
613+
// if type is empty, there is no pins
614+
if (type->is_empty()) {
623615
return false;
624616
}
625-
//ipin should be a valid pin in physical type
617+
618+
// ipin should be a valid pin in physical type
626619
VTR_ASSERT(ipin < type->num_pins);
627-
int pin_layer = from_layer + type->pin_layer_offset[ipin];
628-
//if pin_offset specifies a layer that doesn't exist in arch file, we do a wrap around
620+
unsigned pin_layer = from_layer + type->pin_layer_offset[ipin];
621+
// if pin_offset specifies a layer that doesn't exist in arch file, we do a wrap around
629622
pin_layer = (pin_layer < num_of_avail_layer) ? pin_layer : pin_layer % num_of_avail_layer;
630-
if (from_layer == to_layer || pin_layer == to_layer) {
623+
if (from_layer == to_layer || int(pin_layer) == to_layer) {
631624
return true;
632-
} else {
633-
return false;
634625
}
635-
//not reachable
626+
636627
return false;
637628
}
638629

@@ -643,7 +634,7 @@ std::string block_type_pin_index_to_name(t_physical_tile_type_ptr type, int pin_
643634
std::string pin_name = type->name;
644635

645636
int sub_tile_index, inst_num, logical_num, pb_type_idx;
646-
std::tie<int, int, int, int, int>(pin_index, sub_tile_index, inst_num, logical_num, pb_type_idx) = get_pin_index_for_inst(type, pin_physical_num, is_flat);
637+
std::tie(pin_index, sub_tile_index, inst_num, logical_num, pb_type_idx) = get_pin_index_for_inst(type, pin_physical_num, is_flat);
647638
if (type->sub_tiles[sub_tile_index].capacity.total() > 1) {
648639
pin_name += "[" + std::to_string(inst_num) + "]";
649640
}

libs/libarchfpga/src/physical_types_util.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@
116116
bool is_opin(int ipin, t_physical_tile_type_ptr type);
117117

118118
///@brief Returns true if the specified pin is located at "from_layer" and it is connected to "to_layer"
119-
bool is_pin_conencted_to_layer(t_physical_tile_type_ptr type, int ipin, int from_layer, int to_layer, int num_of_avail_layer);
119+
bool is_pin_conencted_to_layer(t_physical_tile_type_ptr type, int ipin, int from_layer, int to_layer, unsigned num_of_avail_layer);
120120

121121
/**
122122
* @brief Returns the corresponding physical pin based on the input parameters:

libs/libarchfpga/src/read_xml_arch_file_sg.cpp

Lines changed: 6 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "pugixml_util.hpp"
55
#include "arch_error.h"
66
#include "switchblock_types.h"
7+
#include "vtr_util.h"
78

89
/**
910
* @brief Parses all <sg_link> tags under a <sg_link_list> tag.
@@ -26,32 +27,12 @@ static std::vector<t_sg_link> parse_sg_link_tags(pugi::xml_node sg_link_list_tag
2627
sg_link.seg_type = pugiutil::get_attribute(node, "seg_type", loc_data).as_string();
2728

2829
// Since the offset attributes are optional and might not exist, the as_int method will return a value of zero if the attribute is empty
29-
int x_offset = pugiutil::get_attribute(node, "x_offset", loc_data, pugiutil::OPTIONAL).as_int(0);
30-
int y_offset = pugiutil::get_attribute(node, "y_offset", loc_data, pugiutil::OPTIONAL).as_int(0);
31-
int z_offset = pugiutil::get_attribute(node, "z_offset", loc_data, pugiutil::OPTIONAL).as_int(0);
30+
sg_link.x_offset = pugiutil::get_attribute(node, "x_offset", loc_data, pugiutil::OPTIONAL).as_int(0);
31+
sg_link.y_offset = pugiutil::get_attribute(node, "y_offset", loc_data, pugiutil::OPTIONAL).as_int(0);
32+
sg_link.z_offset = pugiutil::get_attribute(node, "z_offset", loc_data, pugiutil::OPTIONAL).as_int(0);
3233

33-
if (x_offset == 0 && y_offset == 0 && z_offset == 0) {
34-
archfpga_throw(loc_data.filename_c_str(), loc_data.line(node), "All offset fields in the <sg_link> are zero or missing.");
35-
}
36-
37-
// We expect exactly one non-zero offset so the gather and scatter points are joined by a node that can be represented by a straight wire.
38-
if (x_offset != 0) {
39-
sg_link.x_offset = x_offset;
40-
if (y_offset != 0 || z_offset != 0) {
41-
archfpga_throw(loc_data.filename_c_str(), loc_data.line(node), "More than one of the offset fields in the <sg_link> are non-zero.");
42-
}
43-
}
44-
if (y_offset != 0) {
45-
sg_link.y_offset = y_offset;
46-
if (x_offset != 0 || z_offset != 0) {
47-
archfpga_throw(loc_data.filename_c_str(), loc_data.line(node), "More than one of the offset fields in the <sg_link> are non-zero.");
48-
}
49-
}
50-
if (z_offset != 0) {
51-
sg_link.z_offset = z_offset;
52-
if (y_offset != 0 || x_offset != 0) {
53-
archfpga_throw(loc_data.filename_c_str(), loc_data.line(node), "More than one of the offset fields in the <sg_link> are non-zero.");
54-
}
34+
if (!vtr::exactly_k_conditions(1, sg_link.x_offset != 0, sg_link.y_offset != 0, sg_link.z_offset != 0)) {
35+
archfpga_throw(loc_data.filename_c_str(), loc_data.line(node), "One and only one of the offset fields in the <sg_link> should be non-zero.");
5536
}
5637

5738
sg_link_list.push_back(sg_link);

libs/libarchfpga/src/switchblock_types.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ enum e_directionality {
1818
/**
1919
* @brief At the intersection of routing channels, left, right, top and bottom specify the x- and y-directed channels
2020
* while above and under specify the switch block wires one a layer above or below the current one. above and below
21-
* are only used for multi-layer FPGAs.
21+
* are only used for multi-layer FPGAs. Note that the order of 2D sides is important, as it corresponds to the bit
22+
* order in t_rr_node_data::dir_side_.sides.
2223
*/
2324
enum e_side : unsigned char {
2425
TOP = 0,

libs/librrgraph/src/base/check_rr_graph.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,8 @@ void check_rr_node(const RRGraphView& rr_graph,
473473

474474
e_pin_type class_type = e_pin_type::OPEN;
475475
int class_num_pins = -1;
476+
std::vector<e_side> rr_graph_sides;
477+
std::vector<e_side> arch_side_vec;
476478
switch (rr_type) {
477479
case e_rr_type::SOURCE:
478480
case e_rr_type::SINK:
@@ -511,6 +513,19 @@ void check_rr_node(const RRGraphView& rr_graph,
511513
VPR_FATAL_ERROR(VPR_ERROR_ROUTE,
512514
"in check_rr_node: inode %d (type %d) has a capacity of %d.\n", inode, rr_type, capacity);
513515
}
516+
rr_graph_sides = rr_graph.node_sides(rr_node);
517+
std::tie(std::ignore, std::ignore, arch_side_vec) = get_pin_coordinates(type, ptc_num, std::vector<e_side>(TOTAL_2D_SIDES.begin(), TOTAL_2D_SIDES.end()));
518+
// sides in the architecture are a superset of the sides for a pin in RR Graph. We iterate over the sides stored
519+
// in the RR Graph to ensure that all of them also exist in the architecture.
520+
for (size_t i = 0; i < rr_graph_sides.size(); i++) {
521+
if (std::find(arch_side_vec.begin(), arch_side_vec.end(), rr_graph_sides[i]) == arch_side_vec.end()) {
522+
VPR_FATAL_ERROR(VPR_ERROR_ROUTE,
523+
"in check_rr_node: inode %d (type %d) has a different side '%s' in the RR graph and the architecture.\n",
524+
inode,
525+
rr_type,
526+
TOTAL_2D_SIDE_STRINGS[rr_graph_sides[i]]);
527+
}
528+
}
514529
break;
515530

516531
case e_rr_type::CHANX:

libs/librrgraph/src/base/rr_graph_storage.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -631,6 +631,17 @@ const std::string& t_rr_graph_storage::node_direction_string(RRNodeId id) const
631631
return CONST_DIRECTION_STRING[int_direction];
632632
}
633633

634+
635+
const std::vector<e_side> t_rr_graph_storage::node_sides(RRNodeId id) const {
636+
std::vector<e_side> sides;
637+
for (const e_side& side : TOTAL_2D_SIDES) {
638+
if (is_node_on_specific_side(id, side)) {
639+
sides.push_back(side);
640+
}
641+
}
642+
return sides;
643+
}
644+
634645
const char* t_rr_graph_storage::node_side_string(RRNodeId id) const {
635646
for (const e_side& side : TOTAL_2D_SIDES) {
636647
if (is_node_on_specific_side(id, side)) {
@@ -807,7 +818,7 @@ void t_rr_graph_storage::set_node_direction(RRNodeId id, Direction new_direction
807818

808819
void t_rr_graph_storage::add_node_side(RRNodeId id, e_side new_side) {
809820
if (node_type(id) != e_rr_type::IPIN && node_type(id) != e_rr_type::OPIN) {
810-
VTR_LOG_ERROR("Attempted to set RR node 'side' for non-channel type '%s'", node_type_string(id));
821+
VTR_LOG_ERROR("Attempted to set RR node 'side' for non-pin type '%s'", node_type_string(id));
811822
}
812823
std::bitset<NUM_2D_SIDES> side_bits = node_storage_[id].dir_side_.sides;
813824
side_bits[size_t(new_side)] = true;

libs/librrgraph/src/base/rr_graph_storage.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,9 @@ class t_rr_graph_storage {
220220
id, side);
221221
}
222222

223+
/** @brief Get the sides where the node locates on. */
224+
const std::vector<e_side> node_sides(RRNodeId id) const;
225+
223226
/* FIXME: This function should be DEPRECATED!
224227
* Developers can easily use the following codes with more flexibility
225228
*

0 commit comments

Comments
 (0)