diff --git a/doc/src/vpr/placement_constraints.rst b/doc/src/vpr/placement_constraints.rst
index cbc0642ec48..637a185ccf4 100644
--- a/doc/src/vpr/placement_constraints.rst
+++ b/doc/src/vpr/placement_constraints.rst
@@ -28,6 +28,14 @@ A Placement Constraints File Example
+
+
+
+
+
+
+
+
@@ -75,7 +83,10 @@ The ``name_pattern`` can be the exact name of the atom from the input atom netli
Region
^^^^^^
-An ```` tag is used to add a region to the partition. A ``region`` is a rectangular area on the chip. A partition can contain any number of independent regions - the regions within one partition must not overlap with each other (in order to ease processing when loading in the file). An ```` tag has the following attributes.
+An ```` tag is used to add a region to the partition. A ``region`` is a rectangular area or cubic volume
+on the chip. A partition can contain any number of independent regions - the regions within one partition **must not**
+overlap with each other (in order to ease processing when loading in the file).
+An ```` tag has the following attributes.
:req_param x_low:
The x value of the lower left point of the rectangle.
@@ -90,11 +101,30 @@ An ```` tag is used to add a region to the partition. A ``region`` i
The y value of the upper right point of the rectangle.
:opt_param subtile:
- Each x, y location on the grid may contain multiple locations known as subtiles. This paramter is an optional value specifying the subtile location that the atom(s) of the partition shall be constrained to.
+ Each x, y location on the grid may contain multiple locations known as subtiles. This parameter is an optional value specifying the subtile location that the atom(s) of the partition shall be constrained to.
+
+:opt_param layer_low:
+ The lowest layer number that the region covers. The default value is 0.
+
+:opt_param layer_high:
+ The highest layer number that the region covers. The default value is 0.
The optional ``subtile`` attribute is commonly used when constraining an atom to a specific location on the chip (e.g. an exact I/O location). It is legal to use with larger regions, but uncommon.
-If a user would like to specify an area on the chip with an unusual shape (e.g. L-shaped or T-shaped), they can simply add multiple ```` tags to cover the area specified.
+In 2D architectures, ``layer_low`` and ``layer_high`` can be safely ignored as their default value is 0.
+In 3D architectures, a region can span across multiple layers or be assigned to a specific layer.
+For assigning a region to a specific non-zero layer, the user should set both ``layer_low`` and ``layer_high`` to the
+desired layer number. If a layer range is to be covered by the region, the user set ``layer_low`` and ``layer_high`` to
+different values.
+
+If a user would like to specify an area on the chip with an unusual shape (e.g. L-shaped or T-shaped),
+they can simply add multiple ```` tags to cover the area specified.
+
+It is strongly recommended that different partitions do not overlap. The packing algorithm compares the number clustered
+blocks and the number of physical blocks in a region to decide pack atoms inside a partition more aggressively when
+there are not enough resources in a partition. Overlapping partitions causes some physical blocks to be counted in more
+than one partition.
+
diff --git a/libs/libarchfpga/src/echo_arch.cpp b/libs/libarchfpga/src/echo_arch.cpp
index 09ba4f364fe..777d655c3e6 100644
--- a/libs/libarchfpga/src/echo_arch.cpp
+++ b/libs/libarchfpga/src/echo_arch.cpp
@@ -236,11 +236,11 @@ void PrintArchInfo(FILE* Echo, const t_arch* arch) {
}
fprintf(Echo, "\tInput Connect Block Switch Name Within a Same Die: %s\n", arch->ipin_cblock_switch_name[ipin_cblock_switch_index_within_die].c_str());
-
+
//if there is more than one layer available, print the connection block switch name that is used for connection between two dice
- for(const auto& layout : arch->grid_layouts){
+ for (const auto& layout : arch->grid_layouts) {
int num_layers = (int)layout.layers.size();
- if(num_layers > 1){
+ if (num_layers > 1) {
fprintf(Echo, "\tInput Connect Block Switch Name Between Two Dice: %s\n", arch->ipin_cblock_switch_name[ipin_cblock_switch_index_between_dice].c_str());
}
}
@@ -295,11 +295,11 @@ void PrintArchInfo(FILE* Echo, const t_arch* arch) {
fprintf(Echo, "\t\t\t\ttype unidir mux_name for within die connections: %s\n",
arch->Switches[seg.arch_wire_switch].name.c_str());
//if there is more than one layer available, print the segment switch name that is used for connection between two dice
- for(const auto& layout : arch->grid_layouts){
+ for (const auto& layout : arch->grid_layouts) {
int num_layers = (int)layout.layers.size();
- if(num_layers > 1){
+ if (num_layers > 1) {
fprintf(Echo, "\t\t\t\ttype unidir mux_name for between two dice connections: %s\n",
- arch->Switches[seg.arch_opin_between_dice_switch].name.c_str());
+ arch->Switches[seg.arch_opin_between_dice_switch].name.c_str());
}
}
} else { //Should be bidir
diff --git a/libs/libvtrutil/src/vtr_geometry.h b/libs/libvtrutil/src/vtr_geometry.h
index 3685c308653..3947eb2cd9d 100644
--- a/libs/libvtrutil/src/vtr_geometry.h
+++ b/libs/libvtrutil/src/vtr_geometry.h
@@ -12,7 +12,7 @@
/**
* @file
- * @brief This file include differents different geometry classes
+ * @brief This file includes different geometry classes
*/
namespace vtr {
@@ -92,11 +92,18 @@ class Point {
///@brief Swap x and y values
void swap();
+ /// @brief += operator
+ Point& operator+= (const Point& rhs);
+
+ /// @brief += operator
+ Point& operator-= (const Point& rhs);
+
private:
T x_;
T y_;
};
+
/**
* @brief A 2D rectangle
*
@@ -144,6 +151,12 @@ class Rect {
///@brief Return the top right point
Point top_right() const;
+ /**
+ * @brief Return the bottom left and top right coordinates
+ * @return [xmin, ymin, xmax, ymax]
+ */
+ std::tuple coordinates() const;
+
///@brief Return the rectangle width
T width() const;
@@ -190,6 +203,12 @@ class Rect {
///@brief set ymax to a point
void set_ymax(T ymax_val);
+ /// @brief += operator
+ Rect& operator+= (const Point& rhs);
+
+ /// @brief -= operator
+ Rect& operator-= (const Point& rhs);
+
///@brief Equivalent to `*this = bounding_box(*this, other)`
Rect& expand_bounding_box(const Rect& other);
@@ -302,7 +321,7 @@ class RectUnion {
friend bool operator!= <>(const RectUnion& lhs, const RectUnion& rhs);
private:
- // Note that a union of rectanges may have holes and may not be contiguous
+ // Note that a union of rectangles may have holes and may not be contiguous
std::vector> rects_;
};
diff --git a/libs/libvtrutil/src/vtr_geometry.tpp b/libs/libvtrutil/src/vtr_geometry.tpp
index 2010700fc50..9ac7ebab642 100644
--- a/libs/libvtrutil/src/vtr_geometry.tpp
+++ b/libs/libvtrutil/src/vtr_geometry.tpp
@@ -58,6 +58,20 @@ void Point::swap() {
std::swap(x_, y_);
}
+template
+Point& Point::operator+=(const Point& rhs) {
+ x_ += rhs.x_;
+ y_ += rhs.y_;
+ return *this;
+}
+
+template
+Point& Point::operator-=(const Point& rhs) {
+ x_ -= rhs.x_;
+ y_ -= rhs.y_;
+ return *this;
+}
+
/*
* Rect
*/
@@ -120,6 +134,11 @@ Point Rect::top_right() const {
return top_right_;
}
+template
+std::tuple Rect::coordinates() const {
+ return {xmin(), ymin(), xmax(), ymax()};
+}
+
template
T Rect::width() const {
return xmax() - xmin();
@@ -224,6 +243,20 @@ void Rect::set_ymax(T ymax_val) {
top_right_.set_y(ymax_val);
}
+template
+Rect& Rect::operator+=(const Point& rhs) {
+ bottom_left_ += rhs;
+ top_right_ += rhs;
+ return *this;
+}
+
+template
+Rect& Rect::operator-=(const Point& rhs) {
+ bottom_left_ -= rhs;
+ top_right_ -= rhs;
+ return *this;
+}
+
template
Rect& Rect::expand_bounding_box(const Rect& other) {
*this = bounding_box(*this, other);
diff --git a/vpr/src/base/gen/vpr_constraints_uxsdcxx.h b/vpr/src/base/gen/vpr_constraints_uxsdcxx.h
index d896dd6bdf5..7361fc63141 100644
--- a/vpr/src/base/gen/vpr_constraints_uxsdcxx.h
+++ b/vpr/src/base/gen/vpr_constraints_uxsdcxx.h
@@ -4,14 +4,13 @@
* https://github.com/duck2/uxsdcxx
* Modify only if your build process doesn't involve regenerating this file.
*
- * Cmdline: /home/kimia/uxsdcxx/uxsdcxx.py ../vpr_constraints.xsd
- * Input file: /home/kimia/vtr-verilog-to-routing/vpr/src/base/vpr_constraints.xsd
- * md5sum of input file: f2b3721db9b14ccdf0787c9c99e00a78
+ * Cmdline: uxsdcxx.py ../vpr_repos/vpr/src/base/vpr_constraints.xsd
+ * Input file: /home/soheil/vpr_repos/vpr/src/base/vpr_constraints.xsd
+ * md5sum of input file: ea99cd05d67036ef541872d9d77a83c5
*/
#include
-
#include
#include
#include
@@ -33,1106 +32,1219 @@ namespace uxsd {
* Internal function for getting line and column number from file based on
* byte offset.
*/
-inline void get_line_number(const char *filename, std::ptrdiff_t offset, int * line, int * col);
+inline void get_line_number(const char* filename, std::ptrdiff_t offset, int* line, int* col);
-[[noreturn]] inline void noreturn_report(const std::function * report_error, const char *msg) {
+[[noreturn]] inline void noreturn_report(const std::function* report_error, const char* msg) {
(*report_error)(msg);
throw std::runtime_error("Unreachable!");
}
/* Declarations for internal load functions for the complex types. */
-template
-inline void load_add_atom(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug);
-template
-inline void load_add_region(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug);
-inline void load_add_region_required_attributes(const pugi::xml_node &root, int * x_high, int * x_low, int * y_high, int * y_low, const std::function * report_error);
-template
-inline void load_partition(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug);
-template
-inline void load_partition_list(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug);
-template
-inline void load_set_global_signal(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug);
-inline void load_set_global_signal_required_attributes(const pugi::xml_node &root, enum_route_model_type * route_model, const std::function * report_error);
-template
-inline void load_global_route_constraints(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug);
-template
-inline void load_vpr_constraints(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug);
+template
+inline void load_add_atom(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug);
+template
+inline void load_add_region(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug);
+inline void load_add_region_required_attributes(const pugi::xml_node& root, int* x_high, int* x_low, int* y_high, int* y_low, const std::function* report_error);
+template
+inline void load_partition(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug);
+template
+inline void load_partition_list(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug);
+template
+inline void load_set_global_signal(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug);
+inline void load_set_global_signal_required_attributes(const pugi::xml_node& root, enum_route_model_type* route_model, const std::function* report_error);
+template
+inline void load_global_route_constraints(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug);
+template
+inline void load_vpr_constraints(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug);
/* Declarations for internal write functions for the complex types. */
-template
-inline void write_partition(T &in, std::ostream &os, const void *data, void *iter);
-template
-inline void write_partition_list(T &in, std::ostream &os, const void *data, void *iter);
-template
-inline void write_global_route_constraints(T &in, std::ostream &os, const void *data, void *iter);
-template
-inline void write_vpr_constraints(T &in, std::ostream &os, const void *data, void *iter);
+template
+inline void write_partition(T& in, std::ostream& os, const void* data, void* iter);
+template
+inline void write_partition_list(T& in, std::ostream& os, const void* data, void* iter);
+template
+inline void write_global_route_constraints(T& in, std::ostream& os, const void* data, void* iter);
+template
+inline void write_vpr_constraints(T& in, std::ostream& os, const void* data, void* iter);
/* Load function for the root element. */
-template
-inline void load_vpr_constraints_xml(T &out, Context &context, const char * filename, std::istream &is){
- pugi::xml_document doc;
- pugi::xml_parse_result result = doc.load(is);
- if(!result) {
- int line, col;
- get_line_number(filename, result.offset, &line, &col);
- std::stringstream msg;
- msg << "Unable to load XML file '" << filename << "', ";
- msg << result.description() << " (line: " << line;
- msg << " col: " << col << ")"; out.error_encountered(filename, line, msg.str().c_str());
- }
- ptrdiff_t offset_debug = 0;
- std::function report_error = [filename, &out, &offset_debug](const char * message) {
- int line, col;
- get_line_number(filename, offset_debug, &line, &col);
- out.error_encountered(filename, line, message);
- // If error_encountered didn't throw, throw now to unwind.
- throw std::runtime_error(message);
- };
- out.start_load(&report_error);
-
- for(pugi::xml_node node= doc.first_child(); node; node = node.next_sibling()){
- if(std::strcmp(node.name(), "vpr_constraints") == 0){
- /* If errno is set up to this point, it messes with strtol errno checking. */
- errno = 0;
- load_vpr_constraints(node, out, context, &report_error, &offset_debug);
- } else {
- offset_debug = node.offset_debug();
- report_error(("Invalid root-level element " + std::string(node.name())).c_str());
- }
- }
- out.finish_load();
+template
+inline void load_vpr_constraints_xml(T& out, Context& context, const char* filename, std::istream& is) {
+ pugi::xml_document doc;
+ pugi::xml_parse_result result = doc.load(is);
+ if (!result) {
+ int line, col;
+ get_line_number(filename, result.offset, &line, &col);
+ std::stringstream msg;
+ msg << "Unable to load XML file '" << filename << "', ";
+ msg << result.description() << " (line: " << line;
+ msg << " col: " << col << ")";
+ out.error_encountered(filename, line, msg.str().c_str());
+ }
+ ptrdiff_t offset_debug = 0;
+ std::function report_error = [filename, &out, &offset_debug](const char* message) {
+ int line, col;
+ get_line_number(filename, offset_debug, &line, &col);
+ out.error_encountered(filename, line, message);
+ // If error_encountered didn't throw, throw now to unwind.
+ throw std::runtime_error(message);
+ };
+ out.start_load(&report_error);
+
+ for (pugi::xml_node node = doc.first_child(); node; node = node.next_sibling()) {
+ if (std::strcmp(node.name(), "vpr_constraints") == 0) {
+ /* If errno is set up to this point, it messes with strtol errno checking. */
+ errno = 0;
+ load_vpr_constraints(node, out, context, &report_error, &offset_debug);
+ } else {
+ offset_debug = node.offset_debug();
+ report_error(("Invalid root-level element " + std::string(node.name())).c_str());
+ }
+ }
+ out.finish_load();
}
/* Write function for the root element. */
-template
-inline void write_vpr_constraints_xml(T &in, Context &context, std::ostream &os){
- in.start_write();
- os << "\n";
- write_vpr_constraints(in, os, context);
- os << "\n";
- in.finish_write();
+template
+inline void write_vpr_constraints_xml(T& in, Context& context, std::ostream& os) {
+ in.start_write();
+ os << "\n";
+ write_vpr_constraints(in, os, context);
+ os << "\n";
+ in.finish_write();
}
-
typedef const uint32_t __attribute__((aligned(1))) triehash_uu32;
typedef const uint64_t __attribute__((aligned(1))) triehash_uu64;
static_assert(alignof(triehash_uu32) == 1, "Unaligned 32-bit access not found.");
static_assert(alignof(triehash_uu64) == 1, "Unaligned 64-bit access not found.");
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
-#define onechar(c, s, l) (((uint64_t)(c)) << (s))
+# define onechar(c, s, l) (((uint64_t)(c)) << (s))
#else
-#define onechar(c, s, l) (((uint64_t)(c)) << (l-8-s))
+# define onechar(c, s, l) (((uint64_t)(c)) << (l - 8 - s))
#endif
/* Tokens for attribute and node names. */
-enum class atok_t_add_atom {NAME_PATTERN};
-constexpr const char *atok_lookup_t_add_atom[] = {"name_pattern"};
-
-
-enum class atok_t_add_region {SUBTILE, X_HIGH, X_LOW, Y_HIGH, Y_LOW};
-constexpr const char *atok_lookup_t_add_region[] = {"subtile", "x_high", "x_low", "y_high", "y_low"};
-
-enum class gtok_t_partition {ADD_ATOM, ADD_REGION};
-constexpr const char *gtok_lookup_t_partition[] = {"add_atom", "add_region"};
-enum class atok_t_partition {NAME};
-constexpr const char *atok_lookup_t_partition[] = {"name"};
-
-enum class gtok_t_partition_list {PARTITION};
-constexpr const char *gtok_lookup_t_partition_list[] = {"partition"};
-
-enum class atok_t_set_global_signal {NAME, NETWORK_NAME, ROUTE_MODEL};
-constexpr const char *atok_lookup_t_set_global_signal[] = {"name", "network_name", "route_model"};
-
-enum class gtok_t_global_route_constraints {SET_GLOBAL_SIGNAL};
-constexpr const char *gtok_lookup_t_global_route_constraints[] = {"set_global_signal"};
-enum class gtok_t_vpr_constraints {PARTITION_LIST, GLOBAL_ROUTE_CONSTRAINTS};
-constexpr const char *gtok_lookup_t_vpr_constraints[] = {"partition_list", "global_route_constraints"};
-enum class atok_t_vpr_constraints {TOOL_NAME};
-constexpr const char *atok_lookup_t_vpr_constraints[] = {"tool_name"};
-
+enum class atok_t_add_atom { NAME_PATTERN };
+constexpr const char* atok_lookup_t_add_atom[] = {"name_pattern"};
+
+enum class atok_t_add_region { LAYER_HIGH,
+ LAYER_LOW,
+ SUBTILE,
+ X_HIGH,
+ X_LOW,
+ Y_HIGH,
+ Y_LOW };
+constexpr const char* atok_lookup_t_add_region[] = {"layer_high", "layer_low", "subtile", "x_high", "x_low", "y_high", "y_low"};
+
+enum class gtok_t_partition { ADD_ATOM,
+ ADD_REGION };
+constexpr const char* gtok_lookup_t_partition[] = {"add_atom", "add_region"};
+enum class atok_t_partition { NAME };
+constexpr const char* atok_lookup_t_partition[] = {"name"};
+
+enum class gtok_t_partition_list { PARTITION };
+constexpr const char* gtok_lookup_t_partition_list[] = {"partition"};
+
+enum class atok_t_set_global_signal { NAME,
+ NETWORK_NAME,
+ ROUTE_MODEL };
+constexpr const char* atok_lookup_t_set_global_signal[] = {"name", "network_name", "route_model"};
+
+enum class gtok_t_global_route_constraints { SET_GLOBAL_SIGNAL };
+constexpr const char* gtok_lookup_t_global_route_constraints[] = {"set_global_signal"};
+enum class gtok_t_vpr_constraints { PARTITION_LIST,
+ GLOBAL_ROUTE_CONSTRAINTS };
+constexpr const char* gtok_lookup_t_vpr_constraints[] = {"partition_list", "global_route_constraints"};
+enum class atok_t_vpr_constraints { TOOL_NAME };
+constexpr const char* atok_lookup_t_vpr_constraints[] = {"tool_name"};
/* Internal lexers. These convert the PugiXML node names to input tokens. */
-inline atok_t_add_atom lex_attr_t_add_atom(const char *in, const std::function * report_error){
- unsigned int len = strlen(in);
- switch(len){
- case 12:
- switch(*((triehash_uu64*)&in[0])){
- case onechar('n', 0, 64) | onechar('a', 8, 64) | onechar('m', 16, 64) | onechar('e', 24, 64) | onechar('_', 32, 64) | onechar('p', 40, 64) | onechar('a', 48, 64) | onechar('t', 56, 64):
- switch(*((triehash_uu32*)&in[8])){
- case onechar('t', 0, 32) | onechar('e', 8, 32) | onechar('r', 16, 32) | onechar('n', 24, 32):
- return atok_t_add_atom::NAME_PATTERN;
- break;
- default: break;
- }
- break;
- default: break;
- }
- break;
- default: break;
- }
- noreturn_report(report_error, ("Found unrecognized attribute " + std::string(in) + " of .").c_str());
+inline atok_t_add_atom lex_attr_t_add_atom(const char* in, const std::function* report_error) {
+ unsigned int len = strlen(in);
+ switch (len) {
+ case 12:
+ switch (*((triehash_uu64*)&in[0])) {
+ case onechar('n', 0, 64) | onechar('a', 8, 64) | onechar('m', 16, 64) | onechar('e', 24, 64) | onechar('_', 32, 64) | onechar('p', 40, 64) | onechar('a', 48, 64) | onechar('t', 56, 64):
+ switch (*((triehash_uu32*)&in[8])) {
+ case onechar('t', 0, 32) | onechar('e', 8, 32) | onechar('r', 16, 32) | onechar('n', 24, 32):
+ return atok_t_add_atom::NAME_PATTERN;
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ noreturn_report(report_error, ("Found unrecognized attribute " + std::string(in) + " of .").c_str());
}
-inline atok_t_add_region lex_attr_t_add_region(const char *in, const std::function * report_error){
- unsigned int len = strlen(in);
- switch(len){
- case 5:
- switch(*((triehash_uu32*)&in[0])){
- case onechar('x', 0, 32) | onechar('_', 8, 32) | onechar('l', 16, 32) | onechar('o', 24, 32):
- switch(in[4]){
- case onechar('w', 0, 8):
- return atok_t_add_region::X_LOW;
- break;
- default: break;
- }
- break;
- case onechar('y', 0, 32) | onechar('_', 8, 32) | onechar('l', 16, 32) | onechar('o', 24, 32):
- switch(in[4]){
- case onechar('w', 0, 8):
- return atok_t_add_region::Y_LOW;
- break;
- default: break;
- }
- break;
- default: break;
- }
- break;
- case 6:
- switch(*((triehash_uu32*)&in[0])){
- case onechar('x', 0, 32) | onechar('_', 8, 32) | onechar('h', 16, 32) | onechar('i', 24, 32):
- switch(in[4]){
- case onechar('g', 0, 8):
- switch(in[5]){
- case onechar('h', 0, 8):
- return atok_t_add_region::X_HIGH;
- break;
- default: break;
- }
- break;
- default: break;
- }
- break;
- case onechar('y', 0, 32) | onechar('_', 8, 32) | onechar('h', 16, 32) | onechar('i', 24, 32):
- switch(in[4]){
- case onechar('g', 0, 8):
- switch(in[5]){
- case onechar('h', 0, 8):
- return atok_t_add_region::Y_HIGH;
- break;
- default: break;
- }
- break;
- default: break;
- }
- break;
- default: break;
- }
- break;
- case 7:
- switch(*((triehash_uu32*)&in[0])){
- case onechar('s', 0, 32) | onechar('u', 8, 32) | onechar('b', 16, 32) | onechar('t', 24, 32):
- switch(in[4]){
- case onechar('i', 0, 8):
- switch(in[5]){
- case onechar('l', 0, 8):
- switch(in[6]){
- case onechar('e', 0, 8):
- return atok_t_add_region::SUBTILE;
- break;
- default: break;
- }
- break;
- default: break;
- }
- break;
- default: break;
- }
- break;
- default: break;
- }
- break;
- default: break;
- }
- noreturn_report(report_error, ("Found unrecognized attribute " + std::string(in) + " of .").c_str());
+inline atok_t_add_region lex_attr_t_add_region(const char* in, const std::function* report_error) {
+ unsigned int len = strlen(in);
+ switch (len) {
+ case 5:
+ switch (*((triehash_uu32*)&in[0])) {
+ case onechar('x', 0, 32) | onechar('_', 8, 32) | onechar('l', 16, 32) | onechar('o', 24, 32):
+ switch (in[4]) {
+ case onechar('w', 0, 8):
+ return atok_t_add_region::X_LOW;
+ break;
+ default:
+ break;
+ }
+ break;
+ case onechar('y', 0, 32) | onechar('_', 8, 32) | onechar('l', 16, 32) | onechar('o', 24, 32):
+ switch (in[4]) {
+ case onechar('w', 0, 8):
+ return atok_t_add_region::Y_LOW;
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ case 6:
+ switch (*((triehash_uu32*)&in[0])) {
+ case onechar('x', 0, 32) | onechar('_', 8, 32) | onechar('h', 16, 32) | onechar('i', 24, 32):
+ switch (in[4]) {
+ case onechar('g', 0, 8):
+ switch (in[5]) {
+ case onechar('h', 0, 8):
+ return atok_t_add_region::X_HIGH;
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ case onechar('y', 0, 32) | onechar('_', 8, 32) | onechar('h', 16, 32) | onechar('i', 24, 32):
+ switch (in[4]) {
+ case onechar('g', 0, 8):
+ switch (in[5]) {
+ case onechar('h', 0, 8):
+ return atok_t_add_region::Y_HIGH;
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ case 7:
+ switch (*((triehash_uu32*)&in[0])) {
+ case onechar('s', 0, 32) | onechar('u', 8, 32) | onechar('b', 16, 32) | onechar('t', 24, 32):
+ switch (in[4]) {
+ case onechar('i', 0, 8):
+ switch (in[5]) {
+ case onechar('l', 0, 8):
+ switch (in[6]) {
+ case onechar('e', 0, 8):
+ return atok_t_add_region::SUBTILE;
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ case 9:
+ switch (*((triehash_uu64*)&in[0])) {
+ case onechar('l', 0, 64) | onechar('a', 8, 64) | onechar('y', 16, 64) | onechar('e', 24, 64) | onechar('r', 32, 64) | onechar('_', 40, 64) | onechar('l', 48, 64) | onechar('o', 56, 64):
+ switch (in[8]) {
+ case onechar('w', 0, 8):
+ return atok_t_add_region::LAYER_LOW;
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ case 10:
+ switch (*((triehash_uu64*)&in[0])) {
+ case onechar('l', 0, 64) | onechar('a', 8, 64) | onechar('y', 16, 64) | onechar('e', 24, 64) | onechar('r', 32, 64) | onechar('_', 40, 64) | onechar('h', 48, 64) | onechar('i', 56, 64):
+ switch (in[8]) {
+ case onechar('g', 0, 8):
+ switch (in[9]) {
+ case onechar('h', 0, 8):
+ return atok_t_add_region::LAYER_HIGH;
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ noreturn_report(report_error, ("Found unrecognized attribute " + std::string(in) + " of .").c_str());
}
-inline gtok_t_partition lex_node_t_partition(const char *in, const std::function *report_error){
- unsigned int len = strlen(in);
- switch(len){
- case 8:
- switch(*((triehash_uu64*)&in[0])){
- case onechar('a', 0, 64) | onechar('d', 8, 64) | onechar('d', 16, 64) | onechar('_', 24, 64) | onechar('a', 32, 64) | onechar('t', 40, 64) | onechar('o', 48, 64) | onechar('m', 56, 64):
- return gtok_t_partition::ADD_ATOM;
- break;
- default: break;
- }
- break;
- case 10:
- switch(*((triehash_uu64*)&in[0])){
- case onechar('a', 0, 64) | onechar('d', 8, 64) | onechar('d', 16, 64) | onechar('_', 24, 64) | onechar('r', 32, 64) | onechar('e', 40, 64) | onechar('g', 48, 64) | onechar('i', 56, 64):
- switch(in[8]){
- case onechar('o', 0, 8):
- switch(in[9]){
- case onechar('n', 0, 8):
- return gtok_t_partition::ADD_REGION;
- break;
- default: break;
- }
- break;
- default: break;
- }
- break;
- default: break;
- }
- break;
- default: break;
- }
- noreturn_report(report_error, ("Found unrecognized child " + std::string(in) + " of .").c_str());
+inline gtok_t_partition lex_node_t_partition(const char* in, const std::function* report_error) {
+ unsigned int len = strlen(in);
+ switch (len) {
+ case 8:
+ switch (*((triehash_uu64*)&in[0])) {
+ case onechar('a', 0, 64) | onechar('d', 8, 64) | onechar('d', 16, 64) | onechar('_', 24, 64) | onechar('a', 32, 64) | onechar('t', 40, 64) | onechar('o', 48, 64) | onechar('m', 56, 64):
+ return gtok_t_partition::ADD_ATOM;
+ break;
+ default:
+ break;
+ }
+ break;
+ case 10:
+ switch (*((triehash_uu64*)&in[0])) {
+ case onechar('a', 0, 64) | onechar('d', 8, 64) | onechar('d', 16, 64) | onechar('_', 24, 64) | onechar('r', 32, 64) | onechar('e', 40, 64) | onechar('g', 48, 64) | onechar('i', 56, 64):
+ switch (in[8]) {
+ case onechar('o', 0, 8):
+ switch (in[9]) {
+ case onechar('n', 0, 8):
+ return gtok_t_partition::ADD_REGION;
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ noreturn_report(report_error, ("Found unrecognized child " + std::string(in) + " of .").c_str());
}
-inline atok_t_partition lex_attr_t_partition(const char *in, const std::function * report_error){
- unsigned int len = strlen(in);
- switch(len){
- case 4:
- switch(*((triehash_uu32*)&in[0])){
- case onechar('n', 0, 32) | onechar('a', 8, 32) | onechar('m', 16, 32) | onechar('e', 24, 32):
- return atok_t_partition::NAME;
- break;
- default: break;
- }
- break;
- default: break;
- }
- noreturn_report(report_error, ("Found unrecognized attribute " + std::string(in) + " of .").c_str());
+inline atok_t_partition lex_attr_t_partition(const char* in, const std::function* report_error) {
+ unsigned int len = strlen(in);
+ switch (len) {
+ case 4:
+ switch (*((triehash_uu32*)&in[0])) {
+ case onechar('n', 0, 32) | onechar('a', 8, 32) | onechar('m', 16, 32) | onechar('e', 24, 32):
+ return atok_t_partition::NAME;
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ noreturn_report(report_error, ("Found unrecognized attribute " + std::string(in) + " of .").c_str());
}
-inline gtok_t_partition_list lex_node_t_partition_list(const char *in, const std::function *report_error){
- unsigned int len = strlen(in);
- switch(len){
- case 9:
- switch(*((triehash_uu64*)&in[0])){
- case onechar('p', 0, 64) | onechar('a', 8, 64) | onechar('r', 16, 64) | onechar('t', 24, 64) | onechar('i', 32, 64) | onechar('t', 40, 64) | onechar('i', 48, 64) | onechar('o', 56, 64):
- switch(in[8]){
- case onechar('n', 0, 8):
- return gtok_t_partition_list::PARTITION;
- break;
- default: break;
- }
- break;
- default: break;
- }
- break;
- default: break;
- }
- noreturn_report(report_error, ("Found unrecognized child " + std::string(in) + " of .").c_str());
+inline gtok_t_partition_list lex_node_t_partition_list(const char* in, const std::function* report_error) {
+ unsigned int len = strlen(in);
+ switch (len) {
+ case 9:
+ switch (*((triehash_uu64*)&in[0])) {
+ case onechar('p', 0, 64) | onechar('a', 8, 64) | onechar('r', 16, 64) | onechar('t', 24, 64) | onechar('i', 32, 64) | onechar('t', 40, 64) | onechar('i', 48, 64) | onechar('o', 56, 64):
+ switch (in[8]) {
+ case onechar('n', 0, 8):
+ return gtok_t_partition_list::PARTITION;
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ noreturn_report(report_error, ("Found unrecognized child " + std::string(in) + " of .").c_str());
}
-inline atok_t_set_global_signal lex_attr_t_set_global_signal(const char *in, const std::function * report_error){
- unsigned int len = strlen(in);
- switch(len){
- case 4:
- switch(*((triehash_uu32*)&in[0])){
- case onechar('n', 0, 32) | onechar('a', 8, 32) | onechar('m', 16, 32) | onechar('e', 24, 32):
- return atok_t_set_global_signal::NAME;
- break;
- default: break;
- }
- break;
- case 11:
- switch(*((triehash_uu64*)&in[0])){
- case onechar('r', 0, 64) | onechar('o', 8, 64) | onechar('u', 16, 64) | onechar('t', 24, 64) | onechar('e', 32, 64) | onechar('_', 40, 64) | onechar('m', 48, 64) | onechar('o', 56, 64):
- switch(in[8]){
- case onechar('d', 0, 8):
- switch(in[9]){
- case onechar('e', 0, 8):
- switch(in[10]){
- case onechar('l', 0, 8):
- return atok_t_set_global_signal::ROUTE_MODEL;
- break;
- default: break;
- }
- break;
- default: break;
- }
- break;
- default: break;
- }
- break;
- default: break;
- }
- break;
- case 12:
- switch(*((triehash_uu64*)&in[0])){
- case onechar('n', 0, 64) | onechar('e', 8, 64) | onechar('t', 16, 64) | onechar('w', 24, 64) | onechar('o', 32, 64) | onechar('r', 40, 64) | onechar('k', 48, 64) | onechar('_', 56, 64):
- switch(*((triehash_uu32*)&in[8])){
- case onechar('n', 0, 32) | onechar('a', 8, 32) | onechar('m', 16, 32) | onechar('e', 24, 32):
- return atok_t_set_global_signal::NETWORK_NAME;
- break;
- default: break;
- }
- break;
- default: break;
- }
- break;
- default: break;
- }
- noreturn_report(report_error, ("Found unrecognized attribute " + std::string(in) + " of .").c_str());
+inline atok_t_set_global_signal lex_attr_t_set_global_signal(const char* in, const std::function* report_error) {
+ unsigned int len = strlen(in);
+ switch (len) {
+ case 4:
+ switch (*((triehash_uu32*)&in[0])) {
+ case onechar('n', 0, 32) | onechar('a', 8, 32) | onechar('m', 16, 32) | onechar('e', 24, 32):
+ return atok_t_set_global_signal::NAME;
+ break;
+ default:
+ break;
+ }
+ break;
+ case 11:
+ switch (*((triehash_uu64*)&in[0])) {
+ case onechar('r', 0, 64) | onechar('o', 8, 64) | onechar('u', 16, 64) | onechar('t', 24, 64) | onechar('e', 32, 64) | onechar('_', 40, 64) | onechar('m', 48, 64) | onechar('o', 56, 64):
+ switch (in[8]) {
+ case onechar('d', 0, 8):
+ switch (in[9]) {
+ case onechar('e', 0, 8):
+ switch (in[10]) {
+ case onechar('l', 0, 8):
+ return atok_t_set_global_signal::ROUTE_MODEL;
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ case 12:
+ switch (*((triehash_uu64*)&in[0])) {
+ case onechar('n', 0, 64) | onechar('e', 8, 64) | onechar('t', 16, 64) | onechar('w', 24, 64) | onechar('o', 32, 64) | onechar('r', 40, 64) | onechar('k', 48, 64) | onechar('_', 56, 64):
+ switch (*((triehash_uu32*)&in[8])) {
+ case onechar('n', 0, 32) | onechar('a', 8, 32) | onechar('m', 16, 32) | onechar('e', 24, 32):
+ return atok_t_set_global_signal::NETWORK_NAME;
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ noreturn_report(report_error, ("Found unrecognized attribute " + std::string(in) + " of .").c_str());
}
-inline gtok_t_global_route_constraints lex_node_t_global_route_constraints(const char *in, const std::function *report_error){
- unsigned int len = strlen(in);
- switch(len){
- case 17:
- switch(*((triehash_uu64*)&in[0])){
- case onechar('s', 0, 64) | onechar('e', 8, 64) | onechar('t', 16, 64) | onechar('_', 24, 64) | onechar('g', 32, 64) | onechar('l', 40, 64) | onechar('o', 48, 64) | onechar('b', 56, 64):
- switch(*((triehash_uu64*)&in[8])){
- case onechar('a', 0, 64) | onechar('l', 8, 64) | onechar('_', 16, 64) | onechar('s', 24, 64) | onechar('i', 32, 64) | onechar('g', 40, 64) | onechar('n', 48, 64) | onechar('a', 56, 64):
- switch(in[16]){
- case onechar('l', 0, 8):
- return gtok_t_global_route_constraints::SET_GLOBAL_SIGNAL;
- break;
- default: break;
- }
- break;
- default: break;
- }
- break;
- default: break;
- }
- break;
- default: break;
- }
- noreturn_report(report_error, ("Found unrecognized child " + std::string(in) + " of .").c_str());
+inline gtok_t_global_route_constraints lex_node_t_global_route_constraints(const char* in, const std::function* report_error) {
+ unsigned int len = strlen(in);
+ switch (len) {
+ case 17:
+ switch (*((triehash_uu64*)&in[0])) {
+ case onechar('s', 0, 64) | onechar('e', 8, 64) | onechar('t', 16, 64) | onechar('_', 24, 64) | onechar('g', 32, 64) | onechar('l', 40, 64) | onechar('o', 48, 64) | onechar('b', 56, 64):
+ switch (*((triehash_uu64*)&in[8])) {
+ case onechar('a', 0, 64) | onechar('l', 8, 64) | onechar('_', 16, 64) | onechar('s', 24, 64) | onechar('i', 32, 64) | onechar('g', 40, 64) | onechar('n', 48, 64) | onechar('a', 56, 64):
+ switch (in[16]) {
+ case onechar('l', 0, 8):
+ return gtok_t_global_route_constraints::SET_GLOBAL_SIGNAL;
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ noreturn_report(report_error, ("Found unrecognized child " + std::string(in) + " of .").c_str());
}
-inline gtok_t_vpr_constraints lex_node_t_vpr_constraints(const char *in, const std::function *report_error){
- unsigned int len = strlen(in);
- switch(len){
- case 14:
- switch(*((triehash_uu64*)&in[0])){
- case onechar('p', 0, 64) | onechar('a', 8, 64) | onechar('r', 16, 64) | onechar('t', 24, 64) | onechar('i', 32, 64) | onechar('t', 40, 64) | onechar('i', 48, 64) | onechar('o', 56, 64):
- switch(*((triehash_uu32*)&in[8])){
- case onechar('n', 0, 32) | onechar('_', 8, 32) | onechar('l', 16, 32) | onechar('i', 24, 32):
- switch(in[12]){
- case onechar('s', 0, 8):
- switch(in[13]){
- case onechar('t', 0, 8):
- return gtok_t_vpr_constraints::PARTITION_LIST;
- break;
- default: break;
- }
- break;
- default: break;
- }
- break;
- default: break;
- }
- break;
- default: break;
- }
- break;
- case 24:
- switch(*((triehash_uu64*)&in[0])){
- case onechar('g', 0, 64) | onechar('l', 8, 64) | onechar('o', 16, 64) | onechar('b', 24, 64) | onechar('a', 32, 64) | onechar('l', 40, 64) | onechar('_', 48, 64) | onechar('r', 56, 64):
- switch(*((triehash_uu64*)&in[8])){
- case onechar('o', 0, 64) | onechar('u', 8, 64) | onechar('t', 16, 64) | onechar('e', 24, 64) | onechar('_', 32, 64) | onechar('c', 40, 64) | onechar('o', 48, 64) | onechar('n', 56, 64):
- switch(*((triehash_uu64*)&in[16])){
- case onechar('s', 0, 64) | onechar('t', 8, 64) | onechar('r', 16, 64) | onechar('a', 24, 64) | onechar('i', 32, 64) | onechar('n', 40, 64) | onechar('t', 48, 64) | onechar('s', 56, 64):
- return gtok_t_vpr_constraints::GLOBAL_ROUTE_CONSTRAINTS;
- break;
- default: break;
- }
- break;
- default: break;
- }
- break;
- default: break;
- }
- break;
- default: break;
- }
- noreturn_report(report_error, ("Found unrecognized child " + std::string(in) + " of .").c_str());
+inline gtok_t_vpr_constraints lex_node_t_vpr_constraints(const char* in, const std::function* report_error) {
+ unsigned int len = strlen(in);
+ switch (len) {
+ case 14:
+ switch (*((triehash_uu64*)&in[0])) {
+ case onechar('p', 0, 64) | onechar('a', 8, 64) | onechar('r', 16, 64) | onechar('t', 24, 64) | onechar('i', 32, 64) | onechar('t', 40, 64) | onechar('i', 48, 64) | onechar('o', 56, 64):
+ switch (*((triehash_uu32*)&in[8])) {
+ case onechar('n', 0, 32) | onechar('_', 8, 32) | onechar('l', 16, 32) | onechar('i', 24, 32):
+ switch (in[12]) {
+ case onechar('s', 0, 8):
+ switch (in[13]) {
+ case onechar('t', 0, 8):
+ return gtok_t_vpr_constraints::PARTITION_LIST;
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ case 24:
+ switch (*((triehash_uu64*)&in[0])) {
+ case onechar('g', 0, 64) | onechar('l', 8, 64) | onechar('o', 16, 64) | onechar('b', 24, 64) | onechar('a', 32, 64) | onechar('l', 40, 64) | onechar('_', 48, 64) | onechar('r', 56, 64):
+ switch (*((triehash_uu64*)&in[8])) {
+ case onechar('o', 0, 64) | onechar('u', 8, 64) | onechar('t', 16, 64) | onechar('e', 24, 64) | onechar('_', 32, 64) | onechar('c', 40, 64) | onechar('o', 48, 64) | onechar('n', 56, 64):
+ switch (*((triehash_uu64*)&in[16])) {
+ case onechar('s', 0, 64) | onechar('t', 8, 64) | onechar('r', 16, 64) | onechar('a', 24, 64) | onechar('i', 32, 64) | onechar('n', 40, 64) | onechar('t', 48, 64) | onechar('s', 56, 64):
+ return gtok_t_vpr_constraints::GLOBAL_ROUTE_CONSTRAINTS;
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ noreturn_report(report_error, ("Found unrecognized child " + std::string(in) + " of .").c_str());
}
-inline atok_t_vpr_constraints lex_attr_t_vpr_constraints(const char *in, const std::function * report_error){
- unsigned int len = strlen(in);
- switch(len){
- case 9:
- switch(*((triehash_uu64*)&in[0])){
- case onechar('t', 0, 64) | onechar('o', 8, 64) | onechar('o', 16, 64) | onechar('l', 24, 64) | onechar('_', 32, 64) | onechar('n', 40, 64) | onechar('a', 48, 64) | onechar('m', 56, 64):
- switch(in[8]){
- case onechar('e', 0, 8):
- return atok_t_vpr_constraints::TOOL_NAME;
- break;
- default: break;
- }
- break;
- default: break;
- }
- break;
- default: break;
- }
- noreturn_report(report_error, ("Found unrecognized attribute " + std::string(in) + " of .").c_str());
+inline atok_t_vpr_constraints lex_attr_t_vpr_constraints(const char* in, const std::function* report_error) {
+ unsigned int len = strlen(in);
+ switch (len) {
+ case 9:
+ switch (*((triehash_uu64*)&in[0])) {
+ case onechar('t', 0, 64) | onechar('o', 8, 64) | onechar('o', 16, 64) | onechar('l', 24, 64) | onechar('_', 32, 64) | onechar('n', 40, 64) | onechar('a', 48, 64) | onechar('m', 56, 64):
+ switch (in[8]) {
+ case onechar('e', 0, 8):
+ return atok_t_vpr_constraints::TOOL_NAME;
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ noreturn_report(report_error, ("Found unrecognized attribute " + std::string(in) + " of .").c_str());
}
/**
* Internal error function for xs:choice and xs:sequence validators.
*/
-[[noreturn]] inline void dfa_error(const char *wrong, const int *states, const char * const *lookup, int len, const std::function * report_error);
+[[noreturn]] inline void dfa_error(const char* wrong, const int* states, const char* const* lookup, int len, const std::function* report_error);
/**
* Internal error function for xs:all validators.
*/
template
-[[noreturn]] inline void all_error(std::bitset gstate, const char * const *lookup, const std::function * report_error);
+[[noreturn]] inline void all_error(std::bitset gstate, const char* const* lookup, const std::function* report_error);
/**
* Internal error function for attribute validators.
*/
template
-[[noreturn]] inline void attr_error(std::bitset astate, const char * const *lookup, const std::function * report_error);
-
+[[noreturn]] inline void attr_error(std::bitset astate, const char* const* lookup, const std::function* report_error);
/* Lookup tables for enums. */
-constexpr const char *lookup_route_model_type[] = {"UXSD_INVALID", "ideal", "route", "dedicated_network"};
+constexpr const char* lookup_route_model_type[] = {"UXSD_INVALID", "ideal", "route", "dedicated_network"};
/* Lexers(string->token functions) for enums. */
-inline enum_route_model_type lex_enum_route_model_type(const char *in, bool throw_on_invalid, const std::function * report_error){
- unsigned int len = strlen(in);
- switch(len){
- case 5:
- switch(*((triehash_uu32*)&in[0])){
- case onechar('i', 0, 32) | onechar('d', 8, 32) | onechar('e', 16, 32) | onechar('a', 24, 32):
- switch(in[4]){
- case onechar('l', 0, 8):
- return enum_route_model_type::IDEAL;
- break;
- default: break;
- }
- break;
- case onechar('r', 0, 32) | onechar('o', 8, 32) | onechar('u', 16, 32) | onechar('t', 24, 32):
- switch(in[4]){
- case onechar('e', 0, 8):
- return enum_route_model_type::ROUTE;
- break;
- default: break;
- }
- break;
- default: break;
- }
- break;
- case 17:
- switch(*((triehash_uu64*)&in[0])){
- case onechar('d', 0, 64) | onechar('e', 8, 64) | onechar('d', 16, 64) | onechar('i', 24, 64) | onechar('c', 32, 64) | onechar('a', 40, 64) | onechar('t', 48, 64) | onechar('e', 56, 64):
- switch(*((triehash_uu64*)&in[8])){
- case onechar('d', 0, 64) | onechar('_', 8, 64) | onechar('n', 16, 64) | onechar('e', 24, 64) | onechar('t', 32, 64) | onechar('w', 40, 64) | onechar('o', 48, 64) | onechar('r', 56, 64):
- switch(in[16]){
- case onechar('k', 0, 8):
- return enum_route_model_type::DEDICATED_NETWORK;
- break;
- default: break;
- }
- break;
- default: break;
- }
- break;
- default: break;
- }
- break;
- default: break;
- }
- if(throw_on_invalid)
- noreturn_report(report_error, ("Found unrecognized enum value " + std::string(in) + " of enum_route_model_type.").c_str());
- return enum_route_model_type::UXSD_INVALID;
+inline enum_route_model_type lex_enum_route_model_type(const char* in, bool throw_on_invalid, const std::function* report_error) {
+ unsigned int len = strlen(in);
+ switch (len) {
+ case 5:
+ switch (*((triehash_uu32*)&in[0])) {
+ case onechar('i', 0, 32) | onechar('d', 8, 32) | onechar('e', 16, 32) | onechar('a', 24, 32):
+ switch (in[4]) {
+ case onechar('l', 0, 8):
+ return enum_route_model_type::IDEAL;
+ break;
+ default:
+ break;
+ }
+ break;
+ case onechar('r', 0, 32) | onechar('o', 8, 32) | onechar('u', 16, 32) | onechar('t', 24, 32):
+ switch (in[4]) {
+ case onechar('e', 0, 8):
+ return enum_route_model_type::ROUTE;
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ case 17:
+ switch (*((triehash_uu64*)&in[0])) {
+ case onechar('d', 0, 64) | onechar('e', 8, 64) | onechar('d', 16, 64) | onechar('i', 24, 64) | onechar('c', 32, 64) | onechar('a', 40, 64) | onechar('t', 48, 64) | onechar('e', 56, 64):
+ switch (*((triehash_uu64*)&in[8])) {
+ case onechar('d', 0, 64) | onechar('_', 8, 64) | onechar('n', 16, 64) | onechar('e', 24, 64) | onechar('t', 32, 64) | onechar('w', 40, 64) | onechar('o', 48, 64) | onechar('r', 56, 64):
+ switch (in[16]) {
+ case onechar('k', 0, 8):
+ return enum_route_model_type::DEDICATED_NETWORK;
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ if (throw_on_invalid)
+ noreturn_report(report_error, ("Found unrecognized enum value " + std::string(in) + " of enum_route_model_type.").c_str());
+ return enum_route_model_type::UXSD_INVALID;
}
-
/* Internal loading functions, which validate and load a PugiXML DOM tree into memory. */
-inline int load_int(const char *in, const std::function * report_error){
- int out;
- out = std::strtol(in, NULL, 10);
- if(errno != 0)
- noreturn_report(report_error, ("Invalid value `" + std::string(in) + "` when loading into a int.").c_str());
- return out;
+inline int load_int(const char* in, const std::function* report_error) {
+ int out;
+ out = std::strtol(in, NULL, 10);
+ if (errno != 0)
+ noreturn_report(report_error, ("Invalid value `" + std::string(in) + "` when loading into a int.").c_str());
+ return out;
}
-inline void load_add_region_required_attributes(const pugi::xml_node &root, int * x_high, int * x_low, int * y_high, int * y_low, const std::function * report_error){
- std::bitset<5> astate = 0;
- for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){
- atok_t_add_region in = lex_attr_t_add_region(attr.name(), report_error);
- if(astate[(int)in] == 0) astate[(int)in] = 1;
- else noreturn_report(report_error, ("Duplicate attribute " + std::string(attr.name()) + " in .").c_str());
- switch(in){
- case atok_t_add_region::SUBTILE:
- /* Attribute subtile set after element init */
- break;
- case atok_t_add_region::X_HIGH:
- *x_high = load_int(attr.value(), report_error);
- break;
- case atok_t_add_region::X_LOW:
- *x_low = load_int(attr.value(), report_error);
- break;
- case atok_t_add_region::Y_HIGH:
- *y_high = load_int(attr.value(), report_error);
- break;
- case atok_t_add_region::Y_LOW:
- *y_low = load_int(attr.value(), report_error);
- break;
- default: break; /* Not possible. */
- }
- }
- std::bitset<5> test_astate = astate | std::bitset<5>(0b00001);
- if(!test_astate.all()) attr_error(test_astate, atok_lookup_t_add_region, report_error);
+inline void load_add_region_required_attributes(const pugi::xml_node& root, int* x_high, int* x_low, int* y_high, int* y_low, const std::function* report_error) {
+ std::bitset<7> astate = 0;
+ for (pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()) {
+ atok_t_add_region in = lex_attr_t_add_region(attr.name(), report_error);
+ if (astate[(int)in] == 0)
+ astate[(int)in] = 1;
+ else
+ noreturn_report(report_error, ("Duplicate attribute " + std::string(attr.name()) + " in .").c_str());
+ switch (in) {
+ case atok_t_add_region::LAYER_HIGH:
+ /* Attribute layer_high set after element init */
+ break;
+ case atok_t_add_region::LAYER_LOW:
+ /* Attribute layer_low set after element init */
+ break;
+ case atok_t_add_region::SUBTILE:
+ /* Attribute subtile set after element init */
+ break;
+ case atok_t_add_region::X_HIGH:
+ *x_high = load_int(attr.value(), report_error);
+ break;
+ case atok_t_add_region::X_LOW:
+ *x_low = load_int(attr.value(), report_error);
+ break;
+ case atok_t_add_region::Y_HIGH:
+ *y_high = load_int(attr.value(), report_error);
+ break;
+ case atok_t_add_region::Y_LOW:
+ *y_low = load_int(attr.value(), report_error);
+ break;
+ default:
+ break; /* Not possible. */
+ }
+ }
+ std::bitset<7> test_astate = astate | std::bitset<7>(0b0000111);
+ if (!test_astate.all()) attr_error(test_astate, atok_lookup_t_add_region, report_error);
}
-inline void load_set_global_signal_required_attributes(const pugi::xml_node &root, enum_route_model_type * route_model, const std::function * report_error){
- std::bitset<3> astate = 0;
- for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){
- atok_t_set_global_signal in = lex_attr_t_set_global_signal(attr.name(), report_error);
- if(astate[(int)in] == 0) astate[(int)in] = 1;
- else noreturn_report(report_error, ("Duplicate attribute " + std::string(attr.name()) + " in .").c_str());
- switch(in){
- case atok_t_set_global_signal::NAME:
- /* Attribute name set after element init */
- break;
- case atok_t_set_global_signal::NETWORK_NAME:
- /* Attribute network_name set after element init */
- break;
- case atok_t_set_global_signal::ROUTE_MODEL:
- *route_model = lex_enum_route_model_type(attr.value(), true, report_error);
- break;
- default: break; /* Not possible. */
- }
- }
- std::bitset<3> test_astate = astate | std::bitset<3>(0b010);
- if(!test_astate.all()) attr_error(test_astate, atok_lookup_t_set_global_signal, report_error);
+inline void load_set_global_signal_required_attributes(const pugi::xml_node& root, enum_route_model_type* route_model, const std::function* report_error) {
+ std::bitset<3> astate = 0;
+ for (pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()) {
+ atok_t_set_global_signal in = lex_attr_t_set_global_signal(attr.name(), report_error);
+ if (astate[(int)in] == 0)
+ astate[(int)in] = 1;
+ else
+ noreturn_report(report_error, ("Duplicate attribute " + std::string(attr.name()) + " in .").c_str());
+ switch (in) {
+ case atok_t_set_global_signal::NAME:
+ /* Attribute name set after element init */
+ break;
+ case atok_t_set_global_signal::NETWORK_NAME:
+ /* Attribute network_name set after element init */
+ break;
+ case atok_t_set_global_signal::ROUTE_MODEL:
+ *route_model = lex_enum_route_model_type(attr.value(), true, report_error);
+ break;
+ default:
+ break; /* Not possible. */
+ }
+ }
+ std::bitset<3> test_astate = astate | std::bitset<3>(0b010);
+ if (!test_astate.all()) attr_error(test_astate, atok_lookup_t_set_global_signal, report_error);
}
template
-inline void load_add_atom(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug){
- (void)root;
- (void)out;
- (void)context;
- (void)report_error;
- // Update current file offset in case an error is encountered.
- *offset_debug = root.offset_debug();
-
- for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){
- atok_t_add_atom in = lex_attr_t_add_atom(attr.name(), report_error);
- switch(in){
- case atok_t_add_atom::NAME_PATTERN:
- out.set_add_atom_name_pattern(attr.value(), context);
- break;
- default: break; /* Not possible. */
- }
- }
-
- if(root.first_child().type() == pugi::node_element)
- noreturn_report(report_error, "Unexpected child element in .");
-
+inline void load_add_atom(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug) {
+ (void)root;
+ (void)out;
+ (void)context;
+ (void)report_error;
+ // Update current file offset in case an error is encountered.
+ *offset_debug = root.offset_debug();
+
+ for (pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()) {
+ atok_t_add_atom in = lex_attr_t_add_atom(attr.name(), report_error);
+ switch (in) {
+ case atok_t_add_atom::NAME_PATTERN:
+ out.set_add_atom_name_pattern(attr.value(), context);
+ break;
+ default:
+ break; /* Not possible. */
+ }
+ }
+
+ if (root.first_child().type() == pugi::node_element)
+ noreturn_report(report_error, "Unexpected child element in .");
}
template
-inline void load_add_region(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug){
- (void)root;
- (void)out;
- (void)context;
- (void)report_error;
- // Update current file offset in case an error is encountered.
- *offset_debug = root.offset_debug();
-
- for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){
- atok_t_add_region in = lex_attr_t_add_region(attr.name(), report_error);
- switch(in){
- case atok_t_add_region::SUBTILE:
- out.set_add_region_subtile(load_int(attr.value(), report_error), context);
- break;
- case atok_t_add_region::X_HIGH:
- /* Attribute x_high is already set */
- break;
- case atok_t_add_region::X_LOW:
- /* Attribute x_low is already set */
- break;
- case atok_t_add_region::Y_HIGH:
- /* Attribute y_high is already set */
- break;
- case atok_t_add_region::Y_LOW:
- /* Attribute y_low is already set */
- break;
- default: break; /* Not possible. */
- }
- }
-
- if(root.first_child().type() == pugi::node_element)
- noreturn_report(report_error, "Unexpected child element in .");
-
+inline void load_add_region(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug) {
+ (void)root;
+ (void)out;
+ (void)context;
+ (void)report_error;
+ // Update current file offset in case an error is encountered.
+ *offset_debug = root.offset_debug();
+
+ for (pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()) {
+ atok_t_add_region in = lex_attr_t_add_region(attr.name(), report_error);
+ switch (in) {
+ case atok_t_add_region::LAYER_HIGH:
+ out.set_add_region_layer_high(load_int(attr.value(), report_error), context);
+ break;
+ case atok_t_add_region::LAYER_LOW:
+ out.set_add_region_layer_low(load_int(attr.value(), report_error), context);
+ break;
+ case atok_t_add_region::SUBTILE:
+ out.set_add_region_subtile(load_int(attr.value(), report_error), context);
+ break;
+ case atok_t_add_region::X_HIGH:
+ /* Attribute x_high is already set */
+ break;
+ case atok_t_add_region::X_LOW:
+ /* Attribute x_low is already set */
+ break;
+ case atok_t_add_region::Y_HIGH:
+ /* Attribute y_high is already set */
+ break;
+ case atok_t_add_region::Y_LOW:
+ /* Attribute y_low is already set */
+ break;
+ default:
+ break; /* Not possible. */
+ }
+ }
+
+ if (root.first_child().type() == pugi::node_element)
+ noreturn_report(report_error, "Unexpected child element in .");
}
constexpr int NUM_T_PARTITION_STATES = 2;
constexpr const int NUM_T_PARTITION_INPUTS = 2;
constexpr int gstate_t_partition[NUM_T_PARTITION_STATES][NUM_T_PARTITION_INPUTS] = {
- {0, 0},
- {0, 0},
+ {0, 0},
+ {0, 0},
};
template
-inline void load_partition(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug){
- (void)root;
- (void)out;
- (void)context;
- (void)report_error;
- // Update current file offset in case an error is encountered.
- *offset_debug = root.offset_debug();
-
- for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){
- atok_t_partition in = lex_attr_t_partition(attr.name(), report_error);
- switch(in){
- case atok_t_partition::NAME:
- out.set_partition_name(attr.value(), context);
- break;
- default: break; /* Not possible. */
- }
- }
-
- // Preallocate arrays by counting child nodes (if any)
- size_t add_atom_count = 0;
- size_t add_region_count = 0;
- {
- int next, state=1;
- for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()) {
- *offset_debug = node.offset_debug();
- gtok_t_partition in = lex_node_t_partition(node.name(), report_error);
- next = gstate_t_partition[state][(int)in];
- if(next == -1)
- dfa_error(gtok_lookup_t_partition[(int)in], gstate_t_partition[state], gtok_lookup_t_partition, 2, report_error);
- state = next;
- switch(in) {
- case gtok_t_partition::ADD_ATOM:
- add_atom_count += 1;
- break;
- case gtok_t_partition::ADD_REGION:
- add_region_count += 1;
- break;
- default: break; /* Not possible. */
- }
- }
-
- out.preallocate_partition_add_atom(context, add_atom_count);
- out.preallocate_partition_add_region(context, add_region_count);
- }
- int next, state=1;
- for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){
- *offset_debug = node.offset_debug();
- gtok_t_partition in = lex_node_t_partition(node.name(), report_error);
- next = gstate_t_partition[state][(int)in];
- if(next == -1)
- dfa_error(gtok_lookup_t_partition[(int)in], gstate_t_partition[state], gtok_lookup_t_partition, 2, report_error);
- state = next;
- switch(in){
- case gtok_t_partition::ADD_ATOM:
- {
- auto child_context = out.add_partition_add_atom(context);
- load_add_atom(node, out, child_context, report_error, offset_debug);
- out.finish_partition_add_atom(child_context);
- }
- break;
- case gtok_t_partition::ADD_REGION:
- {
- int add_region_x_high;
- memset(&add_region_x_high, 0, sizeof(add_region_x_high));
- int add_region_x_low;
- memset(&add_region_x_low, 0, sizeof(add_region_x_low));
- int add_region_y_high;
- memset(&add_region_y_high, 0, sizeof(add_region_y_high));
- int add_region_y_low;
- memset(&add_region_y_low, 0, sizeof(add_region_y_low));
- load_add_region_required_attributes(node, &add_region_x_high, &add_region_x_low, &add_region_y_high, &add_region_y_low, report_error);
- auto child_context = out.add_partition_add_region(context, add_region_x_high, add_region_x_low, add_region_y_high, add_region_y_low);
- load_add_region(node, out, child_context, report_error, offset_debug);
- out.finish_partition_add_region(child_context);
- }
- break;
- default: break; /* Not possible. */
- }
- }
- if(state != 0) dfa_error("end of input", gstate_t_partition[state], gtok_lookup_t_partition, 2, report_error);
-
+inline void load_partition(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug) {
+ (void)root;
+ (void)out;
+ (void)context;
+ (void)report_error;
+ // Update current file offset in case an error is encountered.
+ *offset_debug = root.offset_debug();
+
+ for (pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()) {
+ atok_t_partition in = lex_attr_t_partition(attr.name(), report_error);
+ switch (in) {
+ case atok_t_partition::NAME:
+ out.set_partition_name(attr.value(), context);
+ break;
+ default:
+ break; /* Not possible. */
+ }
+ }
+
+ // Preallocate arrays by counting child nodes (if any)
+ size_t add_atom_count = 0;
+ size_t add_region_count = 0;
+ {
+ int next, state = 1;
+ for (pugi::xml_node node = root.first_child(); node; node = node.next_sibling()) {
+ *offset_debug = node.offset_debug();
+ gtok_t_partition in = lex_node_t_partition(node.name(), report_error);
+ next = gstate_t_partition[state][(int)in];
+ if (next == -1)
+ dfa_error(gtok_lookup_t_partition[(int)in], gstate_t_partition[state], gtok_lookup_t_partition, 2, report_error);
+ state = next;
+ switch (in) {
+ case gtok_t_partition::ADD_ATOM:
+ add_atom_count += 1;
+ break;
+ case gtok_t_partition::ADD_REGION:
+ add_region_count += 1;
+ break;
+ default:
+ break; /* Not possible. */
+ }
+ }
+
+ out.preallocate_partition_add_atom(context, add_atom_count);
+ out.preallocate_partition_add_region(context, add_region_count);
+ }
+ int next, state = 1;
+ for (pugi::xml_node node = root.first_child(); node; node = node.next_sibling()) {
+ *offset_debug = node.offset_debug();
+ gtok_t_partition in = lex_node_t_partition(node.name(), report_error);
+ next = gstate_t_partition[state][(int)in];
+ if (next == -1)
+ dfa_error(gtok_lookup_t_partition[(int)in], gstate_t_partition[state], gtok_lookup_t_partition, 2, report_error);
+ state = next;
+ switch (in) {
+ case gtok_t_partition::ADD_ATOM: {
+ auto child_context = out.add_partition_add_atom(context);
+ load_add_atom(node, out, child_context, report_error, offset_debug);
+ out.finish_partition_add_atom(child_context);
+ } break;
+ case gtok_t_partition::ADD_REGION: {
+ int add_region_x_high;
+ memset(&add_region_x_high, 0, sizeof(add_region_x_high));
+ int add_region_x_low;
+ memset(&add_region_x_low, 0, sizeof(add_region_x_low));
+ int add_region_y_high;
+ memset(&add_region_y_high, 0, sizeof(add_region_y_high));
+ int add_region_y_low;
+ memset(&add_region_y_low, 0, sizeof(add_region_y_low));
+ load_add_region_required_attributes(node, &add_region_x_high, &add_region_x_low, &add_region_y_high, &add_region_y_low, report_error);
+ auto child_context = out.add_partition_add_region(context, add_region_x_high, add_region_x_low, add_region_y_high, add_region_y_low);
+ load_add_region(node, out, child_context, report_error, offset_debug);
+ out.finish_partition_add_region(child_context);
+ } break;
+ default:
+ break; /* Not possible. */
+ }
+ }
+ if (state != 0) dfa_error("end of input", gstate_t_partition[state], gtok_lookup_t_partition, 2, report_error);
}
constexpr int NUM_T_PARTITION_LIST_STATES = 2;
constexpr const int NUM_T_PARTITION_LIST_INPUTS = 1;
constexpr int gstate_t_partition_list[NUM_T_PARTITION_LIST_STATES][NUM_T_PARTITION_LIST_INPUTS] = {
- {0},
- {0},
+ {0},
+ {0},
};
template
-inline void load_partition_list(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug){
- (void)root;
- (void)out;
- (void)context;
- (void)report_error;
- // Update current file offset in case an error is encountered.
- *offset_debug = root.offset_debug();
-
- if(root.first_attribute())
- noreturn_report(report_error, "Unexpected attribute in .");
-
- // Preallocate arrays by counting child nodes (if any)
- size_t partition_count = 0;
- {
- int next, state=1;
- for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()) {
- *offset_debug = node.offset_debug();
- gtok_t_partition_list in = lex_node_t_partition_list(node.name(), report_error);
- next = gstate_t_partition_list[state][(int)in];
- if(next == -1)
- dfa_error(gtok_lookup_t_partition_list[(int)in], gstate_t_partition_list[state], gtok_lookup_t_partition_list, 1, report_error);
- state = next;
- switch(in) {
- case gtok_t_partition_list::PARTITION:
- partition_count += 1;
- break;
- default: break; /* Not possible. */
- }
- }
-
- out.preallocate_partition_list_partition(context, partition_count);
- }
- int next, state=1;
- for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){
- *offset_debug = node.offset_debug();
- gtok_t_partition_list in = lex_node_t_partition_list(node.name(), report_error);
- next = gstate_t_partition_list[state][(int)in];
- if(next == -1)
- dfa_error(gtok_lookup_t_partition_list[(int)in], gstate_t_partition_list[state], gtok_lookup_t_partition_list, 1, report_error);
- state = next;
- switch(in){
- case gtok_t_partition_list::PARTITION:
- {
- auto child_context = out.add_partition_list_partition(context);
- load_partition(node, out, child_context, report_error, offset_debug);
- out.finish_partition_list_partition(child_context);
- }
- break;
- default: break; /* Not possible. */
- }
- }
- if(state != 0) dfa_error("end of input", gstate_t_partition_list[state], gtok_lookup_t_partition_list, 1, report_error);
-
+inline void load_partition_list(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug) {
+ (void)root;
+ (void)out;
+ (void)context;
+ (void)report_error;
+ // Update current file offset in case an error is encountered.
+ *offset_debug = root.offset_debug();
+
+ if (root.first_attribute())
+ noreturn_report(report_error, "Unexpected attribute in .");
+
+ // Preallocate arrays by counting child nodes (if any)
+ size_t partition_count = 0;
+ {
+ int next, state = 1;
+ for (pugi::xml_node node = root.first_child(); node; node = node.next_sibling()) {
+ *offset_debug = node.offset_debug();
+ gtok_t_partition_list in = lex_node_t_partition_list(node.name(), report_error);
+ next = gstate_t_partition_list[state][(int)in];
+ if (next == -1)
+ dfa_error(gtok_lookup_t_partition_list[(int)in], gstate_t_partition_list[state], gtok_lookup_t_partition_list, 1, report_error);
+ state = next;
+ switch (in) {
+ case gtok_t_partition_list::PARTITION:
+ partition_count += 1;
+ break;
+ default:
+ break; /* Not possible. */
+ }
+ }
+
+ out.preallocate_partition_list_partition(context, partition_count);
+ }
+ int next, state = 1;
+ for (pugi::xml_node node = root.first_child(); node; node = node.next_sibling()) {
+ *offset_debug = node.offset_debug();
+ gtok_t_partition_list in = lex_node_t_partition_list(node.name(), report_error);
+ next = gstate_t_partition_list[state][(int)in];
+ if (next == -1)
+ dfa_error(gtok_lookup_t_partition_list[(int)in], gstate_t_partition_list[state], gtok_lookup_t_partition_list, 1, report_error);
+ state = next;
+ switch (in) {
+ case gtok_t_partition_list::PARTITION: {
+ auto child_context = out.add_partition_list_partition(context);
+ load_partition(node, out, child_context, report_error, offset_debug);
+ out.finish_partition_list_partition(child_context);
+ } break;
+ default:
+ break; /* Not possible. */
+ }
+ }
+ if (state != 0) dfa_error("end of input", gstate_t_partition_list[state], gtok_lookup_t_partition_list, 1, report_error);
}
template
-inline void load_set_global_signal(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug){
- (void)root;
- (void)out;
- (void)context;
- (void)report_error;
- // Update current file offset in case an error is encountered.
- *offset_debug = root.offset_debug();
-
- for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){
- atok_t_set_global_signal in = lex_attr_t_set_global_signal(attr.name(), report_error);
- switch(in){
- case atok_t_set_global_signal::NAME:
- out.set_set_global_signal_name(attr.value(), context);
- break;
- case atok_t_set_global_signal::NETWORK_NAME:
- out.set_set_global_signal_network_name(attr.value(), context);
- break;
- case atok_t_set_global_signal::ROUTE_MODEL:
- /* Attribute route_model is already set */
- break;
- default: break; /* Not possible. */
- }
- }
-
- if(root.first_child().type() == pugi::node_element)
- noreturn_report(report_error, "Unexpected child element in .");
-
+inline void load_set_global_signal(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug) {
+ (void)root;
+ (void)out;
+ (void)context;
+ (void)report_error;
+ // Update current file offset in case an error is encountered.
+ *offset_debug = root.offset_debug();
+
+ for (pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()) {
+ atok_t_set_global_signal in = lex_attr_t_set_global_signal(attr.name(), report_error);
+ switch (in) {
+ case atok_t_set_global_signal::NAME:
+ out.set_set_global_signal_name(attr.value(), context);
+ break;
+ case atok_t_set_global_signal::NETWORK_NAME:
+ out.set_set_global_signal_network_name(attr.value(), context);
+ break;
+ case atok_t_set_global_signal::ROUTE_MODEL:
+ /* Attribute route_model is already set */
+ break;
+ default:
+ break; /* Not possible. */
+ }
+ }
+
+ if (root.first_child().type() == pugi::node_element)
+ noreturn_report(report_error, "Unexpected child element in .");
}
constexpr int NUM_T_GLOBAL_ROUTE_CONSTRAINTS_STATES = 2;
constexpr const int NUM_T_GLOBAL_ROUTE_CONSTRAINTS_INPUTS = 1;
constexpr int gstate_t_global_route_constraints[NUM_T_GLOBAL_ROUTE_CONSTRAINTS_STATES][NUM_T_GLOBAL_ROUTE_CONSTRAINTS_INPUTS] = {
- {0},
- {0},
+ {0},
+ {0},
};
template
-inline void load_global_route_constraints(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug){
- (void)root;
- (void)out;
- (void)context;
- (void)report_error;
- // Update current file offset in case an error is encountered.
- *offset_debug = root.offset_debug();
-
- if(root.first_attribute())
- noreturn_report(report_error, "Unexpected attribute in .");
-
- // Preallocate arrays by counting child nodes (if any)
- size_t set_global_signal_count = 0;
- {
- int next, state=1;
- for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()) {
- *offset_debug = node.offset_debug();
- gtok_t_global_route_constraints in = lex_node_t_global_route_constraints(node.name(), report_error);
- next = gstate_t_global_route_constraints[state][(int)in];
- if(next == -1)
- dfa_error(gtok_lookup_t_global_route_constraints[(int)in], gstate_t_global_route_constraints[state], gtok_lookup_t_global_route_constraints, 1, report_error);
- state = next;
- switch(in) {
- case gtok_t_global_route_constraints::SET_GLOBAL_SIGNAL:
- set_global_signal_count += 1;
- break;
- default: break; /* Not possible. */
- }
- }
-
- out.preallocate_global_route_constraints_set_global_signal(context, set_global_signal_count);
- }
- int next, state=1;
- for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){
- *offset_debug = node.offset_debug();
- gtok_t_global_route_constraints in = lex_node_t_global_route_constraints(node.name(), report_error);
- next = gstate_t_global_route_constraints[state][(int)in];
- if(next == -1)
- dfa_error(gtok_lookup_t_global_route_constraints[(int)in], gstate_t_global_route_constraints[state], gtok_lookup_t_global_route_constraints, 1, report_error);
- state = next;
- switch(in){
- case gtok_t_global_route_constraints::SET_GLOBAL_SIGNAL:
- {
- enum_route_model_type set_global_signal_route_model;
- memset(&set_global_signal_route_model, 0, sizeof(set_global_signal_route_model));
- load_set_global_signal_required_attributes(node, &set_global_signal_route_model, report_error);
- auto child_context = out.add_global_route_constraints_set_global_signal(context, set_global_signal_route_model);
- load_set_global_signal(node, out, child_context, report_error, offset_debug);
- out.finish_global_route_constraints_set_global_signal(child_context);
- }
- break;
- default: break; /* Not possible. */
- }
- }
- if(state != 0) dfa_error("end of input", gstate_t_global_route_constraints[state], gtok_lookup_t_global_route_constraints, 1, report_error);
-
+inline void load_global_route_constraints(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug) {
+ (void)root;
+ (void)out;
+ (void)context;
+ (void)report_error;
+ // Update current file offset in case an error is encountered.
+ *offset_debug = root.offset_debug();
+
+ if (root.first_attribute())
+ noreturn_report(report_error, "Unexpected attribute in .");
+
+ // Preallocate arrays by counting child nodes (if any)
+ size_t set_global_signal_count = 0;
+ {
+ int next, state = 1;
+ for (pugi::xml_node node = root.first_child(); node; node = node.next_sibling()) {
+ *offset_debug = node.offset_debug();
+ gtok_t_global_route_constraints in = lex_node_t_global_route_constraints(node.name(), report_error);
+ next = gstate_t_global_route_constraints[state][(int)in];
+ if (next == -1)
+ dfa_error(gtok_lookup_t_global_route_constraints[(int)in], gstate_t_global_route_constraints[state], gtok_lookup_t_global_route_constraints, 1, report_error);
+ state = next;
+ switch (in) {
+ case gtok_t_global_route_constraints::SET_GLOBAL_SIGNAL:
+ set_global_signal_count += 1;
+ break;
+ default:
+ break; /* Not possible. */
+ }
+ }
+
+ out.preallocate_global_route_constraints_set_global_signal(context, set_global_signal_count);
+ }
+ int next, state = 1;
+ for (pugi::xml_node node = root.first_child(); node; node = node.next_sibling()) {
+ *offset_debug = node.offset_debug();
+ gtok_t_global_route_constraints in = lex_node_t_global_route_constraints(node.name(), report_error);
+ next = gstate_t_global_route_constraints[state][(int)in];
+ if (next == -1)
+ dfa_error(gtok_lookup_t_global_route_constraints[(int)in], gstate_t_global_route_constraints[state], gtok_lookup_t_global_route_constraints, 1, report_error);
+ state = next;
+ switch (in) {
+ case gtok_t_global_route_constraints::SET_GLOBAL_SIGNAL: {
+ enum_route_model_type set_global_signal_route_model;
+ memset(&set_global_signal_route_model, 0, sizeof(set_global_signal_route_model));
+ load_set_global_signal_required_attributes(node, &set_global_signal_route_model, report_error);
+ auto child_context = out.add_global_route_constraints_set_global_signal(context, set_global_signal_route_model);
+ load_set_global_signal(node, out, child_context, report_error, offset_debug);
+ out.finish_global_route_constraints_set_global_signal(child_context);
+ } break;
+ default:
+ break; /* Not possible. */
+ }
+ }
+ if (state != 0) dfa_error("end of input", gstate_t_global_route_constraints[state], gtok_lookup_t_global_route_constraints, 1, report_error);
}
template
-inline void load_vpr_constraints(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug){
- (void)root;
- (void)out;
- (void)context;
- (void)report_error;
- // Update current file offset in case an error is encountered.
- *offset_debug = root.offset_debug();
-
- for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){
- atok_t_vpr_constraints in = lex_attr_t_vpr_constraints(attr.name(), report_error);
- switch(in){
- case atok_t_vpr_constraints::TOOL_NAME:
- out.set_vpr_constraints_tool_name(attr.value(), context);
- break;
- default: break; /* Not possible. */
- }
- }
-
- std::bitset<2> gstate = 0;
- for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){
- *offset_debug = node.offset_debug();
- gtok_t_vpr_constraints in = lex_node_t_vpr_constraints(node.name(), report_error);
- if(gstate[(int)in] == 0) gstate[(int)in] = 1;
- else noreturn_report(report_error, ("Duplicate element " + std::string(node.name()) + " in .").c_str());
- switch(in){
- case gtok_t_vpr_constraints::PARTITION_LIST:
- {
- auto child_context = out.init_vpr_constraints_partition_list(context);
- load_partition_list(node, out, child_context, report_error, offset_debug);
- out.finish_vpr_constraints_partition_list(child_context);
- }
- break;
- case gtok_t_vpr_constraints::GLOBAL_ROUTE_CONSTRAINTS:
- {
- auto child_context = out.init_vpr_constraints_global_route_constraints(context);
- load_global_route_constraints(node, out, child_context, report_error, offset_debug);
- out.finish_vpr_constraints_global_route_constraints(child_context);
- }
- break;
- default: break; /* Not possible. */
- }
- }
- std::bitset<2> test_gstate = gstate | std::bitset<2>(0b11);
- if(!test_gstate.all()) all_error(test_gstate, gtok_lookup_t_vpr_constraints, report_error);
-
+inline void load_vpr_constraints(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug) {
+ (void)root;
+ (void)out;
+ (void)context;
+ (void)report_error;
+ // Update current file offset in case an error is encountered.
+ *offset_debug = root.offset_debug();
+
+ for (pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()) {
+ atok_t_vpr_constraints in = lex_attr_t_vpr_constraints(attr.name(), report_error);
+ switch (in) {
+ case atok_t_vpr_constraints::TOOL_NAME:
+ out.set_vpr_constraints_tool_name(attr.value(), context);
+ break;
+ default:
+ break; /* Not possible. */
+ }
+ }
+
+ std::bitset<2> gstate = 0;
+ for (pugi::xml_node node = root.first_child(); node; node = node.next_sibling()) {
+ *offset_debug = node.offset_debug();
+ gtok_t_vpr_constraints in = lex_node_t_vpr_constraints(node.name(), report_error);
+ if (gstate[(int)in] == 0)
+ gstate[(int)in] = 1;
+ else
+ noreturn_report(report_error, ("Duplicate element " + std::string(node.name()) + " in .").c_str());
+ switch (in) {
+ case gtok_t_vpr_constraints::PARTITION_LIST: {
+ auto child_context = out.init_vpr_constraints_partition_list(context);
+ load_partition_list(node, out, child_context, report_error, offset_debug);
+ out.finish_vpr_constraints_partition_list(child_context);
+ } break;
+ case gtok_t_vpr_constraints::GLOBAL_ROUTE_CONSTRAINTS: {
+ auto child_context = out.init_vpr_constraints_global_route_constraints(context);
+ load_global_route_constraints(node, out, child_context, report_error, offset_debug);
+ out.finish_vpr_constraints_global_route_constraints(child_context);
+ } break;
+ default:
+ break; /* Not possible. */
+ }
+ }
+ std::bitset<2> test_gstate = gstate | std::bitset<2>(0b11);
+ if (!test_gstate.all()) all_error(test_gstate, gtok_lookup_t_vpr_constraints, report_error);
}
-
/* Internal writing functions, which uxsdcxx uses to write out a class. */
template
-inline void write_partition(T &in, std::ostream &os, Context &context){
- (void)in;
- (void)os;
- (void)context;
- {
- for(size_t i=0, n=in.num_partition_add_atom(context); i\n";
- }
- }
- {
- for(size_t i=0, n=in.num_partition_add_region(context); i\n";
- }
- }
+inline void write_partition(T& in, std::ostream& os, Context& context) {
+ (void)in;
+ (void)os;
+ (void)context;
+ {
+ for (size_t i = 0, n = in.num_partition_add_atom(context); i < n; i++) {
+ auto child_context = in.get_partition_add_atom(i, context);
+ os << "\n";
+ }
+ }
+ {
+ for (size_t i = 0, n = in.num_partition_add_region(context); i < n; i++) {
+ auto child_context = in.get_partition_add_region(i, context);
+ os << "\n";
+ }
+ }
}
template
-inline void write_partition_list(T &in, std::ostream &os, Context &context){
- (void)in;
- (void)os;
- (void)context;
- {
- for(size_t i=0, n=in.num_partition_list_partition(context); i";
- write_partition(in, os, child_context);
- os << "\n";
- }
- }
+inline void write_partition_list(T& in, std::ostream& os, Context& context) {
+ (void)in;
+ (void)os;
+ (void)context;
+ {
+ for (size_t i = 0, n = in.num_partition_list_partition(context); i < n; i++) {
+ auto child_context = in.get_partition_list_partition(i, context);
+ os << "";
+ write_partition(in, os, child_context);
+ os << "\n";
+ }
+ }
}
template
-inline void write_global_route_constraints(T &in, std::ostream &os, Context &context){
- (void)in;
- (void)os;
- (void)context;
- {
- for(size_t i=0, n=in.num_global_route_constraints_set_global_signal(context); i\n";
- }
- }
+inline void write_global_route_constraints(T& in, std::ostream& os, Context& context) {
+ (void)in;
+ (void)os;
+ (void)context;
+ {
+ for (size_t i = 0, n = in.num_global_route_constraints_set_global_signal(context); i < n; i++) {
+ auto child_context = in.get_global_route_constraints_set_global_signal(i, context);
+ os << "\n";
+ }
+ }
}
template
-inline void write_vpr_constraints(T &in, std::ostream &os, Context &context){
- (void)in;
- (void)os;
- (void)context;
- {
- if(in.has_vpr_constraints_partition_list(context)){
- auto child_context = in.get_vpr_constraints_partition_list(context);
- os << "\n";
- write_partition_list(in, os, child_context);
- os << "\n";
- }
- }
- {
- if(in.has_vpr_constraints_global_route_constraints(context)){
- auto child_context = in.get_vpr_constraints_global_route_constraints(context);
- os << "\n";
- write_global_route_constraints(in, os, child_context);
- os << "\n";
- }
- }
+inline void write_vpr_constraints(T& in, std::ostream& os, Context& context) {
+ (void)in;
+ (void)os;
+ (void)context;
+ {
+ if (in.has_vpr_constraints_partition_list(context)) {
+ auto child_context = in.get_vpr_constraints_partition_list(context);
+ os << "\n";
+ write_partition_list(in, os, child_context);
+ os << "\n";
+ }
+ }
+ {
+ if (in.has_vpr_constraints_global_route_constraints(context)) {
+ auto child_context = in.get_vpr_constraints_global_route_constraints(context);
+ os << "\n";
+ write_global_route_constraints(in, os, child_context);
+ os << "\n";
+ }
+ }
}
-inline void dfa_error(const char *wrong, const int *states, const char * const *lookup, int len, const std::function * report_error){
- std::vector expected;
- for(int i=0; i* report_error) {
+ std::vector expected;
+ for (int i = 0; i < len; i++) {
+ if (states[i] != -1) expected.push_back(lookup[i]);
+ }
- std::string expected_or = expected[0];
- for(unsigned int i=1; i
-inline void all_error(std::bitset gstate, const char * const *lookup, const std::function * report_error){
- std::vector missing;
- for(unsigned int i=0; i gstate, const char* const* lookup, const std::function* report_error) {
+ std::vector missing;
+ for (unsigned int i = 0; i < N; i++) {
+ if (gstate[i] == 0) missing.push_back(lookup[i]);
+ }
- std::string missing_and = missing[0];
- for(unsigned int i=1; i
-inline void attr_error(std::bitset astate, const char * const *lookup, const std::function * report_error){
- std::vector missing;
- for(unsigned int i=0; i astate, const char* const* lookup, const std::function* report_error) {
+ std::vector missing;
+ for (unsigned int i = 0; i < N; i++) {
+ if (astate[i] == 0) missing.push_back(lookup[i]);
+ }
- std::string missing_and = missing[0];
- for(unsigned int i=1; i f(fopen(filename, "rb"), fclose);
-
- if (!f) {
- throw std::runtime_error(std::string("Failed to open file") + filename);
- }
-
- int current_line = 1;
- std::ptrdiff_t offset = 0;
- std::ptrdiff_t last_line_offset = 0;
- std::ptrdiff_t current_line_offset = 0;
-
- char buffer[1024];
- std::size_t size;
-
- while ((size = fread(buffer, 1, sizeof(buffer), f.get())) > 0) {
- for (std::size_t i = 0; i < size; ++i) {
- if (buffer[i] == '\n') {
- current_line += 1;
- last_line_offset = current_line_offset;
- current_line_offset = offset + i;
-
- if(target_offset < current_line_offset) {
- if(target_offset < last_line_offset) {
- throw std::runtime_error("Assertion violation");
- }
-
- *line = current_line - 1;
- *col = target_offset - last_line_offset;
- return;
- }
- }
- }
-
- offset += size;
- }
-
- *line = current_line;
- *col = target_offset - current_line_offset;
+inline void get_line_number(const char* filename, std::ptrdiff_t target_offset, int* line, int* col) {
+ std::unique_ptr f(fopen(filename, "rb"), fclose);
+
+ if (!f) {
+ throw std::runtime_error(std::string("Failed to open file") + filename);
+ }
+
+ int current_line = 1;
+ std::ptrdiff_t offset = 0;
+ std::ptrdiff_t last_line_offset = 0;
+ std::ptrdiff_t current_line_offset = 0;
+
+ char buffer[1024];
+ std::size_t size;
+
+ while ((size = fread(buffer, 1, sizeof(buffer), f.get())) > 0) {
+ for (std::size_t i = 0; i < size; ++i) {
+ if (buffer[i] == '\n') {
+ current_line += 1;
+ last_line_offset = current_line_offset;
+ current_line_offset = offset + i;
+
+ if (target_offset < current_line_offset) {
+ if (target_offset < last_line_offset) {
+ throw std::runtime_error("Assertion violation");
+ }
+
+ *line = current_line - 1;
+ *col = target_offset - last_line_offset;
+ return;
+ }
+ }
+ }
+
+ offset += size;
+ }
+
+ *line = current_line;
+ *col = target_offset - current_line_offset;
}
-
} /* namespace uxsd */
diff --git a/vpr/src/base/gen/vpr_constraints_uxsdcxx_interface.h b/vpr/src/base/gen/vpr_constraints_uxsdcxx_interface.h
index 64c20239e6e..2c3231b70a5 100644
--- a/vpr/src/base/gen/vpr_constraints_uxsdcxx_interface.h
+++ b/vpr/src/base/gen/vpr_constraints_uxsdcxx_interface.h
@@ -4,14 +4,13 @@
* https://github.com/duck2/uxsdcxx
* Modify only if your build process doesn't involve regenerating this file.
*
- * Cmdline: /home/kimia/uxsdcxx/uxsdcxx.py ../vpr_constraints.xsd
- * Input file: /home/kimia/vtr-verilog-to-routing/vpr/src/base/vpr_constraints.xsd
- * md5sum of input file: f2b3721db9b14ccdf0787c9c99e00a78
+ * Cmdline: uxsdcxx.py ../vpr_repos/vpr/src/base/vpr_constraints.xsd
+ * Input file: /home/soheil/vpr_repos/vpr/src/base/vpr_constraints.xsd
+ * md5sum of input file: ea99cd05d67036ef541872d9d77a83c5
*/
#include
-
/* All uxsdcxx functions and structs live in this namespace. */
#include
@@ -21,141 +20,148 @@ namespace uxsd {
/* Enum tokens generated from XSD enumerations. */
-enum class enum_route_model_type {UXSD_INVALID = 0, IDEAL, ROUTE, DEDICATED_NETWORK};
+enum class enum_route_model_type { UXSD_INVALID = 0,
+ IDEAL,
+ ROUTE,
+ DEDICATED_NETWORK };
/* Base class for the schema. */
struct DefaultVprConstraintsContextTypes {
-using AddAtomReadContext = void *;
- using AddRegionReadContext = void *;
- using PartitionReadContext = void *;
- using PartitionListReadContext = void *;
- using SetGlobalSignalReadContext = void *;
- using GlobalRouteConstraintsReadContext = void *;
- using VprConstraintsReadContext = void *;
-using AddAtomWriteContext = void *;
- using AddRegionWriteContext = void *;
- using PartitionWriteContext = void *;
- using PartitionListWriteContext = void *;
- using SetGlobalSignalWriteContext = void *;
- using GlobalRouteConstraintsWriteContext = void *;
- using VprConstraintsWriteContext = void *;
+ using AddAtomReadContext = void*;
+ using AddRegionReadContext = void*;
+ using PartitionReadContext = void*;
+ using PartitionListReadContext = void*;
+ using SetGlobalSignalReadContext = void*;
+ using GlobalRouteConstraintsReadContext = void*;
+ using VprConstraintsReadContext = void*;
+ using AddAtomWriteContext = void*;
+ using AddRegionWriteContext = void*;
+ using PartitionWriteContext = void*;
+ using PartitionListWriteContext = void*;
+ using SetGlobalSignalWriteContext = void*;
+ using GlobalRouteConstraintsWriteContext = void*;
+ using VprConstraintsWriteContext = void*;
};
-template
+template
class VprConstraintsBase {
-public:
- virtual ~VprConstraintsBase() {}
- virtual void start_load(const std::function *report_error) = 0;
- virtual void finish_load() = 0;
- virtual void start_write() = 0;
- virtual void finish_write() = 0;
- virtual void error_encountered(const char * file, int line, const char *message) = 0;
- /** Generated for complex type "add_atom":
- *
- *
- *
- */
- virtual inline const char * get_add_atom_name_pattern(typename ContextTypes::AddAtomReadContext &ctx) = 0;
- virtual inline void set_add_atom_name_pattern(const char * name_pattern, typename ContextTypes::AddAtomWriteContext &ctx) = 0;
-
- /** Generated for complex type "add_region":
- *
- *
- *
- *
- *
- *
- *
- */
- virtual inline int get_add_region_subtile(typename ContextTypes::AddRegionReadContext &ctx) = 0;
- virtual inline void set_add_region_subtile(int subtile, typename ContextTypes::AddRegionWriteContext &ctx) = 0;
- virtual inline int get_add_region_x_high(typename ContextTypes::AddRegionReadContext &ctx) = 0;
- virtual inline int get_add_region_x_low(typename ContextTypes::AddRegionReadContext &ctx) = 0;
- virtual inline int get_add_region_y_high(typename ContextTypes::AddRegionReadContext &ctx) = 0;
- virtual inline int get_add_region_y_low(typename ContextTypes::AddRegionReadContext &ctx) = 0;
-
- /** Generated for complex type "partition":
- *
- *
- *
- *
- *
- *
- *
- *
- *
- */
- virtual inline const char * get_partition_name(typename ContextTypes::PartitionReadContext &ctx) = 0;
- virtual inline void set_partition_name(const char * name, typename ContextTypes::PartitionWriteContext &ctx) = 0;
- virtual inline void preallocate_partition_add_atom(typename ContextTypes::PartitionWriteContext &ctx, size_t size) = 0;
- virtual inline typename ContextTypes::AddAtomWriteContext add_partition_add_atom(typename ContextTypes::PartitionWriteContext &ctx) = 0;
- virtual inline void finish_partition_add_atom(typename ContextTypes::AddAtomWriteContext &ctx) = 0;
- virtual inline size_t num_partition_add_atom(typename ContextTypes::PartitionReadContext &ctx) = 0;
- virtual inline typename ContextTypes::AddAtomReadContext get_partition_add_atom(int n, typename ContextTypes::PartitionReadContext &ctx) = 0;
- virtual inline void preallocate_partition_add_region(typename ContextTypes::PartitionWriteContext &ctx, size_t size) = 0;
- virtual inline typename ContextTypes::AddRegionWriteContext add_partition_add_region(typename ContextTypes::PartitionWriteContext &ctx, int x_high, int x_low, int y_high, int y_low) = 0;
- virtual inline void finish_partition_add_region(typename ContextTypes::AddRegionWriteContext &ctx) = 0;
- virtual inline size_t num_partition_add_region(typename ContextTypes::PartitionReadContext &ctx) = 0;
- virtual inline typename ContextTypes::AddRegionReadContext get_partition_add_region(int n, typename ContextTypes::PartitionReadContext &ctx) = 0;
-
- /** Generated for complex type "partition_list":
- *
- *
- *
- *
- *
- */
- virtual inline void preallocate_partition_list_partition(typename ContextTypes::PartitionListWriteContext &ctx, size_t size) = 0;
- virtual inline typename ContextTypes::PartitionWriteContext add_partition_list_partition(typename ContextTypes::PartitionListWriteContext &ctx) = 0;
- virtual inline void finish_partition_list_partition(typename ContextTypes::PartitionWriteContext &ctx) = 0;
- virtual inline size_t num_partition_list_partition(typename ContextTypes::PartitionListReadContext &ctx) = 0;
- virtual inline typename ContextTypes::PartitionReadContext get_partition_list_partition(int n, typename ContextTypes::PartitionListReadContext &ctx) = 0;
-
- /** Generated for complex type "set_global_signal":
- *
- *
- *
- *
- *
- */
- virtual inline const char * get_set_global_signal_name(typename ContextTypes::SetGlobalSignalReadContext &ctx) = 0;
- virtual inline void set_set_global_signal_name(const char * name, typename ContextTypes::SetGlobalSignalWriteContext &ctx) = 0;
- virtual inline const char * get_set_global_signal_network_name(typename ContextTypes::SetGlobalSignalReadContext &ctx) = 0;
- virtual inline void set_set_global_signal_network_name(const char * network_name, typename ContextTypes::SetGlobalSignalWriteContext &ctx) = 0;
- virtual inline enum_route_model_type get_set_global_signal_route_model(typename ContextTypes::SetGlobalSignalReadContext &ctx) = 0;
-
- /** Generated for complex type "global_route_constraints":
- *
- *
- *
- *
- *
- */
- virtual inline void preallocate_global_route_constraints_set_global_signal(typename ContextTypes::GlobalRouteConstraintsWriteContext &ctx, size_t size) = 0;
- virtual inline typename ContextTypes::SetGlobalSignalWriteContext add_global_route_constraints_set_global_signal(typename ContextTypes::GlobalRouteConstraintsWriteContext &ctx, enum_route_model_type route_model) = 0;
- virtual inline void finish_global_route_constraints_set_global_signal(typename ContextTypes::SetGlobalSignalWriteContext &ctx) = 0;
- virtual inline size_t num_global_route_constraints_set_global_signal(typename ContextTypes::GlobalRouteConstraintsReadContext &ctx) = 0;
- virtual inline typename ContextTypes::SetGlobalSignalReadContext get_global_route_constraints_set_global_signal(int n, typename ContextTypes::GlobalRouteConstraintsReadContext &ctx) = 0;
-
- /** Generated for complex type "vpr_constraints":
- *
- *
- *
- *
- *
- *
- *
- */
- virtual inline const char * get_vpr_constraints_tool_name(typename ContextTypes::VprConstraintsReadContext &ctx) = 0;
- virtual inline void set_vpr_constraints_tool_name(const char * tool_name, typename ContextTypes::VprConstraintsWriteContext &ctx) = 0;
- virtual inline typename ContextTypes::PartitionListWriteContext init_vpr_constraints_partition_list(typename ContextTypes::VprConstraintsWriteContext &ctx) = 0;
- virtual inline void finish_vpr_constraints_partition_list(typename ContextTypes::PartitionListWriteContext &ctx) = 0;
- virtual inline typename ContextTypes::PartitionListReadContext get_vpr_constraints_partition_list(typename ContextTypes::VprConstraintsReadContext &ctx) = 0;
- virtual inline bool has_vpr_constraints_partition_list(typename ContextTypes::VprConstraintsReadContext &ctx) = 0;
- virtual inline typename ContextTypes::GlobalRouteConstraintsWriteContext init_vpr_constraints_global_route_constraints(typename ContextTypes::VprConstraintsWriteContext &ctx) = 0;
- virtual inline void finish_vpr_constraints_global_route_constraints(typename ContextTypes::GlobalRouteConstraintsWriteContext &ctx) = 0;
- virtual inline typename ContextTypes::GlobalRouteConstraintsReadContext get_vpr_constraints_global_route_constraints(typename ContextTypes::VprConstraintsReadContext &ctx) = 0;
- virtual inline bool has_vpr_constraints_global_route_constraints(typename ContextTypes::VprConstraintsReadContext &ctx) = 0;
+ public:
+ virtual ~VprConstraintsBase() {}
+ virtual void start_load(const std::function* report_error) = 0;
+ virtual void finish_load() = 0;
+ virtual void start_write() = 0;
+ virtual void finish_write() = 0;
+ virtual void error_encountered(const char* file, int line, const char* message) = 0;
+ /** Generated for complex type "add_atom":
+ *
+ *
+ *
+ */
+ virtual inline const char* get_add_atom_name_pattern(typename ContextTypes::AddAtomReadContext& ctx) = 0;
+ virtual inline void set_add_atom_name_pattern(const char* name_pattern, typename ContextTypes::AddAtomWriteContext& ctx) = 0;
+
+ /** Generated for complex type "add_region":
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ */
+ virtual inline int get_add_region_layer_high(typename ContextTypes::AddRegionReadContext& ctx) = 0;
+ virtual inline int get_add_region_layer_low(typename ContextTypes::AddRegionReadContext& ctx) = 0;
+ virtual inline int get_add_region_subtile(typename ContextTypes::AddRegionReadContext& ctx) = 0;
+ virtual inline void set_add_region_subtile(int subtile, typename ContextTypes::AddRegionWriteContext& ctx) = 0;
+ virtual inline int get_add_region_x_high(typename ContextTypes::AddRegionReadContext& ctx) = 0;
+ virtual inline int get_add_region_x_low(typename ContextTypes::AddRegionReadContext& ctx) = 0;
+ virtual inline int get_add_region_y_high(typename ContextTypes::AddRegionReadContext& ctx) = 0;
+ virtual inline int get_add_region_y_low(typename ContextTypes::AddRegionReadContext& ctx) = 0;
+
+ /** Generated for complex type "partition":
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ */
+ virtual inline const char* get_partition_name(typename ContextTypes::PartitionReadContext& ctx) = 0;
+ virtual inline void set_partition_name(const char* name, typename ContextTypes::PartitionWriteContext& ctx) = 0;
+ virtual inline void preallocate_partition_add_atom(typename ContextTypes::PartitionWriteContext& ctx, size_t size) = 0;
+ virtual inline typename ContextTypes::AddAtomWriteContext add_partition_add_atom(typename ContextTypes::PartitionWriteContext& ctx) = 0;
+ virtual inline void finish_partition_add_atom(typename ContextTypes::AddAtomWriteContext& ctx) = 0;
+ virtual inline size_t num_partition_add_atom(typename ContextTypes::PartitionReadContext& ctx) = 0;
+ virtual inline typename ContextTypes::AddAtomReadContext get_partition_add_atom(int n, typename ContextTypes::PartitionReadContext& ctx) = 0;
+ virtual inline void preallocate_partition_add_region(typename ContextTypes::PartitionWriteContext& ctx, size_t size) = 0;
+ virtual inline typename ContextTypes::AddRegionWriteContext add_partition_add_region(typename ContextTypes::PartitionWriteContext& ctx, int x_high, int x_low, int y_high, int y_low) = 0;
+ virtual inline void finish_partition_add_region(typename ContextTypes::AddRegionWriteContext& ctx) = 0;
+ virtual inline size_t num_partition_add_region(typename ContextTypes::PartitionReadContext& ctx) = 0;
+ virtual inline typename ContextTypes::AddRegionReadContext get_partition_add_region(int n, typename ContextTypes::PartitionReadContext& ctx) = 0;
+
+ /** Generated for complex type "partition_list":
+ *
+ *
+ *
+ *
+ *
+ */
+ virtual inline void preallocate_partition_list_partition(typename ContextTypes::PartitionListWriteContext& ctx, size_t size) = 0;
+ virtual inline typename ContextTypes::PartitionWriteContext add_partition_list_partition(typename ContextTypes::PartitionListWriteContext& ctx) = 0;
+ virtual inline void finish_partition_list_partition(typename ContextTypes::PartitionWriteContext& ctx) = 0;
+ virtual inline size_t num_partition_list_partition(typename ContextTypes::PartitionListReadContext& ctx) = 0;
+ virtual inline typename ContextTypes::PartitionReadContext get_partition_list_partition(int n, typename ContextTypes::PartitionListReadContext& ctx) = 0;
+
+ /** Generated for complex type "set_global_signal":
+ *
+ *
+ *
+ *
+ *
+ */
+ virtual inline const char* get_set_global_signal_name(typename ContextTypes::SetGlobalSignalReadContext& ctx) = 0;
+ virtual inline void set_set_global_signal_name(const char* name, typename ContextTypes::SetGlobalSignalWriteContext& ctx) = 0;
+ virtual inline const char* get_set_global_signal_network_name(typename ContextTypes::SetGlobalSignalReadContext& ctx) = 0;
+ virtual inline void set_set_global_signal_network_name(const char* network_name, typename ContextTypes::SetGlobalSignalWriteContext& ctx) = 0;
+ virtual inline enum_route_model_type get_set_global_signal_route_model(typename ContextTypes::SetGlobalSignalReadContext& ctx) = 0;
+
+ /** Generated for complex type "global_route_constraints":
+ *
+ *
+ *
+ *
+ *
+ */
+ virtual inline void preallocate_global_route_constraints_set_global_signal(typename ContextTypes::GlobalRouteConstraintsWriteContext& ctx, size_t size) = 0;
+ virtual inline typename ContextTypes::SetGlobalSignalWriteContext add_global_route_constraints_set_global_signal(typename ContextTypes::GlobalRouteConstraintsWriteContext& ctx, enum_route_model_type route_model) = 0;
+ virtual inline void finish_global_route_constraints_set_global_signal(typename ContextTypes::SetGlobalSignalWriteContext& ctx) = 0;
+ virtual inline size_t num_global_route_constraints_set_global_signal(typename ContextTypes::GlobalRouteConstraintsReadContext& ctx) = 0;
+ virtual inline typename ContextTypes::SetGlobalSignalReadContext get_global_route_constraints_set_global_signal(int n, typename ContextTypes::GlobalRouteConstraintsReadContext& ctx) = 0;
+
+ /** Generated for complex type "vpr_constraints":
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ */
+ virtual inline const char* get_vpr_constraints_tool_name(typename ContextTypes::VprConstraintsReadContext& ctx) = 0;
+ virtual inline void set_vpr_constraints_tool_name(const char* tool_name, typename ContextTypes::VprConstraintsWriteContext& ctx) = 0;
+ virtual inline typename ContextTypes::PartitionListWriteContext init_vpr_constraints_partition_list(typename ContextTypes::VprConstraintsWriteContext& ctx) = 0;
+ virtual inline void finish_vpr_constraints_partition_list(typename ContextTypes::PartitionListWriteContext& ctx) = 0;
+ virtual inline typename ContextTypes::PartitionListReadContext get_vpr_constraints_partition_list(typename ContextTypes::VprConstraintsReadContext& ctx) = 0;
+ virtual inline bool has_vpr_constraints_partition_list(typename ContextTypes::VprConstraintsReadContext& ctx) = 0;
+ virtual inline typename ContextTypes::GlobalRouteConstraintsWriteContext init_vpr_constraints_global_route_constraints(typename ContextTypes::VprConstraintsWriteContext& ctx) = 0;
+ virtual inline void finish_vpr_constraints_global_route_constraints(typename ContextTypes::GlobalRouteConstraintsWriteContext& ctx) = 0;
+ virtual inline typename ContextTypes::GlobalRouteConstraintsReadContext get_vpr_constraints_global_route_constraints(typename ContextTypes::VprConstraintsReadContext& ctx) = 0;
+ virtual inline bool has_vpr_constraints_global_route_constraints(typename ContextTypes::VprConstraintsReadContext& ctx) = 0;
};
} /* namespace uxsd */
diff --git a/vpr/src/base/partition.cpp b/vpr/src/base/partition.cpp
index 6e004b86d46..bbb9d472b2c 100644
--- a/vpr/src/base/partition.cpp
+++ b/vpr/src/base/partition.cpp
@@ -3,7 +3,7 @@
#include
#include
-const std::string& Partition::get_name() const{
+const std::string& Partition::get_name() const {
return name;
}
diff --git a/vpr/src/base/partition_region.cpp b/vpr/src/base/partition_region.cpp
index 14961efc919..5014976eec4 100644
--- a/vpr/src/base/partition_region.cpp
+++ b/vpr/src/base/partition_region.cpp
@@ -1,5 +1,7 @@
#include "partition_region.h"
+
#include "region.h"
+#include "globals.h"
#include
@@ -26,7 +28,7 @@ bool PartitionRegion::empty() const {
bool PartitionRegion::is_loc_in_part_reg(const t_pl_loc& loc) const {
bool is_in_pr = false;
- for (const auto & region : regions) {
+ for (const auto& region : regions) {
is_in_pr = region.is_loc_in_reg(loc);
if (is_in_pr) {
break;
@@ -76,11 +78,37 @@ void update_cluster_part_reg(PartitionRegion& cluster_pr, const PartitionRegion&
void print_partition_region(FILE* fp, const PartitionRegion& pr) {
const std::vector& regions = pr.get_regions();
- int pr_size = regions.size();
-
- fprintf(fp, "\tNumber of regions in partition is: %d\n", pr_size);
+ fprintf(fp, "\tNumber of regions in partition is: %d\n", (int)regions.size());
- for (const auto & region : regions) {
+ for (const auto& region : regions) {
print_region(fp, region);
}
}
+
+const PartitionRegion& get_device_partition_region() {
+ // the device partition region is initialized the first time this function is called
+ static PartitionRegion device_pr;
+
+ const auto& grid = g_vpr_ctx.device().grid;
+
+ // this function is supposed to be called when the grid is constructed
+ VTR_ASSERT_SAFE(grid.grid_size() != 0);
+
+ const int n_layers = grid.get_num_layers();
+ const int width = static_cast(grid.width());
+ const int height = static_cast(grid.height());
+
+ if (device_pr.empty()) {
+ Region device_region(0, 0, width - 1, height - 1, 0, n_layers - 1);
+ device_region.set_sub_tile(NO_SUBTILE);
+ device_pr.add_to_part_region(device_region);
+ }
+
+ VTR_ASSERT_SAFE(device_pr.get_regions().size() == 1);
+ const auto [xmin, ymin, xmax, ymax] = device_pr.get_regions()[0].get_rect().coordinates();
+ VTR_ASSERT_SAFE(xmin == 0 && ymin == 0 && xmax == width -1 && ymax == height - 1);
+ const auto [layer_low, layer_high] = device_pr.get_regions()[0].get_layer_range();
+ VTR_ASSERT_SAFE(layer_low == 0 && layer_high == n_layers - 1);
+
+ return device_pr;
+}
\ No newline at end of file
diff --git a/vpr/src/base/partition_region.h b/vpr/src/base/partition_region.h
index db73d2d7f09..9e46a1a849b 100644
--- a/vpr/src/base/partition_region.h
+++ b/vpr/src/base/partition_region.h
@@ -50,6 +50,16 @@ class PartitionRegion {
*/
bool is_loc_in_part_reg(const t_pl_loc& loc) const;
+ /**
+ * @brief Compares whether this PartitionRegion includes the same regions
+ * and another PartitionRegion.
+ * @param pr The other PartitionRegion to be compared with this object.
+ * @return True if both PartitionRegions contain the same regions.
+ */
+ bool operator==(const PartitionRegion& pr) const {
+ return (regions == pr.get_regions());
+ }
+
private:
std::vector regions; ///< union of rectangular regions that a partition can be placed in
};
@@ -58,20 +68,45 @@ class PartitionRegion {
void print_partition_region(FILE* fp, const PartitionRegion& pr);
/**
-* @brief Global function that returns the intersection of two PartitionRegions
-*
-* @param cluster_pr One of the PartitionRegions to be intersected
-* @param new_pr One of the PartitionRegions to be intersected
-*/
+ * @brief Global function that returns the intersection of two PartitionRegions
+ *
+ * @param cluster_pr One of the PartitionRegions to be intersected
+ * @param new_pr One of the PartitionRegions to be intersected
+ */
PartitionRegion intersection(const PartitionRegion& cluster_pr, const PartitionRegion& new_pr);
/**
-* @brief Global function that updates the PartitionRegion of a cluster with the intersection
-* of the cluster PartitionRegion and a new PartitionRegion
-*
-* @param cluster_pr The cluster PartitionRegion that is to be updated
-* @param new_pr The new PartitionRegion that the cluster PartitionRegion will be intersected with
-*/
+ * @brief Global function that updates the PartitionRegion of a cluster with the intersection
+ * of the cluster PartitionRegion and a new PartitionRegion
+ *
+ * @param cluster_pr The cluster PartitionRegion that is to be updated
+ * @param new_pr The new PartitionRegion that the cluster PartitionRegion will be intersected with
+ */
void update_cluster_part_reg(PartitionRegion& cluster_pr, const PartitionRegion& new_pr);
+/**
+ * @brief Get a PartitionRegion with a single Region that covers the entire device.
+ *
+ * @return A PartitionRegion that covers the whole device grid.
+ */
+const PartitionRegion& get_device_partition_region();
+
+namespace std {
+template<>
+struct hash {
+ std::size_t operator()(const PartitionRegion& pr) const noexcept {
+ const std::vector& regions = pr.get_regions();
+
+ std::size_t seed = std::hash{}(regions.size());
+
+ for (const Region& region : regions) {
+ vtr::hash_combine(seed, region);
+ }
+
+ return seed;
+ }
+};
+} // namespace std
+
+
#endif /* PARTITION_REGIONS_H */
diff --git a/vpr/src/base/read_options.cpp b/vpr/src/base/read_options.cpp
index 22d59058230..f14bb940b28 100644
--- a/vpr/src/base/read_options.cpp
+++ b/vpr/src/base/read_options.cpp
@@ -2150,20 +2150,20 @@ argparse::ArgumentParser create_arg_parser(const std::string& prog_name, t_optio
place_grp.add_argument(args.place_constraint_expand, "--place_constraint_expand")
.help(
- "The value used to decide how much to expand the floorplan constraint region when writing"
- "a floorplan constraint XML file. Takes in an integer value from zero to infinity."
- "If the value is zero, the block stays at the same x, y location. If it is"
- "greater than zero the constraint region expands by the specified value in each direction."
- "For example, if 1 was specified, a block at the x, y location (1, 1) would have a constraint region"
+ "The value used to decide how much to expand the floorplan constraint region when writing "
+ "a floorplan constraint XML file. Takes in an integer value from zero to infinity. "
+ "If the value is zero, the block stays at the same x, y location. If it is "
+ "greater than zero the constraint region expands by the specified value in each direction. "
+ "For example, if 1 was specified, a block at the x, y location (1, 1) would have a constraint region "
"of 2x2 centered around (1, 1), from (0, 0) to (2, 2).")
.default_value("0")
.show_in(argparse::ShowIn::HELP_ONLY);
place_grp.add_argument(args.place_constraint_subtile, "--place_constraint_subtile")
.help(
- "The bool used to say whether to print subtile constraints when printing a floorplan constraints XML file."
- "If it is off, no subtile locations are specified when printing the floorplan constraints."
- "If it is on, the floorplan constraints are printed with the subtiles from current placement.")
+ "The bool used to say whether to print subtile constraints when printing a floorplan constraints XML file. "
+ "If it is off, no subtile locations are specified when printing the floorplan constraints. "
+ "If it is on, the floorplan constraints are printed with the subtiles from current placement. ")
.default_value("off")
.show_in(argparse::ShowIn::HELP_ONLY);
diff --git a/vpr/src/base/region.cpp b/vpr/src/base/region.cpp
index e45266c723c..7cc6280626b 100644
--- a/vpr/src/base/region.cpp
+++ b/vpr/src/base/region.cpp
@@ -1,122 +1,98 @@
+
#include "region.h"
-Region::Region() {
- sub_tile = NO_SUBTILE;
+#include
+#include
- //default rect for a region is (999, 999, -1, -1)
- //these values indicate an empty rectangle, they are set as default values to help catch uninitialized use
- region_bounds.set_xmin(999);
- region_bounds.set_ymin(999);
- region_bounds.set_xmax(-1);
- region_bounds.set_ymax(-1);
- layer_num = -1;
-}
+Region::Region(const vtr::Rect& rect, int layer_num_min, int layer_num_max)
+ : rect_(rect)
+ , layer_range_({layer_num_min, layer_num_max})
+ , sub_tile_(NO_SUBTILE) {}
-RegionRectCoord Region::get_region_rect() const {
- return RegionRectCoord(region_bounds, layer_num);
-}
+Region::Region(const vtr::Rect& rect, int layer_num)
+ : Region(rect, layer_num, layer_num) {}
+
+Region::Region(int x_min, int y_min, int x_max, int y_max, int layer_num_min, int layer_num_max)
+ : rect_({x_min, y_min, x_max, y_max})
+ , layer_range_({layer_num_min, layer_num_max})
+ , sub_tile_(NO_SUBTILE) {}
-void Region::set_region_rect(const RegionRectCoord& rect_coord) {
- region_bounds.set_xmin(rect_coord.xmin);
- region_bounds.set_xmax(rect_coord.xmax);
- region_bounds.set_ymin(rect_coord.ymin);
- region_bounds.set_ymax(rect_coord.ymax);
- layer_num = rect_coord.layer_num;
+Region::Region(int x_min, int y_min, int x_max, int y_max, int layer_num)
+ : Region(x_min, y_min, x_max, y_max, layer_num, layer_num) {}
+
+void Region::set_layer_range(std::pair layer_range) {
+ layer_range_ = layer_range;
}
-int Region::get_layer_num() const {
- return layer_num;
+void Region::set_rect(const vtr::Rect& rect) {
+ rect_ = rect;
}
+Region::Region()
+ : rect_({std::numeric_limits::max(), std::numeric_limits::max(),
+ std::numeric_limits::min(), std::numeric_limits::min()})
+ , layer_range_(0, 0)
+ , sub_tile_(NO_SUBTILE) {}
+
int Region::get_sub_tile() const {
- return sub_tile;
+ return sub_tile_;
}
-void Region::set_sub_tile(int _sub_tile) {
- sub_tile = _sub_tile;
+void Region::set_sub_tile(int sub_tile) {
+ sub_tile_ = sub_tile;
}
-bool Region::empty() {
- return (region_bounds.xmax() < region_bounds.xmin()
- || region_bounds.ymax() < region_bounds.ymin()
- || layer_num < 0);
+bool Region::empty() const {
+ const auto [layer_low, layer_high] = layer_range_;
+ return (rect_.xmax() < rect_.xmin() || rect_.ymax() < rect_.ymin() ||
+ layer_high < layer_low);
}
bool Region::is_loc_in_reg(t_pl_loc loc) const {
- bool is_loc_in_reg = false;
- int loc_layer_num = loc.layer;
+ const int loc_layer_num = loc.layer;
+ const auto [layer_low, layer_high] = layer_range_;
- if (layer_num != loc_layer_num) {
- return is_loc_in_reg;
+ // the location is falls outside the layer range
+ if (loc_layer_num > layer_high || loc_layer_num < layer_low) {
+ return false;
}
- vtr::Point loc_coord(loc.x, loc.y);
+ const vtr::Point loc_coord(loc.x, loc.y);
//check that loc x and y coordinates are within region bounds
- bool in_rectangle = region_bounds.coincident(loc_coord);
+ bool in_rectangle = rect_.coincident(loc_coord);
//if a subtile is specified for the region, the location subtile should match
- if (in_rectangle && sub_tile == loc.sub_tile) {
- is_loc_in_reg = true;
+ if (in_rectangle && sub_tile_ == loc.sub_tile) {
+ return true;
}
//if no subtile is specified for the region, it is enough for the location to be in the rectangle
- if (in_rectangle && sub_tile == NO_SUBTILE) {
- is_loc_in_reg = true;
- }
-
- return is_loc_in_reg;
-}
-
-bool do_regions_intersect(Region r1, Region r2) {
- bool intersect = true;
-
- const auto r1_reg_coord = r1.get_region_rect();
- const auto r2_reg_coord = r2.get_region_rect();
-
- vtr::Rect r1_rect(r1_reg_coord.xmin, r1_reg_coord.ymin, r1_reg_coord.xmax, r1_reg_coord.ymax);
- vtr::Rect r2_rect(r2_reg_coord.xmin, r2_reg_coord.ymin, r2_reg_coord.xmax, r2_reg_coord.ymax);
-
- int r1_layer_num = r1_reg_coord.layer_num;
- int r2_layer_num = r2_reg_coord.layer_num;
-
- vtr::Rect intersect_rect;
-
- if (r1_layer_num != r2_layer_num) {
- return intersect;
- }
-
- intersect_rect = intersection(r1_rect, r2_rect);
-
- /**
- * if the intersection rectangle is empty or the subtile of the two regions does not match,
- * the regions do not intersect
- */
- if (intersect_rect.empty() || r1.get_sub_tile() != r2.get_sub_tile()) {
- return intersect = false;
+ if (in_rectangle && sub_tile_ == NO_SUBTILE) {
+ return true;
}
- return intersect;
+ return false;
}
Region intersection(const Region& r1, const Region& r2) {
- Region intersect;
-
- const auto r1_reg_coord = r1.get_region_rect();
- const auto r2_reg_coord = r2.get_region_rect();
-
- vtr::Rect r1_rect(r1_reg_coord.xmin, r1_reg_coord.ymin, r1_reg_coord.xmax, r1_reg_coord.ymax);
- vtr::Rect r2_rect(r2_reg_coord.xmin, r2_reg_coord.ymin, r2_reg_coord.xmax, r2_reg_coord.ymax);
+ const vtr::Rect& r1_rect = r1.get_rect();
+ const vtr::Rect& r2_rect = r2.get_rect();
- int r1_layer_num = r1_reg_coord.layer_num;
- int r2_layer_num = r2_reg_coord.layer_num;
+ auto [r1_layer_low, r1_layer_high] = r1.get_layer_range();
+ auto [r2_layer_low, r2_layer_high] = r2.get_layer_range();
- vtr::Rect intersect_rect;
+ auto [intersect_layer_begin, intersect_layer_end] = std::make_pair(std::max(r1_layer_low, r2_layer_low),
+ std::min(r1_layer_high, r2_layer_high));
- if (r1_layer_num != r2_layer_num) {
- return intersect;
+ // check that the give layer range start from a lower layer and end at a higher or the same layer
+ // negative layer means that the given Region object is an empty region
+ if (intersect_layer_begin > intersect_layer_end || intersect_layer_begin < 0 || intersect_layer_end < 0) {
+ return {};
}
+ Region intersect;
+ intersect.set_layer_range({intersect_layer_begin, intersect_layer_end});
/*
* If the subtiles of two regions match (i.e. they both have no subtile specified, or the same subtile specified),
* the regions are intersected. The resulting intersection region will have a rectangle that reflects their overlap,
@@ -132,28 +108,29 @@ Region intersection(const Region& r1, const Region& r2) {
*/
if (r1.get_sub_tile() == r2.get_sub_tile()) {
intersect.set_sub_tile(r1.get_sub_tile());
- intersect_rect = intersection(r1_rect, r2_rect);
- intersect.set_region_rect({intersect_rect, r1_layer_num});
-
+ vtr::Rect intersect_rect = intersection(r1_rect, r2_rect);
+ intersect.set_rect(intersect_rect);
+ return intersect;
} else if (r1.get_sub_tile() == NO_SUBTILE && r2.get_sub_tile() != NO_SUBTILE) {
intersect.set_sub_tile(r2.get_sub_tile());
- intersect_rect = intersection(r1_rect, r2_rect);
- intersect.set_region_rect({intersect_rect, r1_layer_num});
-
+ vtr::Rect intersect_rect = intersection(r1_rect, r2_rect);
+ intersect.set_rect(intersect_rect);
+ return intersect;
} else if (r1.get_sub_tile() != NO_SUBTILE && r2.get_sub_tile() == NO_SUBTILE) {
intersect.set_sub_tile(r1.get_sub_tile());
- intersect_rect = intersection(r1_rect, r2_rect);
- intersect.set_region_rect({intersect_rect, r1_layer_num});
+ vtr::Rect intersect_rect = intersection(r1_rect, r2_rect);
+ intersect.set_rect(intersect_rect);
+ return intersect;
}
- return intersect;
+ // subtiles are not compatible
+ return {};
}
void print_region(FILE* fp, const Region& region) {
- const auto region_coord = region.get_region_rect();
- const auto region_rect = vtr::Rect(region_coord.xmin, region_coord.ymin, region_coord.xmax, region_coord.ymax);
+ const auto [layer_begin, layer_end] = region.get_layer_range();
fprintf(fp, "\tRegion: \n");
- fprintf(fp, "\tlayer: %d\n", region.get_layer_num());
- print_rect(fp, region_rect);
+ fprintf(fp, "\tlayer range: [%d, %d]\n", layer_begin, layer_end);
+ print_rect(fp, region.get_rect());
fprintf(fp, "\tsubtile: %d\n\n", region.get_sub_tile());
}
diff --git a/vpr/src/base/region.h b/vpr/src/base/region.h
index dfdfd26d20c..18a179af19a 100644
--- a/vpr/src/base/region.h
+++ b/vpr/src/base/region.h
@@ -1,52 +1,9 @@
#ifndef REGION_H
#define REGION_H
-#include
+#include "vtr_geometry.h"
#include "vpr_types.h"
-/**
- * @brief This class stores the data for each constraint region on a layer
- * @param xmin The minimum x coordinate of the region
- * @param ymin The minimum y coordinate of the region
- * @param xmax The maximum x coordinate of the region
- * @param ymax The maximum y coordinate of the region
- * @param layer_num The layer number of the region
- */
-struct RegionRectCoord {
- RegionRectCoord() = default;
- RegionRectCoord(int _xmin, int _ymin, int _xmax, int _ymax, int _layer_num)
- : xmin(_xmin)
- , ymin(_ymin)
- , xmax(_xmax)
- , ymax(_ymax)
- , layer_num(_layer_num) {}
-
- RegionRectCoord(const vtr::Rect& rect, int _layer_num)
- : xmin(rect.xmin())
- , ymin(rect.ymin())
- , xmax(rect.xmax())
- , ymax(rect.ymax())
- , layer_num(_layer_num) {}
-
- int xmin;
- int ymin;
- int xmax;
- int ymax;
- int layer_num;
-
- /// @brief Convert to a vtr::Rect
- vtr::Rect get_rect() const {
- return vtr::Rect(xmin, ymin, xmax, ymax);
- }
-
- /// @brief Equality operator
- bool operator==(const RegionRectCoord& rhs) const {
- vtr::Rect lhs_rect(xmin, ymin, xmax, ymax);
- vtr::Rect rhs_rect(rhs.xmin, rhs.ymin, rhs.xmax, rhs.ymax);
- return (lhs_rect == rhs_rect) && (layer_num == rhs.layer_num);
- }
-};
-
/**
* @file
* @brief This file defines the Region class. The Region class stores the data for each constraint region.
@@ -66,20 +23,33 @@ class Region {
*/
Region();
- /**
- * @brief Accessor for the region's rectangle
- */
- RegionRectCoord get_region_rect() const;
+ Region(const vtr::Rect& rect, int layer_num_max, int layer_num_min);
- /**
- * @brief Mutator for the region's rectangle
- */
- void set_region_rect(const RegionRectCoord& rect_coord);
+ Region(const vtr::Rect& rect, int layer_num);
- /**
- * @brief Accessor for the region's layer number
- */
- int get_layer_num() const;
+ Region(int x_min, int y_min, int x_max, int y_max, int layer_num_min, int layer_num_max);
+
+ Region(int x_min, int y_min, int x_max, int y_max, int layer_num);
+
+ const vtr::Rect& get_rect() const {
+ return rect_;
+ }
+
+ void set_rect(const vtr::Rect& rect);
+
+ vtr::Rect& get_mutable_rect() {
+ return rect_;
+ }
+
+ void set_layer_range(std::pair layer_range);
+
+ std::pair get_layer_range() const {
+ return layer_range_;
+ }
+
+ std::pair& get_mutable_layer_range() {
+ return layer_range_;
+ }
/**
* @brief Accessor for the region's subtile
@@ -89,13 +59,13 @@ class Region {
/**
* @brief Mutator for the region's subtile
*/
- void set_sub_tile(int _sub_tile);
+ void set_sub_tile(int sub_tile);
/**
* @brief Return whether the region is empty (i. e. the region bounds rectangle
* covers no area)
*/
- bool empty();
+ bool empty() const;
/**
* @brief Check if the location is in the region (at a valid x, y, subtile location within the region bounds, inclusive)
@@ -107,29 +77,30 @@ class Region {
bool is_loc_in_reg(t_pl_loc loc) const;
bool operator==(const Region& reg) const {
- return (reg.get_region_rect() == this->get_region_rect()
- && reg.get_sub_tile() == this->get_sub_tile()
- && reg.layer_num == this->layer_num);
+ return (reg.rect_ == rect_ &&
+ reg.layer_range_ == layer_range_ &&
+ reg.get_sub_tile() == sub_tile_);
}
private:
- //may need to include zmin, zmax for future use in 3D FPGA designs
- vtr::Rect region_bounds; ///< xmin, ymin, xmax, ymax inclusive
- int layer_num; ///< layer number of the region
- int sub_tile; ///< users will optionally select a subtile
-};
+ /**
+ * Represents a rectangle in the x-y plane.
+ * This rectangle is the projection of the cube represented by this class
+ * onto the x-y plane.
+ */
+ vtr::Rect rect_;
-/**
- * @brief Returns whether two regions intersect
- *
- * Intersection is the area of overlap between the rectangles of two regions and the subtile value of the intersecting rectangle,
- * given that both regions have matching subtile values, or no subtiles assigned to them
- * The overlap is inclusive of the x and y boundaries of the rectangles
- *
- * @param r1 One of the regions to check for intersection
- * @param r2 One of the regions to check for intersection
- */
-bool do_regions_intersect(Region r1, Region r2);
+ /**
+ * Represents the range of layers spanned by the projected rectangle (rect_).
+ * layer_range_.first --> the lowest layer
+ * layer_range.second --> the higher layer
+ * This range is inclusive, meaning that the lowest and highest layers are
+ * part of the floorplan region.
+ */
+ std::pair layer_range_;
+
+ int sub_tile_; ///< users will optionally select a subtile
+};
/**
* @brief Returns the intersection of two regions
@@ -147,12 +118,15 @@ namespace std {
template<>
struct hash {
std::size_t operator()(const Region& reg) const noexcept {
- const auto region_coord = reg.get_region_rect();
- std::size_t seed = std::hash{}(region_coord.xmin);
- vtr::hash_combine(seed, region_coord.ymin);
- vtr::hash_combine(seed, region_coord.xmax);
- vtr::hash_combine(seed, region_coord.ymax);
- vtr::hash_combine(seed, region_coord.layer_num);
+ const vtr::Rect& rect = reg.get_rect();
+ const auto [layer_begin, layer_end] = reg.get_layer_range();
+
+ std::size_t seed = std::hash{}(rect.xmin());
+ vtr::hash_combine(seed, rect.ymin());
+ vtr::hash_combine(seed, rect.xmax());
+ vtr::hash_combine(seed, rect.ymax());
+ vtr::hash_combine(seed, layer_begin);
+ vtr::hash_combine(seed, layer_end);
vtr::hash_combine(seed, reg.get_sub_tile());
return seed;
}
diff --git a/vpr/src/base/user_place_constraints.h b/vpr/src/base/user_place_constraints.h
index b7bcf69f38a..65043f5d4ad 100644
--- a/vpr/src/base/user_place_constraints.h
+++ b/vpr/src/base/user_place_constraints.h
@@ -72,7 +72,7 @@ class UserPlaceConstraints {
* @param part_id The id of the partition that is wanted
*/
Partition& get_mutable_partition(PartitionId part_id);
-
+
/**
* @brief Return all the atoms that belong to a partition
*
diff --git a/vpr/src/base/user_route_constraints.cpp b/vpr/src/base/user_route_constraints.cpp
index 52888811714..67cabe6b20e 100644
--- a/vpr/src/base/user_route_constraints.cpp
+++ b/vpr/src/base/user_route_constraints.cpp
@@ -1,28 +1,25 @@
#include "user_route_constraints.h"
-
void UserRouteConstraints::add_route_constraint(std::string net_name, RoutingScheme route_scheme) {
route_constraints_.insert({net_name, route_scheme});
}
-
const std::pair UserRouteConstraints::get_route_constraint_by_idx(std::size_t idx) const {
RoutingScheme route_scheme;
// throw an error if the index is out of range
if ((route_constraints_.size() == 0) || (idx > route_constraints_.size() - 1)) {
- VPR_FATAL_ERROR(VPR_ERROR_OTHER,
- "in get_route_constraint_by_idx: index %u is out of range. The unordered map for route constraints has a size of %u\n",
- idx, route_constraints_.size());
- }
-
+ VPR_FATAL_ERROR(VPR_ERROR_OTHER,
+ "in get_route_constraint_by_idx: index %u is out of range. The unordered map for route constraints has a size of %u\n",
+ idx, route_constraints_.size());
+ }
+
auto it = route_constraints_.begin();
std::advance(it, idx);
return *it;
}
bool UserRouteConstraints::has_routing_constraint(std::string net_name) const {
-
// Check if there's an exact match for the net name
auto const& rc_itr = route_constraints_.find(net_name);
if (rc_itr != route_constraints_.end()) {
@@ -40,13 +37,11 @@ bool UserRouteConstraints::has_routing_constraint(std::string net_name) const {
return false;
}
-const RoutingScheme UserRouteConstraints::get_route_scheme_by_net_name(std::string net_name) const{
-
- if(has_routing_constraint(net_name) == false)
- {
+const RoutingScheme UserRouteConstraints::get_route_scheme_by_net_name(std::string net_name) const {
+ if (has_routing_constraint(net_name) == false) {
VPR_FATAL_ERROR(VPR_ERROR_OTHER,
- "in get_route_scheme_by_net_name: no routing constraints exist for net name %s \n",
- net_name.c_str());
+ "in get_route_scheme_by_net_name: no routing constraints exist for net name %s \n",
+ net_name.c_str());
}
RoutingScheme route_scheme;
@@ -63,22 +58,18 @@ const RoutingScheme UserRouteConstraints::get_route_scheme_by_net_name(std::stri
route_scheme = rs_itr->second;
}
return route_scheme;
-
}
-
-e_clock_modeling UserRouteConstraints::get_route_model_by_net_name(std::string net_name) const{
+e_clock_modeling UserRouteConstraints::get_route_model_by_net_name(std::string net_name) const {
RoutingScheme route_scheme = get_route_scheme_by_net_name(net_name);
return route_scheme.route_model();
}
-
-const std::string UserRouteConstraints::get_routing_network_name_by_net_name(std::string net_name) const{
+const std::string UserRouteConstraints::get_routing_network_name_by_net_name(std::string net_name) const {
RoutingScheme route_scheme = get_route_scheme_by_net_name(net_name);
return route_scheme.network_name();
}
-
int UserRouteConstraints::get_num_route_constraints(void) const {
return route_constraints_.size();
}
\ No newline at end of file
diff --git a/vpr/src/base/user_route_constraints.h b/vpr/src/base/user_route_constraints.h
index 57d6a3d2455..ec925d7887d 100644
--- a/vpr/src/base/user_route_constraints.h
+++ b/vpr/src/base/user_route_constraints.h
@@ -24,15 +24,16 @@
* through which the net should be routed.
*/
class RoutingScheme {
-private:
+ private:
std::string network_name_ = "INVALID"; // Name of the clock network (if applicable)
- e_clock_modeling route_model_ = e_clock_modeling::ROUTED_CLOCK;
+ e_clock_modeling route_model_ = e_clock_modeling::ROUTED_CLOCK;
-public:
+ public:
// Constructors
RoutingScheme() = default;
RoutingScheme(const std::string network_name, const e_clock_modeling route_model)
- : network_name_(network_name), route_model_(route_model) {}
+ : network_name_(network_name)
+ , route_model_(route_model) {}
// Getters
std::string network_name() const {
@@ -55,11 +56,10 @@ class RoutingScheme {
// Reset network_name_ and route_model_ to their default values
void reset() {
network_name_ = "INVALID";
- route_model_ = e_clock_modeling::ROUTED_CLOCK;
+ route_model_ = e_clock_modeling::ROUTED_CLOCK;
}
};
-
/**
* @brief This class is used to store information related to global route constraints from a constraints XML file.
*
@@ -147,8 +147,6 @@ class UserRouteConstraints {
*/
int get_num_route_constraints(void) const;
-
-
private:
/**
* store all route constraints
diff --git a/vpr/src/base/vpr_constraints.cpp b/vpr/src/base/vpr_constraints.cpp
index 9ae678c94e0..b504bb1a754 100644
--- a/vpr/src/base/vpr_constraints.cpp
+++ b/vpr/src/base/vpr_constraints.cpp
@@ -1,6 +1,5 @@
#include "vpr_constraints.h"
-
UserPlaceConstraints& VprConstraints::mutable_place_constraints() {
return placement_constraints_;
}
diff --git a/vpr/src/base/vpr_constraints.h b/vpr/src/base/vpr_constraints.h
index 0d5f8049a52..9d520e0107f 100644
--- a/vpr/src/base/vpr_constraints.h
+++ b/vpr/src/base/vpr_constraints.h
@@ -4,7 +4,6 @@
#include "user_place_constraints.h"
#include "user_route_constraints.h"
-
/**
* @brief This file defines the VprConstraints class, which encapsulates user-specified placement and routing constraints
*
@@ -26,7 +25,6 @@
*/
class VprConstraints {
public:
-
/**
* @brief Get a mutable reference to the UserPlaceConstraints instance.
*/
@@ -48,10 +46,8 @@ class VprConstraints {
const UserRouteConstraints& route_constraints() const;
private:
-
UserRouteConstraints route_constraints_;
UserPlaceConstraints placement_constraints_;
-
};
#endif /* VPR_CONSTRAINTS_H */
diff --git a/vpr/src/base/vpr_constraints.xsd b/vpr/src/base/vpr_constraints.xsd
index 704d084f381..ad7cbbac916 100644
--- a/vpr/src/base/vpr_constraints.xsd
+++ b/vpr/src/base/vpr_constraints.xsd
@@ -33,6 +33,8 @@
+
+
diff --git a/vpr/src/base/vpr_constraints_reader.cpp b/vpr/src/base/vpr_constraints_reader.cpp
index 9bb8dccf9bd..57c17d73019 100644
--- a/vpr/src/base/vpr_constraints_reader.cpp
+++ b/vpr/src/base/vpr_constraints_reader.cpp
@@ -37,7 +37,7 @@ void load_vpr_constraints_file(const char* read_vpr_constraints_name) {
auto& routing_ctx = g_vpr_ctx.mutable_routing();
routing_ctx.constraints = reader.constraints_.route_constraints();
-
+
const auto& ctx_constraints = floorplanning_ctx.constraints;
if (getEchoEnabled() && isEchoFileEnabled(E_ECHO_VPR_CONSTRAINTS)) {
diff --git a/vpr/src/base/vpr_constraints_serializer.h b/vpr/src/base/vpr_constraints_serializer.h
index 9ab4c3bd96f..9cfd47829c2 100644
--- a/vpr/src/base/vpr_constraints_serializer.h
+++ b/vpr/src/base/vpr_constraints_serializer.h
@@ -110,8 +110,8 @@ class VprConstraintsSerializer final : public uxsd::VprConstraintsBase
*
*
+ *
+ *
*
*
*/
+ virtual inline int get_add_region_layer_low(Region& r) final {
+ return r.get_layer_range().first;
+ }
- virtual inline int get_add_region_layer_num(Region& r) final {
- return r.get_layer_num();
+ virtual inline int get_add_region_layer_high(Region& r) final {
+ return r.get_layer_range().second;
}
virtual inline int get_add_region_subtile(Region& r) final {
@@ -194,24 +199,32 @@ class VprConstraintsSerializer final : public uxsd::VprConstraintsBaseoperator()("Illegal layer numbers are specified in the constraint file.");
+ }
+ }
+
+ if (loaded_region.empty()) {
+ if (report_error_ == nullptr) {
+ VPR_ERROR(VPR_ERROR_PLACE, "\nThe specified region is empty.\n");
+ } else {
+ report_error_->operator()("The specified region is empty.");
+ }
+ }
+
loaded_part_region.add_to_part_region(loaded_region);
Region clear_region;
@@ -331,7 +362,7 @@ class VprConstraintsSerializer final : public uxsd::VprConstraintsBase
*/
- e_clock_modeling from_uxsd_route_model(uxsd::enum_route_model_type route_model) {
+ e_clock_modeling from_uxsd_route_model(uxsd::enum_route_model_type route_model) {
switch (route_model) {
case uxsd::enum_route_model_type::DEDICATED_NETWORK:
return e_clock_modeling::DEDICATED_NETWORK;
@@ -341,7 +372,7 @@ class VprConstraintsSerializer final : public uxsd::VprConstraintsBase 0)
+ virtual inline bool has_vpr_constraints_global_route_constraints(void*& /*ctx*/) {
+ if (constraints_.route_constraints().get_num_route_constraints() > 0)
return true;
- else
+ else
return false;
}
-
/** Generated for complex type "vpr_constraints":
*
@@ -459,10 +489,10 @@ class VprConstraintsSerializer final : public uxsd::VprConstraintsBase 0)
+ virtual inline bool has_vpr_constraints_partition_list(void*& /*ctx*/) final {
+ if (constraints_.place_constraints().get_num_partitions() > 0)
return true;
- else
+ else
return false;
}
virtual void finish_load() final {
diff --git a/vpr/src/base/vpr_constraints_writer.cpp b/vpr/src/base/vpr_constraints_writer.cpp
index 188fa803f8c..62cb2f666d2 100644
--- a/vpr/src/base/vpr_constraints_writer.cpp
+++ b/vpr/src/base/vpr_constraints_writer.cpp
@@ -12,7 +12,6 @@
#include "globals.h"
#include "pugixml.hpp"
#include "pugixml_util.hpp"
-#include "echo_files.h"
#include "clustered_netlist_utils.h"
#include
@@ -20,6 +19,15 @@
#include "region.h"
#include "re_cluster_util.h"
+/**
+ * @brief Create a partition with the given name and a single region.
+ *
+ * @param part_name The name of the partition to be created.
+ * @param region The region that the partition covers.
+ * @return A newly created partition with the giver name and region.
+ */
+static Partition create_partition(const std::string& part_name, const Region& region);
+
void write_vpr_floorplan_constraints(const char* file_name, int expand, bool subtile, int horizontal_partitions, int vertical_partitions) {
VprConstraints constraints;
@@ -54,26 +62,21 @@ void setup_vpr_floorplan_constraints_one_loc(VprConstraints& constraints, int ex
* The PartitionRegion will be the location of the block in current placement, modified by the expansion factor.
* The subtile can also optionally be set in the PartitionRegion, based on the value passed in by the user.
*/
- for (auto blk_id : cluster_ctx.clb_nlist.blocks()) {
+ for (ClusterBlockId blk_id : cluster_ctx.clb_nlist.blocks()) {
const std::string& part_name = cluster_ctx.clb_nlist.block_name(blk_id);
PartitionId partid(part_id);
Partition part;
part.set_name(part_name);
- PartitionRegion pr;
- Region reg;
-
const auto& loc = place_ctx.block_locs[blk_id].loc;
- reg.set_region_rect({loc.x - expand,
- loc.y - expand,
- loc.x + expand,
- loc.y + expand,
- loc.layer});
+ PartitionRegion pr;
+ Region reg(loc.x - expand, loc.y - expand,
+ loc.x + expand, loc.y + expand, loc.layer);
+
if (subtile) {
- int st = loc.sub_tile;
- reg.set_sub_tile(st);
+ reg.set_sub_tile(loc.sub_tile);
}
pr.add_to_part_region(reg);
@@ -94,15 +97,16 @@ void setup_vpr_floorplan_constraints_cutpoints(VprConstraints& constraints, int
auto& place_ctx = g_vpr_ctx.placement();
auto& device_ctx = g_vpr_ctx.device();
+ const int n_layers = device_ctx.grid.get_num_layers();
+
//calculate the cutpoint values according to the grid size
//load two arrays - one for horizontal cutpoints and one for vertical
std::vector horizontal_cuts;
-
std::vector vertical_cuts;
// This function has not been tested for multi-layer grids
- VTR_ASSERT(device_ctx.grid.get_num_layers() == 1);
+ VTR_ASSERT(n_layers == 1);
int horizontal_interval = device_ctx.grid.width() / horizontal_cutpoints;
VTR_LOG("Device grid width is %d, horizontal interval is %d\n", device_ctx.grid.width(), horizontal_interval);
@@ -142,11 +146,9 @@ void setup_vpr_floorplan_constraints_cutpoints(VprConstraints& constraints, int
int ymin = vertical_cuts[j];
int ymax = vertical_cuts[j + 1] - 1;
- Region reg;
+ Region reg(xmin, ymin, xmax, ymax, 0, n_layers - 1);
// This function has not been tested for multi-layer grids. An assertion is used earlier to make sure that the grid has only one layer
- reg.set_region_rect({xmin, ymin, xmax, ymax, 0});
std::vector atoms;
-
region_atoms.insert({reg, atoms});
}
}
@@ -155,7 +157,7 @@ void setup_vpr_floorplan_constraints_cutpoints(VprConstraints& constraints, int
* For each cluster block, see which region it belongs to, and add its atoms to the
* appropriate region accordingly
*/
- for (auto blk_id : cluster_ctx.clb_nlist.blocks()) {
+ for (ClusterBlockId blk_id : cluster_ctx.clb_nlist.blocks()) {
const std::unordered_set& atoms = cluster_to_atoms(blk_id);
int x = place_ctx.block_locs[blk_id].loc.x;
int y = place_ctx.block_locs[blk_id].loc.y;
@@ -181,9 +183,8 @@ void setup_vpr_floorplan_constraints_cutpoints(VprConstraints& constraints, int
}
}
- Region current_reg;
+ Region current_reg(xminimum, yminimum, xmaximum, ymaximum, 0, n_layers-1);
// This function has not been tested for multi-layer grids. An assertion is used earlier to make sure that the grid has only one layer
- current_reg.set_region_rect({xminimum, yminimum, xmaximum, ymaximum, 0});
auto got = region_atoms.find(current_reg);
@@ -195,16 +196,13 @@ void setup_vpr_floorplan_constraints_cutpoints(VprConstraints& constraints, int
}
int num_partitions = 0;
- for (const auto& region : region_atoms) {
- Partition part;
+ for (const auto& [region, atoms] : region_atoms) {
PartitionId partid(num_partitions);
std::string part_name = "Part" + std::to_string(num_partitions);
- const auto reg_coord = region.first.get_region_rect();
- create_partition(part, part_name,
- {reg_coord.xmin, reg_coord.ymin, reg_coord.xmax, reg_coord.ymax, reg_coord.layer_num});
+ Partition part = create_partition(part_name, region);
constraints.mutable_place_constraints().add_partition(part);
- for (auto blk_id : region.second) {
+ for (AtomBlockId blk_id : atoms) {
constraints.mutable_place_constraints().add_constrained_atom(blk_id, partid);
}
@@ -212,13 +210,13 @@ void setup_vpr_floorplan_constraints_cutpoints(VprConstraints& constraints, int
}
}
-void create_partition(Partition& part, const std::string& part_name, const RegionRectCoord& region_cord) {
+static Partition create_partition(const std::string& part_name, const Region& region) {
+ Partition part;
+
part.set_name(part_name);
PartitionRegion part_pr;
- Region part_region;
- part_region.set_region_rect(region_cord);
- std::vector part_regions;
- part_regions.push_back(part_region);
- part_pr.set_partition_region(part_regions);
+ part_pr.set_partition_region({region});
part.set_part_region(part_pr);
+
+ return part;
}
diff --git a/vpr/src/base/vpr_constraints_writer.h b/vpr/src/base/vpr_constraints_writer.h
index f99335c7c42..25dd7fc08ce 100644
--- a/vpr/src/base/vpr_constraints_writer.h
+++ b/vpr/src/base/vpr_constraints_writer.h
@@ -52,11 +52,16 @@ void write_vpr_floorplan_constraints(const char* file_name, int expand, bool sub
*/
void setup_vpr_floorplan_constraints_one_loc(VprConstraints& constraints, int expand, bool subtile);
-/* Generate constraints which divide the grid into partition according to the horizontal and vertical partition values passed in
- * and lock down blocks to their appropriate partition.
+/**
+ * @brief Populates VprConstraints by dividing the grid into multiple partitions.
+ *
+ * Generate constraints which divide the grid into partition according to the horizontal
+ * and vertical partition values passed in and lock down blocks to their appropriate partition.
+ *
+ * @param constraints The VprConstraints to be populated.
+ * @param horizontal_cutpoints The number of horizontal cut-lines.
+ * @param vertical_cutpoints The number of vertical cut_lines.
*/
void setup_vpr_floorplan_constraints_cutpoints(VprConstraints& constraints, int horizontal_cutpoints, int vertical_cutpoints);
-void create_partition(Partition& part, const std::string& part_name, const RegionRectCoord& region_cord);
-
#endif /* VPR_SRC_BASE_VPR_CONSTRAINTS_WRITER_H_ */
diff --git a/vpr/src/base/vpr_context.h b/vpr/src/base/vpr_context.h
index bf79e52ed05..376a5c6e01e 100644
--- a/vpr/src/base/vpr_context.h
+++ b/vpr/src/base/vpr_context.h
@@ -529,15 +529,24 @@ struct FloorplanningContext : public Context {
/**
* @brief Floorplanning constraints in the compressed grid coordinate system.
*
+ * Indexing --> [0..grid.num_layers-1][0..numClusters-1]
+ *
* Each clustered block has a logical type with a corresponding compressed grid.
* Compressed floorplanning constraints are calculated by translating the grid locations
* of floorplanning regions to compressed grid locations. To ensure regions do not enlarge:
* - The bottom left corner is rounded up to the nearest compressed location.
* - The top right corner is rounded down to the nearest compressed location.
+ *
+ * When the floorplanning constraint spans across multiple layers, a compressed
+ * constraints is created for each a layer that the original constraint includes.
+ * This is because blocks of the same type might have different (x, y) locations
+ * in different layers, and as result, their compressed locations in each layer
+ * may correspond to a different physical (x, y) location.
+ *
*/
- vtr::vector compressed_cluster_constraints;
+ std::vector> compressed_cluster_constraints;
- std::vector overfull_regions;
+ std::vector overfull_partition_regions;
};
/**
diff --git a/vpr/src/base/vpr_types.h b/vpr/src/base/vpr_types.h
index 2f22bc2d1d2..162bc53692b 100644
--- a/vpr/src/base/vpr_types.h
+++ b/vpr/src/base/vpr_types.h
@@ -1501,22 +1501,22 @@ struct t_analysis_opts {
// used to store NoC specific options, when supplied as an input by the user
struct t_noc_opts {
- bool noc; ///
# endif
-static void draw_internal_pb(const ClusterBlockId clb_index, t_pb* current_pb, const t_pb* pb_to_draw, const ezgl::rectangle& parent_bbox, const t_logical_block_type_ptr type, ezgl::color color, ezgl::renderer* g);
+static void draw_internal_pb(const ClusterBlockId clb_index, t_pb* current_pb,
+ const t_pb* pb_to_draw, const ezgl::rectangle& parent_bbox,
+ const t_logical_block_type_ptr type, ezgl::color color,
+ ezgl::renderer* g);
const std::vector kelly_max_contrast_colors_no_black = {
//ezgl::color(242, 243, 244), //white: skip white since it doesn't contrast well with VPR's light background
@@ -83,6 +86,7 @@ static void highlight_partition(ezgl::renderer* g, int partitionID, int alpha) {
auto& floorplanning_ctx = g_vpr_ctx.floorplanning();
auto constraints = floorplanning_ctx.constraints;
t_draw_coords* draw_coords = get_draw_coords_vars();
+ t_draw_state* draw_state = get_draw_state_vars();
const auto& partition = constraints.get_partition((PartitionId)partitionID);
const auto& partition_region = partition.get_part_region();
@@ -90,55 +94,57 @@ static void highlight_partition(ezgl::renderer* g, int partitionID, int alpha) {
bool name_drawn = false;
ezgl::color partition_color = kelly_max_contrast_colors_no_black[partitionID % (kelly_max_contrast_colors_no_black.size())];
- g->set_color(partition_color, alpha);
- // The units of space in the constraints xml file will be refered to as "tile units"
- // The units of space that'll be used by ezgl to draw will be refered to as "on screen units"
+ // The units of space in the constraints xml file will be referred to as "tile units"
+ // The units of space that'll be used by ezgl to draw will be referred to as "on screen units"
// Find the coordinates of the region by retrieving from the xml file
// which tiles are at the corner of the region, then translate that to on
// the on screen units for ezgl to use.
for (int region = 0; (size_t)region < regions.size(); region++) {
- const auto reg_coord = regions[region].get_region_rect();
+ const vtr::Rect& reg_coord = regions[region].get_rect();
+ const auto [layer_low, layer_high] = regions[region].get_layer_range();
- //TODO: 0 should be replaced with the actual z value of the region when graph is 3D
- ezgl::rectangle top_right = draw_coords->get_absolute_clb_bbox(reg_coord.layer_num,
- reg_coord.xmax,
- reg_coord.ymax,
- 0);
- ezgl::rectangle bottom_left = draw_coords->get_absolute_clb_bbox(reg_coord.layer_num,
- reg_coord.xmin,
- reg_coord.ymin,
- 0);
+ for (int layer = layer_low; layer <= layer_high; layer++) {
+ if (!draw_state->draw_layer_display[layer].visible) {
+ continue;
+ }
- ezgl::rectangle on_screen_rect(bottom_left.bottom_left(), top_right.top_right());
+ int alpha_layer_part = alpha * draw_state->draw_layer_display[layer].alpha / 255;
+ g->set_color(partition_color, alpha_layer_part);
- if (!name_drawn) {
- g->set_font_size(10);
- const std::string& partition_name = partition.get_name();
+ ezgl::rectangle top_right = draw_coords->get_absolute_clb_bbox(layer, reg_coord.xmax(), reg_coord.ymax(), 0);
+ ezgl::rectangle bottom_left = draw_coords->get_absolute_clb_bbox(layer, reg_coord.xmin(), reg_coord.ymin(), 0);
- g->set_color(partition_color, 230);
+ ezgl::rectangle on_screen_rect(bottom_left.bottom_left(), top_right.top_right());
- g->draw_text(
- on_screen_rect.center(),
- partition_name,
- on_screen_rect.width() - 10,
- on_screen_rect.height() - 10);
+ if (!name_drawn) {
+ g->set_font_size(10);
+ const std::string& partition_name = partition.get_name();
- name_drawn = true;
+ g->set_color(partition_color, 230);
- g->set_color(partition_color, alpha);
- }
+ g->draw_text(
+ on_screen_rect.center(),
+ partition_name,
+ on_screen_rect.width() - 10,
+ on_screen_rect.height() - 10);
- g->fill_rectangle(on_screen_rect);
+ name_drawn = true;
+
+ g->set_color(partition_color, alpha);
+ }
+
+ g->fill_rectangle(on_screen_rect);
+ }
}
}
//Iterates through all partitions and draws each region of each partition
void highlight_all_regions(ezgl::renderer* g) {
auto& floorplanning_ctx = g_vpr_ctx.floorplanning();
- auto constraints = floorplanning_ctx.constraints;
+ const auto& constraints = floorplanning_ctx.constraints;
auto num_partitions = constraints.get_num_partitions();
//keeps track of what alpha level each partition is
@@ -154,18 +160,18 @@ void highlight_all_regions(ezgl::renderer* g) {
}
}
-// Draws atoms that're constrained to a partition in the colour of their respective partition.
+// Draws atoms that are constrained to a partition in the colour of their respective partition.
void draw_constrained_atoms(ezgl::renderer* g) {
auto& floorplanning_ctx = g_vpr_ctx.floorplanning();
- auto constraints = floorplanning_ctx.constraints;
- auto num_partitions = constraints.get_num_partitions();
+ const auto& constraints = floorplanning_ctx.constraints;
+ int num_partitions = constraints.get_num_partitions();
auto& atom_ctx = g_vpr_ctx.atom();
auto& cluster_ctx = g_vpr_ctx.clustering();
for (int partitionID = 0; partitionID < num_partitions; partitionID++) {
auto atoms = constraints.get_part_atoms((PartitionId)partitionID);
- for (const auto atom_id : atoms) {
+ for (const AtomBlockId atom_id : atoms) {
if (atom_ctx.lookup.atom_pb(atom_id) != nullptr) {
const t_pb* pb = atom_ctx.lookup.atom_pb(atom_id);
auto color = kelly_max_contrast_colors_no_black[partitionID % (kelly_max_contrast_colors_no_black.size())];
@@ -179,7 +185,12 @@ void draw_constrained_atoms(ezgl::renderer* g) {
}
//Recursive function to find where the constrained atom is and draws it
-static void draw_internal_pb(const ClusterBlockId clb_index, t_pb* current_pb, const t_pb* pb_to_draw, const ezgl::rectangle& parent_bbox, const t_logical_block_type_ptr type, ezgl::color color, ezgl::renderer* g) {
+static void draw_internal_pb(const ClusterBlockId clb_index,
+ t_pb* current_pb,
+ const t_pb* pb_to_draw,
+ const ezgl::rectangle& parent_bbox,
+ const t_logical_block_type_ptr type,
+ ezgl::color color, ezgl::renderer* g) {
t_draw_coords* draw_coords = get_draw_coords_vars();
t_draw_state* draw_state = get_draw_state_vars();
@@ -296,11 +307,11 @@ void highlight_selected_partition(GtkWidget* widget) {
}
//Fills in the legend
-static GtkTreeModel* create_and_fill_model(void) {
+static GtkTreeModel* create_and_fill_model() {
auto& atom_ctx = g_vpr_ctx.atom();
auto& floorplanning_ctx = g_vpr_ctx.floorplanning();
- auto constraints = floorplanning_ctx.constraints;
- auto num_partitions = constraints.get_num_partitions();
+ const auto& constraints = floorplanning_ctx.constraints;
+ int num_partitions = constraints.get_num_partitions();
GtkTreeStore* store = gtk_tree_store_new(NUM_COLS, G_TYPE_STRING);
@@ -312,12 +323,12 @@ static GtkTreeModel* create_and_fill_model(void) {
+ " (" + std::to_string(atoms.size()) + " primitives)");
GtkTreeIter iter, child_iter;
- gtk_tree_store_append(store, &iter, NULL);
+ gtk_tree_store_append(store, &iter, nullptr);
gtk_tree_store_set(store, &iter,
COL_NAME, partition_name.c_str(),
-1);
- for (auto const_atom : atoms) {
+ for (AtomBlockId const_atom : atoms) {
std::string atom_name = (atom_ctx.lookup.atom_pb(const_atom))->name;
gtk_tree_store_append(store, &child_iter, &iter);
gtk_tree_store_set(store, &child_iter,
diff --git a/vpr/src/draw/draw_noc.cpp b/vpr/src/draw/draw_noc.cpp
index 83b45d152eb..e8362352292 100644
--- a/vpr/src/draw/draw_noc.cpp
+++ b/vpr/src/draw/draw_noc.cpp
@@ -176,7 +176,7 @@ void draw_noc_connection_marker(ezgl::renderer* g, const vtr::vectordraw_layer_display[router_grid_position_layer];
@@ -201,7 +201,11 @@ void draw_noc_connection_marker(ezgl::renderer* g, const vtr::vector& noc_link_colors, ezgl::rectangle noc_connection_marker_bbox, const vtr::vector& list_of_noc_link_shift_directions) {
+void draw_noc_links(ezgl::renderer* g,
+ t_logical_block_type_ptr noc_router_logical_block_type,
+ vtr::vector& noc_link_colors,
+ ezgl::rectangle noc_connection_marker_bbox,
+ const vtr::vector& list_of_noc_link_shift_directions) {
t_draw_coords* draw_coords = get_draw_coords_vars();
auto& noc_ctx = g_vpr_ctx.noc();
diff --git a/vpr/src/draw/draw_noc.h b/vpr/src/draw/draw_noc.h
index 774e45b48e1..f3de82a3e3b 100644
--- a/vpr/src/draw/draw_noc.h
+++ b/vpr/src/draw/draw_noc.h
@@ -61,7 +61,12 @@ enum NocLinkType {
};
/*
- * Since the noc links run in both directions between any two routers, we want to draw them parallel to each other instead of ovrelapping them. So the idea is to shift one link in one direction and shift the other link in the opposite direction. THe enum below defines the direction a link was shifted, so for example if we had a vertical line, top would be mean shift left and Bottom would mean shift right. SImilarily, if we had a horizontal line, top would mean shift up and bottom would mean shift down.
+ * Since the noc links run in both directions between any two routers,
+ * we want to draw them parallel to each other instead of overlapping them.
+ * So the idea is to shift one link in one direction and shift the other link
+ * in the opposite direction. The enum below defines the direction a link was shifted,
+ * so for example if we had a vertical line, top would be mean shift left and Bottom would mean shift right.
+ * Similarly, if we had a horizontal line, top would mean shift up and bottom would mean shift down.
*/
enum NocLinkShift {
NO_SHIFT, // initially there is no shift
@@ -173,7 +178,11 @@ void draw_noc_connection_marker(ezgl::renderer* g, const vtr::vector& noc_link_colors, ezgl::rectangle noc_connection_marker_bbox, const vtr::vector& list_of_noc_link_shift_directions);
+void draw_noc_links(ezgl::renderer* g,
+ t_logical_block_type_ptr noc_router_logical_block_type,
+ vtr::vector& noc_link_colors,
+ ezgl::rectangle noc_connection_marker_bbox,
+ const vtr::vector& list_of_noc_link_shift_directions);
/**
* @brief Goes through all the links within the NoC and updates the color that
diff --git a/vpr/src/pack/attraction_groups.cpp b/vpr/src/pack/attraction_groups.cpp
index b8f0351d6a7..1cf6f428e37 100644
--- a/vpr/src/pack/attraction_groups.cpp
+++ b/vpr/src/pack/attraction_groups.cpp
@@ -47,35 +47,24 @@ void AttractionInfo::create_att_groups_for_overfull_regions() {
atom_attraction_group.resize(num_atoms);
fill(atom_attraction_group.begin(), atom_attraction_group.end(), AttractGroupId::INVALID());
- const auto& overfull_regions = floorplanning_ctx.overfull_regions;
- PartitionRegion overfull_regions_pr;
- for (const auto& overfull_region : overfull_regions) {
- overfull_regions_pr.add_to_part_region(overfull_region);
- }
- /*
- * Create a PartitionRegion that contains all the overfull regions so that you can
- * make an attraction group for any partition that intersects with any of these regions
- */
+ const std::vector& overfull_prs = floorplanning_ctx.overfull_partition_regions;
/*
- * Create an attraction group for each parition with an overfull region.
+ * Create an attraction group for each partition that overlaps with at least one overfull partition
*/
-
for (int ipart = 0; ipart < num_parts; ipart++) {
PartitionId partid(ipart);
const Partition& part = floorplanning_ctx.constraints.get_partition(partid);
- const auto& pr_regions = part.get_part_region();
- PartitionRegion intersect_pr;
-
- intersect_pr = intersection(overfull_regions_pr, pr_regions);
-
- if (!intersect_pr.empty()) {
- AttractionGroup group_info;
- group_info.group_atoms = floorplanning_ctx.constraints.get_part_atoms(partid);
-
- attraction_groups.push_back(group_info);
+ for (const PartitionRegion& overfull_pr : overfull_prs) {
+ PartitionRegion intersect_pr = intersection(part.get_part_region(), overfull_pr);
+ if (!intersect_pr.empty()) {
+ AttractionGroup group_info;
+ group_info.group_atoms = floorplanning_ctx.constraints.get_part_atoms(partid);
+ attraction_groups.push_back(group_info);
+ break;
+ }
}
}
@@ -108,7 +97,7 @@ void AttractionInfo::create_att_groups_for_all_regions() {
*/
/*
- * Create an attraction group for each parition with an overfull region.
+ * Create an attraction group for each partition with an overfull region.
*/
for (int ipart = 0; ipart < num_parts; ipart++) {
diff --git a/vpr/src/pack/constraints_report.cpp b/vpr/src/pack/constraints_report.cpp
index 2c58ef341a4..5c53744fd5e 100644
--- a/vpr/src/pack/constraints_report.cpp
+++ b/vpr/src/pack/constraints_report.cpp
@@ -1,6 +1,5 @@
#include "constraints_report.h"
-//To-do: alter this routine to check whether whole PartitionRegions are full instead of individual Regions
bool floorplan_constraints_regions_overfull() {
GridTileLookup grid_tiles;
@@ -8,48 +7,55 @@ bool floorplan_constraints_regions_overfull() {
auto& floorplanning_ctx = g_vpr_ctx.mutable_floorplanning();
auto& device_ctx = g_vpr_ctx.device();
- auto& block_types = device_ctx.logical_block_types;
+ const std::vector& block_types = device_ctx.logical_block_types;
- std::unordered_map> regions_count_info;
+ // keep record of how many blocks of each type are assigned to each PartitionRegion
+ std::unordered_map> pr_count_info;
- for (auto blk_id : cluster_ctx.clb_nlist.blocks()) {
+ for (const ClusterBlockId blk_id : cluster_ctx.clb_nlist.blocks()) {
if (!is_cluster_constrained(blk_id)) {
continue;
}
t_logical_block_type_ptr bt = cluster_ctx.clb_nlist.block_type(blk_id);
const PartitionRegion& pr = floorplanning_ctx.cluster_constraints[blk_id];
- const std::vector& regions = pr.get_regions();
-
- for (const auto& current_reg : regions) {
- auto got = regions_count_info.find(current_reg);
-
- if (got == regions_count_info.end()) {
- std::vector block_type_counts(block_types.size(), 0);
-
- block_type_counts[bt->index]++;
-
- regions_count_info.insert({current_reg, block_type_counts});
+ auto got = pr_count_info.find(pr);
- } else {
- got->second[bt->index]++;
- }
+ if (got == pr_count_info.end()) {
+ std::vector block_type_counts(block_types.size(), 0);
+ block_type_counts[bt->index]++;
+ pr_count_info.insert({pr, block_type_counts});
+ } else {
+ got->second[bt->index]++;
}
}
bool floorplan_regions_overfull = false;
- for (auto& region_info : regions_count_info) {
- const auto rect = region_info.first.get_region_rect();
- for (unsigned int j = 0; j < block_types.size(); j++) {
- int num_assigned_blocks = region_info.second[j];
- int num_tiles = 0;
- num_tiles = grid_tiles.region_tile_count(region_info.first, &block_types[j]);
+ for (const auto& [pr, block_type_counts] : pr_count_info) {
+ const std::vector& regions = pr.get_regions();
+
+ for (const t_logical_block_type& block_type : block_types) {
+ int num_assigned_blocks = block_type_counts[block_type.index];
+ int num_tiles = std::accumulate(regions.begin(), regions.end(), 0, [&grid_tiles, &block_type](int acc, const Region& reg) -> int {
+ return acc + grid_tiles.region_tile_count(reg, &block_type);
+ });
+
if (num_assigned_blocks > num_tiles) {
floorplan_regions_overfull = true;
- floorplanning_ctx.overfull_regions.push_back(region_info.first);
- VTR_LOG("\n \nRegion (%d, %d) to (%d, %d) st %d \n", rect.xmin, rect.ymin, rect.xmax, rect.ymax, region_info.first.get_sub_tile());
- VTR_LOG("Assigned %d blocks of type %s, but only has %d tiles of that type\n", num_assigned_blocks, block_types[j].name, num_tiles);
+ floorplanning_ctx.overfull_partition_regions.push_back(pr);
+ VTR_LOG("\n\nA partition including the following regions has been assigned %d blocks of type %s, "
+ "but only has %d tiles of that type\n",
+ num_assigned_blocks, block_type.name, num_tiles);
+ for (const Region& reg : regions) {
+ const vtr::Rect& rect = reg.get_rect();
+ const auto [layer_low, layer_high] = reg.get_layer_range();
+ VTR_LOG("\tRegion (%d, %d, %d) to (%d, %d, %d) st %d \n",
+ rect.xmin(), rect.ymin(), layer_low,
+ rect.xmax(), rect.ymax(), layer_high,
+ reg.get_sub_tile());
+ }
+
}
}
}
diff --git a/vpr/src/pack/constraints_report.h b/vpr/src/pack/constraints_report.h
index c41107f8c78..46af3fa83db 100644
--- a/vpr/src/pack/constraints_report.h
+++ b/vpr/src/pack/constraints_report.h
@@ -9,12 +9,23 @@
#include "grid_tile_lookup.h"
#include "place_constraints.h"
-/*
- * Check if any constraints regions are overfull,
- * i.e. the region contains more clusters of a certain type
- * than it has room for.
- * If the region is overfull, a message is printed saying which
- * region is overfull, and by how many clusters.
+/**
+ * @brief Check if any constraint partition regions are overfull,
+ * i.e. the partition contains more clusters of a certain type
+ * than it has room for. If the region is overfull, a message is
+ * printed saying which partition is overfull, and by how many clusters.
+ *
+ * To reduce the complexity of this function, several assumptions are made.
+ * 1) Regions of a partition do not overlap, meaning that the capacity of each
+ * partition for accommodating blocks of a specific type can be calculated by
+ * accumulating the capacity of its regions.
+ * 2) Partitions do not overlap. This means that each physical tile is in at most
+ * one partition.
+ *
+ * VPR can still work if these assumptions do not hold true, but for tight overlapping
+ * partitions, the placement engine may fail to find a legal placement.
+ *
+ * @return True if there is at least one overfull partition.
*/
bool floorplan_constraints_regions_overfull();
diff --git a/vpr/src/pack/pack.cpp b/vpr/src/pack/pack.cpp
index c151a1eea02..a76c9e698d4 100644
--- a/vpr/src/pack/pack.cpp
+++ b/vpr/src/pack/pack.cpp
@@ -23,7 +23,7 @@
/* #define DUMP_BLIF_INPUT 1 */
static bool try_size_device_grid(const t_arch& arch,
- const std::map& num_type_instances,
+ const std::map& num_type_instances,
float target_device_utilization,
const std::string& device_layout_name);
diff --git a/vpr/src/place/RL_agent_util.cpp b/vpr/src/place/RL_agent_util.cpp
index c05d2a46334..aa149b5d4e4 100644
--- a/vpr/src/place/RL_agent_util.cpp
+++ b/vpr/src/place/RL_agent_util.cpp
@@ -13,7 +13,7 @@ void create_move_generators(std::unique_ptr& move_generator,
VTR_LOG("Using static probabilities for choosing each move type\n");
for (const auto move_type : placer_opts.place_static_move_prob.keys()) {
- const std::string& move_name = move_type_to_string(move_type);
+ const std::string& move_name = move_type_to_string(move_type);
VTR_LOG("Probability of %s : %f \n",
move_name.c_str(),
placer_opts.place_static_move_prob[move_type]);
@@ -40,12 +40,12 @@ void create_move_generators(std::unique_ptr& move_generator,
* only move type. *
* This state is activated late in the anneal and in the Quench */
- std::vector first_state_avail_moves {e_move_type::UNIFORM, e_move_type::MEDIAN, e_move_type::CENTROID};
+ std::vector first_state_avail_moves{e_move_type::UNIFORM, e_move_type::MEDIAN, e_move_type::CENTROID};
if (placer_opts.place_algorithm.is_timing_driven()) {
first_state_avail_moves.push_back(e_move_type::W_CENTROID);
}
- std::vector second_state_avail_moves {e_move_type::UNIFORM, e_move_type::MEDIAN, e_move_type::CENTROID};
+ std::vector second_state_avail_moves{e_move_type::UNIFORM, e_move_type::MEDIAN, e_move_type::CENTROID};
if (placer_opts.place_algorithm.is_timing_driven()) {
second_state_avail_moves.insert(second_state_avail_moves.end(),
{e_move_type::W_CENTROID, e_move_type::W_MEDIAN, e_move_type::CRIT_UNIFORM, e_move_type::FEASIBLE_REGION});
diff --git a/vpr/src/place/RL_agent_util.h b/vpr/src/place/RL_agent_util.h
index c9d41ba5507..b50e2caed42 100644
--- a/vpr/src/place/RL_agent_util.h
+++ b/vpr/src/place/RL_agent_util.h
@@ -3,7 +3,6 @@
#include "move_generator.h"
-
//enum represents the available agent states
enum class e_agent_state {
EARLY_IN_THE_ANNEAL,
diff --git a/vpr/src/place/grid_tile_lookup.cpp b/vpr/src/place/grid_tile_lookup.cpp
index acef24ade63..d2236fdbc8a 100644
--- a/vpr/src/place/grid_tile_lookup.cpp
+++ b/vpr/src/place/grid_tile_lookup.cpp
@@ -74,27 +74,21 @@ int GridTileLookup::total_type_tiles(t_logical_block_type_ptr block_type) const
int GridTileLookup::region_tile_count(const Region& reg, t_logical_block_type_ptr block_type) const {
auto& device_ctx = g_vpr_ctx.device();
+ const int n_layers = device_ctx.grid.get_num_layers();
int subtile = reg.get_sub_tile();
- int layer_num = reg.get_layer_num();
+
/*Intersect the region with the grid, in case the region passed in goes out of bounds
* By intersecting with the grid, we ensure that we are only counting tiles for the part of the
* region that fits on the grid.*/
- Region grid_reg;
- grid_reg.set_region_rect({0,
- 0,
- (int)device_ctx.grid.width() - 1,
- (int)device_ctx.grid.height() - 1,
- layer_num});
- Region intersect_reg;
- intersect_reg = intersection(reg, grid_reg);
-
- const auto intersect_coord = intersect_reg.get_region_rect();
- VTR_ASSERT(intersect_coord.layer_num == layer_num);
-
- int xmin = intersect_coord.xmin;
- int ymin = intersect_coord.ymin;
- int xmax = intersect_coord.xmax;
- int ymax = intersect_coord.ymax;
+ Region grid_reg(0, 0,
+ (int)device_ctx.grid.width() - 1, (int)device_ctx.grid.height() - 1,
+ 0, n_layers - 1);
+ Region intersect_reg = intersection(reg, grid_reg);
+
+// VTR_ASSERT(intersect_coord.layer_num == layer_num);
+
+ const auto [xmin, ymin, xmax, ymax] = intersect_reg.get_rect().coordinates();
+ const auto [layer_low, layer_high] = intersect_reg.get_layer_range();
auto& layer_type_grid = block_type_matrices[block_type->index];
int xdim = (int)layer_type_grid.dim_size(1);
@@ -103,18 +97,22 @@ int GridTileLookup::region_tile_count(const Region& reg, t_logical_block_type_pt
int num_tiles = 0;
if (subtile == NO_SUBTILE) {
- num_tiles = layer_type_grid[layer_num][xmin][ymin];
+ for (int l = layer_low; l <= layer_high; l++) {
+ int num_tiles_in_layer = layer_type_grid[l][xmin][ymin];
- if ((ymax + 1) < ydim) {
- num_tiles -= layer_type_grid[layer_num][xmin][ymax + 1];
- }
+ if ((ymax + 1) < ydim) {
+ num_tiles_in_layer -= layer_type_grid[l][xmin][ymax + 1];
+ }
- if ((xmax + 1) < xdim) {
- num_tiles -= layer_type_grid[layer_num][xmax + 1][ymin];
- }
+ if ((xmax + 1) < xdim) {
+ num_tiles_in_layer -= layer_type_grid[l][xmax + 1][ymin];
+ }
+
+ if ((xmax + 1) < xdim && (ymax + 1) < ydim) {
+ num_tiles_in_layer += layer_type_grid[l][xmax + 1][ymax + 1];
+ }
- if ((xmax + 1) < xdim && (ymax + 1) < ydim) {
- num_tiles += layer_type_grid[layer_num][xmax + 1][ymax + 1];
+ num_tiles += num_tiles_in_layer;
}
} else {
num_tiles = region_with_subtile_count(reg, block_type);
@@ -123,23 +121,22 @@ int GridTileLookup::region_tile_count(const Region& reg, t_logical_block_type_pt
return num_tiles;
}
-int GridTileLookup::region_with_subtile_count(const Region& reg, t_logical_block_type_ptr block_type) const{
+int GridTileLookup::region_with_subtile_count(const Region& reg, t_logical_block_type_ptr block_type) const {
auto& device_ctx = g_vpr_ctx.device();
int num_sub_tiles = 0;
- const auto reg_coord = reg.get_region_rect();
+ const vtr::Rect& reg_rect = reg.get_rect();
+ const auto [xmin, ymin, xmax, ymax] = reg_rect.coordinates();
+ const auto [layer_low, layer_high] = reg.get_layer_range();
int subtile = reg.get_sub_tile();
- int xmin = reg_coord.xmin;
- int ymin = reg_coord.ymin;
- int xmax = reg_coord.xmax;
- int ymax = reg_coord.ymax;
-
for (int i = xmax; i >= xmin; i--) {
for (int j = ymax; j >= ymin; j--) {
- const t_physical_tile_type_ptr tile_type = device_ctx.grid.get_physical_type({i, j, reg_coord.layer_num});
- if (is_sub_tile_compatible(tile_type, block_type, subtile)) {
- num_sub_tiles++;
+ for (int l = layer_low; l <= layer_high; l++) {
+ const t_physical_tile_type_ptr tile_type = device_ctx.grid.get_physical_type({i, j, l});
+ if (is_sub_tile_compatible(tile_type, block_type, subtile)) {
+ num_sub_tiles++;
+ }
}
}
}
diff --git a/vpr/src/place/grid_tile_lookup.h b/vpr/src/place/grid_tile_lookup.h
index 63b99fb55a6..66d9d372db3 100644
--- a/vpr/src/place/grid_tile_lookup.h
+++ b/vpr/src/place/grid_tile_lookup.h
@@ -69,12 +69,13 @@ class GridTileLookup {
void fill_type_matrix(t_logical_block_type_ptr block_type, vtr::NdMatrix& type_count);
/**
- * @brief Stores the cumulative total of subtiles available at each location in the grid for each block type.
+ * @brief Stores the cumulative total of subtiles available at each (x, y) location in each layer
+ * for all block types.
*
* Therefore, the length of the vector will be the number of logical block types. To access the cumulative
- * number of subtiles at a location, you would use block_type_matrices[iblock_type][x][y] - this would
- * give the number of placement locations that are at, or above and to the right of the given [x,y] for
- * the given block type.
+ * number of subtiles at a location in a specific layer, you would use block_type_matrices[iblock_type][layer][x][y].
+ * This would give the number of placement locations that are at, or above (larger y) and to the right of the given [x,y] for
+ * the given block type in the given layer.
*/
std::vector> block_type_matrices;
diff --git a/vpr/src/place/initial_placement.cpp b/vpr/src/place/initial_placement.cpp
index 3781d89febc..2b4f9bfdf4f 100644
--- a/vpr/src/place/initial_placement.cpp
+++ b/vpr/src/place/initial_placement.cpp
@@ -288,10 +288,14 @@ static bool is_loc_legal(const t_pl_loc& loc,
//Check if the location is within its constraint region
for (const auto& reg : pr.get_regions()) {
- const auto reg_coord = reg.get_region_rect();
- vtr::Rect reg_rect(reg_coord.xmin, reg_coord.ymin, reg_coord.xmax, reg_coord.ymax);
- if (reg_coord.layer_num != loc.layer) continue;
- if (reg_rect.contains(vtr::Point(loc.x, loc.y))) {
+ const vtr::Rect& reg_rect = reg.get_rect();
+ const auto [layer_low, layer_high] = reg.get_layer_range();
+
+ if (loc.layer > layer_high || loc.layer < layer_low) {
+ continue;
+ }
+
+ if (reg_rect.contains({loc.x, loc.y})) {
//check if the location is compatible with the block type
const auto& type = grid.get_physical_type({loc.x, loc.y, loc.layer});
int height_offset = grid.get_height_offset({loc.x, loc.y, loc.layer});
@@ -579,17 +583,8 @@ static std::vector init_blk_types_empty_locations(
std::vector