Skip to content

Commit e70f165

Browse files
Merge branch 'master' into temp_add_interposer_wires
2 parents ad376ef + 74d6c84 commit e70f165

File tree

93 files changed

+288
-6529
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

93 files changed

+288
-6529
lines changed
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/**
2+
* @file
3+
* @author Yulang (Robert) Luo
4+
* @date October 2025
5+
* @brief The definitions of the AP Draw Manager class which is used
6+
* to handle graphics updates during analytical placement.
7+
*/
8+
9+
#include "ap_draw_manager.h"
10+
#include "vpr_types.h"
11+
12+
#ifndef NO_GRAPHICS
13+
#include "draw.h"
14+
#include "draw_global.h"
15+
#include "partial_placement.h"
16+
#endif
17+
18+
APDrawManager::APDrawManager(const PartialPlacement& p_placement) {
19+
#ifndef NO_GRAPHICS
20+
// Set the analytical placement reference in draw state
21+
get_draw_state_vars()->set_ap_partial_placement_ref(p_placement);
22+
#else
23+
(void)p_placement;
24+
#endif
25+
}
26+
27+
APDrawManager::~APDrawManager() {
28+
#ifndef NO_GRAPHICS
29+
// Clear the analytical placement reference in draw state
30+
get_draw_state_vars()->clear_ap_partial_placement_ref();
31+
#endif
32+
}
33+
34+
void APDrawManager::update_graphics(unsigned int iteration, enum APDrawType draw_type) {
35+
#ifndef NO_GRAPHICS
36+
std::string msg;
37+
if (draw_type == APDrawType::Solver) {
38+
msg = "Analytical Placement Solver - Iteration: " + std::to_string(iteration);
39+
} else if (draw_type == APDrawType::Legalizer) {
40+
msg = "Analytical Placement Legalizer - Iteration: " + std::to_string(iteration);
41+
} else {
42+
msg = "Analytical Placement";
43+
}
44+
update_screen(ScreenUpdatePriority::MAJOR, msg.c_str(), e_pic_type::ANALYTICAL_PLACEMENT, nullptr);
45+
#else
46+
(void)iteration;
47+
(void)draw_type;
48+
#endif
49+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#pragma once
2+
/**
3+
* @file
4+
* @author Yulang (Robert) Luo
5+
* @date October 2025
6+
* @brief The decalarations of the AP Draw Manager class which is used
7+
* to handle graphics updates during analytical placement.
8+
*/
9+
10+
#include <string>
11+
12+
// Forward declarations
13+
class PartialPlacement;
14+
15+
// Types to indicate the type of drawing operation
16+
enum class APDrawType {
17+
Solver,
18+
Legalizer
19+
};
20+
21+
/**
22+
* @class APDrawManager
23+
* @brief Manages graphics updates during analytical placement operations.
24+
*
25+
* This class provides a clean interface for updating the screen during
26+
* analytical placement without requiring the placement code to be littered
27+
* with NO_GRAPHICS conditional compilation directives.
28+
*/
29+
class APDrawManager {
30+
public:
31+
/**
32+
* @brief Constructor initializes the draw manager with a reference to the
33+
* current partial placement.
34+
*/
35+
explicit APDrawManager(const PartialPlacement& p_placement);
36+
37+
/**
38+
* @brief Destructor cleans up the reference in the draw state.
39+
*/
40+
~APDrawManager();
41+
42+
/**
43+
* @brief Update screen with current analytical placement state
44+
* @param msg A message to display with the update
45+
*/
46+
void update_graphics(unsigned int iteration, enum APDrawType draw_type);
47+
};

vpr/src/analytical_place/global_placer.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <limits>
1212
#include <memory>
1313
#include <vector>
14+
#include "ap_draw_manager.h"
1415
#include "PreClusterTimingManager.h"
1516
#include "analytical_solver.h"
1617
#include "ap_flow_enums.h"
@@ -352,6 +353,10 @@ PartialPlacement SimPLGlobalPlacer::place() {
352353
PartialPlacement best_p_placement(ap_netlist_);
353354
double best_ub_hpwl = std::numeric_limits<double>::max();
354355

356+
// Initialize graphics for analytical placement, setting the reference in
357+
// the draw state.
358+
APDrawManager draw_manager(p_placement);
359+
355360
// Run the global placer.
356361
for (size_t i = 0; i < max_num_iterations_; i++) {
357362
float iter_start_time = runtime_timer.elapsed_sec();
@@ -361,12 +366,18 @@ PartialPlacement SimPLGlobalPlacer::place() {
361366
solver_->solve(i, p_placement);
362367
float solver_end_time = runtime_timer.elapsed_sec();
363368
double lb_hpwl = p_placement.get_hpwl(ap_netlist_);
369+
370+
// Update graphics after analytical solver
371+
draw_manager.update_graphics(i, APDrawType::Solver);
364372

365373
// Run the legalizer.
366374
float legalizer_start_time = runtime_timer.elapsed_sec();
367375
partial_legalizer_->legalize(p_placement);
368376
float legalizer_end_time = runtime_timer.elapsed_sec();
369377
double ub_hpwl = p_placement.get_hpwl(ap_netlist_);
378+
379+
// Update graphics after legalizer
380+
draw_manager.update_graphics(i, APDrawType::Legalizer);
370381

371382
// Perform a timing update
372383
float timing_update_start_time = runtime_timer.elapsed_sec();

vpr/src/base/vpr_types.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,7 @@ enum class e_sched_type {
387387
enum class e_pic_type {
388388
NO_PICTURE,
389389
PLACEMENT,
390+
ANALYTICAL_PLACEMENT,
390391
ROUTING
391392
};
392393

vpr/src/draw/draw.cpp

Lines changed: 95 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,12 @@
1818
#include "draw.h"
1919

2020
#include "draw_interposer.h"
21+
#include "draw_types.h"
2122
#include "timing_info.h"
2223
#include "physical_types.h"
2324

2425
#include "move_utils.h"
26+
#include "vpr_types.h"
2527

2628
#ifndef NO_GRAPHICS
2729

@@ -176,65 +178,71 @@ static void draw_main_canvas(ezgl::renderer* g) {
176178
t_draw_state* draw_state = get_draw_state_vars();
177179

178180
g->set_font_size(14);
181+
if (draw_state->pic_on_screen != e_pic_type::ANALYTICAL_PLACEMENT) {
182+
draw_block_pin_util();
183+
drawplace(g);
184+
draw_internal_draw_subblk(g);
179185

180-
draw_interposer_cuts(g);
186+
draw_interposer_cuts(g);
181187

182-
draw_block_pin_util();
183-
drawplace(g);
184-
draw_internal_draw_subblk(g);
188+
draw_block_pin_util();
189+
drawplace(g);
190+
draw_internal_draw_subblk(g);
185191

186-
if (draw_state->pic_on_screen == e_pic_type::ROUTING) { // ROUTING on screen
192+
if (draw_state->pic_on_screen == e_pic_type::ROUTING) { // ROUTING on screen
187193

188-
draw_rr(g);
194+
draw_rr(g);
189195

190-
if (draw_state->show_nets && draw_state->draw_nets == DRAW_ROUTED_NETS) {
191-
draw_route(ALL_NETS, g);
196+
if (draw_state->show_nets && draw_state->draw_nets == DRAW_ROUTED_NETS) {
197+
draw_route(ALL_NETS, g);
192198

193-
if (draw_state->highlight_fan_in_fan_out) {
194-
draw_route(HIGHLIGHTED, g);
199+
if (draw_state->highlight_fan_in_fan_out) {
200+
draw_route(HIGHLIGHTED, g);
201+
}
195202
}
196-
}
197203

198-
draw_congestion(g);
204+
draw_congestion(g);
199205

200-
draw_routing_costs(g);
206+
draw_routing_costs(g);
201207

202-
draw_router_expansion_costs(g);
208+
draw_router_expansion_costs(g);
203209

204-
draw_routing_util(g);
210+
draw_routing_util(g);
205211

206-
draw_routing_bb(g);
207-
}
212+
draw_routing_bb(g);
213+
}
208214

209-
draw_placement_macros(g);
215+
draw_placement_macros(g);
210216

211217
#ifndef NO_SERVER
212-
if (g_vpr_ctx.server().gate_io.is_running()) {
213-
const ServerContext& server_ctx = g_vpr_ctx.server(); // shortcut
214-
draw_crit_path_elements(server_ctx.crit_paths, server_ctx.crit_path_element_indexes, server_ctx.draw_crit_path_contour, g);
215-
} else {
216-
draw_crit_path(g);
217-
}
218+
if (g_vpr_ctx.server().gate_io.is_running()) {
219+
const ServerContext& server_ctx = g_vpr_ctx.server(); // shortcut
220+
draw_crit_path_elements(server_ctx.crit_paths, server_ctx.crit_path_element_indexes, server_ctx.draw_crit_path_contour, g);
221+
} else {
222+
draw_crit_path(g);
223+
}
218224
#else
219-
draw_crit_path(g);
225+
draw_crit_path(g);
220226
#endif /* NO_SERVER */
221227

222-
draw_logical_connections(g);
228+
draw_logical_connections(g);
223229

224-
draw_selected_pb_flylines(g);
230+
draw_selected_pb_flylines(g);
225231

226-
draw_noc(g);
232+
draw_noc(g);
227233

228-
if (draw_state->draw_partitions) {
229-
highlight_all_regions(g);
230-
draw_constrained_atoms(g);
231-
}
234+
if (draw_state->draw_partitions) {
235+
highlight_all_regions(g);
236+
draw_constrained_atoms(g);
237+
}
232238

233-
if (draw_state->color_map) {
234-
draw_color_map_legend(*draw_state->color_map, g);
235-
draw_state->color_map.reset(); //Free color map in preparation for next redraw
239+
if (draw_state->color_map) {
240+
draw_color_map_legend(*draw_state->color_map, g);
241+
draw_state->color_map.reset(); //Free color map in preparation for next redraw
242+
}
243+
} else {
244+
draw_analytical_place(g);
236245
}
237-
238246
if (draw_state->auto_proceed) {
239247
//Automatically exit the event loop, so user's don't need to manually click proceed
240248

@@ -290,7 +298,7 @@ void update_screen(ScreenUpdatePriority priority,
290298
* value controls whether or not the Proceed button must be clicked to *
291299
* continue. Saves the pic_on_screen_val to allow pan and zoom redraws. */
292300
t_draw_state* draw_state = get_draw_state_vars();
293-
301+
294302
strcpy(draw_state->default_message, msg);
295303

296304
if (!draw_state->show_graphics)
@@ -306,9 +314,23 @@ void update_screen(ScreenUpdatePriority priority,
306314

307315
state_change = true;
308316

317+
if (draw_state->show_graphics) {
318+
if (pic_on_screen_val == e_pic_type::ANALYTICAL_PLACEMENT) {
319+
set_initial_world_ap();
320+
} else {
321+
set_initial_world();
322+
}
323+
}
324+
309325
if (draw_state->pic_on_screen == e_pic_type::NO_PICTURE) {
310326
// Only add the canvas the first time we open graphics
311327
application.add_canvas("MainCanvas", draw_main_canvas, initial_world);
328+
} else {
329+
// TODO: will this ever be null?
330+
auto canvas = application.get_canvas(application.get_main_canvas_id());
331+
if (canvas != nullptr) {
332+
canvas->get_camera().set_world(initial_world);
333+
}
312334
}
313335

314336
draw_state->setup_timing_info = setup_timing_info;
@@ -492,7 +514,7 @@ void init_draw_coords(float clb_width, const BlkLocRegistry& blk_loc_registry) {
492514
constexpr float VISIBLE_MARGIN = 0.01;
493515

494516
float draw_width = draw_coords->tile_x[grid.width() - 1] + draw_coords->get_tile_width();
495-
float draw_height = draw_coords->tile_y[grid.height() - 1] + draw_coords->get_tile_width();
517+
float draw_height = draw_coords->tile_y[grid.height() - 1] + draw_coords->get_tile_height();
496518

497519
initial_world = ezgl::rectangle(
498520
{-VISIBLE_MARGIN * draw_width, -VISIBLE_MARGIN * draw_height},
@@ -506,6 +528,36 @@ void init_draw_coords(float clb_width, const BlkLocRegistry& blk_loc_registry) {
506528

507529
#ifndef NO_GRAPHICS
508530

531+
void set_initial_world() {
532+
constexpr float VISIBLE_MARGIN = 0.01;
533+
t_draw_coords* draw_coords = get_draw_coords_vars();
534+
const DeviceContext& device_ctx = g_vpr_ctx.device();
535+
536+
float draw_width = draw_coords->tile_x[device_ctx.grid.width() - 1] + draw_coords->get_tile_width();
537+
float draw_height = draw_coords->tile_y[device_ctx.grid.height() - 1] + draw_coords->get_tile_width();
538+
539+
initial_world = ezgl::rectangle(
540+
{-VISIBLE_MARGIN * draw_width, -VISIBLE_MARGIN * draw_height},
541+
{(1. + VISIBLE_MARGIN) * draw_width, (1. + VISIBLE_MARGIN)
542+
* draw_height});
543+
}
544+
545+
void set_initial_world_ap() {
546+
constexpr float VISIBLE_MARGIN = 0.01f;
547+
const DeviceContext& device_ctx = g_vpr_ctx.device();
548+
549+
const size_t grid_w = device_ctx.grid.width();
550+
const size_t grid_h = device_ctx.grid.height();
551+
552+
553+
float draw_width = static_cast<float>(grid_w);
554+
float draw_height = static_cast<float>(grid_h);
555+
556+
initial_world = ezgl::rectangle(
557+
{-VISIBLE_MARGIN * draw_width, -VISIBLE_MARGIN * draw_height},
558+
{(1.f + VISIBLE_MARGIN) * draw_width, (1.f + VISIBLE_MARGIN) * draw_height});
559+
}
560+
509561
int get_track_num(int inode, const vtr::OffsetMatrix<int>& chanx_track, const vtr::OffsetMatrix<int>& chany_track) {
510562
/* Returns the track number of this routing resource node. */
511563
e_rr_type rr_type;
@@ -628,6 +680,11 @@ void act_on_mouse_press(ezgl::application* app, GdkEventButton* event, double x,
628680
* fanins and fanouts are highlighted when you click on a block *
629681
* attached to them. */
630682

683+
if (get_draw_state_vars()->pic_on_screen == e_pic_type::ANALYTICAL_PLACEMENT) {
684+
// No selection in analytical placement mode yet
685+
return;
686+
}
687+
631688
/* Control + mouse click to select multiple nets. */
632689
if (!(event->state & GDK_CONTROL_MASK))
633690
deselect_all();

vpr/src/draw/draw.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,20 @@ void update_screen(ScreenUpdatePriority priority,
5555
*/
5656
void init_draw_coords(float clb_width, const BlkLocRegistry& blk_loc_registry);
5757

58+
/**
59+
* @brief Set the intial_world ezgl::rectangle for analytical placement
60+
*
61+
* This function sets graphic initial dimensions so there are no gaps between blocks
62+
*/
63+
void set_initial_world_ap();
64+
65+
/**
66+
* @brief Set the intial_world ezgl::rectangle for default
67+
*
68+
* This function sets graphic initial dimensions so there are gaps between blocks
69+
*/
70+
void set_initial_world();
71+
5872
/* Sets the static show_graphics and gr_automode variables to the *
5973
* desired values. They control if graphics are enabled and, if so, *
6074
* how often the user is prompted for input. */

0 commit comments

Comments
 (0)