Skip to content

Commit 4a05cad

Browse files
committed
Add tileable rr graph support.
1 parent b7cba40 commit 4a05cad

27 files changed

+6800
-5
lines changed

libs/libarchfpga/src/physical_types.h

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -613,6 +613,8 @@ struct t_physical_tile_type {
613613

614614
std::vector<t_class> class_inf; /* [0..num_class-1] */
615615

616+
int num_class = 0;
617+
616618
std::vector<int> pin_width_offset; // [0..num_pins-1]
617619
std::vector<int> pin_height_offset; // [0..num_pins-1]
618620
std::vector<int> pin_class; // [0..num_pins-1]
@@ -1397,7 +1399,7 @@ enum e_directionality {
13971399
BI_DIRECTIONAL
13981400
};
13991401
/* X_AXIS: Data that describes an x-directed wire segment (CHANX) *
1400-
* Y_AXIS: Data that describes an y-directed wire segment (CHANY) *
1402+
* Y_AXIS: Data that describes an y-directed wire segment (CHANY) *
14011403
* BOTH_AXIS: Data that can be applied to both x-directed and y-directed wire segment */
14021404
enum e_parallel_axis {
14031405
X_AXIS,
@@ -1442,7 +1444,7 @@ enum e_Fc_type {
14421444
* Cmetal: Capacitance of a routing track, per unit logic block length. *
14431445
* Rmetal: Resistance of a routing track, per unit logic block length. *
14441446
* (UDSD by AY) drivers: How do signals driving a routing track connect to *
1445-
* the track?
1447+
* the track?
14461448
* seg_index: The index of the segment as stored in the appropriate Segs list*
14471449
* Upon loading the architecture, we use this field to keep track *
14481450
* the segment's index in the unified segment_inf vector. This is *
@@ -1498,12 +1500,12 @@ constexpr std::array<const char*, size_t(SwitchType::NUM_SWITCH_TYPES)> SWITCH_T
14981500

14991501
/* Constant/Reserved names for switches in architecture XML
15001502
* Delayless switch:
1501-
* The zero-delay switch created by VPR internally
1503+
* The zero-delay switch created by VPR internally
15021504
* This is a special switch just to ease CAD algorithms
15031505
* It is mainly used in
1504-
* - the edges between SOURCE and SINK nodes in routing resource graphs
1506+
* - the edges between SOURCE and SINK nodes in routing resource graphs
15051507
* - the edges in CLB-to-CLB connections (defined by <directlist> in arch XML)
1506-
*
1508+
*
15071509
*/
15081510
constexpr const char* VPR_DELAYLESS_SWITCH_NAME = "__vpr_delayless_switch__";
15091511

@@ -1798,12 +1800,18 @@ struct t_arch {
17981800

17991801
char* architecture_id; //Secure hash digest of the architecture file to uniquely identify this architecture
18001802

1803+
/* Xifan Tang: options for tileable routing architectures */
1804+
bool tileable;
1805+
bool through_channel;
1806+
18011807
t_chan_width_dist Chans;
18021808
enum e_switch_block_type SBType;
1809+
enum e_switch_block_type SBSubType;
18031810
std::vector<t_switchblock_inf> switchblocks;
18041811
float R_minW_nmos;
18051812
float R_minW_pmos;
18061813
int Fs;
1814+
int subFs;
18071815
float grid_logic_tile_area;
18081816
std::vector<t_segment_inf> Segments;
18091817
t_arch_switch_inf* Switches = nullptr;

libs/libvtrutil/src/vtr_geometry.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ bool operator!=(const RectUnion<T>& lhs, const RectUnion<T>& rhs);
6161
template<class T>
6262
class Point {
6363
public: //Constructors
64+
// below is to create a no argument constructor for libopenfpga/libopenfpgautil/src/openfpga_pb_parser.cpp
65+
// need to figure out a better solution to avoid change this in libs from vtr
66+
Point();
6467
Point(T x_val, T y_val) noexcept;
6568

6669
public: //Accessors
Lines changed: 299 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,299 @@
1+
/************************************************************************
2+
* This file contains member functions for class ChanNodeDetails
3+
***********************************************************************/
4+
#include <algorithm>
5+
6+
/* Headers from vtrutil library */
7+
#include "vtr_assert.h"
8+
9+
#include "chan_node_details.h"
10+
11+
/* begin namespace openfpga */
12+
namespace openfpga {
13+
14+
/************************************************************************
15+
* Constructors
16+
***********************************************************************/
17+
ChanNodeDetails::ChanNodeDetails(const ChanNodeDetails& src) {
18+
/* duplicate */
19+
size_t chan_width = src.get_chan_width();
20+
this->reserve(chan_width);
21+
for (size_t itrack = 0; itrack < chan_width; ++itrack) {
22+
track_node_ids_.push_back(src.get_track_node_id(itrack));
23+
track_direction_.push_back(src.get_track_direction(itrack));
24+
seg_ids_.push_back(src.get_track_segment_id(itrack));
25+
seg_length_.push_back(src.get_track_segment_length(itrack));
26+
track_start_.push_back(src.is_track_start(itrack));
27+
track_end_.push_back(src.is_track_end(itrack));
28+
}
29+
}
30+
31+
ChanNodeDetails::ChanNodeDetails() {
32+
this->clear();
33+
}
34+
35+
/************************************************************************
36+
* Accessors
37+
***********************************************************************/
38+
size_t ChanNodeDetails::get_chan_width() const {
39+
VTR_ASSERT(validate_chan_width());
40+
return track_node_ids_.size();
41+
}
42+
43+
size_t ChanNodeDetails::get_track_node_id(const size_t& track_id) const {
44+
VTR_ASSERT(validate_track_id(track_id));
45+
return track_node_ids_[track_id];
46+
}
47+
48+
/* Return a copy of vector */
49+
std::vector<size_t> ChanNodeDetails::get_track_node_ids() const {
50+
std::vector<size_t> copy;
51+
for (size_t inode = 0; inode < get_chan_width(); ++inode) {
52+
copy.push_back(track_node_ids_[inode]);
53+
}
54+
return copy;
55+
}
56+
57+
Direction ChanNodeDetails::get_track_direction(const size_t& track_id) const {
58+
VTR_ASSERT(validate_track_id(track_id));
59+
return track_direction_[track_id];
60+
}
61+
62+
size_t ChanNodeDetails::get_track_segment_length(const size_t& track_id) const {
63+
VTR_ASSERT(validate_track_id(track_id));
64+
return seg_length_[track_id];
65+
}
66+
67+
size_t ChanNodeDetails::get_track_segment_id(const size_t& track_id) const {
68+
VTR_ASSERT(validate_track_id(track_id));
69+
return seg_ids_[track_id];
70+
}
71+
72+
bool ChanNodeDetails::is_track_start(const size_t& track_id) const {
73+
VTR_ASSERT(validate_track_id(track_id));
74+
return track_start_[track_id];
75+
}
76+
77+
bool ChanNodeDetails::is_track_end(const size_t& track_id) const {
78+
VTR_ASSERT(validate_track_id(track_id));
79+
return track_end_[track_id];
80+
}
81+
82+
/* Track_id is the starting point of group (whose is_start should be true)
83+
* This function will try to find the track_ids with the same directionality as track_id and seg_length
84+
* A group size is the number of such nodes between the starting points (include the 1st starting point)
85+
*/
86+
std::vector<size_t> ChanNodeDetails::get_seg_group(const size_t& track_id) const {
87+
VTR_ASSERT(validate_chan_width());
88+
VTR_ASSERT(validate_track_id(track_id));
89+
VTR_ASSERT(is_track_start(track_id));
90+
91+
std::vector<size_t> group;
92+
/* Make sure a clean start */
93+
group.clear();
94+
95+
for (size_t itrack = track_id; itrack < get_chan_width(); ++itrack) {
96+
if ( (get_track_direction(itrack) != get_track_direction(track_id) )
97+
|| (get_track_segment_id(itrack) != get_track_segment_id(track_id)) ) {
98+
/* Bypass any nodes in different direction and segment information*/
99+
continue;
100+
}
101+
if ( (false == is_track_start(itrack))
102+
|| ( (true == is_track_start(itrack)) && (itrack == track_id)) ) {
103+
group.push_back(itrack);
104+
continue;
105+
}
106+
/* Stop if this another starting point */
107+
if (true == is_track_start(itrack)) {
108+
break;
109+
}
110+
}
111+
return group;
112+
}
113+
114+
/* Get a list of track_ids with the given list of track indices */
115+
std::vector<size_t> ChanNodeDetails::get_seg_group_node_id(const std::vector<size_t>& seg_group) const {
116+
std::vector<size_t> group;
117+
/* Make sure a clean start */
118+
group.clear();
119+
120+
for (size_t id = 0; id < seg_group.size(); ++id) {
121+
VTR_ASSERT(validate_track_id(seg_group[id]));
122+
group.push_back(get_track_node_id(seg_group[id]));
123+
}
124+
125+
return group;
126+
}
127+
128+
/* Get the number of tracks that starts in this routing channel */
129+
size_t ChanNodeDetails::get_num_starting_tracks(const Direction& track_direction) const {
130+
size_t counter = 0;
131+
for (size_t itrack = 0; itrack < get_chan_width(); ++itrack) {
132+
/* Bypass unmatched track_direction */
133+
if (track_direction != get_track_direction(itrack)) {
134+
continue;
135+
}
136+
if (false == is_track_start(itrack)) {
137+
continue;
138+
}
139+
counter++;
140+
}
141+
return counter;
142+
}
143+
144+
/* Get the number of tracks that ends in this routing channel */
145+
size_t ChanNodeDetails::get_num_ending_tracks(const Direction& track_direction) const {
146+
size_t counter = 0;
147+
for (size_t itrack = 0; itrack < get_chan_width(); ++itrack) {
148+
/* Bypass unmatched track_direction */
149+
if (track_direction != get_track_direction(itrack)) {
150+
continue;
151+
}
152+
if (false == is_track_end(itrack)) {
153+
continue;
154+
}
155+
counter++;
156+
}
157+
return counter;
158+
}
159+
160+
161+
/************************************************************************
162+
* Mutators
163+
***********************************************************************/
164+
/* Reserve the capacitcy of vectors */
165+
void ChanNodeDetails::reserve(const size_t& chan_width) {
166+
track_node_ids_.reserve(chan_width);
167+
track_direction_.reserve(chan_width);
168+
seg_length_.reserve(chan_width);
169+
seg_ids_.reserve(chan_width);
170+
track_start_.reserve(chan_width);
171+
track_end_.reserve(chan_width);
172+
}
173+
174+
/* Add a track to the channel */
175+
void ChanNodeDetails::add_track(const size_t& track_node_id, const Direction& track_direction,
176+
const size_t& seg_id, const size_t& seg_length,
177+
const size_t& is_start, const size_t& is_end) {
178+
track_node_ids_.push_back(track_node_id);
179+
track_direction_.push_back(track_direction);
180+
seg_ids_.push_back(seg_id);
181+
seg_length_.push_back(seg_length);
182+
track_start_.push_back(is_start);
183+
track_end_.push_back(is_end);
184+
}
185+
186+
/* Update the node_id of a given track */
187+
void ChanNodeDetails::set_track_node_id(const size_t& track_index, const size_t& track_node_id) {
188+
VTR_ASSERT(validate_track_id(track_index));
189+
track_node_ids_[track_index] = track_node_id;
190+
}
191+
192+
/* Update the node_ids from a vector */
193+
void ChanNodeDetails::set_track_node_ids(const std::vector<size_t>& track_node_ids) {
194+
/* the size of vector should match chan_width */
195+
VTR_ASSERT ( get_chan_width() == track_node_ids.size() );
196+
for (size_t inode = 0; inode < track_node_ids.size(); ++inode) {
197+
track_node_ids_[inode] = track_node_ids[inode];
198+
}
199+
}
200+
201+
/* Set tracks with a given direction to start */
202+
void ChanNodeDetails::set_tracks_start(const Direction& track_direction) {
203+
for (size_t inode = 0; inode < get_chan_width(); ++inode) {
204+
/* Bypass non-match tracks */
205+
if (track_direction != get_track_direction(inode)) {
206+
continue; /* Pass condition*/
207+
}
208+
track_start_[inode] = true;
209+
}
210+
}
211+
212+
/* Set tracks with a given direction to end */
213+
void ChanNodeDetails::set_tracks_end(const Direction& track_direction) {
214+
for (size_t inode = 0; inode < get_chan_width(); ++inode) {
215+
/* Bypass non-match tracks */
216+
if (track_direction != get_track_direction(inode)) {
217+
continue; /* Pass condition*/
218+
}
219+
track_end_[inode] = true;
220+
}
221+
}
222+
223+
/* rotate the track_node_id by an offset */
224+
void ChanNodeDetails::rotate_track_node_id(const size_t& offset, const Direction& track_direction, const bool& counter_rotate) {
225+
/* Direct return if offset = 0*/
226+
if (0 == offset) {
227+
return;
228+
}
229+
230+
/* Rotate the node_ids by groups
231+
* A group begins from a track_start and ends before another track_start
232+
*/
233+
VTR_ASSERT(validate_chan_width());
234+
for (size_t itrack = 0; itrack < get_chan_width(); ++itrack) {
235+
/* Bypass non-start segment */
236+
if (false == is_track_start(itrack) ) {
237+
continue;
238+
}
239+
/* Bypass segments do not match track_direction */
240+
if (track_direction != get_track_direction(itrack) ) {
241+
continue;
242+
}
243+
/* Find the group nodes */
244+
std::vector<size_t> track_group = get_seg_group(itrack);
245+
/* Build a vector of the node ids of the tracks */
246+
std::vector<size_t> track_group_node_id = get_seg_group_node_id(track_group);
247+
/* adapt offset to the range of track_group_node_id */
248+
size_t actual_offset = offset % track_group_node_id.size();
249+
/* Rotate or Counter rotate */
250+
if (true == counter_rotate) {
251+
std::rotate(track_group_node_id.rbegin(), track_group_node_id.rbegin() + actual_offset, track_group_node_id.rend());
252+
} else {
253+
std::rotate(track_group_node_id.begin(), track_group_node_id.begin() + actual_offset, track_group_node_id.end());
254+
}
255+
/* Update the node_ids */
256+
for (size_t inode = 0; inode < track_group.size(); ++inode) {
257+
track_node_ids_[track_group[inode]] = track_group_node_id[inode];
258+
}
259+
}
260+
return;
261+
}
262+
263+
void ChanNodeDetails::clear() {
264+
track_node_ids_.clear();
265+
track_direction_.clear();
266+
seg_ids_.clear();
267+
seg_length_.clear();
268+
track_start_.clear();
269+
track_end_.clear();
270+
}
271+
272+
/************************************************************************
273+
* Validators
274+
***********************************************************************/
275+
bool ChanNodeDetails::validate_chan_width() const {
276+
size_t chan_width = track_node_ids_.size();
277+
if ( (chan_width == track_direction_.size())
278+
&&(chan_width == seg_ids_.size())
279+
&&(chan_width == seg_length_.size())
280+
&&(chan_width == track_start_.size())
281+
&&(chan_width == track_end_.size()) ) {
282+
return true;
283+
}
284+
return false;
285+
}
286+
287+
bool ChanNodeDetails::validate_track_id(const size_t& track_id) const {
288+
if ( (track_id < track_node_ids_.size())
289+
&& (track_id < track_direction_.size())
290+
&& (track_id < seg_ids_.size())
291+
&& (track_id < seg_length_.size())
292+
&& (track_id < track_start_.size())
293+
&& (track_id < track_end_.size()) ) {
294+
return true;
295+
}
296+
return false;
297+
}
298+
299+
} /* end namespace openfpga */

0 commit comments

Comments
 (0)