Skip to content

Global Nets Routing constraints #2446

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 71 commits into from
Jun 4, 2024
Merged
Show file tree
Hide file tree
Changes from 38 commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
dda93e6
Add a new variable to t_segment_inf_struct that sets whether the segm…
kimiatkh Jul 26, 2023
e9ceea4
Update the architecture XML parser to add support for res_type attrib…
kimiatkh Jul 26, 2023
0b546ac
Update the RRGraph XML parser to add support for res_type attribute a…
kimiatkh Jul 26, 2023
1b71564
Add setter and getter for res_type attribute in t_segment_inf
kimiatkh Jul 26, 2023
204e93c
Set res_type attribute to GCLK for segments added during creation of …
kimiatkh Jul 26, 2023
b4ba730
Merge branch 'master' into clock_resource_detection
kimiatkh Jul 26, 2023
7ba41d8
Fix a bug in segment_res_type setter
kimiatkh Jul 31, 2023
3095426
Add clk_res_type attribute to rr node tag to detect the virtual sink …
kimiatkh Jul 31, 2023
f4e3c64
Move the clock virtual sink node id from device context to rr_graph_s…
kimiatkh Jul 31, 2023
3c1fd46
Add getters and setters for clk_res_type and write the attribute to t…
kimiatkh Aug 1, 2023
d463cdd
Rename the segment resource type from GENERIC to GENERAL as GENERIC c…
kimiatkh Aug 1, 2023
dc268cb
Undo unwanted changes
kimiatkh Aug 1, 2023
1c71627
Merge
kimiatkh Aug 1, 2023
ca5ba48
Changing the type of virtual sink node id from int to RRNodeId
kimiatkh Aug 2, 2023
1200f7a
Add a new optional attribute called name to rr_nodes that can be used…
kimiatkh Aug 8, 2023
fad6d66
Fix a bug in router that caused the second stage of the two stage rou…
kimiatkh Aug 8, 2023
af2c801
Create an unordered map to store more than one virtual sink ids
kimiatkh Aug 8, 2023
e79d3c5
Modify the parser to add support for attribute name and clk_res_type
kimiatkh Aug 14, 2023
71910f3
Fix a segmentation fault when writing the rr node names
kimiatkh Aug 15, 2023
b3689e4
Update the capnp parser to support new attributes name and clk_res_ty…
kimiatkh Aug 15, 2023
7e5ff68
Update the capnp parser to support new attributes name and clk_res_ty…
kimiatkh Aug 15, 2023
460b2a7
Modify rr graph parser not to throw an error when string name is empty
kimiatkh Aug 15, 2023
b4e7e33
Added the RouteConstraint class containing the routing constraint for…
Tulong4Dev Jan 26, 2023
1611242
make format
amin1377 Aug 24, 2023
8f9399d
Redefine the route constraints class
kimiatkh Aug 31, 2023
bbe9076
Encapsulate the floorplan constraints in user_place_constraints class…
kimiatkh Aug 31, 2023
b969445
Update the files using floor plan constraints file to point to the ne…
kimiatkh Aug 31, 2023
cd38989
Add a function that applies the routing constraints read from the con…
kimiatkh Aug 31, 2023
9736316
Update the VPR constraints paraser to process the routing constraints…
kimiatkh Aug 31, 2023
570947a
Update the clock network builder to assign a default name to the virt…
kimiatkh Aug 31, 2023
71c05cf
Update the router to repect the routing constraints provided by the u…
kimiatkh Aug 31, 2023
99c2a53
Add a regression tests for routing constraints
kimiatkh Aug 31, 2023
f9789b2
Merge
kimiatkh Nov 16, 2023
f2200f1
Merge branch 'clock_resource_detection' of https://github.com/verilog…
kimiatkh Nov 16, 2023
d700aa4
Merge
kimiatkh Nov 16, 2023
55e3445
Merge
kimiatkh Nov 16, 2023
37fcafc
Fix the compile errors after merging master
kimiatkh Nov 20, 2023
9541a86
Add routing constraint reg test to the task list
kimiatkh Nov 21, 2023
ce7dbc3
Fix the comments for the newly added functions related to clock network
kimiatkh Nov 27, 2023
06360f6
Convert enum r_seg_res_type to enum class
kimiatkh Nov 27, 2023
d85311d
Update the documentation for segment tag to include the new attribute…
kimiatkh Nov 27, 2023
342784f
Convert all function and class comments to doxygen format
kimiatkh Nov 28, 2023
fd0af8e
Add comments for apply_route_constraints function
kimiatkh Nov 28, 2023
c2e6a55
Convert comments to doxygen format
kimiatkh Nov 28, 2023
c336f09
Fix the compile errors caused by converting SegResType to enum class
kimiatkh Nov 28, 2023
9c862ec
Call place and route methods after fetching constraints instance thro…
kimiatkh Nov 28, 2023
b9c8775
Add the code that allows VPR to respect the global net routing constr…
kimiatkh Nov 30, 2023
8bbd7e9
Fix a syntax error in log printing of routing constraints
kimiatkh Nov 30, 2023
9364e9f
Change the default_clock_network_name from extern variable to a membe…
kimiatkh Nov 30, 2023
f217f82
Merge branch 'master' into routing_constraints
kimiatkh Nov 30, 2023
c8c8865
Update the golden results for routing constraints test
kimiatkh Jan 5, 2024
f1e513c
Merge branch 'master' into routing_constraints
kimiatkh Jan 5, 2024
70b911f
Add documentation for global routing constraints
kimiatkh Jan 9, 2024
1882daa
Add a section to documentation for global route constraints
kimiatkh Jan 9, 2024
fe5b660
Create a new documentation page for VPR constraints with references t…
kimiatkh Jan 9, 2024
835f4d0
Add a new custom domain for vpr constraints file format
kimiatkh Jan 9, 2024
60cc65b
Update references to vpr placement constraints documentation page
kimiatkh Jan 9, 2024
925834f
Add a reference to global routing constraints file in clock network d…
kimiatkh Jan 9, 2024
d3c17e5
Add an exception in update_from_heap to not set _is_isink_reached whe…
kimiatkh Apr 26, 2024
9d9f14a
Remove a depracted warning from packer
kimiatkh Apr 26, 2024
ff06e15
Merge
kimiatkh Jun 2, 2024
904d190
Fix the regression test for routing constraints
kimiatkh Jun 2, 2024
a1d213e
Remove the input argument from the function alloc_and_load_is_clock w…
kimiatkh Jun 2, 2024
a4a4a42
Fix the compile error
kimiatkh Jun 2, 2024
1e7c90d
Fix compile error
kimiatkh Jun 3, 2024
b70e728
Fix typos in the added documentation
kimiatkh Jun 3, 2024
1afe1c5
Don't compare expected node count with the rr_nodes count in the pres…
kimiatkh Jun 3, 2024
9de1631
Add an example for clock network definition in rr graphs
kimiatkh Jun 4, 2024
5c65093
Update the golden results for routing constraints regression tests
kimiatkh Jun 4, 2024
f976e9c
Merge branch 'master' into routing_constraints
vaughnbetz Jun 4, 2024
32983bc
Merge remote-tracking branch 'origin/master' into routing_constraints
AlexandreSinger Jun 4, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions libs/libarchfpga/src/physical_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -1508,6 +1508,16 @@ enum e_parallel_axis {
Y_AXIS,
BOTH_AXIS
};

/* GCLK: Describes a segment type that is part of the clock network *
* GENERAL: Describes a segment type that is part of the general routing resources */
enum e_seg_res_type {
GCLK = 0,
GENERAL = 1,
NUM_RES_TYPES
};
constexpr std::array<const char*, NUM_RES_TYPES> RES_TYPE_STRING = {{"GCLK", "GENERAL"}}; //String versions of segment resource types

enum e_switch_block_type {
SUBSET,
WILTON,
Expand Down Expand Up @@ -1560,6 +1570,14 @@ enum e_Fc_type {
* the segment's index in the unified segment_inf vector. This is *
* usefull when building the rr_graph for different Y & X channels*
* interms of track distribution and segment type. *
* res_type: Determines the routing network to which the segment belongs. *
* Possible values are:
* - GENERAL: The segment is part of the general routing *
* resources. *
* - GCLK: The segment is part of the generic clock network. *
* For backward compatibility, this attribute is optional. If not *
* specified, the resource type for the segment is considered to *
* be generic. *
* meta: Table storing extra arbitrary metadata attributes. */
struct t_segment_inf {
std::string name;
Expand All @@ -1578,6 +1596,7 @@ struct t_segment_inf {
std::vector<bool> cb;
std::vector<bool> sb;
int seg_index;
enum e_seg_res_type res_type = e_seg_res_type::GENERAL;
//float Cmetal_per_m; /* Wire capacitance (per meter) */
};

Expand Down
12 changes: 12 additions & 0 deletions libs/libarchfpga/src/read_xml_arch_file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3722,6 +3722,18 @@ static void ProcessSegments(pugi::xml_node Parent,
y_axis_seg_found = true;
}

/*Get segment resource type*/
tmp = get_attribute(Node, "res_type", loc_data, ReqOpt::OPTIONAL).as_string(nullptr);

if (tmp) {
auto it = std::find(RES_TYPE_STRING.begin(), RES_TYPE_STRING.end(), tmp);
if (it != RES_TYPE_STRING.end()) {
Segs[i].res_type = static_cast<e_seg_res_type>(std::distance(RES_TYPE_STRING.begin(), it));
} else {
archfpga_throw(loc_data.filename_c_str(), loc_data.line(Node), "Unsopported segment res_type: %s\n", tmp);
}
}

/* Get Power info */
/*
* (*Segs)[i].Cmetal_per_m = get_attribute(Node, "Cmetal_per_m", false,
Expand Down
3 changes: 1 addition & 2 deletions libs/librrgraph/src/base/check_rr_graph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ void check_rr_graph(const RRGraphView& rr_graph,
const DeviceGrid& grid,
const t_chan_width& chan_width,
const t_graph_type graph_type,
const int virtual_clock_network_root_idx,
bool is_flat) {
e_route_type route_type = DETAILED;
if (graph_type == GRAPH_GLOBAL) {
Expand All @@ -76,7 +75,7 @@ void check_rr_graph(const RRGraphView& rr_graph,
}

// Virtual clock network sink is special, ignore.
if (virtual_clock_network_root_idx == int(inode)) {
if (rr_graph.is_virtual_clock_network_root(rr_node)) {
continue;
}

Expand Down
1 change: 0 additions & 1 deletion libs/librrgraph/src/base/check_rr_graph.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ void check_rr_graph(const RRGraphView& rr_graph,
const DeviceGrid& grid,
const t_chan_width& chan_width,
const t_graph_type graph_type,
const int virtual_clock_network_root_idx,
bool is_flat);

void check_rr_node(const RRGraphView& rr_graph,
Expand Down
10 changes: 10 additions & 0 deletions libs/librrgraph/src/base/rr_graph_builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,11 @@ class RRGraphBuilder {
inline void set_node_type(RRNodeId id, t_rr_type type) {
node_storage_.set_node_type(id, type);
}

/** @brief Set the node name with a given valid id */
inline void set_node_name(RRNodeId id, std::string name) {
node_storage_.set_node_name(id, name);
}
/**
* @brief Add an existing rr_node in the node storage to the node look-up
*
Expand Down Expand Up @@ -219,6 +224,11 @@ class RRGraphBuilder {
node_storage_.set_node_direction(id, new_direction);
}

/** @brief Set the node id for clock network virtual sink */
inline void set_virtual_clock_network_root_idx(RRNodeId virtual_clock_network_root_idx) {
node_storage_.set_virtual_clock_network_root_idx(virtual_clock_network_root_idx);
}

/** @brief Reserve the lists of edges to be memory efficient.
* This function is mainly used to reserve memory space inside RRGraph,
* when adding a large number of edges in order to avoid memory fragements */
Expand Down
22 changes: 21 additions & 1 deletion libs/librrgraph/src/base/rr_graph_storage.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#include <climits>
#include "arch_types.h"
#include "rr_graph_storage.h"
#include "vtr_expr_eval.h"
#include "vtr_error.h"

#include <algorithm>

Expand Down Expand Up @@ -711,6 +713,9 @@ void t_rr_graph_storage::set_node_type(RRNodeId id, t_rr_type new_type) {
node_storage_[id].type_ = new_type;
}

void t_rr_graph_storage::set_node_name(RRNodeId id, std::string new_name) {
node_name_.insert(std::make_pair(id, new_name));
}
void t_rr_graph_storage::set_node_coordinates(RRNodeId id, short x1, short y1, short x2, short y2) {
auto& node = node_storage_[id];
if (x1 < x2) {
Expand Down Expand Up @@ -767,6 +772,19 @@ void t_rr_graph_storage::add_node_side(RRNodeId id, e_side new_side) {
node_storage_[id].dir_side_.sides = static_cast<unsigned char>(side_bits.to_ulong());
}

void t_rr_graph_storage::set_virtual_clock_network_root_idx(RRNodeId virtual_clock_network_root_idx) {
auto clock_network_name_str = node_name(virtual_clock_network_root_idx);
if(clock_network_name_str)
{
virtual_clock_network_root_idx_.insert(std::make_pair(*(clock_network_name_str.value()), virtual_clock_network_root_idx));
}
else
{
throw vtr::VtrError(vtr::string_fmt("Attribute name is not specified for virtual sink node '%u'\n", size_t(virtual_clock_network_root_idx)), __FILE__, __LINE__);
}

}

int t_rr_graph_view::node_ptc_num(RRNodeId id) const {
return node_ptc_[id].ptc_.pin_num;
}
Expand All @@ -790,10 +808,12 @@ t_rr_graph_view t_rr_graph_storage::view() const {
vtr::make_const_array_view_id(node_first_edge_),
vtr::make_const_array_view_id(node_fan_in_),
vtr::make_const_array_view_id(node_layer_),
node_name_,
vtr::make_const_array_view_id(node_ptc_twist_incr_),
vtr::make_const_array_view_id(edge_src_node_),
vtr::make_const_array_view_id(edge_dest_node_),
vtr::make_const_array_view_id(edge_switch_));
vtr::make_const_array_view_id(edge_switch_),
virtual_clock_network_root_idx_);
}

// Given `order`, a vector mapping each RRNodeId to a new one (old -> new),
Expand Down
97 changes: 95 additions & 2 deletions libs/librrgraph/src/base/rr_graph_storage.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
#include "vtr_memory.h"
#include "vtr_strong_id_range.h"
#include "vtr_array_view.h"
#include<iostream>
#include <optional>

/* Main structure describing one routing resource node. Everything in *
* this structure should describe the graph -- information needed only *
Expand Down Expand Up @@ -234,6 +236,14 @@ class t_rr_graph_storage {
short node_layer(RRNodeId id) const{
return node_layer_[id];
}
/* Retrieve the name assigned to the node id. If no name is assigned, empty string is returned */
std::optional<const std::string*> node_name(RRNodeId id) const{
auto it = node_name_.find(id);
if (it != node_name_.end()) {
return &it->second; // Return the value if key is found
}
return std::nullopt; // Return an empty string if key is not found
}

/** @brief Find the twist number that RR node uses to change ptc number across the same track.
* By default this number is zero, meaning that ptc number across the same track should be the same.
Expand All @@ -247,6 +257,26 @@ class t_rr_graph_storage {
return node_ptc_twist_incr_[id];
}

// Get the node id of the virtual sink for the clock network
RRNodeId virtual_clock_network_root_idx(const char* clock_network_name) const {
std::string clock_network_name_str(clock_network_name);
auto it = virtual_clock_network_root_idx_.find(clock_network_name);
if (it != virtual_clock_network_root_idx_.end()) {
return it->second; // Get
}
return RRNodeId::INVALID();
}

// Returns a bool indicating whether the input node id is a virtual sink for a clock network.
bool is_virtual_clock_network_root(RRNodeId id) const{
for (const auto& pair : virtual_clock_network_root_idx_) {
if (pair.second == id) {
return true;
}
}
return false;
}

/** @brief This prefetechs hot RR node data required for optimization.
*
* Note: This is optional, but may lower time spent on memory stalls in
Expand Down Expand Up @@ -467,6 +497,8 @@ class t_rr_graph_storage {
node_first_edge_.clear();
node_fan_in_.clear();
node_layer_.clear();
node_name_.clear();
virtual_clock_network_root_idx_.clear();
node_ptc_twist_incr_.clear();
edge_src_node_.clear();
edge_dest_node_.clear();
Expand Down Expand Up @@ -533,6 +565,7 @@ class t_rr_graph_storage {
void set_node_class_num(RRNodeId id, int); //Same as set_ptc_num() by checks type() is consistent

void set_node_type(RRNodeId id, t_rr_type new_type);
void set_node_name(RRNodeId id, std::string new_name);
void set_node_coordinates(RRNodeId id, short x1, short y1, short x2, short y2);
void set_node_layer(RRNodeId id, short layer);
void set_node_ptc_twist_incr(RRNodeId id, short twist);
Expand All @@ -547,6 +580,9 @@ class t_rr_graph_storage {
*/
void add_node_side(RRNodeId, e_side new_side);

// Set the node id of the virtual sink for the clock network
void set_virtual_clock_network_root_idx(RRNodeId virtual_clock_network_root_idx);

/****************
* Edge methods *
****************/
Expand Down Expand Up @@ -755,6 +791,25 @@ class t_rr_graph_storage {
*/
vtr::vector<RRNodeId, short> node_layer_;

/**
* @brief Stores the assigned names for the rr_node IDs.
*
* The primary use case for this attribute is to find the name of the clock network that a given virtual sink belongs to.
* If the user is modeling a clock network, they need to specify the clock network virtual sink in the rr_graph
* using the attribute clk_res_type. If the clk_res_type is specified, the attribute name is used as the name for the clock
* network.
*/
std::unordered_map<RRNodeId, std::string> node_name_;

/**
* @brief A map that uses the name for each clock network as the key and stores
* the rr_node index for the virtual sink that connects to all the nodes that
* are clock network entry points.
*
* This map is particularly useful for two-stage clock routing.
*/
std::unordered_map<std::string, RRNodeId> virtual_clock_network_root_idx_;

/** @brief
*Twist Increment number is defined for CHANX/CHANY nodes; it is useful for layout of tileable FPGAs used by openFPGA.
*It gives us a new track index in each tile a longer wire crosses, which enables us to make long wires with a repeated single-tile pattern that "twists" the wires as they cross the tile.
Expand Down Expand Up @@ -833,19 +888,23 @@ class t_rr_graph_view {
const vtr::array_view_id<RRNodeId, const RREdgeId> node_first_edge,
const vtr::array_view_id<RRNodeId, const t_edge_size> node_fan_in,
const vtr::array_view_id<RRNodeId, const short> node_layer,
const std::unordered_map<RRNodeId, std::string>& node_name,
const vtr::array_view_id<RRNodeId, const short> node_ptc_twist_incr,
const vtr::array_view_id<RREdgeId, const RRNodeId> edge_src_node,
const vtr::array_view_id<RREdgeId, const RRNodeId> edge_dest_node,
const vtr::array_view_id<RREdgeId, const short> edge_switch)
const vtr::array_view_id<RREdgeId, const short> edge_switch,
const std::unordered_map<std::string, RRNodeId>& virtual_clock_network_root_idx)
: node_storage_(node_storage)
, node_ptc_(node_ptc)
, node_first_edge_(node_first_edge)
, node_fan_in_(node_fan_in)
, node_layer_(node_layer)
, node_name_(node_name)
, node_ptc_twist_incr_(node_ptc_twist_incr)
, edge_src_node_(edge_src_node)
, edge_dest_node_(edge_dest_node)
, edge_switch_(edge_switch) {}
, edge_switch_(edge_switch)
, virtual_clock_network_root_idx_(virtual_clock_network_root_idx) {}

/****************
* Node methods *
Expand Down Expand Up @@ -904,6 +963,16 @@ class t_rr_graph_view {
return node_layer_[id];
}

/* Retrieve the name assigned to the node id. If no name is assigned, empty string is returned */
std::optional<const std::string*> node_name(RRNodeId id) const{
auto it = node_name_.find(id);
if (it != node_name_.end()) {
return &it->second; // Return the value if key is found
}
return std::nullopt; // Return an empty string if key is not found
}


/* Retrieve twist number (if available) that RRNodeId used for its ptc number */
short node_ptc_twist_incr(RRNodeId id) const{
//check if ptc twist increment allocated
Expand All @@ -921,6 +990,27 @@ class t_rr_graph_view {
VTR_PREFETCH(&node_storage_[id], 0, 0);
}

// Returns the node id of the virtual sink for the given clock network name
RRNodeId virtual_clock_network_root_idx(const char* clock_network_name) const{
std::string clock_network_name_str(clock_network_name);
auto it = virtual_clock_network_root_idx_.find(clock_network_name_str);
if (it != virtual_clock_network_root_idx_.end()) {
return it->second; // Get
}
return RRNodeId::INVALID();
}


// Returns a bool indicating whether the input node id is a virtual sink for a clock network.
bool is_virtual_clock_network_root(RRNodeId id) const{
for (const auto& pair : virtual_clock_network_root_idx_) {
if (pair.second == id) {
return true;
}
}
return false;
}

/* Edge accessors */

// Returns a range of RREdgeId's belonging to RRNodeId id.
Expand Down Expand Up @@ -954,10 +1044,13 @@ class t_rr_graph_view {
vtr::array_view_id<RRNodeId, const RREdgeId> node_first_edge_;
vtr::array_view_id<RRNodeId, const t_edge_size> node_fan_in_;
vtr::array_view_id<RRNodeId, const short> node_layer_;
const std::unordered_map<RRNodeId, std::string>& node_name_;
vtr::array_view_id<RRNodeId, const short> node_ptc_twist_incr_;
vtr::array_view_id<RREdgeId, const RRNodeId> edge_src_node_;
vtr::array_view_id<RREdgeId, const RRNodeId> edge_dest_node_;
vtr::array_view_id<RREdgeId, const short> edge_switch_;
const std::unordered_map<std::string, RRNodeId>& virtual_clock_network_root_idx_;

};

#endif /* _RR_GRAPH_STORAGE_ */
16 changes: 16 additions & 0 deletions libs/librrgraph/src/base/rr_graph_view.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,11 @@ class RRGraphView {
return node_storage_.node_type(node);
}

/** @brief Get the name assigned to a node id. */
std::optional<const std::string*> node_name(RRNodeId node) const {
return node_storage_.node_name(node);
}

/** @brief Get the type string of a routing resource node. This function is inlined for runtime optimization. */
inline const char* node_type_string(RRNodeId node) const {
return node_storage_.node_type_string(node);
Expand Down Expand Up @@ -310,6 +315,17 @@ class RRGraphView {
inline const char* node_side_string(RRNodeId node) const {
return node_storage_.node_side_string(node);
}

/** @brief Get the node id of the clock network virtual sink */
inline RRNodeId virtual_clock_network_root_idx(const char* clock_network_name) const {
return node_storage_.virtual_clock_network_root_idx(clock_network_name);
}

/** @brief Get the node id of the clock network virtual sink */
inline bool is_virtual_clock_network_root(RRNodeId id) const {
return node_storage_.is_virtual_clock_network_root(id);
}

/** @brief Get the switch id that represents the iedge'th outgoing edge from a specific node
* TODO: We may need to revisit this API and think about higher level APIs, like ``switch_delay()``
**/
Expand Down
Loading