Skip to content

Commit b69453a

Browse files
committed
Added clock network switches
- Missing clock to general routing - Missing clock to any type pin and any type pin to clock - Sill needs some polishing - Invalid read reported by valigrind needs fixing (may cause segfault)
1 parent 3fac425 commit b69453a

9 files changed

+464
-41
lines changed

vpr/src/route/clock_connection_types.cpp

Lines changed: 287 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
#include "clock_connection_types.h"
22

33
#include "globals.h"
4+
#include "rr_graph2.h"
45

56
#include "vtr_assert.h"
67
#include "vtr_log.h"
78
#include "vtr_error.h"
89

10+
#include <random>
11+
#include <math.h>
12+
913
/*
1014
* RoutingToClockConnection (getters)
1115
*/
@@ -35,7 +39,7 @@ void RoutingToClockConnection::set_switch(int switch_index) {
3539
switch_idx = switch_index;
3640
}
3741

38-
void RoutingToClockConnection::set_fc_val(int fc_val) {
42+
void RoutingToClockConnection::set_fc_val(float fc_val) {
3943
fc = fc_val;
4044
}
4145

@@ -45,10 +49,56 @@ void RoutingToClockConnection::set_fc_val(int fc_val) {
4549

4650
void RoutingToClockConnection::create_switches(const ClockRRGraph& clock_graph) {
4751

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+
4877
}
4978

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+
}
5091

92+
std::vector<int> RoutingToClockConnection::get_clock_indices_at_switch_location(
93+
const ClockRRGraph& clock_graph)
94+
{
5195

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+
}
52102

53103
/*
54104
* ClockToClockConneciton (getters)
@@ -82,7 +132,7 @@ void ClockToClockConneciton::set_switch(int switch_index) {
82132
switch_idx = switch_index;
83133
}
84134

85-
void ClockToClockConneciton::set_fc_val(int fc_val) {
135+
void ClockToClockConneciton::set_fc_val(float fc_val) {
86136
fc = fc_val;
87137
}
88138

@@ -92,6 +142,48 @@ void ClockToClockConneciton::set_fc_val(int fc_val) {
92142

93143
void ClockToClockConneciton::create_switches(const ClockRRGraph& clock_graph) {
94144

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+
}
95187
}
96188

97189

@@ -121,7 +213,7 @@ void ClockToPinsConnection::set_switch(int switch_index) {
121213
switch_idx = switch_index;
122214
}
123215

124-
void ClockToPinsConnection::set_fc_val(int fc_val) {
216+
void ClockToPinsConnection::set_fc_val(float fc_val) {
125217
fc = fc_val;
126218
}
127219

@@ -131,6 +223,197 @@ void ClockToPinsConnection::set_fc_val(int fc_val) {
131223

132224
void ClockToPinsConnection::create_switches(const ClockRRGraph& clock_graph) {
133225

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+
134417
}
135418

136419

@@ -148,7 +431,7 @@ ClockConnectionType RoutingToPins::get_connection_type() const {
148431
* RoutingToPins (setters)
149432
*/
150433

151-
void RoutingToPins::set_fc_val(int fc_val) {
434+
void RoutingToPins::set_fc_val(float fc_val) {
152435
fc = fc_val;
153436
}
154437

0 commit comments

Comments
 (0)