1
1
#include " clock_connection_types.h"
2
2
3
3
#include " globals.h"
4
+ #include " rr_graph2.h"
4
5
5
6
#include " vtr_assert.h"
6
7
#include " vtr_log.h"
7
8
#include " vtr_error.h"
8
9
10
+ #include < random>
11
+ #include < math.h>
12
+
9
13
/*
10
14
* RoutingToClockConnection (getters)
11
15
*/
@@ -35,7 +39,7 @@ void RoutingToClockConnection::set_switch(int switch_index) {
35
39
switch_idx = switch_index;
36
40
}
37
41
38
- void RoutingToClockConnection::set_fc_val (int fc_val) {
42
+ void RoutingToClockConnection::set_fc_val (float fc_val) {
39
43
fc = fc_val;
40
44
}
41
45
@@ -45,10 +49,56 @@ void RoutingToClockConnection::set_fc_val(int fc_val) {
45
49
46
50
void RoutingToClockConnection::create_switches (const ClockRRGraph& clock_graph) {
47
51
52
+ auto & device_ctx = g_vpr_ctx.mutable_device ();
53
+ auto & rr_nodes = device_ctx.rr_nodes ;
54
+
55
+ // rr_node indices for x and y channel routing wires and clock wires to connect to
56
+ auto x_wire_indices = get_chan_wire_indices_at_switch_location (CHANX);
57
+ auto y_wire_indices = get_chan_wire_indices_at_switch_location (CHANY);
58
+ auto clock_indices = get_clock_indices_at_switch_location (clock_graph);
59
+
60
+ for (auto clock_index : clock_indices) {
61
+
62
+ // Select wires to connect to at random
63
+ std::random_shuffle (x_wire_indices.begin (), x_wire_indices.end ());
64
+ std::random_shuffle (y_wire_indices.begin (), y_wire_indices.end ());
65
+
66
+ // Connect to x-channel wires
67
+ for (size_t i = 0 ; i < x_wire_indices.size ()*fc; i++) {
68
+ rr_nodes[x_wire_indices[i]].add_edge (clock_index, switch_idx);
69
+ }
70
+
71
+ // Connect to y-channel wires
72
+ for (size_t i = 0 ; i < y_wire_indices.size ()*fc; i++) {
73
+ rr_nodes[y_wire_indices[i]].add_edge (clock_index, switch_idx);
74
+ }
75
+ }
76
+
48
77
}
49
78
79
+ std::vector<int > RoutingToClockConnection::get_chan_wire_indices_at_switch_location (
80
+ t_rr_type rr_type)
81
+ {
82
+ auto & device_ctx = g_vpr_ctx.device ();
83
+ auto & rr_node_indices = device_ctx.rr_node_indices ;
84
+
85
+ return get_rr_node_chan_wires_at_location (
86
+ rr_node_indices,
87
+ rr_type,
88
+ switch_location.x ,
89
+ switch_location.y );
90
+ }
50
91
92
+ std::vector<int > RoutingToClockConnection::get_clock_indices_at_switch_location (
93
+ const ClockRRGraph& clock_graph)
94
+ {
51
95
96
+ return clock_graph.get_rr_node_indices_at_switch_location (
97
+ clock_to_connect_to,
98
+ switch_name,
99
+ switch_location.x ,
100
+ switch_location.y );
101
+ }
52
102
53
103
/*
54
104
* ClockToClockConneciton (getters)
@@ -82,7 +132,7 @@ void ClockToClockConneciton::set_switch(int switch_index) {
82
132
switch_idx = switch_index;
83
133
}
84
134
85
- void ClockToClockConneciton::set_fc_val (int fc_val) {
135
+ void ClockToClockConneciton::set_fc_val (float fc_val) {
86
136
fc = fc_val;
87
137
}
88
138
@@ -92,6 +142,48 @@ void ClockToClockConneciton::set_fc_val(int fc_val) {
92
142
93
143
void ClockToClockConneciton::create_switches (const ClockRRGraph& clock_graph) {
94
144
145
+ auto & device_ctx = g_vpr_ctx.mutable_device ();
146
+ auto & rr_nodes = device_ctx.rr_nodes ;
147
+
148
+ auto to_locations = clock_graph.get_switch_locations (to_clock, to_switch);
149
+
150
+ for (auto location : to_locations) {
151
+
152
+ auto x = location.first ;
153
+ auto y = location.second ;
154
+
155
+ auto to_indices = clock_graph.get_rr_node_indices_at_switch_location (
156
+ to_clock,
157
+ to_switch,
158
+ x,
159
+ y);
160
+
161
+ // boundry condition: y = 0 and y = 1 connections share the same drive point
162
+ if (y == 0 ) {
163
+ y = 1 ;
164
+ }
165
+
166
+ auto from_indices = clock_graph.get_rr_node_indices_at_switch_location (
167
+ from_clock,
168
+ from_switch,
169
+ x,
170
+ y);
171
+
172
+ auto from_itter = from_indices.begin ();
173
+ size_t num_connections = ceil (from_indices.size ()*fc);
174
+
175
+ for (auto to_index : to_indices) {
176
+
177
+ // Connect to x-channel wires
178
+ for (size_t i = 0 ; i < num_connections; i++) {
179
+ if (from_itter == from_indices.end ()){
180
+ from_itter = from_indices.begin ();
181
+ }
182
+ rr_nodes[*from_itter].add_edge (to_index, switch_idx);
183
+ from_itter++;
184
+ }
185
+ }
186
+ }
95
187
}
96
188
97
189
@@ -121,7 +213,7 @@ void ClockToPinsConnection::set_switch(int switch_index) {
121
213
switch_idx = switch_index;
122
214
}
123
215
124
- void ClockToPinsConnection::set_fc_val (int fc_val) {
216
+ void ClockToPinsConnection::set_fc_val (float fc_val) {
125
217
fc = fc_val;
126
218
}
127
219
@@ -131,6 +223,197 @@ void ClockToPinsConnection::set_fc_val(int fc_val) {
131
223
132
224
void ClockToPinsConnection::create_switches (const ClockRRGraph& clock_graph) {
133
225
226
+ auto & device_ctx = g_vpr_ctx.mutable_device ();
227
+ auto & rr_nodes = device_ctx.rr_nodes ;
228
+ auto & rr_node_indices = device_ctx.rr_node_indices ;
229
+ auto & grid = device_ctx.grid ;
230
+
231
+ for (size_t x = 1 ; x < grid.width () - 1 ; x++) {
232
+ for (size_t y = 1 ; y < grid.height () - 1 ; y++) {
233
+
234
+ auto type = grid[x][y].type ;
235
+ auto width_offset = grid[x][y].width_offset ;
236
+ auto height_offset = grid[x][y].height_offset ;
237
+
238
+ for (e_side side : SIDES) {
239
+ for (auto clock_pin_idx : type->get_clock_pins_indices ()) {
240
+
241
+ /* Can't do anything if pin isn't at this location */
242
+ if (0 == type->pinloc [width_offset][height_offset][side][clock_pin_idx]) {
243
+ continue ;
244
+ }
245
+
246
+ auto clock_pin_node_idx = get_rr_node_index (
247
+ rr_node_indices,
248
+ x,
249
+ y,
250
+ IPIN,
251
+ clock_pin_idx,
252
+ side);
253
+
254
+ // TODO: revisit for chany wires
255
+ int clock_y = y - 1 ; // Done inorder to select chanx wires bellow the block
256
+
257
+ auto clock_indices = clock_graph.get_rr_node_indices_at_switch_location (
258
+ clock_to_connect_from,
259
+ switch_name,
260
+ x,
261
+ clock_y);
262
+
263
+
264
+ for (size_t i = 0 ; i < clock_indices.size ()*fc; i++) {
265
+ rr_nodes[clock_indices[i]].add_edge (clock_pin_node_idx, switch_idx);
266
+ }
267
+ }
268
+ }
269
+ }
270
+ }
271
+
272
+ size_t y;
273
+ size_t x;
274
+ // TODO: revisit if I/O has pins without logical equivilance (can check class)
275
+ // bottom row connections to chanx (only connect the top of the block to the channel)
276
+ y = 0 ;
277
+ for (x = 1 ; x < grid.width () - 1 ; x++) {
278
+ auto type = grid[x][y].type ;
279
+ auto width_offset = grid[x][y].width_offset ;
280
+ auto height_offset = grid[x][y].height_offset ;
281
+
282
+ for (auto clock_pin_idx : type->get_clock_pins_indices ()) {
283
+
284
+ /* Can't do anything if pin isn't at this location */
285
+ if (0 == type->pinloc [width_offset][height_offset][TOP][clock_pin_idx]) {
286
+ continue ;
287
+ }
288
+
289
+ auto clock_pin_node_idx = get_rr_node_index (
290
+ rr_node_indices,
291
+ x,
292
+ y,
293
+ IPIN,
294
+ clock_pin_idx,
295
+ TOP);
296
+
297
+ auto clock_indices = clock_graph.get_rr_node_indices_at_switch_location (
298
+ clock_to_connect_from,
299
+ switch_name,
300
+ x,
301
+ y);
302
+
303
+ for (size_t i = 0 ; i < clock_indices.size ()*fc; i++) {
304
+ rr_nodes[clock_indices[i]].add_edge (clock_pin_node_idx, switch_idx);
305
+ }
306
+ }
307
+ }
308
+
309
+ // left row connections to chanx (only connect the right of the block to the channel)
310
+ x = 0 ;
311
+ for (y = 1 ; y < grid.height () - 1 ; y++) {
312
+ auto type = grid[x][y].type ;
313
+ auto width_offset = grid[x][y].width_offset ;
314
+ auto height_offset = grid[x][y].height_offset ;
315
+
316
+ for (auto clock_pin_idx : type->get_clock_pins_indices ()) {
317
+
318
+ /* Can't do anything if pin isn't at this location */
319
+ if (0 == type->pinloc [width_offset][height_offset][TOP][clock_pin_idx]) {
320
+ continue ;
321
+ }
322
+
323
+ auto clock_pin_node_idx = get_rr_node_index (
324
+ rr_node_indices,
325
+ x,
326
+ y,
327
+ IPIN,
328
+ clock_pin_idx,
329
+ RIGHT);
330
+
331
+ int clock_x = x + 1 ; // pick the chanx clock that always starts at 1 offset
332
+ int clock_y = y - 1 ; // pick the chanx below the block
333
+ auto clock_indices = clock_graph.get_rr_node_indices_at_switch_location (
334
+ clock_to_connect_from,
335
+ switch_name,
336
+ clock_x,
337
+ clock_y);
338
+
339
+ for (size_t i = 0 ; i < clock_indices.size ()*fc; i++) {
340
+ rr_nodes[clock_indices[i]].add_edge (clock_pin_node_idx, switch_idx);
341
+ }
342
+ }
343
+ }
344
+
345
+ // right row connections to chanx (only connect the left of the block to the channel)
346
+ x = grid.width () - 1 ;
347
+ for (y = 1 ; y < grid.height () - 1 ; y++) {
348
+ auto type = grid[x][y].type ;
349
+ auto width_offset = grid[x][y].width_offset ;
350
+ auto height_offset = grid[x][y].height_offset ;
351
+
352
+ for (auto clock_pin_idx : type->get_clock_pins_indices ()) {
353
+
354
+ /* Can't do anything if pin isn't at this location */
355
+ if (0 == type->pinloc [width_offset][height_offset][TOP][clock_pin_idx]) {
356
+ continue ;
357
+ }
358
+
359
+ auto clock_pin_node_idx = get_rr_node_index (
360
+ rr_node_indices,
361
+ x,
362
+ y,
363
+ IPIN,
364
+ clock_pin_idx,
365
+ LEFT);
366
+
367
+ int clock_x = x - 1 ; // pick the chanx clock that always starts at 1 offset
368
+ int clock_y = y - 1 ; // pick the chanx below the block
369
+ auto clock_indices = clock_graph.get_rr_node_indices_at_switch_location (
370
+ clock_to_connect_from,
371
+ switch_name,
372
+ clock_x,
373
+ clock_y);
374
+
375
+ for (size_t i = 0 ; i < clock_indices.size ()*fc; i++) {
376
+ rr_nodes[clock_indices[i]].add_edge (clock_pin_node_idx, switch_idx);
377
+ }
378
+ }
379
+ }
380
+
381
+ // top row connections to chanx (only connect the botom of the block to the channel)
382
+ y = grid.height () - 1 ;
383
+ for (x = 1 ; x < grid.width () - 1 ; x++) {
384
+ auto type = grid[x][y].type ;
385
+ auto width_offset = grid[x][y].width_offset ;
386
+ auto height_offset = grid[x][y].height_offset ;
387
+
388
+ for (auto clock_pin_idx : type->get_clock_pins_indices ()) {
389
+
390
+ /* Can't do anything if pin isn't at this location */
391
+ if (0 == type->pinloc [width_offset][height_offset][TOP][clock_pin_idx]) {
392
+ continue ;
393
+ }
394
+
395
+ auto clock_pin_node_idx = get_rr_node_index (
396
+ rr_node_indices,
397
+ x,
398
+ y,
399
+ IPIN,
400
+ clock_pin_idx,
401
+ BOTTOM);
402
+
403
+ int clock_x = x;
404
+ int clock_y = y - 1 ; // pick the chanx below the block
405
+ auto clock_indices = clock_graph.get_rr_node_indices_at_switch_location (
406
+ clock_to_connect_from,
407
+ switch_name,
408
+ clock_x,
409
+ clock_y);
410
+
411
+ for (size_t i = 0 ; i < clock_indices.size ()*fc; i++) {
412
+ rr_nodes[clock_indices[i]].add_edge (clock_pin_node_idx, switch_idx);
413
+ }
414
+ }
415
+ }
416
+
134
417
}
135
418
136
419
@@ -148,7 +431,7 @@ ClockConnectionType RoutingToPins::get_connection_type() const {
148
431
* RoutingToPins (setters)
149
432
*/
150
433
151
- void RoutingToPins::set_fc_val (int fc_val) {
434
+ void RoutingToPins::set_fc_val (float fc_val) {
152
435
fc = fc_val;
153
436
}
154
437
0 commit comments