Skip to content

Commit 486be09

Browse files
authored
Merge pull request #2490 from verilog-to-routing/fix_3d_delay
Fix 3D SIV Delay & Median Move
2 parents 7ed749f + bb4073c commit 486be09

10 files changed

+289
-64
lines changed

vpr/src/place/centroid_move_generator.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,9 @@ e_create_move CentroidMoveGenerator::propose_move(t_pl_blocks_to_be_moved& block
7676
/* Calculate the centroid location*/
7777
calculate_centroid_loc(b_from, false, centroid, nullptr, noc_attraction_enabled_, noc_attraction_w_);
7878

79-
// Centroid location is not necessarily a valid location, and the downstream location expect a valid
80-
// layer for "to" location. So if the layer is not valid, we set it to the same layer as from loc.
81-
to.layer = (centroid.layer < 0) ? from.layer : centroid.layer;
79+
// Centroid location is not necessarily a valid location, and the downstream location expects a valid
80+
// layer for the centroid location. So if the layer is not valid, we set it to the same layer as from loc.
81+
centroid.layer = (centroid.layer < 0) ? from.layer : centroid.layer;
8282
/* Find a location near the weighted centroid_loc */
8383
if (!find_to_loc_centroid(cluster_from_type, from, centroid, range_limiters, to, b_from)) {
8484
return e_create_move::ABORT;

vpr/src/place/median_move_generator.cpp

Lines changed: 116 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,14 @@
55
#include "placer_globals.h"
66
#include "move_utils.h"
77

8-
static bool get_bb_incrementally(ClusterNetId net_id, t_bb& bb_coord_new, int xold, int yold, int xnew, int ynew);
8+
static bool get_bb_incrementally(ClusterNetId net_id,
9+
t_bb& bb_coord_new,
10+
int xold,
11+
int yold,
12+
int layer_old,
13+
int xnew,
14+
int ynew,
15+
int layer_new);
916

1017
static void get_bb_from_scratch_excluding_block(ClusterNetId net_id, t_bb& bb_coord_new, ClusterBlockId block_id, bool& skip_net);
1118

@@ -29,7 +36,7 @@ e_create_move MedianMoveGenerator::propose_move(t_pl_blocks_to_be_moved& blocks_
2936
auto& place_move_ctx = g_placer_ctx.mutable_move();
3037

3138
const int num_layers = device_ctx.grid.get_num_layers();
32-
bool is_multi_layer = (num_layers > 1);
39+
3340

3441
t_pl_loc from = place_ctx.block_locs[b_from].loc;
3542
int from_layer = from.layer;
@@ -43,12 +50,13 @@ e_create_move MedianMoveGenerator::propose_move(t_pl_blocks_to_be_moved& blocks_
4350
t_bb coords(OPEN, OPEN, OPEN, OPEN, OPEN, OPEN);
4451
t_bb limit_coords;
4552
ClusterBlockId bnum;
46-
int pnum, xnew, xold, ynew, yold;
53+
int pnum, xnew, xold, ynew, yold, layer_new, layer_old;
4754

4855
//clear the vectors that saves X & Y coords
4956
//reused to save allocation time
5057
place_move_ctx.X_coord.clear();
5158
place_move_ctx.Y_coord.clear();
59+
place_move_ctx.layer_coord.clear();
5260
std::vector<int> layer_blk_cnt(num_layers, 0);
5361

5462
//true if the net is a feedback from the block to itself
@@ -84,8 +92,11 @@ e_create_move MedianMoveGenerator::propose_move(t_pl_blocks_to_be_moved& blocks_
8492
VTR_ASSERT(pnum >= 0);
8593
xold = place_ctx.block_locs[bnum].loc.x + physical_tile_type(bnum)->pin_width_offset[pnum];
8694
yold = place_ctx.block_locs[bnum].loc.y + physical_tile_type(bnum)->pin_height_offset[pnum];
95+
layer_old = place_ctx.block_locs[bnum].loc.layer;
96+
8797
xold = std::max(std::min(xold, (int)device_ctx.grid.width() - 2), 1); //-2 for no perim channels
8898
yold = std::max(std::min(yold, (int)device_ctx.grid.height() - 2), 1); //-2 for no perim channels
99+
layer_old = std::max(std::min(layer_old, (int)device_ctx.grid.get_num_layers() - 1), 0);
89100

90101
//To calulate the bb incrementally while excluding the moving block
91102
//assume that the moving block is moved to a non-critical coord of the bb
@@ -101,7 +112,23 @@ e_create_move MedianMoveGenerator::propose_move(t_pl_blocks_to_be_moved& blocks_
101112
ynew = net_bb_coords.ymin;
102113
}
103114

104-
if (!get_bb_incrementally(net_id, coords, xold, yold, xnew, ynew)) {
115+
if (net_bb_coords.layer_min == layer_old) {
116+
layer_new = net_bb_coords.layer_max;
117+
} else {
118+
layer_new = net_bb_coords.layer_min;
119+
}
120+
121+
// If the mvoing block is on the border of the bounding box, we cannot get
122+
// the bounding box incrementatlly. In that case, bounding box should be calculated
123+
// from scratch.
124+
if (!get_bb_incrementally(net_id,
125+
coords,
126+
xold,
127+
yold,
128+
layer_old,
129+
xnew,
130+
ynew,
131+
layer_new)) {
105132
get_bb_from_scratch_excluding_block(net_id, coords, b_from, skip_net);
106133
if (skip_net)
107134
continue;
@@ -112,34 +139,29 @@ e_create_move MedianMoveGenerator::propose_move(t_pl_blocks_to_be_moved& blocks_
112139
place_move_ctx.X_coord.push_back(coords.xmax);
113140
place_move_ctx.Y_coord.push_back(coords.ymin);
114141
place_move_ctx.Y_coord.push_back(coords.ymax);
115-
if (is_multi_layer) {
116-
for (int layer_num = 0; layer_num < num_layers; layer_num++) {
117-
layer_blk_cnt[layer_num] += place_move_ctx.num_sink_pin_layer[size_t(net_id)][layer_num];
118-
}
119-
// If the pin under consideration is of type sink, it shouldn't be added to layer_blk_cnt since the block
120-
// is moving
121-
if (cluster_ctx.clb_nlist.pin_type(pin_id) == PinType::SINK) {
122-
VTR_ASSERT_SAFE(layer_blk_cnt[from_layer] > 0);
123-
layer_blk_cnt[from_layer]--;
124-
}
125-
}
142+
place_move_ctx.layer_coord.push_back(coords.layer_min);
143+
place_move_ctx.layer_coord.push_back(coords.layer_max);
126144
}
127145

128-
if ((place_move_ctx.X_coord.empty()) || (place_move_ctx.Y_coord.empty())) {
129-
VTR_LOGV_DEBUG(g_vpr_ctx.placement().f_placer_debug, "\tMove aborted - X_coord and y_coord are empty\n");
146+
if ((place_move_ctx.X_coord.empty()) || (place_move_ctx.Y_coord.empty()) || (place_move_ctx.layer_coord.empty())) {
147+
VTR_LOGV_DEBUG(g_vpr_ctx.placement().f_placer_debug, "\tMove aborted - X_coord or y_coord or layer_coord are empty\n");
130148
return e_create_move::ABORT;
131149
}
132150

133151
//calculate the median region
134152
std::stable_sort(place_move_ctx.X_coord.begin(), place_move_ctx.X_coord.end());
135153
std::stable_sort(place_move_ctx.Y_coord.begin(), place_move_ctx.Y_coord.end());
154+
std::stable_sort(place_move_ctx.layer_coord.begin(), place_move_ctx.layer_coord.end());
136155

137156
limit_coords.xmin = place_move_ctx.X_coord[floor((place_move_ctx.X_coord.size() - 1) / 2)];
138157
limit_coords.xmax = place_move_ctx.X_coord[floor((place_move_ctx.X_coord.size() - 1) / 2) + 1];
139158

140159
limit_coords.ymin = place_move_ctx.Y_coord[floor((place_move_ctx.Y_coord.size() - 1) / 2)];
141160
limit_coords.ymax = place_move_ctx.Y_coord[floor((place_move_ctx.Y_coord.size() - 1) / 2) + 1];
142161

162+
limit_coords.layer_min = place_move_ctx.layer_coord[floor((place_move_ctx.layer_coord.size() - 1) / 2)];
163+
limit_coords.layer_max = place_move_ctx.layer_coord[floor((place_move_ctx.layer_coord.size() - 1) / 2) + 1];
164+
143165
//arrange the different range limiters
144166
t_range_limiters range_limiters{rlim,
145167
place_move_ctx.first_rlim,
@@ -149,17 +171,8 @@ e_create_move MedianMoveGenerator::propose_move(t_pl_blocks_to_be_moved& blocks_
149171
t_pl_loc median_point;
150172
median_point.x = (limit_coords.xmin + limit_coords.xmax) / 2;
151173
median_point.y = (limit_coords.ymin + limit_coords.ymax) / 2;
174+
median_point.layer = (limit_coords.layer_min + limit_coords.layer_max) / 2;
152175

153-
// Before calling find_to_loc_centroid a valid layer should be assigned to "to" location. If there are multiple layers, the layer
154-
// with highest number of sinks will be used. Otherwise, the same layer as "from" loc is assigned.
155-
if (is_multi_layer) {
156-
int layer_num = std::distance(layer_blk_cnt.begin(), std::max_element(layer_blk_cnt.begin(), layer_blk_cnt.end()));
157-
median_point.layer = layer_num;
158-
to.layer = layer_num;
159-
} else {
160-
median_point.layer = from.layer;
161-
to.layer = from.layer;
162-
}
163176
if (!find_to_loc_centroid(cluster_from_type, from, median_point, range_limiters, to, b_from)) {
164177
return e_create_move::ABORT;
165178
}
@@ -194,6 +207,9 @@ static void get_bb_from_scratch_excluding_block(ClusterNetId net_id, t_bb& bb_co
194207
int ymin = OPEN;
195208
int ymax = OPEN;
196209

210+
int layer_min = OPEN;
211+
int layer_max = OPEN;
212+
197213
int pnum;
198214

199215
auto& cluster_ctx = g_vpr_ctx.clustering();
@@ -208,11 +224,14 @@ static void get_bb_from_scratch_excluding_block(ClusterNetId net_id, t_bb& bb_co
208224
pnum = net_pin_to_tile_pin_index(net_id, 0);
209225
int src_x = place_ctx.block_locs[bnum].loc.x + physical_tile_type(bnum)->pin_width_offset[pnum];
210226
int src_y = place_ctx.block_locs[bnum].loc.y + physical_tile_type(bnum)->pin_height_offset[pnum];
227+
int src_layer = place_ctx.block_locs[bnum].loc.layer;
211228

212229
xmin = src_x;
213230
ymin = src_y;
214231
xmax = src_x;
215232
ymax = src_y;
233+
layer_min = src_layer;
234+
layer_max = src_layer;
216235
first_block = true;
217236
}
218237

@@ -225,12 +244,15 @@ static void get_bb_from_scratch_excluding_block(ClusterNetId net_id, t_bb& bb_co
225244
const auto& block_loc = place_ctx.block_locs[bnum].loc;
226245
int x = block_loc.x + physical_tile_type(bnum)->pin_width_offset[pnum];
227246
int y = block_loc.y + physical_tile_type(bnum)->pin_height_offset[pnum];
247+
int layer = block_loc.layer;
228248

229249
if (!first_block) {
230250
xmin = x;
231251
ymin = y;
232252
xmax = x;
233253
ymax = y;
254+
layer_max = layer;
255+
layer_min = layer;
234256
first_block = true;
235257
continue;
236258
}
@@ -245,6 +267,12 @@ static void get_bb_from_scratch_excluding_block(ClusterNetId net_id, t_bb& bb_co
245267
} else if (y > ymax) {
246268
ymax = y;
247269
}
270+
271+
if (layer < layer_min) {
272+
layer_min = layer;
273+
} else if (layer > layer_max) {
274+
layer_max = layer;
275+
}
248276
}
249277

250278
/* Now I've found the coordinates of the bounding box. There are no *
@@ -256,8 +284,10 @@ static void get_bb_from_scratch_excluding_block(ClusterNetId net_id, t_bb& bb_co
256284
* is 0). See route_common.cpp for a channel diagram. */
257285
bb_coord_new.xmin = std::max(std::min<int>(xmin, device_ctx.grid.width() - 2), 1); //-2 for no perim channels
258286
bb_coord_new.ymin = std::max(std::min<int>(ymin, device_ctx.grid.height() - 2), 1); //-2 for no perim channels
287+
bb_coord_new.layer_min = std::max(std::min<int>(layer_min, device_ctx.grid.get_num_layers() - 1), 0);
259288
bb_coord_new.xmax = std::max(std::min<int>(xmax, device_ctx.grid.width() - 2), 1); //-2 for no perim channels
260289
bb_coord_new.ymax = std::max(std::min<int>(ymax, device_ctx.grid.height() - 2), 1); //-2 for no perim channels
290+
bb_coord_new.layer_max = std::max(std::min<int>(layer_max, device_ctx.grid.get_num_layers() - 1), 0);
261291
}
262292

263293
/*
@@ -273,20 +303,36 @@ static void get_bb_from_scratch_excluding_block(ClusterNetId net_id, t_bb& bb_co
273303
* the pins always lie on the outside of the bounding box. *
274304
* The x and y coordinates are the pin's x and y coordinates. */
275305
/* IO blocks are considered to be one cell in for simplicity. */
276-
static bool get_bb_incrementally(ClusterNetId net_id, t_bb& bb_coord_new, int xold, int yold, int xnew, int ynew) {
306+
static bool get_bb_incrementally(ClusterNetId net_id,
307+
t_bb& bb_coord_new,
308+
int xold,
309+
int yold,
310+
int layer_old,
311+
int xnew,
312+
int ynew,
313+
int layer_new) {
277314
//TODO: account for multiple physical pin instances per logical pin
278315

279316
auto& device_ctx = g_vpr_ctx.device();
280317
auto& place_move_ctx = g_placer_ctx.move();
281318

282319
xnew = std::max(std::min<int>(xnew, device_ctx.grid.width() - 2), 1); //-2 for no perim channels
283320
ynew = std::max(std::min<int>(ynew, device_ctx.grid.height() - 2), 1); //-2 for no perim channels
321+
layer_new = std::max(std::min<int>(layer_new, device_ctx.grid.get_num_layers() - 1), 0);
322+
284323
xold = std::max(std::min<int>(xold, device_ctx.grid.width() - 2), 1); //-2 for no perim channels
285324
yold = std::max(std::min<int>(yold, device_ctx.grid.height() - 2), 1); //-2 for no perim channels
325+
layer_old = std::max(std::min<int>(layer_old, device_ctx.grid.get_num_layers() - 1), 0);
286326

287327
t_bb union_bb_edge;
288328
t_bb union_bb;
289329
const bool& cube_bb = g_vpr_ctx.placement().cube_bb;
330+
/* Calculating per-layer bounding box is more time consuming compared to cube bounding box. To speed up
331+
* this move, the bounding box used for this move is of the type cube bounding box even if the per-layer
332+
* bounding box is used by placement SA engine.
333+
* If per-layer bounding box is used, we take a union of boundinx boxes on each layer to make a cube bounding box.
334+
* For example, the xmax of this cube boundix box is determined by the maximim x coordinate across all blocks on all layers.
335+
*/
290336
if (!cube_bb) {
291337
std::tie(union_bb_edge, union_bb) = union_2d_bb_incr(place_move_ctx.layer_bb_num_on_edges[net_id],
292338
place_move_ctx.layer_bb_coords[net_id]);
@@ -410,5 +456,47 @@ static bool get_bb_incrementally(ClusterNetId net_id, t_bb& bb_coord_new, int xo
410456
bb_coord_new.ymin = curr_bb_coord.ymin;
411457
bb_coord_new.ymax = curr_bb_coord.ymax;
412458
}
459+
460+
if (layer_new < layer_old) {
461+
if (layer_old == curr_bb_coord.layer_max) {
462+
if (curr_bb_edge.layer_max == 1) {
463+
return false;
464+
} else {
465+
bb_coord_new.layer_max = curr_bb_coord.layer_max;
466+
}
467+
} else {
468+
bb_coord_new.layer_max = curr_bb_coord.layer_max;
469+
}
470+
471+
if (layer_new < curr_bb_coord.layer_min) {
472+
bb_coord_new.layer_min = layer_new;
473+
} else if (layer_new == curr_bb_coord.layer_min) {
474+
bb_coord_new.layer_min = layer_new;
475+
} else {
476+
bb_coord_new.layer_min = curr_bb_coord.layer_min;
477+
}
478+
479+
} else if (layer_new > layer_old) {
480+
if (layer_old == curr_bb_coord.layer_min) {
481+
if (curr_bb_edge.layer_min == 1) {
482+
return false;
483+
} else {
484+
bb_coord_new.layer_min = curr_bb_coord.layer_min;
485+
}
486+
} else {
487+
bb_coord_new.layer_min = curr_bb_coord.layer_min;
488+
}
489+
490+
if (layer_new > curr_bb_coord.layer_max) {
491+
bb_coord_new.layer_max = layer_new;
492+
} else if (layer_new == curr_bb_coord.layer_max) {
493+
bb_coord_new.layer_max = layer_new;
494+
} else {
495+
bb_coord_new.layer_max = curr_bb_coord.layer_max;
496+
}
497+
} else {
498+
bb_coord_new.layer_min = curr_bb_coord.layer_min;
499+
bb_coord_new.layer_max = curr_bb_coord.layer_max;
500+
}
413501
return true;
414502
}

vpr/src/place/move_utils.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -928,7 +928,7 @@ bool find_to_loc_centroid(t_logical_block_type_ptr blk_type,
928928
ClusterBlockId b_from) {
929929
//Retrieve the compressed block grid for this block type
930930
const auto& compressed_block_grid = g_vpr_ctx.placement().compressed_block_grids[blk_type->index];
931-
const int to_layer_num = to_loc.layer;
931+
const int to_layer_num = centroid.layer;
932932
VTR_ASSERT(to_layer_num >= 0);
933933
const int num_layers = g_vpr_ctx.device().grid.get_num_layers();
934934

vpr/src/place/move_utils.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ struct t_bb_cost {
7070
t_edge_cost xmax = {0, 0.0};
7171
t_edge_cost ymin = {0, 0.0};
7272
t_edge_cost ymax = {0, 0.0};
73+
t_edge_cost layer_min = {0, 0.};
74+
t_edge_cost layer_max = {0, 0.};
7375
};
7476

7577
/**

0 commit comments

Comments
 (0)