Skip to content

Commit cc11623

Browse files
Merge pull request #3154 from AlexandreSinger/feature-ap-global-nets
[AP] Marking Global Nets in AP
2 parents 141ab41 + 9b06376 commit cc11623

File tree

5 files changed

+62
-28
lines changed

5 files changed

+62
-28
lines changed

vpr/src/analytical_place/gen_ap_netlist_from_atoms.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,13 +126,38 @@ APNetlist gen_ap_netlist_from_atoms(const AtomNetlist& atom_netlist,
126126
ap_netlist.set_net_is_ignored(ap_net_id, true);
127127
continue;
128128
}
129+
129130
// Is the net global, if so mark as global for AP (also ignored)
130131
if (atom_netlist.net_is_global(atom_net_id)) {
131132
ap_netlist.set_net_is_global(ap_net_id, true);
132133
// Global nets are also ignored by the AP flow.
133134
ap_netlist.set_net_is_ignored(ap_net_id, true);
134135
continue;
135136
}
137+
138+
// Prior to AP, it is likely that the nets in the Atom Netlist have not
139+
// been annotated with being global or ignored. To get around this, we
140+
// annotate the AP Netlist speculatively.
141+
// We label a net as being global if one of its pin connect to a clock
142+
// port or a non-clock global model port.
143+
bool is_global = false;
144+
for (AtomPinId pin_id : atom_netlist.net_pins(atom_net_id)) {
145+
AtomPortId port_id = atom_netlist.pin_port(pin_id);
146+
if (atom_netlist.port_type(port_id) == PortType::CLOCK) {
147+
is_global = true;
148+
break;
149+
}
150+
if (atom_netlist.port_model(port_id)->is_non_clock_global) {
151+
is_global = true;
152+
break;
153+
}
154+
}
155+
if (is_global) {
156+
ap_netlist.set_net_is_global(ap_net_id, true);
157+
// Global nets are also ignored in the AP flow.
158+
ap_netlist.set_net_is_ignored(ap_net_id, true);
159+
}
160+
136161
// Get the unique blocks connectioned to this net
137162
std::unordered_set<APBlockId> net_blocks;
138163
for (APPinId ap_pin_id : ap_netlist.net_pins(ap_net_id)) {

vpr/src/analytical_place/global_placer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ static void print_placement_stats(const PartialPlacement& p_placement,
132132
const PreClusterTimingManager& pre_cluster_timing_manager) {
133133
// Print the placement HPWL
134134
VTR_LOG("\tPlacement objective HPWL: %f\n", p_placement.get_hpwl(ap_netlist));
135-
VTR_LOG("\tPlacement estimated wirelength: %u\n", p_placement.estimate_post_placement_wirelength(ap_netlist));
135+
VTR_LOG("\tPlacement estimated wirelength: %g\n", p_placement.estimate_post_placement_wirelength(ap_netlist));
136136

137137
// Print the timing information.
138138
if (pre_cluster_timing_manager.is_valid()) {

vpr/src/analytical_place/partial_placement.cpp

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <cstddef>
1111
#include <limits>
1212
#include "ap_netlist.h"
13+
#include "net_cost_handler.h"
1314

1415
double PartialPlacement::get_hpwl(const APNetlist& netlist) const {
1516
double hpwl = 0.0;
@@ -27,6 +28,11 @@ double PartialPlacement::get_hpwl(const APNetlist& netlist) const {
2728
min_y = std::min(min_y, block_y_locs[blk_id]);
2829
max_y = std::max(max_y, block_y_locs[blk_id]);
2930
}
31+
// TODO: In the placer, the x and y dimensions are multiplied by cost
32+
// factors based on the channel width. Should somehow bring these
33+
// in here.
34+
// Vaughn thinks these may make sense in the objective HPWL, but
35+
// not the in the estimated post-placement wirelength.
3036
VTR_ASSERT_SAFE(max_x >= min_x && max_y >= min_y);
3137
hpwl += max_x - min_x + max_y - min_y;
3238
}
@@ -38,23 +44,26 @@ double PartialPlacement::estimate_post_placement_wirelength(const APNetlist& net
3844
// we want to estimate the post-placement wirelength, we do not want the
3945
// flat placement positions of the blocks. Instead we compute the HPWL over
4046
// the tiles that the flat placement is placing the blocks over.
41-
unsigned total_hpwl = 0;
47+
double total_hpwl = 0;
4248
for (APNetId net_id : netlist.nets()) {
43-
// Note: Other wirelength estimates in VTR ignore global nets; however
44-
// it is not known if a net is global or not until packing is
45-
// complete. For now, we just approximate post-placement wirelength
46-
// using the HPWL (in tile space).
47-
// TODO: The reason we do not know what nets are ignored / global is
48-
// because the pin on the tile that the net connects to is what
49-
// decides if a net is global / ignored for place and route. Since
50-
// we have not packed anything yet, we do not know what pin each
51-
// net will go to; however, we can probably get a good idea based
52-
// on some properties of the net and the tile its going to / from.
53-
// Should investigate this to get a better estimate of wirelength.
54-
double min_x = std::numeric_limits<unsigned>::max();
55-
double max_x = std::numeric_limits<unsigned>::lowest();
56-
double min_y = std::numeric_limits<unsigned>::max();
57-
double max_y = std::numeric_limits<unsigned>::lowest();
49+
// To align with other wirelength estimators in VTR (for example in the
50+
// placer), we do not include global nets (clocks, etc.) in the wirelength
51+
// calculation.
52+
if (netlist.net_is_global(net_id))
53+
continue;
54+
55+
// Similar to the placer, weight the wirelength of this net as a function
56+
// of its fanout. Since these fanouts are at the AP netlist (unclustered)
57+
// level, the correction factor may lead to a somewhat higher HPWL prediction
58+
// than after clustering.
59+
// TODO: Investigate the clustered vs unclustered factors further.
60+
// TODO: Should update the costs to 3D.
61+
double crossing = wirelength_crossing_count(netlist.net_pins(net_id).size());
62+
63+
double min_x = std::numeric_limits<double>::max();
64+
double max_x = std::numeric_limits<double>::lowest();
65+
double min_y = std::numeric_limits<double>::max();
66+
double max_y = std::numeric_limits<double>::lowest();
5867
for (APPinId pin_id : netlist.net_pins(net_id)) {
5968
APBlockId blk_id = netlist.pin_block(pin_id);
6069
min_x = std::min(min_x, block_x_locs[blk_id]);
@@ -66,10 +75,10 @@ double PartialPlacement::estimate_post_placement_wirelength(const APNetlist& net
6675

6776
// Floor the positions to get the x and y coordinates of the tiles each
6877
// block belongs to.
69-
unsigned tile_dx = std::floor(max_x) - std::floor(min_x);
70-
unsigned tile_dy = std::floor(max_y) - std::floor(min_y);
78+
double tile_dx = std::floor(max_x) - std::floor(min_x);
79+
double tile_dy = std::floor(max_y) - std::floor(min_y);
7180

72-
total_hpwl += tile_dx + tile_dy;
81+
total_hpwl += (tile_dx + tile_dy) * crossing;
7382
}
7483

7584
return total_hpwl;

vpr/src/place/net_cost_handler.cpp

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -84,13 +84,6 @@ static void add_block_to_bb(const t_physical_tile_loc& new_pin_loc,
8484
t_2D_bb& bb_edge_new,
8585
t_2D_bb& bb_coord_new);
8686

87-
/**
88-
* @brief To get the wirelength cost/est, BB perimeter is multiplied by a factor to approximately correct for the half-perimeter
89-
* bounding box wirelength's underestimate of wiring for nets with fanout greater than 2.
90-
* @return Multiplicative wirelength correction factor
91-
*/
92-
static double wirelength_crossing_count(size_t fanout);
93-
9487
/******************************* End of Function definitions ************************************/
9588

9689
NetCostHandler::NetCostHandler(const t_placer_opts& placer_opts,
@@ -1492,7 +1485,7 @@ double NetCostHandler::recompute_bb_cost_() {
14921485
return cost;
14931486
}
14941487

1495-
static double wirelength_crossing_count(size_t fanout) {
1488+
double wirelength_crossing_count(size_t fanout) {
14961489
/* Get the expected "crossing count" of a net, based on its number *
14971490
* of pins. Extrapolate for very large nets. */
14981491

vpr/src/place/net_cost_handler.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,13 @@
1515
class PlacerState;
1616
class PlacerCriticalities;
1717

18+
/**
19+
* @brief To get the wirelength cost/est, BB perimeter is multiplied by a factor to approximately correct for the half-perimeter
20+
* bounding box wirelength's underestimate of wiring for nets with fanout greater than 2.
21+
* @return Multiplicative wirelength correction factor
22+
*/
23+
double wirelength_crossing_count(size_t fanout);
24+
1825
/**
1926
* @brief The method used to calculate placement cost
2027
* @details For comp_cost. NORMAL means use the method that generates updatable bounding boxes for speed.

0 commit comments

Comments
 (0)