Skip to content

Commit 3a23dcd

Browse files
committed
Get Xilinx 7 series to work
Signed-off-by: Maciej Dudek <[email protected]>
1 parent feec365 commit 3a23dcd

File tree

2 files changed

+108
-47
lines changed

2 files changed

+108
-47
lines changed

vpr/src/route/rr_graph_fpga_interchange.cpp

Lines changed: 57 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ struct intermediate_node {
5555
visited = nullptr;
5656
on_route = false;
5757
has_pins = false;
58+
segment_id = -1;
5859
}
5960
};
6061

@@ -83,14 +84,6 @@ struct RR_Graph_Builder {
8384
wire_name_to_seg_idx_[segment_inf_[RRSegmentId(i)].name] = i;
8485
}
8586

86-
for (size_t i = 1; i < grid.width() - 1; ++i) {
87-
for (size_t j = 1; j < grid.height() - 1; ++j) {
88-
location loc(i, j);
89-
if (grid[i][j].type->index == 0)
90-
empty_tiles.insert(loc);
91-
}
92-
}
93-
9487
auto primLib = ar_.getPrimLibs();
9588
auto portList = primLib.getPortList();
9689

@@ -158,15 +151,13 @@ struct RR_Graph_Builder {
158151

159152
std::unordered_map<std::string, int> wire_name_to_seg_idx_;
160153

161-
std::set<location> empty_tiles;
162-
163154
std::set<uint32_t> bel_cell_mappings_;
164155

165156
std::unordered_map<int /*tile_id(name)*/, location> tile_to_loc_;
166-
std::map<location, int /*tile_id(name)*/> loc_to_tile_;
157+
std::unordered_map<location, int /*tile_id(name)*/, hash_tuple::hash<location>> loc_to_tile_;
167158

168-
std::map<std::tuple<int /*timing_model*/, bool /*buffered*/>, int /*idx*/> pips_models_;
169-
std::map<std::tuple<int /*node_id*/, int /*node_id*/>, std::tuple<int /*switch_id*/, int /* tile_id */, std::tuple<int /*name*/, int /*wire0*/, int /*wire1*/, bool /*forward*/>>> pips_;
159+
std::unordered_map<std::tuple<int /*timing_model*/, bool /*buffered*/>, int /*idx*/, hash_tuple::hash<std::tuple<int, bool>>> pips_models_;
160+
std::unordered_map<std::tuple<int /*node_id*/, int /*node_id*/>, std::tuple<int /*switch_id*/, int /* tile_id */, std::tuple<int /*name*/, int /*wire0*/, int /*wire1*/, bool /*forward*/>>, hash_tuple::hash<std::tuple<int, int>>> pips_;
170161

171162
std::map<std::tuple<int, int>, int> wire_to_node_;
172163
std::unordered_map<int, std::set<location>> node_to_locs_;
@@ -192,9 +183,9 @@ struct RR_Graph_Builder {
192183
* Sets contain tuples of node ids and location.
193184
* Each value <n,l> correspondence to node id n being used by either pip or pin at location l.
194185
*/
195-
std::set<std::tuple<int /*node_id*/, location>> used_by_pip_;
196-
std::set<std::tuple<int /*node_id*/, location>> used_by_pin_;
197-
std::set<int /* node_id*/> usefull_node_;
186+
std::unordered_set<std::tuple<int /*node_id*/, location>, hash_tuple::hash<std::tuple<int, location>>> used_by_pip_;
187+
std::unordered_set<std::tuple<int /*node_id*/, location>, hash_tuple::hash<std::tuple<int, location>>> used_by_pin_;
188+
std::unordered_set<int /* node_id*/> usefull_node_;
198189

199190
/* Sink_source_loc_map is used to create ink/source and ipin/opin rr_nodes,
200191
* rr_edges from sink/source to ipin/opin and from ipin/opin to their coresponding segments
@@ -423,6 +414,10 @@ struct RR_Graph_Builder {
423414
const auto& wire = ar_.getWires()[wire_id_];
424415
int tile_id = wire.getTile();
425416
int wire_id = wire.getWire();
417+
if (tile_id == 6038 && wire_id == 5471) {
418+
VTR_LOG("id:%d, wire_id_:%d\n", id, (int)wire_id_);
419+
VTR_LOG("tile:%s wire:%s\n", str(tile_id).c_str(), str(wire_id).c_str());
420+
}
426421
wire_to_node_[std::make_tuple(tile_id, wire_id)] = id;
427422
node_to_locs_[id].insert(tile_to_loc_[tile_id]);
428423
if (wire_name_to_seg_idx_.find(str(wire_id)) == wire_name_to_seg_idx_.end())
@@ -494,15 +489,19 @@ struct RR_Graph_Builder {
494489
* Build graph of FPGA Interchange node for further computations
495490
*/
496491
std::set<intermediate_node*> build_node_graph(int node_id,
497-
std::set<location> nodes) {
492+
std::set<location> nodes,
493+
int& seg_id) {
494+
498495
std::set<intermediate_node*> roots;
499496
std::map<location, intermediate_node*> existing_nodes;
500497
do {
501498
intermediate_node* root_node = new intermediate_node((*nodes.begin()).first,
502499
(*nodes.begin()).second);
503500
location key = *nodes.begin();
504501

505-
root_node->segment_id = node_tile_to_segment_[std::make_tuple(node_id, loc_to_tile_[key])];
502+
if (node_tile_to_segment_[std::make_tuple(node_id, loc_to_tile_[key])] != -1)
503+
seg_id = node_tile_to_segment_[std::make_tuple(node_id, loc_to_tile_[key])];
504+
506505
nodes.erase(key);
507506

508507
existing_nodes.emplace(key, root_node);
@@ -523,7 +522,8 @@ struct RR_Graph_Builder {
523522
temp = existing_nodes[other_loc];
524523
} else if (nodes.find(other_loc) != nodes.end()) {
525524
temp = new intermediate_node(other_loc.first, other_loc.second);
526-
temp->segment_id = node_tile_to_segment_[std::make_tuple(node_id, loc_to_tile_[other_loc])];
525+
if (node_tile_to_segment_[std::make_tuple(node_id, loc_to_tile_[other_loc])] != -1)
526+
seg_id = node_tile_to_segment_[std::make_tuple(node_id, loc_to_tile_[other_loc])];
527527
nodes.erase(other_loc);
528528
existing_nodes.emplace(other_loc, temp);
529529
builder.push(temp);
@@ -550,7 +550,7 @@ struct RR_Graph_Builder {
550550
* Removes dangling nodes from a graph represented by the root node.
551551
* Dangling nodes are nodes that do not connect to a pin, a pip or other non-dangling node.
552552
*/
553-
int reduce_graph_and_count_nodes_left(std::set<intermediate_node*>& roots) {
553+
int reduce_graph_and_count_nodes_left(std::set<intermediate_node*>& roots, int seg_id) {
554554
int cnt = 0;
555555
std::queue<intermediate_node*> walker;
556556
std::stack<intermediate_node*> back_walker;
@@ -564,6 +564,7 @@ struct RR_Graph_Builder {
564564
intermediate_node* vertex = walker.front();
565565
walker.pop();
566566
back_walker.push(vertex);
567+
vertex->segment_id = seg_id;
567568
for (auto i : NODESIDES) {
568569
if (vertex->links[i] != nullptr) {
569570
all_nulls = false;
@@ -581,9 +582,6 @@ struct RR_Graph_Builder {
581582
intermediate_node* vertex = back_walker.top();
582583
back_walker.pop();
583584
if (!vertex->has_pins && !vertex->on_route) {
584-
if (vertex->visited->segment_id == -1) {
585-
vertex->visited->segment_id = vertex->segment_id;
586-
}
587585
for (auto i : NODESIDES) {
588586
intermediate_node* temp = nullptr;
589587
if (vertex->links[i] != nullptr) {
@@ -598,8 +596,6 @@ struct RR_Graph_Builder {
598596
delete vertex;
599597
} else if (vertex->on_route) {
600598
vertex->visited->on_route = true;
601-
if (vertex->visited->segment_id == -1)
602-
vertex->visited->segment_id = vertex->segment_id;
603599
}
604600
}
605601
return cnt;
@@ -642,7 +638,10 @@ struct RR_Graph_Builder {
642638
std::tuple<location, e_rr_type> key1(vertex->loc, e_rr_type::CHANY);
643639
std::tuple<location, e_rr_type> key2(location(vertex->loc.first, vertex->loc.second - 1), e_rr_type::CHANX);
644640

645-
VTR_ASSERT(vertex->segment_id != -1);
641+
if (vertex->segment_id == -1) {
642+
VTR_LOG("node_id:%d X:%d Y:%d\n", node_id, vertex->loc.first, vertex->loc.second);
643+
VTR_ASSERT(false);
644+
}
646645

647646
if (is_chany) {
648647
loc_chan_idx[key1] = chan_loc_map_[key1].size();
@@ -818,13 +817,14 @@ struct RR_Graph_Builder {
818817
for (auto const& node : ar_.getNodes()) {
819818
std::tuple<int, int> base_wire_(wires[node.getWires()[0]].getTile(), wires[node.getWires()[0]].getWire());
820819
int node_id = wire_to_node_[base_wire_];
820+
int seg_id;
821821
if (usefull_node_.find(node_id) == usefull_node_.end()) {
822822
continue;
823823
}
824824
std::set<location> all_possible_tiles = node_to_locs_[node_id];
825825

826-
std::set<intermediate_node*> roots = build_node_graph(node_id, all_possible_tiles);
827-
int div = reduce_graph_and_count_nodes_left(roots);
826+
std::set<intermediate_node*> roots = build_node_graph(node_id, all_possible_tiles, seg_id);
827+
int div = reduce_graph_and_count_nodes_left(roots, seg_id);
828828
if (roots.empty()) {
829829
continue;
830830
}
@@ -900,8 +900,11 @@ struct RR_Graph_Builder {
900900
int pin_id = sub_tile.sub_tile_to_tile_pin_indices[port.index];
901901
std::tuple<int, int, std::string> key{tile_type_id, it, std::string(port.name)};
902902
std::tie<float, int>(value, wire_id) = tile_type_site_num_pin_name_model[key];
903-
VTR_ASSERT(wire_to_node_.find(std::make_tuple(tile_id, wire_id)) != wire_to_node_.end());
904-
node_id = wire_to_node_[std::make_tuple(tile_id, wire_id)];
903+
if (wire_to_node_.find(std::make_tuple(tile_id, wire_id)) == wire_to_node_.end()) {
904+
node_id = -1;
905+
} else {
906+
node_id = wire_to_node_[std::make_tuple(tile_id, wire_id)];
907+
}
905908

906909
location loc = tile_to_loc_[tile_id];
907910

@@ -965,18 +968,23 @@ struct RR_Graph_Builder {
965968
float R, C;
966969
std::tie(R, C) = input ? std::tuple<float, float>(0, RC) : std::tuple<float, float>(RC, 0);
967970

968-
location track_loc;
969-
e_rr_type track_type;
970-
int track_idx;
971-
VTR_ASSERT(redirect_.find(std::make_tuple(FPGA_Interchange_node_id, loc)) != redirect_.end());
972-
std::tie(track_loc, track_type, track_idx) = redirect_[std::make_tuple(FPGA_Interchange_node_id, loc)];
973-
auto val = chan_loc_map_[std::make_tuple(track_loc, track_type)][track_idx];
974-
int track_seg;
975-
float track_R, track_C;
976-
std::tie(track_seg, track_R, track_C) = val;
977-
track_R += R;
978-
track_C += C;
979-
chan_loc_map_[std::make_tuple(track_loc, track_type)][track_idx] = std::make_tuple(track_seg, track_R, track_C);
971+
if(FPGA_Interchange_node_id != -1) {
972+
location track_loc;
973+
e_rr_type track_type;
974+
int track_idx;
975+
if (redirect_.find(std::make_tuple(FPGA_Interchange_node_id, loc)) == redirect_.end()) {
976+
VTR_LOG("node_id:%d, loc->X:%d Y:%d\n", FPGA_Interchange_node_id, loc.first, loc.second);
977+
VTR_ASSERT(false);
978+
}
979+
std::tie(track_loc, track_type, track_idx) = redirect_[std::make_tuple(FPGA_Interchange_node_id, loc)];
980+
auto val = chan_loc_map_[std::make_tuple(track_loc, track_type)][track_idx];
981+
int track_seg;
982+
float track_R, track_C;
983+
std::tie(track_seg, track_R, track_C) = val;
984+
track_R += R;
985+
track_C += C;
986+
chan_loc_map_[std::make_tuple(track_loc, track_type)][track_idx] = std::make_tuple(track_seg, track_R, track_C);
987+
}
980988

981989
device_ctx_.rr_nodes.make_room_for_node(RRNodeId(rr_idx));
982990
loc_type_idx_to_rr_idx_[std::make_tuple(loc, pin, j)] = rr_idx;
@@ -996,7 +1004,10 @@ struct RR_Graph_Builder {
9961004
}
9971005
for (size_t j = 0; j < pin_vec.size(); ++j) {
9981006
bool input;
999-
std::tie(input, std::ignore, std::ignore) = pin_vec[j];
1007+
int FPGA_Interchange_node_id;
1008+
std::tie(input, std::ignore, FPGA_Interchange_node_id) = pin_vec[j];
1009+
if (FPGA_Interchange_node_id == -1)
1010+
continue;
10001011
e_rr_type pin = input ? e_rr_type::IPIN : e_rr_type::OPIN;
10011012

10021013
device_ctx_.rr_nodes.make_room_for_node(RRNodeId(rr_idx));
@@ -1076,6 +1087,8 @@ struct RR_Graph_Builder {
10761087
bool input;
10771088
int node_id;
10781089
std::tie(input, std::ignore, node_id) = pin_vec[j];
1090+
if (node_id == -1)
1091+
continue;
10791092
VTR_ASSERT(redirect_.find(std::make_tuple(node_id, loc)) != redirect_.end());
10801093
auto chan_key = redirect_[std::make_tuple(node_id, loc)];
10811094
e_rr_type pin = input ? e_rr_type::SINK : e_rr_type::SOURCE;
@@ -1162,10 +1175,7 @@ struct RR_Graph_Builder {
11621175
temp = int_to_string(temp, forward ? 1 : 0);
11631176
*temp++ = 0;
11641177

1165-
vtr::interned_string name_(device_ctx_.arch->strings.intern_string(vtr::string_view("FPGAInterchange")));
1166-
vtr::interned_string value_(device_ctx_.arch->strings.intern_string(vtr::string_view(metadata_)));
1167-
1168-
vpr::add_rr_edge_metadata(src, sink, sw_id, name_, value_);
1178+
vpr::add_rr_edge_metadata(src, sink, sw_id, vtr::string_view("FPGAInterchange"), vtr::string_view(metadata_));
11691179
}
11701180
}
11711181

vpr/src/route/rr_graph_fpga_interchange.h

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "LogicalNetlist.capnp.h"
1010
#include "capnp/serialize.h"
1111
#include "capnp/serialize-packed.h"
12+
#include <functional>
1213

1314
void build_rr_graph_fpga_interchange(const t_graph_type graph_type,
1415
const DeviceGrid& grid,
@@ -17,4 +18,54 @@ void build_rr_graph_fpga_interchange(const t_graph_type graph_type,
1718
int* wire_to_rr_ipin_switch,
1819
bool do_check_rr_graph);
1920

21+
namespace hash_tuple{
22+
namespace {
23+
template <typename TT>
24+
struct hash {
25+
size_t operator()(TT const& tt) const {
26+
return std::hash<TT>()(tt);
27+
}
28+
};
29+
30+
template<class T1, class T2>
31+
struct hash <std::pair<T1, T2>> {
32+
size_t operator()(const std::pair<T1, T2> &p) const noexcept(true) {
33+
size_t lhs, rhs;
34+
lhs = std::hash<T1>()(p.first);
35+
rhs = std::hash<T2>()(p.second);
36+
lhs ^= rhs + 0x9e3779b9 + (lhs << 6) + (lhs >> 2);
37+
return lhs;
38+
}
39+
};
40+
template <class T>
41+
inline void hash_combine(std::size_t& seed, T const& v) {
42+
seed ^= hash_tuple::hash<T>()(v) + 0x9e3779b9 + (seed<<6) + (seed>>2);
43+
}
44+
// Recursive template code derived from Matthieu M.
45+
template <class Tuple, size_t Index = std::tuple_size<Tuple>::value - 1>
46+
struct HashValueImpl {
47+
static void apply(size_t& seed, Tuple const& tuple) {
48+
HashValueImpl<Tuple, Index-1>::apply(seed, tuple);
49+
hash_combine(seed, std::get<Index>(tuple));
50+
}
51+
};
52+
53+
template <class Tuple>
54+
struct HashValueImpl<Tuple,0> {
55+
static void apply(size_t& seed, Tuple const& tuple) {
56+
hash_combine(seed, std::get<0>(tuple));
57+
}
58+
};
59+
}
60+
61+
template <typename ... TT>
62+
struct hash<std::tuple<TT...>> {
63+
size_t operator()(std::tuple<TT...> const& tt) const {
64+
size_t seed = 0;
65+
HashValueImpl<std::tuple<TT...> >::apply(seed, tt);
66+
return seed;
67+
}
68+
};
69+
}
70+
2071
#endif /* RR_GRAPH_FPGA_INTERCHANGE_H */

0 commit comments

Comments
 (0)