1010#include < cstddef>
1111#include < limits>
1212#include " ap_netlist.h"
13+ #include " net_cost_handler.h"
1314
1415double 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;
0 commit comments