Skip to content

Commit c881146

Browse files
Merge pull request #2930 from verilog-to-routing/ingest_per_edge_delay
Override edge attributes in RR graph
2 parents 3663572 + d390291 commit c881146

25 files changed

+514
-95
lines changed

Makefile

+2-2
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,14 @@ ifeq ($(VERBOSE),1)
4848
override CMAKE_PARAMS := -DVTR_ENABLE_VERBOSE=on ${CMAKE_PARAMS}
4949
endif
5050

51-
# -s : Suppresss makefile output (e.g. entering/leaving directories)
51+
# -s : Suppresses makefile output (e.g. entering/leaving directories)
5252
# --output-sync target : For parallel compilation ensure output for each target is synchronized (make version >= 4.0)
5353
MAKEFLAGS := -s
5454

5555
SOURCE_DIR := $(PWD)
5656
BUILD_DIR ?= build
5757

58-
#Check for the cmake exectuable
58+
#Check for the cmake executable
5959
CMAKE := $(shell command -v cmake 2> /dev/null)
6060

6161
#Show test log on failures with 'make test'

doc/src/vpr/command_line_usage.rst

+8
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,14 @@ Use the options below to override this default naming behaviour.
379379

380380
.. seealso:: :ref:`Routing Resource XML File <vpr_route_resource_file>`.
381381

382+
.. option:: --read_rr_edge_override <file>
383+
384+
Reads a file that overrides the intrinsic delay of specific edges in RR graph.
385+
386+
This option should be used with both :option:`--read_rr_graph` and :option:`--write_rr_graph`. When used this way,
387+
VPR reads the RR graph, updates the delays of selected edges using :option:`--read_rr_edge_override`,
388+
and writes the updated RR graph. The modified RR graph can then be used in later VPR runs.
389+
382390
.. option:: --read_vpr_constraints <file>
383391

384392
Reads the :ref:`VPR constraints <vpr_constraints>` that the flow must respect from the specified XML file.

doc/src/vpr/file_formats.rst

+22
Original file line numberDiff line numberDiff line change
@@ -1100,6 +1100,28 @@ To aid in handling large graphs, rr_graph files can also be :ref:`saved in <file
11001100

11011101
.. _end:
11021102

1103+
RR Graph Edge Attribute Override File Format (.txt)
1104+
---------------------------------------------------
1105+
This file lets users override attributes of specific edges in the RR graph. Currently, only the intrinsic delay (Tdel)
1106+
can be changed. The expected format is:
1107+
1108+
.. code-block:: none
1109+
1110+
# edge Tdel
1111+
64812 5.9e-11
1112+
9981 4.2e-11
1113+
1234 7.1e-11
1114+
4321 9.4e-11
1115+
(42, 64) 7.3e-11
1116+
1117+
.. _end:
1118+
1119+
Lines starting with # are comments and ignored. Each other line should specify either: an edge ID and its new delay, or
1120+
a source/sink node pair and its delay.
1121+
1122+
This allows more accurate modeling of switch delays in the RR graph without creating many switch types
1123+
in the architecture file and limiting them to small regions. This can be useful for more detailed modeling of
1124+
a fabricated FPGA where layout differences lead to small delay differences in the same type of routing switch.
11031125

11041126
Network-on-Chip (NoC) Traffic Flows Format (.flows)
11051127
---------------------------------------------------

libs/libarchfpga/src/physical_types.cpp

+36
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,42 @@ bool t_rr_switch_inf::configurable() const {
7171
return switch_type_is_configurable(type());
7272
}
7373

74+
bool t_rr_switch_inf::operator==(const t_rr_switch_inf& other) const {
75+
return R == other.R
76+
&& Cin == other.Cin
77+
&& Cout == other.Cout
78+
&& Cinternal == other.Cinternal
79+
&& Tdel == other.Tdel
80+
&& mux_trans_size == other.mux_trans_size
81+
&& buf_size == other.buf_size
82+
&& power_buffer_type == other.power_buffer_type
83+
&& power_buffer_size == other.power_buffer_size
84+
&& intra_tile == other.intra_tile
85+
&& type() == other.type();
86+
}
87+
88+
std::size_t t_rr_switch_inf::Hasher::operator()(const t_rr_switch_inf& s) const {
89+
std::size_t hash_val = 0;
90+
91+
auto hash_combine = [&hash_val](auto&& val) {
92+
hash_val ^= std::hash<std::decay_t<decltype(val)>>{}(val) + 0x9e3779b9 + (hash_val << 6) + (hash_val >> 2);
93+
};
94+
95+
hash_combine(s.R);
96+
hash_combine(s.Cin);
97+
hash_combine(s.Cout);
98+
hash_combine(s.Cinternal);
99+
hash_combine(s.Tdel);
100+
hash_combine(s.mux_trans_size);
101+
hash_combine(s.buf_size);
102+
hash_combine(static_cast<int>(s.power_buffer_type));
103+
hash_combine(s.power_buffer_size);
104+
hash_combine(s.intra_tile);
105+
hash_combine(static_cast<int>(s.type()));
106+
107+
return hash_val;
108+
}
109+
74110
void t_rr_switch_inf::set_type(SwitchType type_val) {
75111
type_ = type_val;
76112
}

libs/libarchfpga/src/physical_types.h

+33-6
Original file line numberDiff line numberDiff line change
@@ -1588,16 +1588,31 @@ enum class SegResType {
15881588
NUM_RES_TYPES
15891589
};
15901590

1591-
constexpr std::array<const char*, static_cast<size_t>(SegResType::NUM_RES_TYPES)> RES_TYPE_STRING = {{"GCLK", "GENERAL"}}; //String versions of segment resource types
1591+
/// String versions of segment resource types
1592+
constexpr std::array<const char*, static_cast<size_t>(SegResType::NUM_RES_TYPES)> RES_TYPE_STRING{"GCLK", "GENERAL"};
15921593

1594+
/// Defines the type of switch block used in FPGA routing.
15931595
enum e_switch_block_type {
1596+
/// If the type is SUBSET, I use a Xilinx-like switch block where track i in one channel always
1597+
/// connects to track i in other channels.
15941598
SUBSET,
1599+
1600+
/// If type is WILTON, I use a switch block where track i
1601+
/// does not always connect to track i in other channels.
1602+
/// See Steve Wilton, PhD Thesis, University of Toronto, 1996.
15951603
WILTON,
1604+
1605+
/// The UNIVERSAL switch block is from Y. W. Chang et al, TODAES, Jan. 1996, pp. 80 - 101.
15961606
UNIVERSAL,
1607+
1608+
/// The FULL switch block type allows for complete connectivity between tracks.
15971609
FULL,
1610+
1611+
/// A CUSTOM switch block has also been added which allows a user to describe custom permutation functions and connection patterns.
1612+
/// See comment at top of SRC/route/build_switchblocks.c
15981613
CUSTOM
15991614
};
1600-
typedef enum e_switch_block_type t_switch_block_type;
1615+
16011616
enum e_Fc_type {
16021617
ABSOLUTE,
16031618
FRACTIONAL
@@ -1906,16 +1921,28 @@ struct t_rr_switch_inf {
19061921
bool intra_tile = false;
19071922

19081923
public:
1909-
//Returns the type of switch
1924+
/// Returns the type of switch
19101925
SwitchType type() const;
19111926

1912-
//Returns true if this switch type isolates its input and output into
1913-
//separate DC-connected subcircuits
1927+
/// Returns true if this switch type isolates its input and output into
1928+
/// separate DC-connected subcircuits
19141929
bool buffered() const;
19151930

1916-
//Returns true if this switch type is configurable
1931+
/// Returns true if this switch type is configurable
19171932
bool configurable() const;
19181933

1934+
bool operator==(const t_rr_switch_inf& other) const;
1935+
1936+
/**
1937+
* @brief Functor for computing a hash value for t_rr_switch_inf.
1938+
*
1939+
* This custom hasher enables the use of t_rr_switch_inf objects as keys
1940+
* in unordered containers such as std::unordered_map or std::unordered_set.
1941+
*/
1942+
struct Hasher {
1943+
std::size_t operator()(const t_rr_switch_inf& s) const;
1944+
};
1945+
19191946
public:
19201947
void set_type(SwitchType type_val);
19211948

libs/librrgraph/src/base/rr_graph_builder.h

+8-2
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ class RRGraphBuilder {
239239

240240
/** @brief Reserve the lists of edges to be memory efficient.
241241
* This function is mainly used to reserve memory space inside RRGraph,
242-
* when adding a large number of edges in order to avoid memory fragements */
242+
* when adding a large number of edges in order to avoid memory fragments */
243243
inline void reserve_edges(size_t num_edges) {
244244
node_storage_.reserve_edges(num_edges);
245245
}
@@ -264,6 +264,12 @@ class RRGraphBuilder {
264264
node_storage_.alloc_and_load_edges(rr_edges_to_create);
265265
}
266266

267+
/** @brief Overrides the associated switch for a given edge by
268+
* updating the edge to use the passed in switch. */
269+
inline void override_edge_switch(RREdgeId edge_id, RRSwitchId switch_id) {
270+
node_storage_.override_edge_switch(edge_id, switch_id);
271+
}
272+
267273
/** @brief set_node_cost_index gets the index of cost data in the list of cost_indexed_data data structure
268274
* It contains the routing cost for different nodes in the RRGraph
269275
* when used in evaluate different routing paths
@@ -304,7 +310,7 @@ class RRGraphBuilder {
304310
/** @brief Reserve the lists of nodes, edges, switches etc. to be memory efficient.
305311
* This function is mainly used to reserve memory space inside RRGraph,
306312
* when adding a large number of nodes/edge/switches/segments,
307-
* in order to avoid memory fragements */
313+
* in order to avoid memory fragments */
308314
inline void reserve_nodes(size_t size) {
309315
node_storage_.reserve(size);
310316
}

libs/librrgraph/src/base/rr_graph_storage.cpp

+9-4
Original file line numberDiff line numberDiff line change
@@ -536,10 +536,9 @@ void t_rr_graph_storage::partition_edges(const vtr::vector<RRSwitchId, t_rr_swit
536536
// by assign_first_edges()
537537
// - Edges within a source node have the configurable edges before the
538538
// non-configurable edges.
539-
std::stable_sort(
540-
edge_sort_iterator(this, 0),
541-
edge_sort_iterator(this, edge_src_node_.size()),
542-
edge_compare_src_node_and_configurable_first(rr_switches));
539+
std::stable_sort(edge_sort_iterator(this, 0),
540+
edge_sort_iterator(this, edge_src_node_.size()),
541+
edge_compare_src_node_and_configurable_first(rr_switches));
543542

544543
partitioned_ = true;
545544

@@ -548,6 +547,12 @@ void t_rr_graph_storage::partition_edges(const vtr::vector<RRSwitchId, t_rr_swit
548547
VTR_ASSERT_SAFE(validate(rr_switches));
549548
}
550549

550+
void t_rr_graph_storage::override_edge_switch(RREdgeId edge_id, RRSwitchId switch_id) {
551+
VTR_ASSERT_DEBUG(partitioned_);
552+
VTR_ASSERT_DEBUG(remapped_edges_);
553+
edge_switch_[edge_id] = (short)((size_t)switch_id);
554+
}
555+
551556
t_edge_size t_rr_graph_storage::num_configurable_edges(RRNodeId id, const vtr::vector<RRSwitchId, t_rr_switch_inf>& rr_switches) const {
552557
VTR_ASSERT(!node_first_edge_.empty() && remapped_edges_);
553558

libs/librrgraph/src/base/rr_graph_storage.h

+26-9
Original file line numberDiff line numberDiff line change
@@ -393,13 +393,27 @@ class t_rr_graph_storage {
393393
* This method should generally not be used, and instead first_edge and
394394
* last_edge should be used.
395395
*/
396-
RREdgeId edge_id(const RRNodeId& id, t_edge_size iedge) const {
396+
RREdgeId edge_id(RRNodeId id, t_edge_size iedge) const {
397397
RREdgeId first_edge = this->first_edge(id);
398398
RREdgeId ret(size_t(first_edge) + iedge);
399399
VTR_ASSERT_SAFE(ret < last_edge(id));
400400
return ret;
401401
}
402402

403+
/**
404+
* @brief Retrieve the RREdgeId that connects the given source and sink nodes.
405+
* If the given source/sink nodes are not connected, RREdgeId::INVALID() is returned.
406+
*/
407+
RREdgeId edge_id(RRNodeId src, RRNodeId sink) const {
408+
for (RREdgeId outgoing_edge_id : edge_range(src)) {
409+
if (edge_sink_node(outgoing_edge_id) == sink) {
410+
return outgoing_edge_id;
411+
}
412+
}
413+
414+
return RREdgeId::INVALID();
415+
}
416+
403417
/** @brief Get the source node for the specified edge. */
404418
RRNodeId edge_src_node(const RREdgeId& edge) const {
405419
VTR_ASSERT_DEBUG(edge.is_valid());
@@ -448,7 +462,7 @@ class t_rr_graph_storage {
448462
*
449463
* The following methods implement an interface that appears to be
450464
* equivalent to the interface exposed by std::vector<t_rr_node>.
451-
* This was done for backwards compability. See t_rr_node for more details.
465+
* This was done for backwards compatibility. See t_rr_node for more details.
452466
*
453467
* Proxy methods:
454468
*
@@ -483,8 +497,8 @@ class t_rr_graph_storage {
483497
***************************/
484498

485499
/** @brief
486-
* Makes room in storage for RRNodeId in amoritized O(1) fashion.
487-
* This results in an allocation pattern similiar to what would happen
500+
* Makes room in storage for RRNodeId in amortized O(1) fashion.
501+
* This results in an allocation pattern similar to what would happen
488502
* if push_back(x) / emplace_back() were used if underlying storage
489503
* was not pre-allocated.
490504
*/
@@ -616,8 +630,8 @@ class t_rr_graph_storage {
616630
void set_node_direction(RRNodeId, Direction new_direction);
617631

618632
/** @brief
619-
* Add a side to the node abbributes
620-
* This is the function to use when you just add a new side WITHOUT reseting side attributes
633+
* Add a side to the node attributes
634+
* This is the function to use when you just add a new side WITHOUT resetting side attributes
621635
*/
622636
void add_node_side(RRNodeId, e_side new_side);
623637

@@ -707,9 +721,8 @@ class t_rr_graph_storage {
707721
*
708722
* init_fan_in does not need to be invoked before this method.
709723
*/
710-
size_t count_rr_switches(
711-
const std::vector<t_arch_switch_inf>& arch_switch_inf,
712-
t_arch_switch_fanin& arch_switch_fanins);
724+
size_t count_rr_switches(const std::vector<t_arch_switch_inf>& arch_switch_inf,
725+
t_arch_switch_fanin& arch_switch_fanins);
713726

714727
/** @brief Maps arch_switch_inf indicies to rr_switch_inf indicies.
715728
*
@@ -731,6 +744,10 @@ class t_rr_graph_storage {
731744
*/
732745
void partition_edges(const vtr::vector<RRSwitchId, t_rr_switch_inf>& rr_switches);
733746

747+
/** @brief Overrides the associated switch for a given edge by
748+
* updating the edge to use the passed in switch. */
749+
void override_edge_switch(RREdgeId edge_id, RRSwitchId switch_id);
750+
734751
/** @brief Validate that edge data is partitioned correctly.*/
735752
bool validate_node(RRNodeId node_id, const vtr::vector<RRSwitchId, t_rr_switch_inf>& rr_switches) const;
736753
bool validate(const vtr::vector<RRSwitchId, t_rr_switch_inf>& rr_switches) const;

libs/librrgraph/src/base/rr_graph_view.h

+5
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,11 @@ class RRGraphView {
413413
return node_storage_.edge_switch(id, iedge);
414414
}
415415

416+
/// @brief Returns the associated switch for a given edge.
417+
inline short edge_switch(RREdgeId id) const {
418+
return node_storage_.edge_switch(id);
419+
}
420+
416421
/** @brief Return the source node for the specified edge.
417422
*/
418423
inline RRNodeId edge_src_node(const RREdgeId edge_id) const {

0 commit comments

Comments
 (0)