Skip to content

Commit b6094d4

Browse files
Merge pull request #2765 from AlexandreSinger/feature-ap-partial-legalizer-upstreaming
[AP] Partial Legalizer
2 parents 5a062ba + 499b266 commit b6094d4

File tree

9 files changed

+2133
-23
lines changed

9 files changed

+2133
-23
lines changed

vpr/src/analytical_place/analytical_placement_flow.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "full_legalizer.h"
1414
#include "gen_ap_netlist_from_atoms.h"
1515
#include "globals.h"
16+
#include "partial_legalizer.h"
1617
#include "partial_placement.h"
1718
#include "prepack.h"
1819
#include "user_place_constraints.h"
@@ -53,6 +54,7 @@ static void print_ap_netlist_stats(const APNetlist& netlist) {
5354
VTR_LOG("\t\tAverage Fanout: %.2f\n", average_fanout);
5455
VTR_LOG("\t\tHighest Fanout: %zu\n", highest_fanout);
5556
VTR_LOG("\tPins: %zu\n", netlist.pins().size());
57+
VTR_LOG("\n");
5658
}
5759

5860
void run_analytical_placement_flow(t_vpr_setup& vpr_setup) {
@@ -77,11 +79,16 @@ void run_analytical_placement_flow(t_vpr_setup& vpr_setup) {
7779
print_ap_netlist_stats(ap_netlist);
7880

7981
// Run the Global Placer
80-
// For now, just runs the solver.
82+
// For now, just runs the solver and partial legalizer 10 times arbitrarily.
8183
PartialPlacement p_placement(ap_netlist);
8284
std::unique_ptr<AnalyticalSolver> solver = make_analytical_solver(e_analytical_solver::QP_HYBRID,
8385
ap_netlist);
84-
solver->solve(0, p_placement);
86+
std::unique_ptr<PartialLegalizer> legalizer = make_partial_legalizer(e_partial_legalizer::FLOW_BASED,
87+
ap_netlist);
88+
for (size_t i = 0; i < 10; i++) {
89+
solver->solve(i, p_placement);
90+
legalizer->legalize(p_placement);
91+
}
8592

8693
// Verify that the partial placement is valid before running the full
8794
// legalizer.

vpr/src/analytical_place/full_legalizer.cpp

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
* @file
33
* @author Alex Singer
44
* @date September 2024
5-
* @brief Implements the full legalizer in the AP flow.
5+
* @brief Implements the full legalizer in the AP flow. The Full Legalizer
6+
* takes a partial placement and fully legalizes it. This involves
7+
* creating legal clusters and placing them into valid tile sites.
68
*/
79

810
#include "full_legalizer.h"
@@ -33,6 +35,7 @@
3335
#include "vpr_error.h"
3436
#include "vpr_types.h"
3537
#include "vtr_assert.h"
38+
#include "vtr_geometry.h"
3639
#include "vtr_ndmatrix.h"
3740
#include "vtr_strong_id.h"
3841
#include "vtr_time.h"
@@ -126,9 +129,8 @@ class APClusterPlacer {
126129
const t_physical_tile_loc& tile_loc,
127130
int sub_tile) {
128131
const DeviceContext& device_ctx = g_vpr_ctx.device();
129-
// FIXME: THIS MUST TAKE INTO ACCOUNT THE CONSTRAINTS AS WELL!!!
130-
// - Right now it is just implied.
131-
// - Will work but is unstable.
132+
const FloorplanningContext& floorplanning_ctx = g_vpr_ctx.floorplanning();
133+
const ClusteringContext& cluster_ctx = g_vpr_ctx.clustering();
132134
const auto& block_locs = g_vpr_ctx.placement().block_locs();
133135
auto& blk_loc_registry = g_vpr_ctx.mutable_placement().mutable_blk_loc_registry();
134136
VTR_ASSERT(!is_block_placed(clb_blk_id, block_locs) && "Block already placed. Is this intentional?");
@@ -141,11 +143,24 @@ class APClusterPlacer {
141143
if (device_ctx.grid.get_physical_type(tile_loc)->sub_tiles.size() == 0)
142144
return false;
143145
VTR_ASSERT(sub_tile >= 0 && sub_tile < device_ctx.grid.get_physical_type(tile_loc)->capacity);
144-
// FIXME: Do this better.
145-
// - May need to try all the sub-tiles in a location.
146-
// - https://github.com/AlexandreSinger/vtr-verilog-to-routing/blob/feature-analytical-placer/vpr/src/place/initial_placement.cpp#L755
147-
to_loc.sub_tile = sub_tile;
148-
return try_place_macro(pl_macro, to_loc, blk_loc_registry);
146+
// Check if this cluster is constrained and this location is legal.
147+
if (is_cluster_constrained(clb_blk_id)) {
148+
const auto& cluster_constraints = floorplanning_ctx.cluster_constraints;
149+
if (cluster_constraints[clb_blk_id].is_loc_in_part_reg(to_loc))
150+
return false;
151+
}
152+
// If the location is legal, try to exhaustively place it at this tile
153+
// location. This should try all sub_tiles.
154+
PartitionRegion pr;
155+
vtr::Rect<int> rect(tile_loc.x, tile_loc.y, tile_loc.x, tile_loc.y);
156+
pr.add_to_part_region(Region(rect, to_loc.layer));
157+
const ClusteredNetlist& clb_nlist = cluster_ctx.clb_nlist;
158+
t_logical_block_type_ptr block_type = clb_nlist.block_type(clb_blk_id);
159+
enum e_pad_loc_type pad_loc_type = g_vpr_ctx.device().pad_loc_type;
160+
// FIXME: This currently ignores the sub_tile. Was running into issues
161+
// with trying to force clusters to specific sub_tiles.
162+
return try_place_macro_exhaustively(pl_macro, pr, block_type,
163+
pad_loc_type, blk_loc_registry);
149164
}
150165

151166
// This is not the best way of doing things, but its the simplest. Given a
@@ -356,10 +371,6 @@ void FullLegalizer::place_clusters(const ClusteredNetlist& clb_nlist,
356371
bool placed = ap_cluster_placer.place_cluster(cluster_blk_id, tile_loc, blk_sub_tile);
357372
if (placed)
358373
continue;
359-
// FIXME: Should now try all sub-tiles at this tile location.
360-
// - May need to try all the sub-tiles in a location.
361-
// - however this may need to be done after.
362-
// - https://github.com/AlexandreSinger/vtr-verilog-to-routing/blob/feature-analytical-placer/vpr/src/place/initial_placement.cpp#L755
363374

364375
// Add to list of unplaced clusters.
365376
unplaced_clusters.push_back(cluster_blk_id);

0 commit comments

Comments
 (0)