10
10
#include < cstddef>
11
11
#include < limits>
12
12
#include " ap_netlist.h"
13
+ #include " net_cost_handler.h"
13
14
14
15
double PartialPlacement::get_hpwl (const APNetlist& netlist) const {
15
16
double hpwl = 0.0 ;
@@ -27,6 +28,11 @@ double PartialPlacement::get_hpwl(const APNetlist& netlist) const {
27
28
min_y = std::min (min_y, block_y_locs[blk_id]);
28
29
max_y = std::max (max_y, block_y_locs[blk_id]);
29
30
}
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.
30
36
VTR_ASSERT_SAFE (max_x >= min_x && max_y >= min_y);
31
37
hpwl += max_x - min_x + max_y - min_y;
32
38
}
@@ -38,23 +44,26 @@ double PartialPlacement::estimate_post_placement_wirelength(const APNetlist& net
38
44
// we want to estimate the post-placement wirelength, we do not want the
39
45
// flat placement positions of the blocks. Instead we compute the HPWL over
40
46
// the tiles that the flat placement is placing the blocks over.
41
- unsigned total_hpwl = 0 ;
47
+ double total_hpwl = 0 ;
42
48
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 ();
58
67
for (APPinId pin_id : netlist.net_pins (net_id)) {
59
68
APBlockId blk_id = netlist.pin_block (pin_id);
60
69
min_x = std::min (min_x, block_x_locs[blk_id]);
@@ -66,10 +75,10 @@ double PartialPlacement::estimate_post_placement_wirelength(const APNetlist& net
66
75
67
76
// Floor the positions to get the x and y coordinates of the tiles each
68
77
// 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);
71
80
72
- total_hpwl += tile_dx + tile_dy;
81
+ total_hpwl += ( tile_dx + tile_dy) * crossing ;
73
82
}
74
83
75
84
return total_hpwl;
0 commit comments