diff --git a/doc/src/vpr/graphics.rst b/doc/src/vpr/graphics.rst
index 780b223e0b0..103f32ccba2 100644
--- a/doc/src/vpr/graphics.rst
+++ b/doc/src/vpr/graphics.rst
@@ -213,4 +213,30 @@ Button Description Table
| | | | FPGA |
+-------------------+-------------------+------------------------------+------------------------------+
+Manual Moves
+------------
+
+The manual moves feature allows the user to specify the next move in placement. If the move is legal, blocks are swapped and the new move is shown on the architecture.
+
+.. figure:: https://www.verilogtorouting.org/img/manual_move_toggle_button.png
+ :align: center
+
+To enable the feature, activate the Manual Move toggle button and press Proceed. Alternatively, the user can active the Manual Move toggle button and click on the block to be moved.
+
+.. figure:: https://www.verilogtorouting.org/img/draw_manual_moves_window.png
+ :align: center
+
+On the manual move window, the user can specify the Block ID/Block name of the block to move and the To location, with the x position, y position and subtile position. For the manual move to be valid:
+
+- The To location requested by the user should be within the grid's dimensions.
+- The block to be moved is found, valid and not fixed.
+- The blocks to be swapped are compatible.
+- The location choosen by the user is different from the block's current location.
+
+If the manual move is legal, the cost summary window will display the delta cost, delta timing, delta bounding box cost and the placer's annealing decision that would result from this move.
+
+.. figure:: https://www.verilogtorouting.org/img/manual_move_cost_dialog.png
+ :align: center
+
+The user can Accept or Reject the manual move based on the values provided. If accepted the block's new location is shown.
diff --git a/vpr/main.ui b/vpr/main.ui
index 5b63af252a3..ad1308cc694 100644
--- a/vpr/main.ui
+++ b/vpr/main.ui
@@ -192,7 +192,7 @@
1
-
+
-
+
+
+
+
+
+ 0
+ 3
+ 1
+ 1
+
+
+
4
@@ -254,7 +271,7 @@
1
1
-
+
diff --git a/vpr/src/draw/draw.cpp b/vpr/src/draw/draw.cpp
index a07cb64ce6b..c8275e910c2 100644
--- a/vpr/src/draw/draw.cpp
+++ b/vpr/src/draw/draw.cpp
@@ -47,6 +47,7 @@
#include "physical_types.h"
#include "route_common.h"
#include "breakpoint.h"
+#include "manual_moves.h"
#include "move_utils.h"
@@ -100,7 +101,8 @@ void act_on_mouse_press(ezgl::application* app, GdkEventButton* event, double x,
void act_on_mouse_move(ezgl::application* app, GdkEventButton* event, double x, double y);
static void draw_routed_net(ClusterNetId net, ezgl::renderer* g);
-void draw_partial_route(const std::vector& rr_nodes_to_draw, ezgl::renderer* g);
+void draw_partial_route(const std::vector& rr_nodes_to_draw,
+ ezgl::renderer* g);
static void draw_rr(ezgl::renderer* g);
static void draw_rr_edges(int from_node, ezgl::renderer* g);
static void draw_rr_pin(int inode, const ezgl::color& color, ezgl::renderer* g);
@@ -120,7 +122,8 @@ static int get_track_num(int inode, const vtr::OffsetMatrix& chanx_track, c
static bool draw_if_net_highlighted(ClusterNetId inet);
static int draw_check_rr_node_hit(float click_x, float click_y);
-static void draw_expand_non_configurable_rr_nodes_recurr(int from_node, std::set& expanded_nodes);
+static void draw_expand_non_configurable_rr_nodes_recurr(int from_node,
+ std::set& expanded_nodes);
static bool highlight_rr_nodes(float x, float y);
static void highlight_blocks(double x, double y);
static void draw_reset_blk_colors();
@@ -131,10 +134,22 @@ static inline ezgl::rectangle draw_mux(ezgl::point2d origin, e_side orientation,
static inline ezgl::rectangle draw_mux(ezgl::point2d origin, e_side orientation, float height, float width, float height_scale, ezgl::renderer* g);
static void draw_flyline_timing_edge(ezgl::point2d start, ezgl::point2d end, float incr_delay, ezgl::renderer* g);
-static void draw_routed_timing_edge(tatum::NodeId start_tnode, tatum::NodeId end_tnode, float incr_delay, ezgl::color color, ezgl::renderer* g);
-static void draw_routed_timing_edge_connection(tatum::NodeId src_tnode, tatum::NodeId sink_tnode, ezgl::color color, ezgl::renderer* g);
-static std::vector trace_routed_connection_rr_nodes(const ClusterNetId net_id, const int driver_pin, const int sink_pin);
-static bool trace_routed_connection_rr_nodes_recurr(const t_rt_node* rt_node, int sink_rr_node, std::vector& rr_nodes_on_path);
+static void draw_routed_timing_edge(tatum::NodeId start_tnode,
+ tatum::NodeId end_tnode,
+ float incr_delay,
+ ezgl::color color,
+ ezgl::renderer* g);
+static void draw_routed_timing_edge_connection(tatum::NodeId src_tnode,
+ tatum::NodeId sink_tnode,
+ ezgl::color color,
+ ezgl::renderer* g);
+static std::vector trace_routed_connection_rr_nodes(
+ const ClusterNetId net_id,
+ const int driver_pin,
+ const int sink_pin);
+static bool trace_routed_connection_rr_nodes_recurr(const t_rt_node* rt_node,
+ int sink_rr_node,
+ std::vector& rr_nodes_on_path);
static t_edge_size find_edge(int prev_inode, int inode);
static void draw_color_map_legend(const vtr::ColorMap& cmap, ezgl::renderer* g);
@@ -143,18 +158,28 @@ ezgl::color lighten_color(ezgl::color color, float amount);
static void draw_block_pin_util();
-static float get_router_expansion_cost(const t_rr_node_route_inf node_inf, e_draw_router_expansion_cost draw_router_expansion_cost);
+static float get_router_expansion_cost(const t_rr_node_route_inf node_inf,
+ e_draw_router_expansion_cost draw_router_expansion_cost);
static void draw_router_expansion_costs(ezgl::renderer* g);
static void draw_rr_costs(ezgl::renderer* g, const std::vector& rr_costs, bool lowest_cost_first = true);
static void draw_main_canvas(ezgl::renderer* g);
-static void initial_setup_NO_PICTURE_to_PLACEMENT(ezgl::application* app, bool is_new_window);
-static void initial_setup_NO_PICTURE_to_PLACEMENT_with_crit_path(ezgl::application* app, bool is_new_window);
-static void initial_setup_PLACEMENT_to_ROUTING(ezgl::application* app, bool is_new_window);
-static void initial_setup_ROUTING_to_PLACEMENT(ezgl::application* app, bool is_new_window);
-static void initial_setup_NO_PICTURE_to_ROUTING(ezgl::application* app, bool is_new_window);
-static void initial_setup_NO_PICTURE_to_ROUTING_with_crit_path(ezgl::application* app, bool is_new_window);
-static void toggle_window_mode(GtkWidget* /*widget*/, ezgl::application* /*app*/);
+static void initial_setup_NO_PICTURE_to_PLACEMENT(ezgl::application* app,
+ bool is_new_window);
+static void initial_setup_NO_PICTURE_to_PLACEMENT_with_crit_path(
+ ezgl::application* app,
+ bool is_new_window);
+static void initial_setup_PLACEMENT_to_ROUTING(ezgl::application* app,
+ bool is_new_window);
+static void initial_setup_ROUTING_to_PLACEMENT(ezgl::application* app,
+ bool is_new_window);
+static void initial_setup_NO_PICTURE_to_ROUTING(ezgl::application* app,
+ bool is_new_window);
+static void initial_setup_NO_PICTURE_to_ROUTING_with_crit_path(
+ ezgl::application* app,
+ bool is_new_window);
+static void toggle_window_mode(GtkWidget* /*widget*/,
+ ezgl::application* /*app*/);
static void setup_default_ezgl_callbacks(ezgl::application* app);
static void set_force_pause(GtkWidget* /*widget*/, gint /*response_id*/, gpointer /*data*/);
static void set_block_outline(GtkWidget* widget, gint /*response_id*/, gpointer /*data*/);
@@ -162,9 +187,6 @@ static void set_block_text(GtkWidget* widget, gint /*response_id*/, gpointer /*d
static void clip_routing_util(GtkWidget* widget, gint /*response_id*/, gpointer /*data*/);
static void run_graphics_commands(std::string commands);
-void manual_move_generator_window();
-void move_generator_button_callback(GtkWidget* /*widget*/, GtkWidget* grid);
-
/************************** File Scope Variables ****************************/
//The arrow head position for turning/straight-thru connections in a switch box
@@ -202,11 +224,7 @@ const std::vector kelly_max_contrast_colors = {
ezgl::color(43, 61, 38) //olive green
};
-ezgl::application::settings settings("/ezgl/main.ui",
- "MainWindow",
- "MainCanvas",
- "org.verilogtorouting.vpr.PID" + std::to_string(vtr::get_pid()),
- setup_default_ezgl_callbacks);
+ezgl::application::settings settings("/ezgl/main.ui", "MainWindow", "MainCanvas", "org.verilogtorouting.vpr.PID" + std::to_string(vtr::get_pid()), setup_default_ezgl_callbacks);
ezgl::application application(settings);
bool window_mode = false;
@@ -312,8 +330,10 @@ static void draw_main_canvas(ezgl::renderer* g) {
/* function below intializes the interface window with a set of buttons and links
* signals to corresponding functions for situation where the window is opened from
* NO_PICTURE_to_PLACEMENT */
-static void initial_setup_NO_PICTURE_to_PLACEMENT(ezgl::application* app, bool is_new_window) {
- if (!is_new_window) return;
+static void initial_setup_NO_PICTURE_to_PLACEMENT(ezgl::application* app,
+ bool is_new_window) {
+ if (!is_new_window)
+ return;
//button to enter window_mode, created in main.ui
GtkButton* window = (GtkButton*)app->get_object("Window");
@@ -327,16 +347,19 @@ static void initial_setup_NO_PICTURE_to_PLACEMENT(ezgl::application* app, bool i
//button for save graphcis, created in main.ui
GtkButton* save = (GtkButton*)app->get_object("SaveGraphics");
- g_signal_connect(save, "clicked", G_CALLBACK(save_graphics_dialog_box), app);
+ g_signal_connect(save, "clicked", G_CALLBACK(save_graphics_dialog_box),
+ app);
//combo box for search type, created in main.ui
GObject* search_type = (GObject*)app->get_object("SearchType");
- gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(search_type), "Block ID"); // index 0
- gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(search_type), "Block Name"); // index 1
- gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(search_type), "Net ID"); // index 2
- gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(search_type), "Net Name"); // index 3
- gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(search_type), "RR Node ID"); // index 4
- gtk_combo_box_set_active((GtkComboBox*)search_type, 0); // default set to Block ID which has an index 0
+ gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(search_type), "Block ID"); // index 0
+ gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(search_type),
+ "Block Name"); // index 1
+ gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(search_type), "Net ID"); // index 2
+ gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(search_type), "Net Name"); // index 3
+ gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(search_type),
+ "RR Node ID"); // index 4
+ gtk_combo_box_set_active((GtkComboBox*)search_type, 0); // default set to Block ID which has an index 0
button_for_toggle_nets();
button_for_net_max_fanout();
@@ -349,7 +372,9 @@ static void initial_setup_NO_PICTURE_to_PLACEMENT(ezgl::application* app, bool i
/* function below intializes the interface window with a set of buttons and links
* signals to corresponding functions for situation where the window is opened from
* NO_PICTURE_to_PLACEMENT_with_crit_path */
-static void initial_setup_NO_PICTURE_to_PLACEMENT_with_crit_path(ezgl::application* app, bool is_new_window) {
+static void initial_setup_NO_PICTURE_to_PLACEMENT_with_crit_path(
+ ezgl::application* app,
+ bool is_new_window) {
initial_setup_NO_PICTURE_to_PLACEMENT(app, is_new_window);
button_for_toggle_crit_path();
}
@@ -357,7 +382,8 @@ static void initial_setup_NO_PICTURE_to_PLACEMENT_with_crit_path(ezgl::applicati
/* function below intializes the interface window with a set of buttons and links
* signals to corresponding functions for situation where the window is opened from
* PLACEMENT_to_ROUTING */
-static void initial_setup_PLACEMENT_to_ROUTING(ezgl::application* app, bool is_new_window) {
+static void initial_setup_PLACEMENT_to_ROUTING(ezgl::application* app,
+ bool is_new_window) {
initial_setup_NO_PICTURE_to_PLACEMENT_with_crit_path(app, is_new_window);
button_for_toggle_rr();
button_for_toggle_congestion();
@@ -370,7 +396,8 @@ static void initial_setup_PLACEMENT_to_ROUTING(ezgl::application* app, bool is_n
/* function below intializes the interface window with a set of buttons and links
* signals to corresponding functions for situation where the window is opened from
* ROUTING_to_PLACEMENT */
-static void initial_setup_ROUTING_to_PLACEMENT(ezgl::application* app, bool is_new_window) {
+static void initial_setup_ROUTING_to_PLACEMENT(ezgl::application* app,
+ bool is_new_window) {
initial_setup_PLACEMENT_to_ROUTING(app, is_new_window);
std::string toggle_rr = "toggle_rr";
std::string toggle_congestion = "toggle_congestion";
@@ -390,8 +417,10 @@ static void initial_setup_ROUTING_to_PLACEMENT(ezgl::application* app, bool is_n
/* function below intializes the interface window with a set of buttons and links
* signals to corresponding functions for situation where the window is opened from
* NO_PICTURE_to_ROUTING */
-static void initial_setup_NO_PICTURE_to_ROUTING(ezgl::application* app, bool is_new_window) {
- if (!is_new_window) return;
+static void initial_setup_NO_PICTURE_to_ROUTING(ezgl::application* app,
+ bool is_new_window) {
+ if (!is_new_window)
+ return;
GtkButton* window = (GtkButton*)app->get_object("Window");
gtk_button_set_label(window, "Window");
@@ -402,14 +431,17 @@ static void initial_setup_NO_PICTURE_to_ROUTING(ezgl::application* app, bool is_
g_signal_connect(search, "clicked", G_CALLBACK(search_and_highlight), app);
GtkButton* save = (GtkButton*)app->get_object("SaveGraphics");
- g_signal_connect(save, "clicked", G_CALLBACK(save_graphics_dialog_box), app);
+ g_signal_connect(save, "clicked", G_CALLBACK(save_graphics_dialog_box),
+ app);
GObject* search_type = (GObject*)app->get_object("SearchType");
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(search_type), "Block ID");
- gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(search_type), "Block Name");
+ gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(search_type),
+ "Block Name");
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(search_type), "Net ID");
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(search_type), "Net Name");
- gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(search_type), "RR Node ID");
+ gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(search_type),
+ "RR Node ID");
button_for_toggle_nets();
button_for_net_max_fanout();
@@ -428,7 +460,9 @@ static void initial_setup_NO_PICTURE_to_ROUTING(ezgl::application* app, bool is_
/* function below intializes the interface window with a set of buttons and links
* signals to corresponding functions for situation where the window is opened from
* NO_PICTURE_to_ROUTING_with_crit_path */
-static void initial_setup_NO_PICTURE_to_ROUTING_with_crit_path(ezgl::application* app, bool is_new_window) {
+static void initial_setup_NO_PICTURE_to_ROUTING_with_crit_path(
+ ezgl::application* app,
+ bool is_new_window) {
initial_setup_NO_PICTURE_to_ROUTING(app, is_new_window);
button_for_toggle_crit_path();
}
@@ -456,12 +490,14 @@ void update_screen(ScreenUpdatePriority priority, const char* msg, enum pic_type
if (draw_state->pic_on_screen == NO_PICTURE) {
//Only add the canvas the first time we open graphics
- application.add_canvas("MainCanvas", draw_main_canvas, initial_world);
+ application.add_canvas("MainCanvas", draw_main_canvas,
+ initial_world);
}
draw_state->setup_timing_info = setup_timing_info;
- if (pic_on_screen_val == PLACEMENT && draw_state->pic_on_screen == NO_PICTURE) {
+ if (pic_on_screen_val == PLACEMENT
+ && draw_state->pic_on_screen == NO_PICTURE) {
if (setup_timing_info) {
init_setup = initial_setup_NO_PICTURE_to_PLACEMENT_with_crit_path;
} else {
@@ -469,16 +505,19 @@ void update_screen(ScreenUpdatePriority priority, const char* msg, enum pic_type
}
draw_state->save_graphics_file_base = "vpr_placement";
- } else if (pic_on_screen_val == ROUTING && draw_state->pic_on_screen == PLACEMENT) {
+ } else if (pic_on_screen_val == ROUTING
+ && draw_state->pic_on_screen == PLACEMENT) {
//Routing, opening after placement
init_setup = initial_setup_PLACEMENT_to_ROUTING;
draw_state->save_graphics_file_base = "vpr_routing";
- } else if (pic_on_screen_val == PLACEMENT && draw_state->pic_on_screen == ROUTING) {
+ } else if (pic_on_screen_val == PLACEMENT
+ && draw_state->pic_on_screen == ROUTING) {
init_setup = initial_setup_ROUTING_to_PLACEMENT;
draw_state->save_graphics_file_base = "vpr_placement";
- } else if (pic_on_screen_val == ROUTING && draw_state->pic_on_screen == NO_PICTURE) {
+ } else if (pic_on_screen_val == ROUTING
+ && draw_state->pic_on_screen == NO_PICTURE) {
//Routing opening first
if (setup_timing_info) {
init_setup = initial_setup_NO_PICTURE_to_ROUTING_with_crit_path;
@@ -514,7 +553,8 @@ void update_screen(ScreenUpdatePriority priority, const char* msg, enum pic_type
draw_state->forced_pause = false; //Reset pause flag
}
- application.run(init_setup, act_on_mouse_press, act_on_mouse_move, act_on_key_press);
+ application.run(init_setup, act_on_mouse_press, act_on_mouse_move,
+ act_on_key_press);
if (!draw_state->graphics_commands.empty()) {
run_graphics_commands(draw_state->graphics_commands);
@@ -541,12 +581,13 @@ void update_screen(ScreenUpdatePriority priority, const char* msg, enum pic_type
}
#ifndef NO_GRAPHICS
-static void toggle_window_mode(GtkWidget* /*widget*/, ezgl::application* /*app*/) {
+static void toggle_window_mode(GtkWidget* /*widget*/,
+ ezgl::application* /*app*/) {
window_mode = true;
}
void toggle_nets(GtkWidget* /*widget*/, gint /*response_id*/, gpointer /*data*/) {
- /* this is the callback function for runtime created toggle_nets button
+ /* this is the callback function for runtime created toggle_nets button
* which is written in button.cpp */
t_draw_state* draw_state = get_draw_state_vars();
@@ -556,7 +597,8 @@ void toggle_nets(GtkWidget* /*widget*/, gint /*response_id*/, gpointer /*data*/)
// use the pointer to get the active text
enum e_draw_nets new_state;
- gchar* combo_box_content = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(toggle_nets));
+ gchar* combo_box_content = gtk_combo_box_text_get_active_text(
+ GTK_COMBO_BOX_TEXT(toggle_nets));
// assign corresponding enum value to draw_state->show_nets
if (strcmp(combo_box_content, "None") == 0)
@@ -578,14 +620,15 @@ void toggle_nets(GtkWidget* /*widget*/, gint /*response_id*/, gpointer /*data*/)
}
void toggle_rr(GtkWidget* /*widget*/, gint /*response_id*/, gpointer /*data*/) {
- /* this is the callback function for runtime created toggle_rr button
+ /* this is the callback function for runtime created toggle_rr button
* which is written in button.cpp */
t_draw_state* draw_state = get_draw_state_vars();
std::string button_name = "toggle_rr";
auto toggle_rr = find_button(button_name.c_str());
enum e_draw_rr_toggle new_state;
- gchar* combo_box_content = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(toggle_rr));
+ gchar* combo_box_content = gtk_combo_box_text_get_active_text(
+ GTK_COMBO_BOX_TEXT(toggle_rr));
if (strcmp(combo_box_content, "None") == 0)
new_state = DRAW_NO_RR;
else if (strcmp(combo_box_content, "Nodes") == 0)
@@ -596,7 +639,8 @@ void toggle_rr(GtkWidget* /*widget*/, gint /*response_id*/, gpointer /*data*/) {
new_state = DRAW_NODES_SBOX_CBOX_RR;
else if (strcmp(combo_box_content, "Nodes SBox CBox Internal") == 0)
new_state = DRAW_NODES_SBOX_CBOX_INTERNAL_RR;
- else // all rr
+ else
+ // all rr
new_state = DRAW_ALL_RR;
//free dynamically allocated pointers
@@ -610,19 +654,21 @@ void toggle_rr(GtkWidget* /*widget*/, gint /*response_id*/, gpointer /*data*/) {
}
void toggle_congestion(GtkWidget* /*widget*/, gint /*response_id*/, gpointer /*data*/) {
- /* this is the callback function for runtime created toggle_congestion button
+ /* this is the callback function for runtime created toggle_congestion button
* which is written in button.cpp */
t_draw_state* draw_state = get_draw_state_vars();
std::string button_name = "toggle_congestion";
auto toggle_congestion = find_button(button_name.c_str());
enum e_draw_congestion new_state;
- gchar* combo_box_content = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(toggle_congestion));
+ gchar* combo_box_content = gtk_combo_box_text_get_active_text(
+ GTK_COMBO_BOX_TEXT(toggle_congestion));
if (strcmp(combo_box_content, "None") == 0)
new_state = DRAW_NO_CONGEST;
else if (strcmp(combo_box_content, "Congested") == 0)
new_state = DRAW_CONGESTED;
- else // congested with nets
+ else
+ // congested with nets
new_state = DRAW_CONGESTED_WITH_NETS;
draw_state->reset_nets_congestion_and_rr();
@@ -635,13 +681,14 @@ void toggle_congestion(GtkWidget* /*widget*/, gint /*response_id*/, gpointer /*d
}
void toggle_routing_congestion_cost(GtkWidget* /*widget*/, gint /*response_id*/, gpointer /*data*/) {
- /* this is the callback function for runtime created toggle_routing_congestion_cost button
+ /* this is the callback function for runtime created toggle_routing_congestion_cost button
* which is written in button.cpp */
t_draw_state* draw_state = get_draw_state_vars();
std::string button_name = "toggle_routing_congestion_cost";
auto toggle_routing_congestion_cost = find_button(button_name.c_str());
enum e_draw_routing_costs new_state;
- gchar* combo_box_content = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(toggle_routing_congestion_cost));
+ gchar* combo_box_content = gtk_combo_box_text_get_active_text(
+ GTK_COMBO_BOX_TEXT(toggle_routing_congestion_cost));
if (strcmp(combo_box_content, "None") == 0)
new_state = DRAW_NO_ROUTING_COSTS;
else if (strcmp(combo_box_content, "Total Routing Costs") == 0)
@@ -669,7 +716,7 @@ void toggle_routing_congestion_cost(GtkWidget* /*widget*/, gint /*response_id*/,
}
void toggle_routing_bounding_box(GtkWidget* /*widget*/, gint /*response_id*/, gpointer /*data*/) {
- /* this is the callback function for runtime created toggle_routing_bounding_box button
+ /* this is the callback function for runtime created toggle_routing_bounding_box button
* which is written in button.cpp */
t_draw_state* draw_state = get_draw_state_vars();
auto& route_ctx = g_vpr_ctx.routing();
@@ -681,7 +728,8 @@ void toggle_routing_bounding_box(GtkWidget* /*widget*/, gint /*response_id*/, gp
return; //Nothing to draw
// use the pointer to get the active value
- int new_value = gtk_spin_button_get_value_as_int((GtkSpinButton*)toggle_routing_bounding_box);
+ int new_value = gtk_spin_button_get_value_as_int(
+ (GtkSpinButton*)toggle_routing_bounding_box);
// assign value to draw_state->show_routing_bb, bound check + set OPEN when it's -1 (draw nothing)
if (new_value < -1)
@@ -694,21 +742,23 @@ void toggle_routing_bounding_box(GtkWidget* /*widget*/, gint /*response_id*/, gp
draw_state->show_routing_bb = new_value;
//redraw
- if ((int)(draw_state->show_routing_bb) == (int)((int)(route_ctx.route_bb.size()) - 1)) {
+ if ((int)(draw_state->show_routing_bb)
+ == (int)((int)(route_ctx.route_bb.size()) - 1)) {
application.update_message(draw_state->default_message);
}
application.refresh_drawing();
}
void toggle_routing_util(GtkWidget* /*widget*/, gint /*response_id*/, gpointer /*data*/) {
- /* this is the callback function for runtime created toggle_routing_util button
+ /* this is the callback function for runtime created toggle_routing_util button
* which is written in button.cpp */
t_draw_state* draw_state = get_draw_state_vars();
std::string button_name = "toggle_routing_util";
auto toggle_routing_util = find_button(button_name.c_str());
enum e_draw_routing_util new_state;
- gchar* combo_box_content = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(toggle_routing_util));
+ gchar* combo_box_content = gtk_combo_box_text_get_active_text(
+ GTK_COMBO_BOX_TEXT(toggle_routing_util));
if (strcmp(combo_box_content, "None") == 0)
new_state = DRAW_NO_ROUTING_UTIL;
else if (strcmp(combo_box_content, "Routing Util") == 0)
@@ -730,13 +780,14 @@ void toggle_routing_util(GtkWidget* /*widget*/, gint /*response_id*/, gpointer /
}
void toggle_blk_internal(GtkWidget* /*widget*/, gint /*response_id*/, gpointer /*data*/) {
- /* this is the callback function for runtime created toggle_blk_internal button
+ /* this is the callback function for runtime created toggle_blk_internal button
* which is written in button.cpp */
t_draw_state* draw_state = get_draw_state_vars();
std::string button_name = "toggle_blk_internal";
auto toggle_blk_internal = find_button(button_name.c_str());
- int new_value = gtk_spin_button_get_value_as_int((GtkSpinButton*)toggle_blk_internal);
+ int new_value = gtk_spin_button_get_value_as_int(
+ (GtkSpinButton*)toggle_blk_internal);
if (new_value < 0)
draw_state->show_blk_internal = 0;
else if (new_value >= draw_state->max_sub_blk_lvl)
@@ -747,12 +798,13 @@ void toggle_blk_internal(GtkWidget* /*widget*/, gint /*response_id*/, gpointer /
}
void toggle_block_pin_util(GtkWidget* /*widget*/, gint /*response_id*/, gpointer /*data*/) {
- /* this is the callback function for runtime created toggle_block_pin_util button
+ /* this is the callback function for runtime created toggle_block_pin_util button
* which is written in button.cpp */
t_draw_state* draw_state = get_draw_state_vars();
std::string button_name = "toggle_block_pin_util";
auto toggle_block_pin_util = find_button(button_name.c_str());
- gchar* combo_box_content = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(toggle_block_pin_util));
+ gchar* combo_box_content = gtk_combo_box_text_get_active_text(
+ GTK_COMBO_BOX_TEXT(toggle_block_pin_util));
if (strcmp(combo_box_content, "None") == 0) {
draw_state->show_blk_pin_util = DRAW_NO_BLOCK_PIN_UTIL;
draw_reset_blk_colors();
@@ -769,13 +821,14 @@ void toggle_block_pin_util(GtkWidget* /*widget*/, gint /*response_id*/, gpointer
}
void toggle_placement_macros(GtkWidget* /*widget*/, gint /*response_id*/, gpointer /*data*/) {
- /* this is the callback function for runtime created toggle_placement_macros button
+ /* this is the callback function for runtime created toggle_placement_macros button
* which is written in button.cpp */
t_draw_state* draw_state = get_draw_state_vars();
std::string button_name = "toggle_placement_macros";
auto toggle_placement_macros = find_button(button_name.c_str());
- gchar* combo_box_content = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(toggle_placement_macros));
+ gchar* combo_box_content = gtk_combo_box_text_get_active_text(
+ GTK_COMBO_BOX_TEXT(toggle_placement_macros));
if (strcmp(combo_box_content, "None") == 0)
draw_state->show_placement_macros = DRAW_NO_PLACEMENT_MACROS;
else
@@ -786,13 +839,14 @@ void toggle_placement_macros(GtkWidget* /*widget*/, gint /*response_id*/, gpoint
}
void toggle_crit_path(GtkWidget* /*widget*/, gint /*response_id*/, gpointer /*data*/) {
- /* this is the callback function for runtime created toggle_crit_path button
+ /* this is the callback function for runtime created toggle_crit_path button
* which is written in button.cpp */
t_draw_state* draw_state = get_draw_state_vars();
std::string button_name = "toggle_crit_path";
auto toggle_crit_path = find_button(button_name.c_str());
- gchar* combo_box_content = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(toggle_crit_path));
+ gchar* combo_box_content = gtk_combo_box_text_get_active_text(
+ GTK_COMBO_BOX_TEXT(toggle_crit_path));
if (strcmp(combo_box_content, "None") == 0) {
draw_state->show_crit_path = DRAW_NO_CRIT_PATH;
} else if (strcmp(combo_box_content, "Crit Path Flylines") == 0)
@@ -801,7 +855,8 @@ void toggle_crit_path(GtkWidget* /*widget*/, gint /*response_id*/, gpointer /*da
draw_state->show_crit_path = DRAW_CRIT_PATH_FLYLINES_DELAYS;
else if (strcmp(combo_box_content, "Crit Path Routing") == 0)
draw_state->show_crit_path = DRAW_CRIT_PATH_ROUTING;
- else // Crit Path Routing Delays
+ else
+ // Crit Path Routing Delays
draw_state->show_crit_path = DRAW_CRIT_PATH_ROUTING_DELAYS;
g_free(combo_box_content);
@@ -809,14 +864,15 @@ void toggle_crit_path(GtkWidget* /*widget*/, gint /*response_id*/, gpointer /*da
}
void toggle_router_expansion_costs(GtkWidget* /*widget*/, gint /*response_id*/, gpointer /*data*/) {
- /* this is the callback function for runtime created toggle_router_expansion_costs button
+ /* this is the callback function for runtime created toggle_router_expansion_costs button
* which is written in button.cpp */
t_draw_state* draw_state = get_draw_state_vars();
std::string button_name = "toggle_router_expansion_costs";
auto toggle_router_expansion_costs = find_button(button_name.c_str());
e_draw_router_expansion_cost new_state;
- gchar* combo_box_content = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(toggle_router_expansion_costs));
+ gchar* combo_box_content = gtk_combo_box_text_get_active_text(
+ GTK_COMBO_BOX_TEXT(toggle_router_expansion_costs));
if (strcmp(combo_box_content, "None") == 0) {
new_state = DRAW_NO_ROUTER_EXPANSION_COST;
} else if (strcmp(combo_box_content, "Total") == 0) {
@@ -838,7 +894,8 @@ void toggle_router_expansion_costs(GtkWidget* /*widget*/, gint /*response_id*/,
g_free(combo_box_content);
draw_state->show_router_expansion_cost = new_state;
- if (draw_state->show_router_expansion_cost == DRAW_NO_ROUTER_EXPANSION_COST) {
+ if (draw_state->show_router_expansion_cost
+ == DRAW_NO_ROUTER_EXPANSION_COST) {
application.update_message(draw_state->default_message);
}
application.refresh_drawing();
@@ -856,15 +913,18 @@ void alloc_draw_structs(const t_arch* arch) {
/* Allocate the structures needed to draw the placement and routing-> Set *
* up the default colors for blocks and nets. */
- draw_coords->tile_x = (float*)vtr::malloc(device_ctx.grid.width() * sizeof(float));
- draw_coords->tile_y = (float*)vtr::malloc(device_ctx.grid.height() * sizeof(float));
+ draw_coords->tile_x = (float*)vtr::malloc(
+ device_ctx.grid.width() * sizeof(float));
+ draw_coords->tile_y = (float*)vtr::malloc(
+ device_ctx.grid.height() * sizeof(float));
/* For sub-block drawings inside clbs */
draw_internal_alloc_blk();
draw_state->net_color.resize(cluster_ctx.clb_nlist.nets().size());
draw_state->block_color_.resize(cluster_ctx.clb_nlist.blocks().size());
- draw_state->use_default_block_color_.resize(cluster_ctx.clb_nlist.blocks().size());
+ draw_state->use_default_block_color_.resize(
+ cluster_ctx.clb_nlist.blocks().size());
/* Space is allocated for draw_rr_node but not initialized because we do *
* not yet know information about the routing resources. */
@@ -914,13 +974,15 @@ void init_draw_coords(float width_val) {
t_draw_coords* draw_coords = get_draw_coords_vars();
auto& device_ctx = g_vpr_ctx.device();
- if (!draw_state->show_graphics && !draw_state->save_graphics && draw_state->graphics_commands.empty())
+ if (!draw_state->show_graphics && !draw_state->save_graphics
+ && draw_state->graphics_commands.empty())
return; //do not initialize only if --disp off and --save_graphics off
/* Each time routing is on screen, need to reallocate the color of each *
* rr_node, as the number of rr_nodes may change. */
if (device_ctx.rr_nodes.size() != 0) {
- draw_state->draw_rr_node = (t_draw_rr_node*)vtr::realloc(draw_state->draw_rr_node,
- (device_ctx.rr_nodes.size()) * sizeof(t_draw_rr_node));
+ draw_state->draw_rr_node = (t_draw_rr_node*)vtr::realloc(
+ draw_state->draw_rr_node,
+ (device_ctx.rr_nodes.size()) * sizeof(t_draw_rr_node));
for (size_t i = 0; i < device_ctx.rr_nodes.size(); i++) {
draw_state->draw_rr_node[i].color = DEFAULT_RR_NODE_COLOR;
draw_state->draw_rr_node[i].node_highlighted = false;
@@ -941,13 +1003,17 @@ void init_draw_coords(float width_val) {
draw_coords->tile_x[i] = (i * draw_coords->get_tile_width()) + j;
j += device_ctx.chan_width.y_list[i] + 1; /* N wires need N+1 units of space */
}
- draw_coords->tile_x[device_ctx.grid.width() - 1] = ((device_ctx.grid.width() - 1) * draw_coords->get_tile_width()) + j;
+ draw_coords->tile_x[device_ctx.grid.width() - 1] = ((device_ctx.grid.width()
+ - 1)
+ * draw_coords->get_tile_width())
+ + j;
j = 0;
for (size_t i = 0; i < (device_ctx.grid.height() - 1); ++i) {
draw_coords->tile_y[i] = (i * draw_coords->get_tile_width()) + j;
j += device_ctx.chan_width.x_list[i] + 1;
}
- draw_coords->tile_y[device_ctx.grid.height() - 1] = ((device_ctx.grid.height() - 1) * draw_coords->get_tile_width()) + j;
+ draw_coords->tile_y[device_ctx.grid.height() - 1] = ((device_ctx.grid.height() - 1) * draw_coords->get_tile_width())
+ + j;
/* Load coordinates of sub-blocks inside the clbs */
draw_internal_init_blk();
//Margin beyond edge of the drawn device to extend the visible world
@@ -955,10 +1021,15 @@ void init_draw_coords(float width_val) {
//space around the device edges
constexpr float VISIBLE_MARGIN = 0.01;
- float draw_width = draw_coords->tile_x[device_ctx.grid.width() - 1] + draw_coords->get_tile_width();
- float draw_height = draw_coords->tile_y[device_ctx.grid.height() - 1] + draw_coords->get_tile_width();
+ float draw_width = draw_coords->tile_x[device_ctx.grid.width() - 1]
+ + draw_coords->get_tile_width();
+ float draw_height = draw_coords->tile_y[device_ctx.grid.height() - 1]
+ + draw_coords->get_tile_width();
- initial_world = ezgl::rectangle({-VISIBLE_MARGIN * draw_width, -VISIBLE_MARGIN * draw_height}, {(1. + VISIBLE_MARGIN) * draw_width, (1. + VISIBLE_MARGIN) * draw_height});
+ initial_world = ezgl::rectangle(
+ {-VISIBLE_MARGIN * draw_width, -VISIBLE_MARGIN * draw_height},
+ {(1. + VISIBLE_MARGIN) * draw_width, (1. + VISIBLE_MARGIN)
+ * draw_height});
#else
(void)width_val;
#endif /* NO_GRAPHICS */
@@ -982,7 +1053,8 @@ static void drawplace(ezgl::renderer* g) {
for (size_t i = 0; i < device_ctx.grid.width(); i++) {
for (size_t j = 0; j < device_ctx.grid.height(); j++) {
/* Only the first block of a group should control drawing */
- if (device_ctx.grid[i][j].width_offset > 0 || device_ctx.grid[i][j].height_offset > 0)
+ if (device_ctx.grid[i][j].width_offset > 0
+ || device_ctx.grid[i][j].height_offset > 0)
continue;
num_sub_tiles = device_ctx.grid[i][j].type->capacity;
@@ -1008,15 +1080,18 @@ static void drawplace(ezgl::renderer* g) {
bool current_loc_is_highlighted = false;
if (placer_breakpoint_reached())
- current_loc_is_highlighted = highlight_loc_with_specific_color(int(i), int(j), block_color);
+ current_loc_is_highlighted = highlight_loc_with_specific_color(int(i), int(j),
+ block_color);
// No color specified at this location; use the block color.
if (current_loc_is_highlighted == false) {
if (bnum != EMPTY_BLOCK_ID) {
block_color = draw_state->block_color(bnum);
} else {
- block_color = get_block_type_color(device_ctx.grid[i][j].type);
- block_color = lighten_color(block_color, EMPTY_BLOCK_LIGHTEN_FACTOR);
+ block_color = get_block_type_color(
+ device_ctx.grid[i][j].type);
+ block_color = lighten_color(block_color,
+ EMPTY_BLOCK_LIGHTEN_FACTOR);
}
}
@@ -1025,14 +1100,16 @@ static void drawplace(ezgl::renderer* g) {
g->set_color(block_color);
/* Get coords of current sub_tile */
- ezgl::rectangle abs_clb_bbox = draw_coords->get_absolute_clb_bbox(i, j, k, logical_block_type);
+ ezgl::rectangle abs_clb_bbox = draw_coords->get_absolute_clb_bbox(i, j, k,
+ logical_block_type);
ezgl::point2d center = abs_clb_bbox.center();
g->fill_rectangle(abs_clb_bbox);
g->set_color(ezgl::BLACK);
- g->set_line_dash((EMPTY_BLOCK_ID == bnum) ? ezgl::line_dash::asymmetric_5_3 : ezgl::line_dash::none);
+ g->set_line_dash(
+ (EMPTY_BLOCK_ID == bnum) ? ezgl::line_dash::asymmetric_5_3 : ezgl::line_dash::none);
if (draw_state->draw_block_outlines) {
g->draw_rectangle(abs_clb_bbox);
}
@@ -1040,17 +1117,25 @@ static void drawplace(ezgl::renderer* g) {
if (draw_state->draw_block_text) {
/* Draw text if the space has parts of the netlist */
if (bnum != EMPTY_BLOCK_ID && bnum != INVALID_BLOCK_ID) {
- std::string name = cluster_ctx.clb_nlist.block_name(bnum) + vtr::string_fmt(" (#%zu)", size_t(bnum));
+ std::string name = cluster_ctx.clb_nlist.block_name(
+ bnum)
+ + vtr::string_fmt(" (#%zu)", size_t(bnum));
- g->draw_text(center, name.c_str(), abs_clb_bbox.width(), abs_clb_bbox.height());
+ g->draw_text(center, name.c_str(), abs_clb_bbox.width(),
+ abs_clb_bbox.height());
}
/* Draw text for block type so that user knows what block */
- if (device_ctx.grid[i][j].width_offset == 0 && device_ctx.grid[i][j].height_offset == 0) {
+ if (device_ctx.grid[i][j].width_offset == 0
+ && device_ctx.grid[i][j].height_offset == 0) {
std::string block_type_loc = device_ctx.grid[i][j].type->name;
block_type_loc += vtr::string_fmt(" (%d,%d)", i, j);
- g->draw_text(center - ezgl::point2d(0, abs_clb_bbox.height() / 4),
- block_type_loc.c_str(), abs_clb_bbox.width(), abs_clb_bbox.height());
+ g->draw_text(
+ center
+ - ezgl::point2d(0,
+ abs_clb_bbox.height() / 4),
+ block_type_loc.c_str(), abs_clb_bbox.width(),
+ abs_clb_bbox.height());
}
}
}
@@ -1080,12 +1165,17 @@ static void drawnets(ezgl::renderer* g) {
if (cluster_ctx.clb_nlist.net_is_ignored(net_id))
continue; /* Don't draw */
- g->set_color(draw_state->net_color[net_id], draw_state->net_color[net_id].alpha * NET_ALPHA);
+ g->set_color(draw_state->net_color[net_id],
+ draw_state->net_color[net_id].alpha * NET_ALPHA);
b1 = cluster_ctx.clb_nlist.net_driver_block(net_id);
- ezgl::point2d driver_center = draw_coords->get_absolute_clb_bbox(b1, cluster_ctx.clb_nlist.block_type(b1)).center();
+ ezgl::point2d driver_center = draw_coords->get_absolute_clb_bbox(b1,
+ cluster_ctx.clb_nlist.block_type(b1))
+ .center();
for (auto pin_id : cluster_ctx.clb_nlist.net_sinks(net_id)) {
b2 = cluster_ctx.clb_nlist.pin_block(pin_id);
- ezgl::point2d sink_center = draw_coords->get_absolute_clb_bbox(b2, cluster_ctx.clb_nlist.block_type(b2)).center();
+ ezgl::point2d sink_center = draw_coords->get_absolute_clb_bbox(b2,
+ cluster_ctx.clb_nlist.block_type(b2))
+ .center();
g->draw_line(driver_center, sink_center);
/* Uncomment to draw a chain instead of a star. */
/* driver_center = sink_center; */
@@ -1202,9 +1292,9 @@ static void draw_routing_costs(ezgl::renderer* g) {
t_draw_state* draw_state = get_draw_state_vars();
- /* show_routing_costs controls whether the total/sum of the costs or individual
- * cost components (base cost, accumulated cost, present cost) are shown, and
- * whether colours are proportional to the node's cost or the logarithm of
+ /* show_routing_costs controls whether the total/sum of the costs or individual
+ * cost components (base cost, accumulated cost, present cost) are shown, and
+ * whether colours are proportional to the node's cost or the logarithm of
* it's cost.*/
if (draw_state->show_routing_costs == DRAW_NO_ROUTING_COSTS) {
return;
@@ -1223,25 +1313,32 @@ static void draw_routing_costs(ezgl::renderer* g) {
for (size_t inode = 0; inode < device_ctx.rr_nodes.size(); inode++) {
float cost = 0.;
if (draw_state->show_routing_costs == DRAW_TOTAL_ROUTING_COSTS
- || draw_state->show_routing_costs == DRAW_LOG_TOTAL_ROUTING_COSTS) {
- cost = get_single_rr_cong_cost(inode, get_draw_state_vars()->pres_fac);
+ || draw_state->show_routing_costs
+ == DRAW_LOG_TOTAL_ROUTING_COSTS) {
+ cost = get_single_rr_cong_cost(inode,
+ get_draw_state_vars()->pres_fac);
} else if (draw_state->show_routing_costs == DRAW_BASE_ROUTING_COSTS) {
cost = get_single_rr_cong_base_cost(inode);
} else if (draw_state->show_routing_costs == DRAW_ACC_ROUTING_COSTS
- || draw_state->show_routing_costs == DRAW_LOG_ACC_ROUTING_COSTS) {
+ || draw_state->show_routing_costs
+ == DRAW_LOG_ACC_ROUTING_COSTS) {
cost = get_single_rr_cong_acc_cost(inode);
} else {
- VTR_ASSERT(draw_state->show_routing_costs == DRAW_PRES_ROUTING_COSTS
- || draw_state->show_routing_costs == DRAW_LOG_PRES_ROUTING_COSTS);
- cost = get_single_rr_cong_pres_cost(inode, get_draw_state_vars()->pres_fac);
+ VTR_ASSERT(
+ draw_state->show_routing_costs == DRAW_PRES_ROUTING_COSTS
+ || draw_state->show_routing_costs
+ == DRAW_LOG_PRES_ROUTING_COSTS);
+ cost = get_single_rr_cong_pres_cost(inode,
+ get_draw_state_vars()->pres_fac);
}
if (draw_state->show_routing_costs == DRAW_LOG_TOTAL_ROUTING_COSTS
|| draw_state->show_routing_costs == DRAW_LOG_ACC_ROUTING_COSTS
- || draw_state->show_routing_costs == DRAW_LOG_PRES_ROUTING_COSTS) {
+ || draw_state->show_routing_costs
+ == DRAW_LOG_PRES_ROUTING_COSTS) {
cost = std::log(cost);
}
rr_node_costs[inode] = cost;
@@ -1257,19 +1354,26 @@ static void draw_routing_costs(ezgl::renderer* g) {
}
char msg[vtr::bufsize];
if (draw_state->show_routing_costs == DRAW_TOTAL_ROUTING_COSTS) {
- sprintf(msg, "Total Congestion Cost Range [%g, %g]", min_cost, max_cost);
+ sprintf(msg, "Total Congestion Cost Range [%g, %g]", min_cost,
+ max_cost);
} else if (draw_state->show_routing_costs == DRAW_LOG_TOTAL_ROUTING_COSTS) {
- sprintf(msg, "Log Total Congestion Cost Range [%g, %g]", min_cost, max_cost);
+ sprintf(msg, "Log Total Congestion Cost Range [%g, %g]", min_cost,
+ max_cost);
} else if (draw_state->show_routing_costs == DRAW_BASE_ROUTING_COSTS) {
sprintf(msg, "Base Congestion Cost Range [%g, %g]", min_cost, max_cost);
} else if (draw_state->show_routing_costs == DRAW_ACC_ROUTING_COSTS) {
- sprintf(msg, "Accumulated (Historical) Congestion Cost Range [%g, %g]", min_cost, max_cost);
+ sprintf(msg, "Accumulated (Historical) Congestion Cost Range [%g, %g]",
+ min_cost, max_cost);
} else if (draw_state->show_routing_costs == DRAW_LOG_ACC_ROUTING_COSTS) {
- sprintf(msg, "Log Accumulated (Historical) Congestion Cost Range [%g, %g]", min_cost, max_cost);
+ sprintf(msg,
+ "Log Accumulated (Historical) Congestion Cost Range [%g, %g]",
+ min_cost, max_cost);
} else if (draw_state->show_routing_costs == DRAW_PRES_ROUTING_COSTS) {
- sprintf(msg, "Present Congestion Cost Range [%g, %g]", min_cost, max_cost);
+ sprintf(msg, "Present Congestion Cost Range [%g, %g]", min_cost,
+ max_cost);
} else if (draw_state->show_routing_costs == DRAW_LOG_PRES_ROUTING_COSTS) {
- sprintf(msg, "Log Present Congestion Cost Range [%g, %g]", min_cost, max_cost);
+ sprintf(msg, "Log Present Congestion Cost Range [%g, %g]", min_cost,
+ max_cost);
} else {
sprintf(msg, "Cost Range [%g, %g]", min_cost, max_cost);
}
@@ -1312,8 +1416,10 @@ static void draw_routing_bb(ezgl::renderer* g) {
//the drawn box contains the top/right channels
double draw_xlow = draw_coords->tile_x[bb->xmin];
double draw_ylow = draw_coords->tile_y[bb->ymin];
- double draw_xhigh = draw_coords->tile_x[bb->xmax] + 2 * draw_coords->get_tile_width();
- double draw_yhigh = draw_coords->tile_y[bb->ymax] + 2 * draw_coords->get_tile_height();
+ double draw_xhigh = draw_coords->tile_x[bb->xmax]
+ + 2 * draw_coords->get_tile_width();
+ double draw_yhigh = draw_coords->tile_y[bb->ymax]
+ + 2 * draw_coords->get_tile_height();
g->set_color(blk_RED);
g->draw_rectangle({draw_xlow, draw_ylow}, {draw_xhigh, draw_yhigh});
@@ -1327,8 +1433,11 @@ static void draw_routing_bb(ezgl::renderer* g) {
std::string msg;
msg += "Showing BB";
- msg += " (" + std::to_string(bb->xmin) + ", " + std::to_string(bb->ymin) + ", " + std::to_string(bb->xmax) + ", " + std::to_string(bb->ymax) + ")";
- msg += " and routing for net '" + cluster_ctx.clb_nlist.net_name(net_id) + "'";
+ msg += " (" + std::to_string(bb->xmin) + ", " + std::to_string(bb->ymin)
+ + ", " + std::to_string(bb->xmax) + ", " + std::to_string(bb->ymax)
+ + ")";
+ msg += " and routing for net '" + cluster_ctx.clb_nlist.net_name(net_id)
+ + "'";
msg += " (#" + std::to_string(size_t(net_id)) + ")";
application.update_message(msg.c_str());
}
@@ -1866,11 +1975,16 @@ static void draw_chanx_to_chany_edge(int chanx_node, int chanx_track, int chany_
g->draw_line({x1, y1}, {x2, y2});
- if (draw_state->draw_rr_toggle == DRAW_ALL_RR || draw_state->draw_rr_node[chanx_node].node_highlighted) {
+ if (draw_state->draw_rr_toggle == DRAW_ALL_RR
+ || draw_state->draw_rr_node[chanx_node].node_highlighted) {
if (edge_dir == FROM_X_TO_Y) {
- draw_rr_switch(x1, y1, x2, y2, device_ctx.rr_switch_inf[switch_type].buffered(), device_ctx.rr_switch_inf[switch_type].configurable(), g);
+ draw_rr_switch(x1, y1, x2, y2,
+ device_ctx.rr_switch_inf[switch_type].buffered(),
+ device_ctx.rr_switch_inf[switch_type].configurable(), g);
} else {
- draw_rr_switch(x2, y2, x1, y1, device_ctx.rr_switch_inf[switch_type].buffered(), device_ctx.rr_switch_inf[switch_type].configurable(), g);
+ draw_rr_switch(x2, y2, x1, y1,
+ device_ctx.rr_switch_inf[switch_type].buffered(),
+ device_ctx.rr_switch_inf[switch_type].configurable(), g);
}
}
}
@@ -1926,7 +2040,8 @@ static void draw_chanx_to_chanx_edge(int from_node, int to_node, int to_track, s
VTR_ASSERT(from_xlow < to_xlow);
x2 = to_chan.left();
/* since no U-turns from_track must be INC as well */
- x1 = draw_coords->tile_x[to_xlow - 1] + draw_coords->get_tile_width();
+ x1 = draw_coords->tile_x[to_xlow - 1]
+ + draw_coords->get_tile_width();
} else { /* DEC wire starts at rightmost edge */
VTR_ASSERT(from_xhigh > to_xhigh);
x2 = to_chan.right();
@@ -1935,9 +2050,11 @@ static void draw_chanx_to_chanx_edge(int from_node, int to_node, int to_track, s
} else {
if (to_xlow < from_xlow) { /* Draw from left edge of one to other */
x1 = from_chan.left();
- x2 = draw_coords->tile_x[from_xlow - 1] + draw_coords->get_tile_width();
+ x2 = draw_coords->tile_x[from_xlow - 1]
+ + draw_coords->get_tile_width();
} else if (from_xlow < to_xlow) {
- x1 = draw_coords->tile_x[to_xlow - 1] + draw_coords->get_tile_width();
+ x1 = draw_coords->tile_x[to_xlow - 1]
+ + draw_coords->get_tile_width();
x2 = to_chan.left();
} /* The following then is executed when from_xlow == to_xlow */
@@ -1956,8 +2073,11 @@ static void draw_chanx_to_chanx_edge(int from_node, int to_node, int to_track, s
g->draw_line({x1, y1}, {x2, y2});
- if (draw_state->draw_rr_toggle == DRAW_ALL_RR || draw_state->draw_rr_node[from_node].node_highlighted) {
- draw_rr_switch(x1, y1, x2, y2, device_ctx.rr_switch_inf[switch_type].buffered(), device_ctx.rr_switch_inf[switch_type].configurable(), g);
+ if (draw_state->draw_rr_toggle == DRAW_ALL_RR
+ || draw_state->draw_rr_node[from_node].node_highlighted) {
+ draw_rr_switch(x1, y1, x2, y2,
+ device_ctx.rr_switch_inf[switch_type].buffered(),
+ device_ctx.rr_switch_inf[switch_type].configurable(), g);
}
}
@@ -2011,7 +2131,8 @@ static void draw_chany_to_chany_edge(int from_node, int to_node, int to_track, s
y2 = to_chan.bottom();
/* since no U-turns from_track must be INC as well */
- y1 = draw_coords->tile_y[to_ylow - 1] + draw_coords->get_tile_width();
+ y1 = draw_coords->tile_y[to_ylow - 1]
+ + draw_coords->get_tile_width();
} else { /* DEC wire starts at top edge */
y2 = to_chan.top();
@@ -2020,9 +2141,11 @@ static void draw_chany_to_chany_edge(int from_node, int to_node, int to_track, s
} else {
if (to_ylow < from_ylow) { /* Draw from bottom edge of one to other. */
y1 = from_chan.bottom();
- y2 = draw_coords->tile_y[from_ylow - 1] + draw_coords->get_tile_width();
+ y2 = draw_coords->tile_y[from_ylow - 1]
+ + draw_coords->get_tile_width();
} else if (from_ylow < to_ylow) {
- y1 = draw_coords->tile_y[to_ylow - 1] + draw_coords->get_tile_width();
+ y1 = draw_coords->tile_y[to_ylow - 1]
+ + draw_coords->get_tile_width();
y2 = to_chan.bottom();
} else if (to_yhigh > from_yhigh) { /* Draw from top edge of one to other. */
y1 = from_chan.top();
@@ -2040,8 +2163,11 @@ static void draw_chany_to_chany_edge(int from_node, int to_node, int to_track, s
/* UDSD Modification by WMF End */
g->draw_line({x1, y1}, {x2, y2});
- if (draw_state->draw_rr_toggle == DRAW_ALL_RR || draw_state->draw_rr_node[from_node].node_highlighted) {
- draw_rr_switch(x1, y1, x2, y2, device_ctx.rr_switch_inf[switch_type].buffered(), device_ctx.rr_switch_inf[switch_type].configurable(), g);
+ if (draw_state->draw_rr_toggle == DRAW_ALL_RR
+ || draw_state->draw_rr_node[from_node].node_highlighted) {
+ draw_rr_switch(x1, y1, x2, y2,
+ device_ctx.rr_switch_inf[switch_type].buffered(),
+ device_ctx.rr_switch_inf[switch_type].configurable(), g);
}
}
@@ -2105,10 +2231,12 @@ static void draw_rr_switch(float from_x, float from_y, float to_x, float to_y, b
} else { /* Buffer */
if (from_x == to_x || from_y == to_y) {
//Straight connection
- draw_triangle_along_line(g, {from_x, from_y}, {to_x, to_y}, SB_EDGE_STRAIGHT_ARROW_POSITION);
+ draw_triangle_along_line(g, {from_x, from_y}, {to_x, to_y},
+ SB_EDGE_STRAIGHT_ARROW_POSITION);
} else {
//Turn connection
- draw_triangle_along_line(g, {from_x, from_y}, {to_x, to_y}, SB_EDGE_TURN_ARROW_POSITION);
+ draw_triangle_along_line(g, {from_x, from_y}, {to_x, to_y},
+ SB_EDGE_TURN_ARROW_POSITION);
}
}
}
@@ -2129,7 +2257,7 @@ static void draw_rr_pin(int inode, const ezgl::color& color, ezgl::renderer* g)
g->set_color(color);
/* TODO: This is where we can hide fringe physical pins and also identify globals (hide, color, show) */
- /* As nodes may appear on more than one side, walk through the possible nodes
+ /* As nodes may appear on more than one side, walk through the possible nodes
* - draw the pin on each side that it appears
*/
for (const e_side& pin_side : SIDES) {
@@ -2137,11 +2265,13 @@ static void draw_rr_pin(int inode, const ezgl::color& color, ezgl::renderer* g)
continue;
}
draw_get_rr_pin_coords(inode, &xcen, &ycen, pin_side);
- g->fill_rectangle({xcen - draw_coords->pin_size, ycen - draw_coords->pin_size},
- {xcen + draw_coords->pin_size, ycen + draw_coords->pin_size});
+ g->fill_rectangle(
+ {xcen - draw_coords->pin_size, ycen - draw_coords->pin_size},
+ {xcen + draw_coords->pin_size, ycen + draw_coords->pin_size});
sprintf(str, "%d", ipin);
g->set_color(ezgl::BLACK);
- g->draw_text({xcen, ycen}, str, 2 * draw_coords->pin_size, 2 * draw_coords->pin_size);
+ g->draw_text({xcen, ycen}, str, 2 * draw_coords->pin_size,
+ 2 * draw_coords->pin_size);
g->set_color(color);
}
}
@@ -2177,7 +2307,8 @@ void draw_get_rr_pin_coords(const t_rr_node& node, float* xcen, float* ycen, con
* we can treat as a block box for this step */
/* For each sub_tile we need and extra padding space */
- step = (float)(draw_coords->get_tile_width()) / (float)(type->num_pins + type->capacity);
+ step = (float)(draw_coords->get_tile_width())
+ / (float)(type->num_pins + type->capacity);
offset = (ipin + k + 1) * step;
switch (pin_side) {
@@ -2220,12 +2351,15 @@ static void draw_rr_src_sink(int inode, ezgl::color color, ezgl::renderer* g) {
g->set_color(color);
- g->fill_rectangle({xcen - draw_coords->pin_size, ycen - draw_coords->pin_size},
- {xcen + draw_coords->pin_size, ycen + draw_coords->pin_size});
+ g->fill_rectangle(
+ {xcen - draw_coords->pin_size, ycen - draw_coords->pin_size},
+ {xcen + draw_coords->pin_size, ycen + draw_coords->pin_size});
- std::string str = vtr::string_fmt("%d", device_ctx.rr_nodes[inode].ptc_num());
+ std::string str = vtr::string_fmt("%d",
+ device_ctx.rr_nodes[inode].ptc_num());
g->set_color(ezgl::BLACK);
- g->draw_text({xcen, ycen}, str.c_str(), 2 * draw_coords->pin_size, 2 * draw_coords->pin_size);
+ g->draw_text({xcen, ycen}, str.c_str(), 2 * draw_coords->pin_size,
+ 2 * draw_coords->pin_size);
g->set_color(color);
}
@@ -2279,7 +2413,8 @@ static void drawroute(enum e_draw_net_type draw_net_type, ezgl::renderer* g) {
/* Now draw each net, one by one. */
for (auto net_id : cluster_ctx.clb_nlist.nets()) {
- if (draw_net_type == HIGHLIGHTED && draw_state->net_color[net_id] == ezgl::BLACK)
+ if (draw_net_type == HIGHLIGHTED
+ && draw_state->net_color[net_id] == ezgl::BLACK)
continue;
draw_routed_net(net_id, g);
@@ -2490,7 +2625,8 @@ static int get_track_num(int inode, const vtr::OffsetMatrix& chanx_track, c
default:
vpr_throw(VPR_ERROR_OTHER, __FILE__, __LINE__,
- "in get_track_num: Unexpected node type %d for node %d.\n", rr_type, inode);
+ "in get_track_num: Unexpected node type %d for node %d.\n",
+ rr_type, inode);
return OPEN;
}
}
@@ -2520,15 +2656,18 @@ void highlight_nets(char* message, int hit_node) {
t_draw_state* draw_state = get_draw_state_vars();
for (auto net_id : cluster_ctx.clb_nlist.nets()) {
- for (tptr = route_ctx.trace[net_id].head; tptr != nullptr; tptr = tptr->next) {
+ for (tptr = route_ctx.trace[net_id].head; tptr != nullptr;
+ tptr = tptr->next) {
if (draw_state->draw_rr_node[tptr->index].color == ezgl::MAGENTA) {
draw_state->net_color[net_id] = draw_state->draw_rr_node[tptr->index].color;
if (tptr->index == hit_node) {
std::string orig_msg(message);
- sprintf(message, "%s || Net: %zu (%s)", orig_msg.c_str(), size_t(net_id),
+ sprintf(message, "%s || Net: %zu (%s)", orig_msg.c_str(),
+ size_t(net_id),
cluster_ctx.clb_nlist.net_name(net_id).c_str());
}
- } else if (draw_state->draw_rr_node[tptr->index].color == ezgl::WHITE) {
+ } else if (draw_state->draw_rr_node[tptr->index].color
+ == ezgl::WHITE) {
// If node is de-selected.
draw_state->net_color[net_id] = ezgl::BLACK;
break;
@@ -2549,10 +2688,13 @@ void draw_highlight_fan_in_fan_out(const std::set& nodes) {
for (auto node : nodes) {
/* Highlight the fanout nodes in red. */
- for (t_edge_size iedge = 0, l = device_ctx.rr_nodes[node].num_edges(); iedge < l; iedge++) {
+ for (t_edge_size iedge = 0, l = device_ctx.rr_nodes[node].num_edges();
+ iedge < l; iedge++) {
int fanout_node = device_ctx.rr_nodes[node].edge_sink_node(iedge);
- if (draw_state->draw_rr_node[node].color == ezgl::MAGENTA && draw_state->draw_rr_node[fanout_node].color != ezgl::MAGENTA) {
+ if (draw_state->draw_rr_node[node].color == ezgl::MAGENTA
+ && draw_state->draw_rr_node[fanout_node].color
+ != ezgl::MAGENTA) {
// If node is highlighted, highlight its fanout
draw_state->draw_rr_node[fanout_node].color = DRIVES_IT_COLOR;
draw_state->draw_rr_node[fanout_node].node_highlighted = true;
@@ -2565,14 +2707,19 @@ void draw_highlight_fan_in_fan_out(const std::set& nodes) {
/* Highlight the nodes that can fanin to this node in blue. */
for (size_t inode = 0; inode < device_ctx.rr_nodes.size(); inode++) {
- for (t_edge_size iedge = 0, l = device_ctx.rr_nodes[inode].num_edges(); iedge < l; iedge++) {
- int fanout_node = device_ctx.rr_nodes[inode].edge_sink_node(iedge);
+ for (t_edge_size iedge = 0, l = device_ctx.rr_nodes[inode].num_edges(); iedge < l;
+ iedge++) {
+ int fanout_node = device_ctx.rr_nodes[inode].edge_sink_node(
+ iedge);
if (fanout_node == node) {
- if (draw_state->draw_rr_node[node].color == ezgl::MAGENTA && draw_state->draw_rr_node[inode].color != ezgl::MAGENTA) {
+ if (draw_state->draw_rr_node[node].color == ezgl::MAGENTA
+ && draw_state->draw_rr_node[inode].color
+ != ezgl::MAGENTA) {
// If node is highlighted, highlight its fanin
draw_state->draw_rr_node[inode].color = ezgl::BLUE;
draw_state->draw_rr_node[inode].node_highlighted = true;
- } else if (draw_state->draw_rr_node[node].color == ezgl::WHITE) {
+ } else if (draw_state->draw_rr_node[node].color
+ == ezgl::WHITE) {
// If node is de-highlighted, de-highlight its fanin
draw_state->draw_rr_node[inode].color = DEFAULT_RR_NODE_COLOR;
draw_state->draw_rr_node[inode].node_highlighted = false;
@@ -2660,17 +2807,20 @@ std::set draw_expand_non_configurable_rr_nodes(int from_node) {
return expanded_nodes;
}
-void draw_expand_non_configurable_rr_nodes_recurr(int from_node, std::set& expanded_nodes) {
+void draw_expand_non_configurable_rr_nodes_recurr(int from_node,
+ std::set& expanded_nodes) {
auto& device_ctx = g_vpr_ctx.device();
expanded_nodes.insert(from_node);
- for (t_edge_size iedge = 0; iedge < device_ctx.rr_nodes[from_node].num_edges(); ++iedge) {
+ for (t_edge_size iedge = 0;
+ iedge < device_ctx.rr_nodes[from_node].num_edges(); ++iedge) {
bool edge_configurable = device_ctx.rr_nodes[from_node].edge_is_configurable(iedge);
int to_node = device_ctx.rr_nodes[from_node].edge_sink_node(iedge);
if (!edge_configurable && !expanded_nodes.count(to_node)) {
- draw_expand_non_configurable_rr_nodes_recurr(to_node, expanded_nodes);
+ draw_expand_non_configurable_rr_nodes_recurr(to_node,
+ expanded_nodes);
}
}
}
@@ -2724,10 +2874,14 @@ void act_on_mouse_press(ezgl::application* app, GdkEventButton* event, double x,
//click on any two points to form new window rectangle bound
ezgl::point2d point_2 = {x, y};
- ezgl::rectangle current_window = (app->get_canvas(app->get_main_canvas_id()))->get_camera().get_world();
+ ezgl::rectangle current_window = (app->get_canvas(
+ app->get_main_canvas_id()))
+ ->get_camera()
+ .get_world();
//calculate a rectangle with the same ratio based on the two clicks
- double window_ratio = current_window.height() / current_window.width();
+ double window_ratio = current_window.height()
+ / current_window.width();
double new_height = abs(point_1.y - point_2.y);
double new_width = new_height / window_ratio;
@@ -2811,7 +2965,8 @@ void act_on_mouse_move(ezgl::application* app, GdkEventButton* event, double x,
event = event; // just for hiding warning message
}
-void draw_highlight_blocks_color(t_logical_block_type_ptr type, ClusterBlockId blk_id) {
+void draw_highlight_blocks_color(t_logical_block_type_ptr type,
+ ClusterBlockId blk_id) {
int k, iclass;
ClusterBlockId fanblk;
@@ -2915,7 +3070,8 @@ void draw_triangle_along_line(ezgl::renderer* g, ezgl::point2d start, ezgl::poin
float xtri = start.x + xdelta * relative_position;
float ytri = start.y + ydelta * relative_position;
- draw_triangle_along_line(g, xtri, ytri, start.x, end.x, start.y, end.y, arrow_size);
+ draw_triangle_along_line(g, xtri, ytri, start.x, end.x, start.y, end.y,
+ arrow_size);
}
/* Draws a triangle with it's center at loc, and of length & width
@@ -2923,7 +3079,8 @@ void draw_triangle_along_line(ezgl::renderer* g, ezgl::point2d start, ezgl::poin
* of the directed line segment start -> end.
*/
void draw_triangle_along_line(ezgl::renderer* g, ezgl::point2d loc, ezgl::point2d start, ezgl::point2d end, float arrow_size) {
- draw_triangle_along_line(g, loc.x, loc.y, start.x, end.x, start.y, end.y, arrow_size);
+ draw_triangle_along_line(g, loc.x, loc.y, start.x, end.x, start.y, end.y,
+ arrow_size);
}
/**
@@ -2953,8 +3110,10 @@ void draw_triangle_along_line(ezgl::renderer* g, float xend, float yend, float x
poly.push_back({xend + xunit * switch_rad, yend + yunit * switch_rad});
xbaseline = xend - xunit * switch_rad;
ybaseline = yend - yunit * switch_rad;
- poly.push_back({xbaseline + yunit * switch_rad, ybaseline - xunit * switch_rad});
- poly.push_back({xbaseline - yunit * switch_rad, ybaseline + xunit * switch_rad});
+ poly.push_back(
+ {xbaseline + yunit * switch_rad, ybaseline - xunit * switch_rad});
+ poly.push_back(
+ {xbaseline - yunit * switch_rad, ybaseline + xunit * switch_rad});
g->fill_poly(poly);
}
@@ -3172,7 +3331,8 @@ static void draw_pin_to_sink(int ipin_node, int sink_node, ezgl::renderer* g) {
float x1 = 0, y1 = 0;
/* Draw the line for each ipin on different sides */
for (const e_side& pin_side : SIDES) {
- if (!device_ctx.rr_nodes[ipin_node].is_node_on_specific_side(pin_side)) {
+ if (!device_ctx.rr_nodes[ipin_node].is_node_on_specific_side(
+ pin_side)) {
continue;
}
@@ -3197,7 +3357,8 @@ static void draw_source_to_pin(int source_node, int opin_node, ezgl::renderer* g
/* Draw the line for each ipin on different sides */
for (const e_side& pin_side : SIDES) {
- if (!device_ctx.rr_nodes[opin_node].is_node_on_specific_side(pin_side)) {
+ if (!device_ctx.rr_nodes[opin_node].is_node_on_specific_side(
+ pin_side)) {
continue;
}
@@ -3217,7 +3378,8 @@ static inline void draw_mux_with_size(ezgl::point2d origin, e_side orientation,
auto bounds = draw_mux(origin, orientation, height, g);
g->set_color(ezgl::BLACK);
- g->draw_text(bounds.center(), std::to_string(size), bounds.width(), bounds.height());
+ g->draw_text(bounds.center(), std::to_string(size), bounds.width(),
+ bounds.height());
}
//Draws a mux
@@ -3233,21 +3395,27 @@ static inline ezgl::rectangle draw_mux(ezgl::point2d origin, e_side orientation,
case TOP:
//Clock-wise from bottom left
mux_polygon.push_back({origin.x - height / 2, origin.y - width / 2});
- mux_polygon.push_back({origin.x - (scale * height) / 2, origin.y + width / 2});
- mux_polygon.push_back({origin.x + (scale * height) / 2, origin.y + width / 2});
+ mux_polygon.push_back(
+ {origin.x - (scale * height) / 2, origin.y + width / 2});
+ mux_polygon.push_back(
+ {origin.x + (scale * height) / 2, origin.y + width / 2});
mux_polygon.push_back({origin.x + height / 2, origin.y - width / 2});
break;
case BOTTOM:
//Clock-wise from bottom left
- mux_polygon.push_back({origin.x - (scale * height) / 2, origin.y - width / 2});
+ mux_polygon.push_back(
+ {origin.x - (scale * height) / 2, origin.y - width / 2});
mux_polygon.push_back({origin.x - height / 2, origin.y + width / 2});
mux_polygon.push_back({origin.x + height / 2, origin.y + width / 2});
- mux_polygon.push_back({origin.x + (scale * height) / 2, origin.y - width / 2});
+ mux_polygon.push_back(
+ {origin.x + (scale * height) / 2, origin.y - width / 2});
break;
case LEFT:
//Clock-wise from bottom left
- mux_polygon.push_back({origin.x - width / 2, origin.y - (scale * height) / 2});
- mux_polygon.push_back({origin.x - width / 2, origin.y + (scale * height) / 2});
+ mux_polygon.push_back(
+ {origin.x - width / 2, origin.y - (scale * height) / 2});
+ mux_polygon.push_back(
+ {origin.x - width / 2, origin.y + (scale * height) / 2});
mux_polygon.push_back({origin.x + width / 2, origin.y + height / 2});
mux_polygon.push_back({origin.x + width / 2, origin.y - height / 2});
break;
@@ -3255,8 +3423,10 @@ static inline ezgl::rectangle draw_mux(ezgl::point2d origin, e_side orientation,
//Clock-wise from bottom left
mux_polygon.push_back({origin.x - width / 2, origin.y - height / 2});
mux_polygon.push_back({origin.x - width / 2, origin.y + height / 2});
- mux_polygon.push_back({origin.x + width / 2, origin.y + (scale * height) / 2});
- mux_polygon.push_back({origin.x + width / 2, origin.y - (scale * height) / 2});
+ mux_polygon.push_back(
+ {origin.x + width / 2, origin.y + (scale * height) / 2});
+ mux_polygon.push_back(
+ {origin.x + width / 2, origin.y - (scale * height) / 2});
break;
default:
@@ -3291,7 +3461,8 @@ ezgl::point2d atom_pin_draw_coord(AtomPinId pin) {
const t_pb_graph_node* pg_gnode = atom_ctx.lookup.atom_pb_graph_node(blk);
t_draw_coords* draw_coords = get_draw_coords_vars();
- ezgl::rectangle pb_bbox = draw_coords->get_absolute_pb_bbox(clb_index, pg_gnode);
+ ezgl::rectangle pb_bbox = draw_coords->get_absolute_pb_bbox(clb_index,
+ pg_gnode);
//We place each atom pin inside it's pb bounding box
//and distribute the pins along it's vertical centre line
@@ -3303,9 +3474,8 @@ ezgl::point2d atom_pin_draw_coord(AtomPinId pin) {
int pin_index, pin_total;
find_pin_index_at_model_scope(pin, blk, &pin_index, &pin_total);
- const ezgl::point2d point = {
- x_offset + usable_width * pin_index / ((float)pin_total),
- pb_bbox.center_y()};
+ const ezgl::point2d point = {x_offset + usable_width * pin_index / ((float)pin_total),
+ pb_bbox.center_y()};
return point;
}
@@ -3325,7 +3495,9 @@ static void draw_crit_path(ezgl::renderer* g) {
}
//Get the worst timing path
- auto paths = path_collector.collect_worst_setup_timing_paths(*timing_ctx.graph, *(draw_state->setup_timing_info->setup_analyzer()), 1);
+ auto paths = path_collector.collect_worst_setup_timing_paths(
+ *timing_ctx.graph,
+ *(draw_state->setup_timing_info->setup_analyzer()), 1);
tatum::TimingPath path = paths[0];
//Walk through the timing path drawing each edge
@@ -3340,14 +3512,18 @@ static void draw_crit_path(ezgl::renderer* g) {
//any routing which corresponds to the edge
//
//We pick colors from the kelly max-contrast list, for long paths there may be repeats
- ezgl::color color = kelly_max_contrast_colors[i++ % kelly_max_contrast_colors.size()];
+ ezgl::color color = kelly_max_contrast_colors[i++
+ % kelly_max_contrast_colors.size()];
float delay = arr_time - prev_arr_time;
- if (draw_state->show_crit_path == DRAW_CRIT_PATH_FLYLINES || draw_state->show_crit_path == DRAW_CRIT_PATH_FLYLINES_DELAYS) {
+ if (draw_state->show_crit_path == DRAW_CRIT_PATH_FLYLINES
+ || draw_state->show_crit_path
+ == DRAW_CRIT_PATH_FLYLINES_DELAYS) {
g->set_color(color);
g->set_line_dash(ezgl::line_dash::none);
g->set_line_width(4);
- draw_flyline_timing_edge(tnode_draw_coord(prev_node), tnode_draw_coord(node), delay, g);
+ draw_flyline_timing_edge(tnode_draw_coord(prev_node),
+ tnode_draw_coord(node), delay, g);
} else {
VTR_ASSERT(draw_state->show_crit_path != DRAW_NO_CRIT_PATH);
@@ -3365,8 +3541,10 @@ static void draw_flyline_timing_edge(ezgl::point2d start, ezgl::point2d end, flo
draw_triangle_along_line(g, start, end, 0.95, 40 * DEFAULT_ARROW_SIZE);
draw_triangle_along_line(g, start, end, 0.05, 40 * DEFAULT_ARROW_SIZE);
- bool draw_delays = (get_draw_state_vars()->show_crit_path == DRAW_CRIT_PATH_FLYLINES_DELAYS
- || get_draw_state_vars()->show_crit_path == DRAW_CRIT_PATH_ROUTING_DELAYS);
+ bool draw_delays = (get_draw_state_vars()->show_crit_path
+ == DRAW_CRIT_PATH_FLYLINES_DELAYS
+ || get_draw_state_vars()->show_crit_path
+ == DRAW_CRIT_PATH_ROUTING_DELAYS);
if (draw_delays) {
//Determine the strict bounding box based on the lines start/end
float min_x = std::min(start.x, end.x);
@@ -3398,7 +3576,8 @@ static void draw_flyline_timing_edge(ezgl::point2d start, ezgl::point2d end, flo
std::string incr_delay_str = ss.str();
// Get the angle of line, to rotate the text
- float text_angle = (180 / M_PI) * atan((end.y - start.y) / (end.x - start.x));
+ float text_angle = (180 / M_PI)
+ * atan((end.y - start.y) / (end.x - start.x));
// Get the screen coordinates for text drawing
ezgl::rectangle screen_coords = g->world_to_screen(text_bbox);
@@ -3411,11 +3590,14 @@ static void draw_flyline_timing_edge(ezgl::point2d start, ezgl::point2d end, flo
g->set_coordinate_system(ezgl::SCREEN);
// Find an offset so it is sitting on top/below of the line
- float x_offset = screen_coords.center().x - 8 * sin(text_angle * (M_PI / 180));
- float y_offset = screen_coords.center().y - 8 * cos(text_angle * (M_PI / 180));
+ float x_offset = screen_coords.center().x
+ - 8 * sin(text_angle * (M_PI / 180));
+ float y_offset = screen_coords.center().y
+ - 8 * cos(text_angle * (M_PI / 180));
ezgl::point2d offset_text_bbox(x_offset, y_offset);
- g->draw_text(offset_text_bbox, incr_delay_str.c_str(), text_bbox.width(), text_bbox.height());
+ g->draw_text(offset_text_bbox, incr_delay_str.c_str(),
+ text_bbox.width(), text_bbox.height());
g->set_font_size(14);
@@ -3424,21 +3606,30 @@ static void draw_flyline_timing_edge(ezgl::point2d start, ezgl::point2d end, flo
}
}
-static void draw_routed_timing_edge(tatum::NodeId start_tnode, tatum::NodeId end_tnode, float incr_delay, ezgl::color color, ezgl::renderer* g) {
+static void draw_routed_timing_edge(tatum::NodeId start_tnode,
+ tatum::NodeId end_tnode,
+ float incr_delay,
+ ezgl::color color,
+ ezgl::renderer* g) {
draw_routed_timing_edge_connection(start_tnode, end_tnode, color, g);
g->set_line_dash(ezgl::line_dash::asymmetric_5_3);
g->set_line_width(3);
g->set_color(color);
- draw_flyline_timing_edge((ezgl::point2d)tnode_draw_coord(start_tnode), (ezgl::point2d)tnode_draw_coord(end_tnode), (float)incr_delay, (ezgl::renderer*)g);
+ draw_flyline_timing_edge((ezgl::point2d)tnode_draw_coord(start_tnode),
+ (ezgl::point2d)tnode_draw_coord(end_tnode), (float)incr_delay,
+ (ezgl::renderer*)g);
g->set_line_width(0);
g->set_line_dash(ezgl::line_dash::none);
}
//Collect all the drawing locations associated with the timing edge between start and end
-static void draw_routed_timing_edge_connection(tatum::NodeId src_tnode, tatum::NodeId sink_tnode, ezgl::color color, ezgl::renderer* g) {
+static void draw_routed_timing_edge_connection(tatum::NodeId src_tnode,
+ tatum::NodeId sink_tnode,
+ ezgl::color color,
+ ezgl::renderer* g) {
auto& atom_ctx = g_vpr_ctx.atom();
auto& cluster_ctx = g_vpr_ctx.clustering();
auto& timing_ctx = g_vpr_ctx.timing();
@@ -3467,10 +3658,12 @@ static void draw_routed_timing_edge_connection(tatum::NodeId src_tnode, tatum::N
ClusterBlockId clb_src_block = atom_ctx.lookup.atom_clb(atom_src_block);
VTR_ASSERT(clb_src_block != ClusterBlockId::INVALID());
- ClusterBlockId clb_sink_block = atom_ctx.lookup.atom_clb(atom_sink_block);
+ ClusterBlockId clb_sink_block = atom_ctx.lookup.atom_clb(
+ atom_sink_block);
VTR_ASSERT(clb_sink_block != ClusterBlockId::INVALID());
- const t_pb_graph_pin* sink_gpin = atom_ctx.lookup.atom_pin_pb_graph_pin(atom_sink_pin);
+ const t_pb_graph_pin* sink_gpin = atom_ctx.lookup.atom_pin_pb_graph_pin(
+ atom_sink_pin);
VTR_ASSERT(sink_gpin);
int sink_pb_route_id = sink_gpin->pin_count_in_cluster;
@@ -3478,13 +3671,18 @@ static void draw_routed_timing_edge_connection(tatum::NodeId src_tnode, tatum::N
int sink_block_pin_index = -1;
int sink_net_pin_index = -1;
- std::tie(net_id, sink_block_pin_index, sink_net_pin_index) = find_pb_route_clb_input_net_pin(clb_sink_block, sink_pb_route_id);
- if (net_id != ClusterNetId::INVALID() && sink_block_pin_index != -1 && sink_net_pin_index != -1) {
+ std::tie(net_id, sink_block_pin_index, sink_net_pin_index) = find_pb_route_clb_input_net_pin(clb_sink_block,
+ sink_pb_route_id);
+ if (net_id != ClusterNetId::INVALID() && sink_block_pin_index != -1
+ && sink_net_pin_index != -1) {
//Connection leaves the CLB
//Now that we have the CLB source and sink pins, we need to grab all the points on the routing connecting the pins
- VTR_ASSERT(cluster_ctx.clb_nlist.net_driver_block(net_id) == clb_src_block);
+ VTR_ASSERT(
+ cluster_ctx.clb_nlist.net_driver_block(net_id)
+ == clb_src_block);
- std::vector routed_rr_nodes = trace_routed_connection_rr_nodes(net_id, 0, sink_net_pin_index);
+ std::vector routed_rr_nodes = trace_routed_connection_rr_nodes(
+ net_id, 0, sink_net_pin_index);
//Mark all the nodes highlighted
t_draw_state* draw_state = get_draw_state_vars();
@@ -3492,7 +3690,8 @@ static void draw_routed_timing_edge_connection(tatum::NodeId src_tnode, tatum::N
draw_state->draw_rr_node[inode].color = color;
}
- draw_partial_route((std::vector)routed_rr_nodes, (ezgl::renderer*)g);
+ draw_partial_route((std::vector)routed_rr_nodes,
+ (ezgl::renderer*)g);
} else {
//Connection entirely within the CLB, we don't draw the internal routing so treat it as a fly-line
VTR_ASSERT(clb_src_block == clb_sink_block);
@@ -3503,7 +3702,10 @@ static void draw_routed_timing_edge_connection(tatum::NodeId src_tnode, tatum::N
}
//Returns the set of rr nodes which connect driver to sink
-static std::vector trace_routed_connection_rr_nodes(const ClusterNetId net_id, const int driver_pin, const int sink_pin) {
+static std::vector trace_routed_connection_rr_nodes(
+ const ClusterNetId net_id,
+ const int driver_pin,
+ const int sink_pin) {
auto& route_ctx = g_vpr_ctx.routing();
bool allocated_route_tree_structs = alloc_route_tree_timing_structs(true); //Needed for traceback_to_route_tree
@@ -3511,14 +3713,18 @@ static std::vector trace_routed_connection_rr_nodes(const ClusterNetId net_
//Conver the traceback into an easily search-able
t_rt_node* rt_root = traceback_to_route_tree(net_id);
- VTR_ASSERT(rt_root && rt_root->inode == route_ctx.net_rr_terminals[net_id][driver_pin]);
+ VTR_ASSERT(
+ rt_root
+ && rt_root->inode
+ == route_ctx.net_rr_terminals[net_id][driver_pin]);
int sink_rr_node = route_ctx.net_rr_terminals[net_id][sink_pin];
std::vector rr_nodes_on_path;
//Collect the rr nodes
- trace_routed_connection_rr_nodes_recurr(rt_root, sink_rr_node, rr_nodes_on_path);
+ trace_routed_connection_rr_nodes_recurr(rt_root, sink_rr_node,
+ rr_nodes_on_path);
//Traced from sink to source, but we want to draw from source to sink
std::reverse(rr_nodes_on_path.begin(), rr_nodes_on_path.end());
@@ -3534,7 +3740,9 @@ static std::vector trace_routed_connection_rr_nodes(const ClusterNetId net_
//Helper function for trace_routed_connection_rr_nodes
//Adds the rr nodes linking rt_node to sink_rr_node to rr_nodes_on_path
//Returns true if rt_node is on the path
-bool trace_routed_connection_rr_nodes_recurr(const t_rt_node* rt_node, int sink_rr_node, std::vector& rr_nodes_on_path) {
+bool trace_routed_connection_rr_nodes_recurr(const t_rt_node* rt_node,
+ int sink_rr_node,
+ std::vector& rr_nodes_on_path) {
//DFS from the current rt_node to the sink_rr_node, when the sink is found trace back the used rr nodes
if (rt_node->inode == sink_rr_node) {
@@ -3546,7 +3754,8 @@ bool trace_routed_connection_rr_nodes_recurr(const t_rt_node* rt_node, int sink_
t_rt_node* child_rt_node = edge->child;
VTR_ASSERT(child_rt_node);
- bool on_path_to_sink = trace_routed_connection_rr_nodes_recurr(child_rt_node, sink_rr_node, rr_nodes_on_path);
+ bool on_path_to_sink = trace_routed_connection_rr_nodes_recurr(
+ child_rt_node, sink_rr_node, rr_nodes_on_path);
if (on_path_to_sink) {
rr_nodes_on_path.push_back(rt_node->inode);
@@ -3560,7 +3769,8 @@ bool trace_routed_connection_rr_nodes_recurr(const t_rt_node* rt_node, int sink_
//Find the edge between two rr nodes
static t_edge_size find_edge(int prev_inode, int inode) {
auto& device_ctx = g_vpr_ctx.device();
- for (t_edge_size iedge = 0; iedge < device_ctx.rr_nodes[prev_inode].num_edges(); ++iedge) {
+ for (t_edge_size iedge = 0;
+ iedge < device_ctx.rr_nodes[prev_inode].num_edges(); ++iedge) {
if (device_ctx.rr_nodes[prev_inode].edge_sink_node(iedge) == inode) {
return iedge;
}
@@ -3573,7 +3783,8 @@ ezgl::color to_ezgl_color(vtr::Color color) {
return ezgl::color(color.r * 255, color.g * 255, color.b * 255);
}
-static void draw_color_map_legend(const vtr::ColorMap& cmap, ezgl::renderer* g) {
+static void draw_color_map_legend(const vtr::ColorMap& cmap,
+ ezgl::renderer* g) {
constexpr float LEGEND_WIDTH_FAC = 0.075;
constexpr float LEGEND_VERT_OFFSET_FAC = 0.05;
constexpr float TEXT_OFFSET = 10;
@@ -3581,13 +3792,18 @@ static void draw_color_map_legend(const vtr::ColorMap& cmap, ezgl::renderer* g)
g->set_coordinate_system(ezgl::SCREEN);
- float screen_width = application.get_canvas(application.get_main_canvas_id())->width();
- float screen_height = application.get_canvas(application.get_main_canvas_id())->height();
+ float screen_width = application.get_canvas(
+ application.get_main_canvas_id())
+ ->width();
+ float screen_height = application.get_canvas(
+ application.get_main_canvas_id())
+ ->height();
float vert_offset = screen_height * LEGEND_VERT_OFFSET_FAC;
float legend_width = std::min(LEGEND_WIDTH_FAC * screen_width, 100);
// In SCREEN coordinate: bottom_left is (0,0), right_top is (screen_width, screen_height)
- ezgl::rectangle legend({0, vert_offset}, {legend_width, screen_height - vert_offset});
+ ezgl::rectangle legend({0, vert_offset},
+ {legend_width, screen_height - vert_offset});
float range = cmap.max() - cmap.min();
float height_incr = legend.height() / float(NUM_COLOR_POINTS);
@@ -3596,14 +3812,14 @@ static void draw_color_map_legend(const vtr::ColorMap& cmap, ezgl::renderer* g)
ezgl::color color = to_ezgl_color(cmap.color(val));
g->set_color(color);
- g->fill_rectangle({legend.left(), legend.top() - i * height_incr},
- {legend.right(), legend.top() - (i + 1) * height_incr});
+ g->fill_rectangle({legend.left(), legend.top() - i * height_incr}, {legend.right(), legend.top() - (i + 1) * height_incr});
}
//Min mark
g->set_color(blk_SKYBLUE); // set to skyblue so its easier to see
std::string str = vtr::string_fmt("%.3g", cmap.min());
- g->draw_text({legend.center_x(), legend.top() - TEXT_OFFSET}, str.c_str());
+ g->draw_text({legend.center_x(), legend.top() - TEXT_OFFSET},
+ str.c_str());
//Mid marker
g->set_color(ezgl::BLACK);
@@ -3613,7 +3829,8 @@ static void draw_color_map_legend(const vtr::ColorMap& cmap, ezgl::renderer* g)
//Max marker
g->set_color(ezgl::BLACK);
str = vtr::string_fmt("%.3g", cmap.max());
- g->draw_text({legend.center_x(), legend.bottom() + TEXT_OFFSET}, str.c_str());
+ g->draw_text({legend.center_x(), legend.bottom() + TEXT_OFFSET},
+ str.c_str());
g->set_color(ezgl::BLACK);
g->draw_rectangle(legend);
@@ -3642,7 +3859,8 @@ ezgl::color lighten_color(ezgl::color color, float amount) {
static void draw_block_pin_util() {
t_draw_state* draw_state = get_draw_state_vars();
- if (draw_state->show_blk_pin_util == DRAW_NO_BLOCK_PIN_UTIL) return;
+ if (draw_state->show_blk_pin_util == DRAW_NO_BLOCK_PIN_UTIL)
+ return;
auto& device_ctx = g_vpr_ctx.device();
auto& cluster_ctx = g_vpr_ctx.clustering();
@@ -3664,17 +3882,24 @@ static void draw_block_pin_util() {
auto type = physical_tile_type(blk);
if (draw_state->show_blk_pin_util == DRAW_BLOCK_PIN_UTIL_TOTAL) {
- pin_util[blk] = cluster_ctx.clb_nlist.block_pins(blk).size() / float(total_input_pins[type] + total_output_pins[type]);
- } else if (draw_state->show_blk_pin_util == DRAW_BLOCK_PIN_UTIL_INPUTS) {
- pin_util[blk] = (cluster_ctx.clb_nlist.block_input_pins(blk).size() + cluster_ctx.clb_nlist.block_clock_pins(blk).size()) / float(total_input_pins[type]);
- } else if (draw_state->show_blk_pin_util == DRAW_BLOCK_PIN_UTIL_OUTPUTS) {
- pin_util[blk] = (cluster_ctx.clb_nlist.block_output_pins(blk).size()) / float(total_output_pins[type]);
+ pin_util[blk] = cluster_ctx.clb_nlist.block_pins(blk).size()
+ / float(total_input_pins[type] + total_output_pins[type]);
+ } else if (draw_state->show_blk_pin_util
+ == DRAW_BLOCK_PIN_UTIL_INPUTS) {
+ pin_util[blk] = (cluster_ctx.clb_nlist.block_input_pins(blk).size()
+ + cluster_ctx.clb_nlist.block_clock_pins(blk).size())
+ / float(total_input_pins[type]);
+ } else if (draw_state->show_blk_pin_util
+ == DRAW_BLOCK_PIN_UTIL_OUTPUTS) {
+ pin_util[blk] = (cluster_ctx.clb_nlist.block_output_pins(blk).size())
+ / float(total_output_pins[type]);
} else {
VTR_ASSERT(false);
}
}
- std::unique_ptr cmap = std::make_unique(0., 1.);
+ std::unique_ptr cmap = std::make_unique(
+ 0., 1.);
for (auto blk : blks) {
ezgl::color color = to_ezgl_color(cmap->color(pin_util[blk]));
@@ -3722,8 +3947,10 @@ static void draw_routing_util(ezgl::renderer* g) {
float max_util = -std::numeric_limits::infinity();
for (size_t x = 0; x < device_ctx.grid.width() - 1; ++x) {
for (size_t y = 0; y < device_ctx.grid.height() - 1; ++y) {
- max_util = std::max(max_util, routing_util(chanx_usage[x][y], chanx_avail[x][y]));
- max_util = std::max(max_util, routing_util(chany_usage[x][y], chany_avail[x][y]));
+ max_util = std::max(max_util,
+ routing_util(chanx_usage[x][y], chanx_avail[x][y]));
+ max_util = std::max(max_util,
+ routing_util(chany_usage[x][y], chany_avail[x][y]));
}
}
max_util = std::max(max_util, 1.f);
@@ -3755,18 +3982,30 @@ static void draw_routing_util(ezgl::renderer* g) {
if (draw_state->clip_routing_util) {
chanx_util = std::min(chanx_util, 1.f);
}
- ezgl::color chanx_color = to_ezgl_color(cmap->color(chanx_util));
+ ezgl::color chanx_color = to_ezgl_color(
+ cmap->color(chanx_util));
chanx_color.alpha *= ALPHA;
g->set_color(chanx_color);
- ezgl::rectangle bb({draw_coords->tile_x[x], draw_coords->tile_y[y] + 1 * tile_height},
- {draw_coords->tile_x[x] + 1 * tile_width, draw_coords->tile_y[y + 1]});
+ ezgl::rectangle bb(
+ {draw_coords->tile_x[x], draw_coords->tile_y[y]
+ + 1 * tile_height},
+ {draw_coords->tile_x[x] + 1 * tile_width,
+ draw_coords->tile_y[y + 1]});
g->fill_rectangle(bb);
g->set_color(ezgl::BLACK);
- if (draw_state->show_routing_util == DRAW_ROUTING_UTIL_WITH_VALUE) {
- g->draw_text(bb.center(), vtr::string_fmt("%.2f", chanx_util).c_str(), bb.width(), bb.height());
- } else if (draw_state->show_routing_util == DRAW_ROUTING_UTIL_WITH_FORMULA) {
- g->draw_text(bb.center(), vtr::string_fmt("%.2f = %.0f / %.0f", chanx_util, chanx_usage[x][y], chanx_avail[x][y]).c_str(), bb.width(), bb.height());
+ if (draw_state->show_routing_util
+ == DRAW_ROUTING_UTIL_WITH_VALUE) {
+ g->draw_text(bb.center(),
+ vtr::string_fmt("%.2f", chanx_util).c_str(),
+ bb.width(), bb.height());
+ } else if (draw_state->show_routing_util
+ == DRAW_ROUTING_UTIL_WITH_FORMULA) {
+ g->draw_text(bb.center(),
+ vtr::string_fmt("%.2f = %.0f / %.0f", chanx_util,
+ chanx_usage[x][y], chanx_avail[x][y])
+ .c_str(),
+ bb.width(), bb.height());
}
sb_util += chanx_util;
@@ -3778,18 +4017,29 @@ static void draw_routing_util(ezgl::renderer* g) {
if (draw_state->clip_routing_util) {
chany_util = std::min(chany_util, 1.f);
}
- ezgl::color chany_color = to_ezgl_color(cmap->color(chany_util));
+ ezgl::color chany_color = to_ezgl_color(
+ cmap->color(chany_util));
chany_color.alpha *= ALPHA;
g->set_color(chany_color);
- ezgl::rectangle bb({draw_coords->tile_x[x] + 1 * tile_width, draw_coords->tile_y[y]},
- {draw_coords->tile_x[x + 1], draw_coords->tile_y[y] + 1 * tile_height});
+ ezgl::rectangle bb({draw_coords->tile_x[x] + 1 * tile_width,
+ draw_coords->tile_y[y]},
+ {draw_coords->tile_x[x + 1], draw_coords->tile_y[y]
+ + 1 * tile_height});
g->fill_rectangle(bb);
g->set_color(ezgl::BLACK);
- if (draw_state->show_routing_util == DRAW_ROUTING_UTIL_WITH_VALUE) {
- g->draw_text(bb.center(), vtr::string_fmt("%.2f", chany_util).c_str(), bb.width(), bb.height());
- } else if (draw_state->show_routing_util == DRAW_ROUTING_UTIL_WITH_FORMULA) {
- g->draw_text(bb.center(), vtr::string_fmt("%.2f = %.0f / %.0f", chany_util, chany_usage[x][y], chany_avail[x][y]).c_str(), bb.width(), bb.height());
+ if (draw_state->show_routing_util
+ == DRAW_ROUTING_UTIL_WITH_VALUE) {
+ g->draw_text(bb.center(),
+ vtr::string_fmt("%.2f", chany_util).c_str(),
+ bb.width(), bb.height());
+ } else if (draw_state->show_routing_util
+ == DRAW_ROUTING_UTIL_WITH_FORMULA) {
+ g->draw_text(bb.center(),
+ vtr::string_fmt("%.2f = %.0f / %.0f", chany_util,
+ chany_usage[x][y], chany_avail[x][y])
+ .c_str(),
+ bb.width(), bb.height());
}
sb_util += chany_util;
@@ -3798,9 +4048,11 @@ static void draw_routing_util(ezgl::renderer* g) {
//For now SB util is just average of surrounding channels
//TODO: calculate actual usage
- sb_util += routing_util(chanx_usage[x + 1][y], chanx_avail[x + 1][y]);
+ sb_util += routing_util(chanx_usage[x + 1][y],
+ chanx_avail[x + 1][y]);
chan_count += 1;
- sb_util += routing_util(chany_usage[x][y + 1], chany_avail[x][y + 1]);
+ sb_util += routing_util(chany_usage[x][y + 1],
+ chany_avail[x][y + 1]);
chan_count += 1;
VTR_ASSERT(chan_count > 0);
@@ -3811,22 +4063,31 @@ static void draw_routing_util(ezgl::renderer* g) {
ezgl::color sb_color = to_ezgl_color(cmap->color(sb_util));
sb_color.alpha *= ALPHA;
g->set_color(sb_color);
- ezgl::rectangle bb({draw_coords->tile_x[x] + 1 * tile_width, draw_coords->tile_y[y] + 1 * tile_height},
- {draw_coords->tile_x[x + 1], draw_coords->tile_y[y + 1]});
+ ezgl::rectangle bb(
+ {draw_coords->tile_x[x] + 1 * tile_width,
+ draw_coords->tile_y[y] + 1 * tile_height},
+ {draw_coords->tile_x[x + 1], draw_coords->tile_y[y + 1]});
g->fill_rectangle(bb);
//Draw over blocks
- if (draw_state->show_routing_util == DRAW_ROUTING_UTIL_OVER_BLOCKS) {
- if (x < device_ctx.grid.width() - 2 && y < device_ctx.grid.height() - 2) {
- ezgl::rectangle bb2({draw_coords->tile_x[x + 1], draw_coords->tile_y[y + 1]},
- {draw_coords->tile_x[x + 1] + 1 * tile_width, draw_coords->tile_y[y + 1] + 1 * tile_width});
+ if (draw_state->show_routing_util
+ == DRAW_ROUTING_UTIL_OVER_BLOCKS) {
+ if (x < device_ctx.grid.width() - 2
+ && y < device_ctx.grid.height() - 2) {
+ ezgl::rectangle bb2({draw_coords->tile_x[x + 1],
+ draw_coords->tile_y[y + 1]},
+ {draw_coords->tile_x[x + 1] + 1 * tile_width,
+ draw_coords->tile_y[y + 1] + 1 * tile_width});
g->fill_rectangle(bb2);
}
}
g->set_color(ezgl::BLACK);
if (draw_state->show_routing_util == DRAW_ROUTING_UTIL_WITH_VALUE
- || draw_state->show_routing_util == DRAW_ROUTING_UTIL_WITH_FORMULA) {
- g->draw_text(bb.center(), vtr::string_fmt("%.2f", sb_util).c_str(), bb.width(), bb.height());
+ || draw_state->show_routing_util
+ == DRAW_ROUTING_UTIL_WITH_FORMULA) {
+ g->draw_text(bb.center(),
+ vtr::string_fmt("%.2f", sb_util).c_str(), bb.width(),
+ bb.height());
}
}
}
@@ -3834,12 +4095,19 @@ static void draw_routing_util(ezgl::renderer* g) {
draw_state->color_map = std::move(cmap);
}
-static float get_router_expansion_cost(const t_rr_node_route_inf node_inf, e_draw_router_expansion_cost draw_router_expansion_cost) {
- if (draw_router_expansion_cost == DRAW_ROUTER_EXPANSION_COST_TOTAL || draw_router_expansion_cost == DRAW_ROUTER_EXPANSION_COST_TOTAL_WITH_EDGES) {
+static float get_router_expansion_cost(const t_rr_node_route_inf node_inf,
+ e_draw_router_expansion_cost draw_router_expansion_cost) {
+ if (draw_router_expansion_cost == DRAW_ROUTER_EXPANSION_COST_TOTAL
+ || draw_router_expansion_cost
+ == DRAW_ROUTER_EXPANSION_COST_TOTAL_WITH_EDGES) {
return node_inf.path_cost;
- } else if (draw_router_expansion_cost == DRAW_ROUTER_EXPANSION_COST_KNOWN || draw_router_expansion_cost == DRAW_ROUTER_EXPANSION_COST_KNOWN_WITH_EDGES) {
+ } else if (draw_router_expansion_cost == DRAW_ROUTER_EXPANSION_COST_KNOWN
+ || draw_router_expansion_cost
+ == DRAW_ROUTER_EXPANSION_COST_KNOWN_WITH_EDGES) {
return node_inf.backward_path_cost;
- } else if (draw_router_expansion_cost == DRAW_ROUTER_EXPANSION_COST_EXPECTED || draw_router_expansion_cost == DRAW_ROUTER_EXPANSION_COST_EXPECTED_WITH_EDGES) {
+ } else if (draw_router_expansion_cost == DRAW_ROUTER_EXPANSION_COST_EXPECTED
+ || draw_router_expansion_cost
+ == DRAW_ROUTER_EXPANSION_COST_EXPECTED_WITH_EDGES) {
return node_inf.path_cost - node_inf.backward_path_cost;
}
@@ -3848,7 +4116,8 @@ static float get_router_expansion_cost(const t_rr_node_route_inf node_inf, e_dra
static void draw_router_expansion_costs(ezgl::renderer* g) {
t_draw_state* draw_state = get_draw_state_vars();
- if (draw_state->show_router_expansion_cost == DRAW_NO_ROUTER_EXPANSION_COST) {
+ if (draw_state->show_router_expansion_cost
+ == DRAW_NO_ROUTER_EXPANSION_COST) {
return;
}
@@ -3858,7 +4127,9 @@ static void draw_router_expansion_costs(ezgl::renderer* g) {
std::vector rr_costs(device_ctx.rr_nodes.size());
for (size_t inode = 0; inode < device_ctx.rr_nodes.size(); ++inode) {
- float cost = get_router_expansion_cost(routing_ctx.rr_node_route_inf[inode], draw_state->show_router_expansion_cost);
+ float cost = get_router_expansion_cost(
+ routing_ctx.rr_node_route_inf[inode],
+ draw_state->show_router_expansion_cost);
rr_costs[inode] = cost;
}
@@ -3874,12 +4145,23 @@ static void draw_router_expansion_costs(ezgl::renderer* g) {
if (!all_nan) {
draw_rr_costs(g, rr_costs, false);
}
- if (draw_state->show_router_expansion_cost == DRAW_ROUTER_EXPANSION_COST_TOTAL || draw_state->show_router_expansion_cost == DRAW_ROUTER_EXPANSION_COST_TOTAL_WITH_EDGES) {
- application.update_message("Routing Expected Total Cost (known + estimate)");
- } else if (draw_state->show_router_expansion_cost == DRAW_ROUTER_EXPANSION_COST_KNOWN || draw_state->show_router_expansion_cost == DRAW_ROUTER_EXPANSION_COST_KNOWN_WITH_EDGES) {
+ if (draw_state->show_router_expansion_cost
+ == DRAW_ROUTER_EXPANSION_COST_TOTAL
+ || draw_state->show_router_expansion_cost
+ == DRAW_ROUTER_EXPANSION_COST_TOTAL_WITH_EDGES) {
+ application.update_message(
+ "Routing Expected Total Cost (known + estimate)");
+ } else if (draw_state->show_router_expansion_cost
+ == DRAW_ROUTER_EXPANSION_COST_KNOWN
+ || draw_state->show_router_expansion_cost
+ == DRAW_ROUTER_EXPANSION_COST_KNOWN_WITH_EDGES) {
application.update_message("Routing Known Cost (from source to node)");
- } else if (draw_state->show_router_expansion_cost == DRAW_ROUTER_EXPANSION_COST_EXPECTED || draw_state->show_router_expansion_cost == DRAW_ROUTER_EXPANSION_COST_EXPECTED_WITH_EDGES) {
- application.update_message("Routing Expected Cost (from node to target)");
+ } else if (draw_state->show_router_expansion_cost
+ == DRAW_ROUTER_EXPANSION_COST_EXPECTED
+ || draw_state->show_router_expansion_cost
+ == DRAW_ROUTER_EXPANSION_COST_EXPECTED_WITH_EDGES) {
+ application.update_message(
+ "Routing Expected Cost (from node to target)");
} else {
VPR_THROW(VPR_ERROR_DRAW, "Invalid Router RR cost drawing type");
}
@@ -3980,7 +4262,8 @@ static void draw_placement_macros(ezgl::renderer* g) {
int x_root = OPEN;
int y_root = OPEN;
- for (size_t imember = 0; imember < pl_macro->members.size(); ++imember) {
+ for (size_t imember = 0; imember < pl_macro->members.size();
+ ++imember) {
const t_pl_macro_member* member = &pl_macro->members[imember];
ClusterBlockId blk = member->blk_index;
@@ -4005,12 +4288,14 @@ static void draw_placement_macros(ezgl::renderer* g) {
double draw_yhigh = draw_coords->tile_y[yhigh];
g->set_color(blk_RED);
- g->draw_rectangle({draw_xlow, draw_ylow}, {draw_xhigh, draw_yhigh});
+ g->draw_rectangle({draw_xlow, draw_ylow},
+ {draw_xhigh, draw_yhigh});
ezgl::color fill = blk_SKYBLUE;
fill.alpha *= 0.3;
g->set_color(fill);
- g->fill_rectangle({draw_xlow, draw_ylow}, {draw_xhigh, draw_yhigh});
+ g->fill_rectangle({draw_xlow, draw_ylow},
+ {draw_xhigh, draw_yhigh});
}
}
@@ -4041,7 +4326,8 @@ static void highlight_blocks(double x, double y) {
for (int k = 0; k < grid_tile->type->capacity; ++k) {
clb_index = place_ctx.grid_blocks[i][j].blocks[k];
if (clb_index != EMPTY_BLOCK_ID) {
- clb_bbox = draw_coords->get_absolute_clb_bbox(clb_index, cluster_ctx.clb_nlist.block_type(clb_index));
+ clb_bbox = draw_coords->get_absolute_clb_bbox(clb_index,
+ cluster_ctx.clb_nlist.block_type(clb_index));
if (clb_bbox.contains({x, y})) {
break;
} else {
@@ -4068,20 +4354,34 @@ static void highlight_blocks(double x, double y) {
// note: this will clear the selected sub-block if show_blk_internal is 0,
// or if it doesn't find anything
ezgl::point2d point_in_clb = ezgl::point2d(x, y) - clb_bbox.bottom_left();
- highlight_sub_block(point_in_clb, clb_index, cluster_ctx.clb_nlist.block_pb(clb_index));
+ highlight_sub_block(point_in_clb, clb_index,
+ cluster_ctx.clb_nlist.block_pb(clb_index));
if (get_selected_sub_block_info().has_selection()) {
t_pb* selected_subblock = get_selected_sub_block_info().get_selected_pb();
sprintf(msg, "sub-block %s (a \"%s\") selected",
- selected_subblock->name, selected_subblock->pb_graph_node->pb_type->name);
+ selected_subblock->name,
+ selected_subblock->pb_graph_node->pb_type->name);
} else {
/* Highlight block and fan-in/fan-outs. */
- draw_highlight_blocks_color(cluster_ctx.clb_nlist.block_type(clb_index), clb_index);
- sprintf(msg, "Block #%zu (%s) at (%d, %d) selected.", size_t(clb_index), cluster_ctx.clb_nlist.block_name(clb_index).c_str(), place_ctx.block_locs[clb_index].loc.x, place_ctx.block_locs[clb_index].loc.y);
+ draw_highlight_blocks_color(cluster_ctx.clb_nlist.block_type(clb_index),
+ clb_index);
+ sprintf(msg, "Block #%zu (%s) at (%d, %d) selected.", size_t(clb_index),
+ cluster_ctx.clb_nlist.block_name(clb_index).c_str(),
+ place_ctx.block_locs[clb_index].loc.x,
+ place_ctx.block_locs[clb_index].loc.y);
}
- application.update_message(msg);
+ //If manual moves is activated, then user can select block from the grid.
+ t_draw_state* draw_state = get_draw_state_vars();
+ if (draw_state->manual_moves_state.manual_move_enabled) {
+ draw_state->manual_moves_state.user_highlighted_block = true;
+ if (!draw_state->manual_moves_state.manual_move_window_is_open) {
+ draw_manual_moves_window(std::to_string(size_t(clb_index)));
+ }
+ }
+ application.update_message(msg);
application.refresh_drawing();
}
void set_net_alpha_value(GtkWidget* widget, gint /*response_id*/, gpointer /*data*/) {
@@ -4106,11 +4406,13 @@ float get_net_alpha() {
static void setup_default_ezgl_callbacks(ezgl::application* app) {
// Connect press_proceed function to the Proceed button
GObject* proceed_button = app->get_object("ProceedButton");
- g_signal_connect(proceed_button, "clicked", G_CALLBACK(ezgl::press_proceed), app);
+ g_signal_connect(proceed_button, "clicked", G_CALLBACK(ezgl::press_proceed),
+ app);
// Connect press_zoom_fit function to the Zoom-fit button
GObject* zoom_fit_button = app->get_object("ZoomFitButton");
- g_signal_connect(zoom_fit_button, "clicked", G_CALLBACK(ezgl::press_zoom_fit), app);
+ g_signal_connect(zoom_fit_button, "clicked",
+ G_CALLBACK(ezgl::press_zoom_fit), app);
// Connect Pause button
GObject* pause_button = app->get_object("PauseButton");
@@ -4118,7 +4420,8 @@ static void setup_default_ezgl_callbacks(ezgl::application* app) {
// Connect Block Outline checkbox
GObject* block_outline = app->get_object("blockOutline");
- g_signal_connect(block_outline, "toggled", G_CALLBACK(set_block_outline), app);
+ g_signal_connect(block_outline, "toggled", G_CALLBACK(set_block_outline),
+ app);
// Connect Block Text checkbox
GObject* block_text = app->get_object("blockText");
@@ -4126,7 +4429,8 @@ static void setup_default_ezgl_callbacks(ezgl::application* app) {
// Connect Clip Routing Util checkbox
GObject* clip_routing = app->get_object("clipRoutingUtil");
- g_signal_connect(clip_routing, "toggled", G_CALLBACK(clip_routing_util), app);
+ g_signal_connect(clip_routing, "toggled", G_CALLBACK(clip_routing_util),
+ app);
// Connect Debug Button
GObject* debugger = app->get_object("debugButton");
@@ -4179,14 +4483,15 @@ static void clip_routing_util(GtkWidget* widget, gint /*response_id*/, gpointer
// Callback function for NetMax Fanout checkbox
void net_max_fanout(GtkWidget* /*widget*/, gint /*response_id*/, gpointer /*data*/) {
- /* this is the callback function for runtime created net_max_fanout widget
+ /* this is the callback function for runtime created net_max_fanout widget
* which is written in button.cpp */
std::string button_name = "netMaxFanout";
auto max_fanout = find_button(button_name.c_str());
t_draw_state* draw_state = get_draw_state_vars();
//set draw_state->draw_net_max_fanout to its corresponding value in the ui
- int new_value = gtk_spin_button_get_value_as_int((GtkSpinButton*)max_fanout);
+ int new_value = gtk_spin_button_get_value_as_int(
+ (GtkSpinButton*)max_fanout);
draw_state->draw_net_max_fanout = new_value;
//redraw
@@ -4219,61 +4524,77 @@ static void run_graphics_commands(std::string commands) {
VTR_LOG("\n");
if (cmd[0] == "save_graphics") {
- VTR_ASSERT_MSG(cmd.size() == 2, "Expect filename after 'save_graphics'");
+ VTR_ASSERT_MSG(cmd.size() == 2,
+ "Expect filename after 'save_graphics'");
auto name_ext = vtr::split_ext(cmd[1]);
//Replace {i} with the sequence number
- std::string name = vtr::replace_all(name_ext[0], "{i}", std::to_string(draw_state->sequence_number));
+ std::string name = vtr::replace_all(name_ext[0], "{i}",
+ std::to_string(draw_state->sequence_number));
save_graphics(/*extension=*/name_ext[1], /*filename=*/name);
VTR_LOG("Saving to %s\n", std::string(name + name_ext[1]).c_str());
} else if (cmd[0] == "set_macros") {
- VTR_ASSERT_MSG(cmd.size() == 2, "Expect net draw state after 'set_macro'");
+ VTR_ASSERT_MSG(cmd.size() == 2,
+ "Expect net draw state after 'set_macro'");
draw_state->show_placement_macros = (e_draw_placement_macros)vtr::atoi(cmd[1]);
VTR_LOG("%d\n", (int)draw_state->show_placement_macros);
} else if (cmd[0] == "set_nets") {
- VTR_ASSERT_MSG(cmd.size() == 2, "Expect net draw state after 'set_nets'");
+ VTR_ASSERT_MSG(cmd.size() == 2,
+ "Expect net draw state after 'set_nets'");
draw_state->show_nets = (e_draw_nets)vtr::atoi(cmd[1]);
VTR_LOG("%d\n", (int)draw_state->show_nets);
} else if (cmd[0] == "set_cpd") {
- VTR_ASSERT_MSG(cmd.size() == 2, "Expect cpd draw state after 'set_cpd'");
+ VTR_ASSERT_MSG(cmd.size() == 2,
+ "Expect cpd draw state after 'set_cpd'");
draw_state->show_crit_path = (e_draw_crit_path)vtr::atoi(cmd[1]);
VTR_LOG("%d\n", (int)draw_state->show_crit_path);
} else if (cmd[0] == "set_routing_util") {
- VTR_ASSERT_MSG(cmd.size() == 2, "Expect routing util draw state after 'set_routing_util'");
- draw_state->show_routing_util = (e_draw_routing_util)vtr::atoi(cmd[1]);
+ VTR_ASSERT_MSG(cmd.size() == 2,
+ "Expect routing util draw state after 'set_routing_util'");
+ draw_state->show_routing_util = (e_draw_routing_util)vtr::atoi(
+ cmd[1]);
VTR_LOG("%d\n", (int)draw_state->show_routing_util);
} else if (cmd[0] == "set_clip_routing_util") {
- VTR_ASSERT_MSG(cmd.size() == 2, "Expect routing util draw state after 'set_routing_util'");
+ VTR_ASSERT_MSG(cmd.size() == 2,
+ "Expect routing util draw state after 'set_routing_util'");
draw_state->clip_routing_util = (bool)vtr::atoi(cmd[1]);
VTR_LOG("%d\n", (int)draw_state->clip_routing_util);
} else if (cmd[0] == "set_congestion") {
- VTR_ASSERT_MSG(cmd.size() == 2, "Expect congestion draw state after 'set_congestion'");
+ VTR_ASSERT_MSG(cmd.size() == 2,
+ "Expect congestion draw state after 'set_congestion'");
draw_state->show_congestion = (e_draw_congestion)vtr::atoi(cmd[1]);
VTR_LOG("%d\n", (int)draw_state->show_congestion);
} else if (cmd[0] == "set_draw_block_outlines") {
- VTR_ASSERT_MSG(cmd.size() == 2, "Expect draw block outlines state after 'set_draw_block_outlines'");
+ VTR_ASSERT_MSG(cmd.size() == 2,
+ "Expect draw block outlines state after 'set_draw_block_outlines'");
draw_state->draw_block_outlines = vtr::atoi(cmd[1]);
VTR_LOG("%d\n", (int)draw_state->draw_block_outlines);
} else if (cmd[0] == "set_draw_block_text") {
- VTR_ASSERT_MSG(cmd.size() == 2, "Expect draw block text state after 'set_draw_block_text'");
+ VTR_ASSERT_MSG(cmd.size() == 2,
+ "Expect draw block text state after 'set_draw_block_text'");
draw_state->draw_block_text = vtr::atoi(cmd[1]);
VTR_LOG("%d\n", (int)draw_state->draw_block_text);
} else if (cmd[0] == "set_draw_block_internals") {
- VTR_ASSERT_MSG(cmd.size() == 2, "Expect draw state after 'set_draw_block_internals'");
+ VTR_ASSERT_MSG(cmd.size() == 2,
+ "Expect draw state after 'set_draw_block_internals'");
draw_state->show_blk_internal = vtr::atoi(cmd[1]);
VTR_LOG("%d\n", (int)draw_state->show_blk_internal);
} else if (cmd[0] == "set_draw_net_max_fanout") {
- VTR_ASSERT_MSG(cmd.size() == 2, "Expect maximum fanout after 'set_draw_net_max_fanout'");
+ VTR_ASSERT_MSG(cmd.size() == 2,
+ "Expect maximum fanout after 'set_draw_net_max_fanout'");
draw_state->draw_net_max_fanout = vtr::atoi(cmd[1]);
VTR_LOG("%d\n", (int)draw_state->draw_net_max_fanout);
} else if (cmd[0] == "exit") {
VTR_ASSERT_MSG(cmd.size() == 2, "Expect exit code after 'exit'");
exit(vtr::atoi(cmd[1]));
} else {
- VPR_ERROR(VPR_ERROR_DRAW, vtr::string_fmt("Unrecognized graphics command '%s'", cmd[0].c_str()).c_str());
+ VPR_ERROR(VPR_ERROR_DRAW,
+ vtr::string_fmt("Unrecognized graphics command '%s'",
+ cmd[0].c_str())
+ .c_str());
}
}
@@ -4287,19 +4608,25 @@ static void run_graphics_commands(std::string commands) {
* It highlights the old and new locations of the moved blocks *
* It also highlights the moved block input and output terminals *
* Currently, it is used in placer debugger when breakpoint is reached */
-void highlight_moved_block_and_its_terminals(const t_pl_blocks_to_be_moved& blocks_affected) {
+void highlight_moved_block_and_its_terminals(
+ const t_pl_blocks_to_be_moved& blocks_affected) {
auto& cluster_ctx = g_vpr_ctx.clustering();
//clear all selected blocks
deselect_all();
//highlight the input/output terminals of the moved block
- draw_highlight_blocks_color(cluster_ctx.clb_nlist.block_type(blocks_affected.moved_blocks[0].block_num), blocks_affected.moved_blocks[0].block_num);
+ draw_highlight_blocks_color(
+ cluster_ctx.clb_nlist.block_type(
+ blocks_affected.moved_blocks[0].block_num),
+ blocks_affected.moved_blocks[0].block_num);
//highlight the old and new locations of the moved block
clear_colored_locations();
- set_draw_loc_color(blocks_affected.moved_blocks[0].old_loc, OLD_BLK_LOC_COLOR);
- set_draw_loc_color(blocks_affected.moved_blocks[0].old_loc, NEW_BLK_LOC_COLOR);
+ set_draw_loc_color(blocks_affected.moved_blocks[0].old_loc,
+ OLD_BLK_LOC_COLOR);
+ set_draw_loc_color(blocks_affected.moved_blocks[0].old_loc,
+ NEW_BLK_LOC_COLOR);
}
// pass in an (x,y,subtile) location and the color in which it should be drawn.
@@ -4327,7 +4654,12 @@ bool highlight_loc_with_specific_color(int x, int y, ezgl::color& loc_color) {
curr_loc.y = y;
//search for the current location in the vector of colored locations
- auto it = std::find_if(draw_state->colored_locations.begin(), draw_state->colored_locations.end(), [&curr_loc](const std::pair& vec_element) { return (vec_element.first.x == curr_loc.x && vec_element.first.y == curr_loc.y); });
+ auto it = std::find_if(draw_state->colored_locations.begin(),
+ draw_state->colored_locations.end(),
+ [&curr_loc](const std::pair& vec_element) {
+ return (vec_element.first.x == curr_loc.x
+ && vec_element.first.y == curr_loc.y);
+ });
if (it != draw_state->colored_locations.end()) {
/* found a colored location at the spot I am drawing *
diff --git a/vpr/src/draw/draw.h b/vpr/src/draw/draw.h
index 8e3cacd9dd0..ebe90441955 100644
--- a/vpr/src/draw/draw.h
+++ b/vpr/src/draw/draw.h
@@ -14,6 +14,7 @@
# include "draw_color.h"
# include "search_bar.h"
# include "draw_debug.h"
+# include "manual_moves.h"
extern ezgl::application::settings settings;
extern ezgl::application application;
diff --git a/vpr/src/draw/draw_debug.h b/vpr/src/draw/draw_debug.h
index c50f93162f2..e02b360e726 100644
--- a/vpr/src/draw/draw_debug.h
+++ b/vpr/src/draw/draw_debug.h
@@ -1,4 +1,7 @@
/** This file contains all functions reagrding the graphics related to the setting of place and route breakpoints **/
+#ifndef DRAW_DEBUG_H
+#define DRAW_DEBUG_H
+
#ifndef NO_GRAPHICS
# include "breakpoint.h"
@@ -35,4 +38,6 @@ void invalid_breakpoint_entry_window(std::string error);
bool valid_expression(std::string exp);
void breakpoint_info_window(std::string bpDescription, BreakpointState draw_breakpoint_state, bool in_placer);
-#endif
+#endif /*NO_GRAPHICS*/
+
+#endif /*DRAW_DEBUG_H*/
diff --git a/vpr/src/draw/draw_types.h b/vpr/src/draw/draw_types.h
index b6e011c855d..52640d8e7d6 100644
--- a/vpr/src/draw/draw_types.h
+++ b/vpr/src/draw/draw_types.h
@@ -27,6 +27,7 @@
# include "vtr_color_map.h"
# include "vtr_vector.h"
# include "breakpoint.h"
+# include "manual_moves.h"
# include "ezgl/point.hpp"
# include "ezgl/rectangle.hpp"
@@ -196,6 +197,7 @@ struct t_draw_state {
int sequence_number = 0;
float net_alpha = 0.1;
float pres_fac = 1.;
+ ManualMovesState manual_moves_state;
std::vector list_of_breakpoints;
diff --git a/vpr/src/draw/manual_moves.cpp b/vpr/src/draw/manual_moves.cpp
new file mode 100644
index 00000000000..65b752fb56c
--- /dev/null
+++ b/vpr/src/draw/manual_moves.cpp
@@ -0,0 +1,315 @@
+/*
+ * @file manual_moves.cpp
+ * @author Paula Perdomo
+ * @date 2021-07-19
+ * @brief Contains the function definitions needed for manual moves feature.
+ *
+ * Includes the graphics/gtk function for manual moves. The Manual Move Generator class is defined manual_move_generator.h/cpp.
+ * The manual move feature allows the user to select a move by choosing the block to move, x position, y position, subtile position. If the placer accepts the move, the user can accept or reject the move with respect to the delta cost, delta timing and delta bounding box cost displayed on the UI. The manual move feature interacts with placement through the ManualMoveGenerator class in the manual_move_generator.cpp/h files and in the place.cpp file by checking if the manual move toggle button in the UI is active or not, and calls the function needed.
+ */
+
+#include "manual_moves.h"
+#include "globals.h"
+#include "draw.h"
+#include "buttons.h"
+
+#ifndef NO_GRAPHICS
+
+void draw_manual_moves_window(std::string block_id) {
+ t_draw_state* draw_state = get_draw_state_vars();
+
+ if (!draw_state->manual_moves_state.manual_move_window_is_open) {
+ draw_state->manual_moves_state.manual_move_window_is_open = true;
+
+ //Window settings-
+ draw_state->manual_moves_state.manual_move_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_position((GtkWindow*)draw_state->manual_moves_state.manual_move_window, GTK_WIN_POS_CENTER);
+ gtk_window_set_title((GtkWindow*)draw_state->manual_moves_state.manual_move_window, "Manual Moves Generator");
+ gtk_widget_set_name(draw_state->manual_moves_state.manual_move_window, "manual_move_window");
+
+ GtkWidget* grid = gtk_grid_new();
+ GtkWidget* block_entry = gtk_entry_new();
+
+ if (draw_state->manual_moves_state.user_highlighted_block) {
+ gtk_entry_set_text((GtkEntry*)block_entry, block_id.c_str());
+ draw_state->manual_moves_state.user_highlighted_block = false;
+ }
+
+ GtkWidget* x_position_entry = gtk_entry_new();
+ GtkWidget* y_position_entry = gtk_entry_new();
+ GtkWidget* subtile_position_entry = gtk_entry_new();
+ GtkWidget* block_label = gtk_label_new("Block ID/Block Name:");
+ GtkWidget* to_label = gtk_label_new("To Location:");
+ GtkWidget* x = gtk_label_new("x:");
+ GtkWidget* y = gtk_label_new("y:");
+ GtkWidget* subtile = gtk_label_new("Subtile:");
+
+ GtkWidget* calculate_cost_button = gtk_button_new_with_label("Calculate Costs");
+
+ //Add all to grid
+ gtk_grid_attach((GtkGrid*)grid, block_label, 0, 0, 1, 1);
+ gtk_grid_attach((GtkGrid*)grid, block_entry, 0, 1, 1, 1);
+ gtk_grid_attach((GtkGrid*)grid, to_label, 2, 0, 1, 1);
+ gtk_grid_attach((GtkGrid*)grid, x, 1, 1, 1, 1);
+ gtk_grid_attach((GtkGrid*)grid, x_position_entry, 2, 1, 1, 1);
+ gtk_grid_attach((GtkGrid*)grid, y, 1, 2, 1, 1);
+ gtk_grid_attach((GtkGrid*)grid, y_position_entry, 2, 2, 1, 1);
+ gtk_grid_attach((GtkGrid*)grid, subtile, 1, 3, 1, 1);
+ gtk_grid_attach((GtkGrid*)grid, subtile_position_entry, 2, 3, 1, 1);
+ gtk_grid_attach((GtkGrid*)grid, calculate_cost_button, 0, 4, 3, 1); //spans three columns
+
+ //Set margins
+ gtk_widget_set_margin_bottom(grid, 20);
+ gtk_widget_set_margin_top(grid, 20);
+ gtk_widget_set_margin_start(grid, 20);
+ gtk_widget_set_margin_end(grid, 20);
+ gtk_widget_set_margin_bottom(block_label, 5);
+ gtk_widget_set_margin_bottom(to_label, 5);
+ gtk_widget_set_margin_top(calculate_cost_button, 15);
+ gtk_widget_set_margin_start(x, 13);
+ gtk_widget_set_margin_start(y, 13);
+ gtk_widget_set_halign(calculate_cost_button, GTK_ALIGN_CENTER);
+
+ //connect signals
+ g_signal_connect(calculate_cost_button, "clicked", G_CALLBACK(calculate_cost_callback), grid);
+ g_signal_connect(G_OBJECT(draw_state->manual_moves_state.manual_move_window), "destroy", G_CALLBACK(close_manual_moves_window), NULL);
+
+ gtk_container_add(GTK_CONTAINER(draw_state->manual_moves_state.manual_move_window), grid);
+ gtk_widget_show_all(draw_state->manual_moves_state.manual_move_window);
+ }
+}
+
+void calculate_cost_callback(GtkWidget* /*widget*/, GtkWidget* grid) {
+ int block_id = -1;
+ int x_location = -1;
+ int y_location = -1;
+ int subtile_location = -1;
+ bool valid_input = true;
+
+ t_draw_state* draw_state = get_draw_state_vars();
+
+ //Loading the context/data structures needed.
+ auto& cluster_ctx = g_vpr_ctx.clustering();
+
+ //Getting entry values
+ GtkWidget* block_entry = gtk_grid_get_child_at((GtkGrid*)grid, 0, 1);
+ std::string block_id_string = gtk_entry_get_text((GtkEntry*)block_entry);
+
+ if (string_is_a_number(block_id_string)) { //for block ID
+ block_id = std::atoi(block_id_string.c_str());
+ } else { //for block name
+ block_id = size_t(cluster_ctx.clb_nlist.find_block(gtk_entry_get_text((GtkEntry*)block_entry)));
+ }
+
+ GtkWidget* x_position_entry = gtk_grid_get_child_at((GtkGrid*)grid, 2, 1);
+ GtkWidget* y_position_entry = gtk_grid_get_child_at((GtkGrid*)grid, 2, 2);
+ GtkWidget* subtile_position_entry = gtk_grid_get_child_at((GtkGrid*)grid, 2, 3);
+
+ x_location = std::atoi(gtk_entry_get_text((GtkEntry*)x_position_entry));
+ y_location = std::atoi(gtk_entry_get_text((GtkEntry*)y_position_entry));
+ subtile_location = std::atoi(gtk_entry_get_text((GtkEntry*)subtile_position_entry));
+
+ if (std::string(gtk_entry_get_text((GtkEntry*)block_entry)).empty() || std::string(gtk_entry_get_text((GtkEntry*)x_position_entry)).empty() || std::string(gtk_entry_get_text((GtkEntry*)y_position_entry)).empty() || std::string(gtk_entry_get_text((GtkEntry*)subtile_position_entry)).empty()) {
+ invalid_breakpoint_entry_window("Not all fields are complete");
+ valid_input = false;
+ }
+
+ t_pl_loc to = t_pl_loc(x_location, y_location, subtile_location);
+ valid_input = is_manual_move_legal(ClusterBlockId(block_id), to);
+
+ if (valid_input) {
+ draw_state->manual_moves_state.manual_move_info.valid_input = true;
+ draw_state->manual_moves_state.manual_move_info.blockID = block_id;
+ draw_state->manual_moves_state.manual_move_info.x_pos = x_location;
+ draw_state->manual_moves_state.manual_move_info.y_pos = y_location;
+ draw_state->manual_moves_state.manual_move_info.subtile = subtile_location;
+ draw_state->manual_moves_state.manual_move_info.to_location = to;
+
+ //Highlighting the block
+ deselect_all();
+ ClusterBlockId clb_index = ClusterBlockId(draw_state->manual_moves_state.manual_move_info.blockID);
+ draw_highlight_blocks_color(cluster_ctx.clb_nlist.block_type(clb_index), clb_index);
+ application.refresh_drawing();
+
+ //Continues to move costs window.
+ GtkWidget* proceed = find_button("ProceedButton");
+ ezgl::press_proceed(proceed, &application);
+
+ } else {
+ draw_state->manual_moves_state.manual_move_info.valid_input = false;
+ }
+}
+
+bool is_manual_move_legal(ClusterBlockId block_id, t_pl_loc to) {
+ auto& cluster_ctx = g_vpr_ctx.clustering();
+ auto& place_ctx = g_vpr_ctx.placement();
+ auto& device_ctx = g_vpr_ctx.device();
+
+ //if the block is not found
+ if ((!cluster_ctx.clb_nlist.valid_block_id(ClusterBlockId(block_id)))) {
+ invalid_breakpoint_entry_window("Invalid block ID/Name");
+ return false;
+ }
+
+ //If the dimensions are out of bounds
+ if (to.x < 0 || to.x >= int(device_ctx.grid.width())
+ || to.y < 0 || to.y >= int(device_ctx.grid.height())) {
+ invalid_breakpoint_entry_window("Dimensions are out of bounds");
+ return false;
+ }
+
+ //If the block s not compatible
+ auto physical_tile = device_ctx.grid[to.x][to.y].type;
+ auto logical_block = cluster_ctx.clb_nlist.block_type(block_id);
+ if (to.sub_tile < 0 || to.sub_tile >= physical_tile->capacity || !is_sub_tile_compatible(physical_tile, logical_block, to.sub_tile)) {
+ invalid_breakpoint_entry_window("Blocks are not compatible");
+ return false;
+ }
+
+ //If the destination block is user constrained, abort this swap
+ auto b_to = place_ctx.grid_blocks[to.x][to.y].blocks[to.sub_tile];
+ if (b_to != INVALID_BLOCK_ID && b_to != EMPTY_BLOCK_ID) {
+ if (place_ctx.block_locs[b_to].is_fixed) {
+ invalid_breakpoint_entry_window("Block is fixed");
+ return false;
+ }
+ }
+
+ //If the block requested is already in that location.
+ t_pl_loc current_block_loc = place_ctx.block_locs[block_id].loc;
+ if (to.x == current_block_loc.x && to.y == current_block_loc.y && to.sub_tile == current_block_loc.sub_tile) {
+ invalid_breakpoint_entry_window("The block is currently in this location");
+ return false;
+ }
+
+ return true;
+}
+
+bool manual_move_is_selected() {
+ t_draw_state* draw_state = get_draw_state_vars();
+ GObject* manual_moves = application.get_object("manualMove");
+ draw_state->manual_moves_state.manual_move_enabled = gtk_toggle_button_get_active((GtkToggleButton*)manual_moves);
+ return draw_state->manual_moves_state.manual_move_enabled;
+}
+
+void manual_move_cost_summary_dialog() {
+ t_draw_state* draw_state = get_draw_state_vars();
+ GtkWidget* dialog;
+ GtkWidget* content_area;
+
+ //Creating the dialog window
+ dialog = gtk_dialog_new_with_buttons("Move Costs",
+ (GtkWindow*)draw_state->manual_moves_state.manual_move_window,
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ ("Accept"),
+ GTK_RESPONSE_ACCEPT,
+ ("Reject"),
+ GTK_RESPONSE_REJECT,
+ NULL);
+
+ gtk_window_set_transient_for((GtkWindow*)dialog, (GtkWindow*)draw_state->manual_moves_state.manual_move_window);
+
+ //Create elements for the dialog and printing costs to the user.
+ GtkWidget* title_label = gtk_label_new(NULL);
+ gtk_label_set_markup((GtkLabel*)title_label, "Move Costs and Outcomes");
+ std::string delta_cost = "Delta Cost: " + std::to_string(draw_state->manual_moves_state.manual_move_info.delta_cost) + " ";
+ GtkWidget* delta_cost_label = gtk_label_new(delta_cost.c_str());
+ std::string delta_timing = " Delta Timing: " + std::to_string(draw_state->manual_moves_state.manual_move_info.delta_timing) + " ";
+ GtkWidget* delta_timing_label = gtk_label_new(delta_timing.c_str());
+ std::string delta_bounding_box = " Delta Bounding Box Cost: " + std::to_string(draw_state->manual_moves_state.manual_move_info.delta_bounding_box) + " ";
+ GtkWidget* delta_bounding_box_label = gtk_label_new(delta_bounding_box.c_str());
+ std::string outcome = e_move_result_to_string(draw_state->manual_moves_state.manual_move_info.placer_move_outcome);
+ std::string move_outcome = " Annealing Decision: " + outcome + " ";
+ GtkWidget* move_outcome_label = gtk_label_new(move_outcome.c_str());
+ GtkWidget* space_label1 = gtk_label_new(" ");
+ GtkWidget* space_label2 = gtk_label_new(" ");
+
+ //Attach elements to the content area of the dialog.
+ content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
+ gtk_container_add(GTK_CONTAINER(content_area), title_label);
+ gtk_container_add(GTK_CONTAINER(content_area), space_label1);
+ gtk_container_add(GTK_CONTAINER(content_area), delta_cost_label);
+ gtk_container_add(GTK_CONTAINER(content_area), delta_timing_label);
+ gtk_container_add(GTK_CONTAINER(content_area), delta_bounding_box_label);
+ gtk_container_add(GTK_CONTAINER(content_area), move_outcome_label);
+ gtk_container_add(GTK_CONTAINER(content_area), space_label2);
+
+ //Show the dialog with all the labels.
+ gtk_widget_show_all(dialog);
+
+ //Update message if user accepts the move.
+ std::string msg = "Manual move accepted. Block #" + std::to_string(draw_state->manual_moves_state.manual_move_info.blockID);
+ msg += " to location (" + std::to_string(draw_state->manual_moves_state.manual_move_info.x_pos) + ", " + std::to_string(draw_state->manual_moves_state.manual_move_info.y_pos) + ")";
+
+ //Waiting for the user to respond to return to try_swa function.
+ int result = gtk_dialog_run(GTK_DIALOG(dialog));
+ switch (result) {
+ //If the user accepts the manual move
+ case GTK_RESPONSE_ACCEPT:
+ draw_state->manual_moves_state.manual_move_info.user_move_outcome = ACCEPTED;
+ application.update_message(msg.c_str());
+ break;
+ //If the user rejects the manual move
+ case GTK_RESPONSE_REJECT:
+ draw_state->manual_moves_state.manual_move_info.user_move_outcome = REJECTED;
+ application.update_message("Manual move was rejected");
+ break;
+ default:
+ draw_state->manual_moves_state.manual_move_info.user_move_outcome = ABORTED;
+ break;
+ }
+
+ //Destroys the move outcome dialog.
+ gtk_widget_destroy(dialog);
+}
+
+void manual_move_highlight_new_block_location() {
+ t_draw_state* draw_state = get_draw_state_vars();
+ auto& cluster_ctx = g_vpr_ctx.clustering();
+ //Unselects all blocks first
+ deselect_all();
+ //Highlighting the block
+ ClusterBlockId clb_index = ClusterBlockId(draw_state->manual_moves_state.manual_move_info.blockID);
+ draw_highlight_blocks_color(cluster_ctx.clb_nlist.block_type(clb_index), clb_index);
+ application.refresh_drawing();
+}
+
+//Manual move window turns false, the window is destroyed.
+void close_manual_moves_window() {
+ t_draw_state* draw_state = get_draw_state_vars();
+ draw_state->manual_moves_state.manual_move_window_is_open = false;
+}
+
+bool string_is_a_number(std::string block_id) {
+ for (size_t i = 0; i < block_id.size(); i++) {
+ //Returns 0 if the string does not have characters from 0-9
+ if (isdigit(block_id[i]) == 0) {
+ return false;
+ }
+ }
+ return true;
+}
+
+//Updates ManualMovesInfo cost and placer move outcome variables. User_move_outcome is also updated.
+e_move_result pl_do_manual_move(double d_cost, double d_timing, double d_bounding_box, e_move_result& move_outcome) {
+ t_draw_state* draw_state = get_draw_state_vars();
+ draw_state->manual_moves_state.manual_move_info.delta_cost = d_cost;
+ draw_state->manual_moves_state.manual_move_info.delta_timing = d_timing;
+ draw_state->manual_moves_state.manual_move_info.delta_bounding_box = d_bounding_box;
+ draw_state->manual_moves_state.manual_move_info.placer_move_outcome = move_outcome;
+
+ //Displays the delta cost to the user.
+ manual_move_cost_summary_dialog();
+ //User accepts or rejects the move.
+ move_outcome = draw_state->manual_moves_state.manual_move_info.user_move_outcome;
+ return move_outcome;
+}
+
+e_create_move manual_move_display_and_propose(ManualMoveGenerator& manual_move_generator, t_pl_blocks_to_be_moved& blocks_affected, e_move_type& move_type, float rlim, const t_placer_opts& placer_opts, const PlacerCriticalities* criticalities) {
+ draw_manual_moves_window("");
+ update_screen(ScreenUpdatePriority::MAJOR, " ", PLACEMENT, nullptr);
+ move_type = e_move_type::MANUAL_MOVE;
+ return manual_move_generator.propose_move(blocks_affected, move_type, rlim, placer_opts, criticalities);
+}
+
+#endif /*NO_GRAPHICS*/
diff --git a/vpr/src/draw/manual_moves.h b/vpr/src/draw/manual_moves.h
new file mode 100644
index 00000000000..d364dd1882a
--- /dev/null
+++ b/vpr/src/draw/manual_moves.h
@@ -0,0 +1,160 @@
+/*
+ * @file manual_moves.h
+ * @author Paula Perdomo
+ * @date 2021-07-19
+ * @brief Contains the function prototypes needed for manual moves feature.
+ *
+ * Includes the data structures and gtk function for manual moves. The Manual Move Generator class is defined manual_move_generator.h/cpp.
+ */
+
+#ifndef MANUAL_MOVES_H
+#define MANUAL_MOVES_H
+
+/** This file contains all functions for manual moves **/
+#ifndef NO_GRAPHICS
+
+# include "ezgl/application.hpp"
+# include "ezgl/graphics.hpp"
+# include "manual_move_generator.h"
+
+# include "move_utils.h"
+# include
+# include
+# include
+# include
+# include
+# include
+
+/**
+ * @brief ManualMovesInfo struct
+ *
+ * Contains information about the block, location, validity of user input, timing variables, and placer outcomes.
+ *
+ * GUI writes to:
+ * blockID: Stores the block ID of the block requested to move by the user. This block is the from block in the move generator.
+ * x_pos: Stores the x position of the block requested to move by the user.
+ * y_pos: Stores the y position of the block requested to move by the user.
+ * subtile: Stores the subtile of the block requested to move by the user.
+ * valid input: Stores whether the manual move is valid with respect to the user's input in the UI.
+ * user_move_outcome: The user determines to acceopt or reject the manual move.
+ *
+ * Placer writes to:
+ * delta_cost: Stores the delta cost of the manual move requested by the user.
+ * delta_timing: Stores the delta timing of the manual move requested by the user.
+ * delta_bounding_box: Stores the delta bounding box cost of the manual move requested by the user.
+ * to_location: Stores the x position, y position and subtile position requested by the user in a t_pl_loc variable.
+ * placer_move_outcome: The placer determines if the manual move requested by the user is valid.
+ */
+
+struct ManualMovesInfo {
+ int blockID = -1;
+ int x_pos = -1;
+ int y_pos = -1;
+ int subtile = 0;
+ double delta_cost = 0;
+ double delta_timing = 0;
+ double delta_bounding_box = 0;
+ bool valid_input = true;
+ t_pl_loc to_location;
+ e_move_result placer_move_outcome = ABORTED;
+ e_move_result user_move_outcome = ABORTED;
+};
+
+/**
+ * @brief ManualMovesState struct
+ *
+ * Contains a ManualMovesInfo variable to store manual move data, boolean values to check the state of the windows needed and gtk manual move widow variable.
+ * ManualMovesInfo: Stores the manual move information from the user's input and the placer's/user's outcome to the move.
+ * manual_move_window_is_open: Stores whether the manual move window is open or not.
+ * user_highlighted_block: Stores whether user highlighted block in UI instead of entering the block ID manually.
+ * manual_move_window: GtkWindow for the manual move. In this window the user inputs the block ID and to position of the block to move.
+ */
+
+struct ManualMovesState {
+ ManualMovesInfo manual_move_info;
+ bool manual_move_window_is_open = false;
+ bool user_highlighted_block = false;
+ bool manual_move_enabled = false;
+ GtkWidget* manual_move_window;
+};
+
+/** manual moves functions **/
+
+/**
+ * @brief Gets the state of the manual moves togle button and assigns it to the manual_move_enabled in the ManualMovesState struct.
+ *
+ * @return True if the toggle button is active, false otherwise.
+ */
+bool manual_move_is_selected();
+
+/**
+ * @brief Draws the manual move window.
+ *
+ * Window prompts the user for input: block id/name used as the from block in the move generator, x position, y position, and subtile position.
+ * @param block_id: The block id is passed in if the user decides to highlight the block in the UI. If the user decides to manually input the block ID in the manual move window, the string will be empty and the block ID will later be assigned to ManualMovesState struct.
+ */
+void draw_manual_moves_window(std::string block_id);
+
+/**
+ * @brief Evaluates if the user input is valid and allowed.
+ *
+ * Sets the members from the ManualMovesState manual_moves_state variable to their respective values (block id and locations).
+ * @param GtkWidget* widget: Passed in for gtk callback functions (Needed due to the GTK function protoype, in GTK documentation).
+ * @param GtkWidget* grid: The grid is used to extract the user input from the manual move window, to later assign to the ManualMovesState variable.
+ */
+void calculate_cost_callback(GtkWidget* /*widget*/, GtkWidget* grid);
+
+/**
+ * @brief In -detail checking of the user's input.
+ *
+ * Checks if the user input is between the grid's dimensions, block comptaibility, if the block requested to move is valid, if the block is fixed, and if the curent location of the block is different from the location requested by the user.
+ * @param block_id: The ID of the block to move used as the from block in the move generator).
+ * @param to: Location of where the user wants to move the block.
+ *
+ * @return True if all conditions are met, false otherwise.
+ */
+bool is_manual_move_legal(ClusterBlockId block_id, t_pl_loc to);
+
+/**
+ * @brief Draws the cost summary dialog.
+ *
+ * Window displays the delta cost, delta timing, delta bounding box timing, annealing decision to the user. Waits for the user to ACCEPT/REJECT the manual move.
+ */
+void manual_move_cost_summary_dialog();
+
+/**
+ * @brief Highlights new block location
+ *
+ * Highlights block in the new location if the manual move is active and the user accepted the manual move.
+ */
+void manual_move_highlight_new_block_location();
+
+/**
+ * @brief Disables the manual_move_window_is_open boolean and destroys the window
+ */
+void close_manual_moves_window();
+
+/**
+ * @brief Checks if the given string is a number
+ *
+ * @return True if the string only contains numbers, false otherwise.
+ */
+bool string_is_a_number(std::string block_id);
+
+/**
+ * @brief Updates the ManualMovesState variable members.
+ *
+ * @param d_cost: Delta cost for cost summary dialog function.
+ * @param d_timing: Delta timing for cost summary dialog function.
+ * @param d_bounding_box: Delta bounding box for cost summary dialog function.
+ * @param move_outcome: Move result from placement for cost summary dialog function.
+ *
+ * Helper function used in place.cpp. The ManualMovesState variable are updated and the manual_move_cost_summary_dialog is called to display the cost members to the user in the UI and waits for the user to either ACCPET/REJECT the manual move.
+ */
+e_move_result pl_do_manual_move(double d_cost, double d_timing, double d_bounding_box, e_move_result& move_outcome);
+
+e_create_move manual_move_display_and_propose(ManualMoveGenerator& manual_move_generator, t_pl_blocks_to_be_moved& blocks_affected, e_move_type& move_type, float rlim, const t_placer_opts& placer_opts, const PlacerCriticalities* criticalities);
+
+#endif /*NO_GRAPHICS*/
+
+#endif /* MANUAL_MOVES_H */
diff --git a/vpr/src/place/RL_agent_util.cpp b/vpr/src/place/RL_agent_util.cpp
index 66352786a1d..171b710e99d 100644
--- a/vpr/src/place/RL_agent_util.cpp
+++ b/vpr/src/place/RL_agent_util.cpp
@@ -1,4 +1,5 @@
#include "RL_agent_util.h"
+#include "manual_move_generator.h"
void create_move_generators(std::unique_ptr& move_generator, std::unique_ptr& move_generator2, const t_placer_opts& placer_opts, int move_lim) {
if (placer_opts.RL_agent_placement == false) {
@@ -42,7 +43,6 @@ void create_move_generators(std::unique_ptr& move_generator, std:
karmed_bandit_agent1 = std::make_unique(NUM_PL_1ST_STATE_MOVE_TYPES, placer_opts.place_agent_epsilon);
karmed_bandit_agent1->set_step(placer_opts.place_agent_gamma, move_lim);
move_generator = std::make_unique(karmed_bandit_agent1);
-
//agent's 2nd state
karmed_bandit_agent2 = std::make_unique(NUM_PL_MOVE_TYPES, placer_opts.place_agent_epsilon);
karmed_bandit_agent2->set_step(placer_opts.place_agent_gamma, move_lim);
@@ -52,7 +52,6 @@ void create_move_generators(std::unique_ptr& move_generator, std:
karmed_bandit_agent1 = std::make_unique(NUM_PL_NONTIMING_MOVE_TYPES, placer_opts.place_agent_epsilon);
karmed_bandit_agent1->set_step(placer_opts.place_agent_gamma, move_lim);
move_generator = std::make_unique(karmed_bandit_agent1);
-
//agent's 2nd state
karmed_bandit_agent2 = std::make_unique(NUM_PL_NONTIMING_MOVE_TYPES, placer_opts.place_agent_epsilon);
karmed_bandit_agent2->set_step(placer_opts.place_agent_gamma, move_lim);
diff --git a/vpr/src/place/RL_agent_util.h b/vpr/src/place/RL_agent_util.h
index 5b23cf464d3..ebfee697850 100644
--- a/vpr/src/place/RL_agent_util.h
+++ b/vpr/src/place/RL_agent_util.h
@@ -3,6 +3,7 @@
#include "static_move_generator.h"
#include "simpleRL_move_generator.h"
+#include "manual_move_generator.h"
//enum represents the available agent states
enum e_agent_state {
diff --git a/vpr/src/place/manual_move_generator.cpp b/vpr/src/place/manual_move_generator.cpp
new file mode 100644
index 00000000000..cb482f0cbce
--- /dev/null
+++ b/vpr/src/place/manual_move_generator.cpp
@@ -0,0 +1,56 @@
+/*
+ * @file manual_move_generator.cpp
+ * @author Paula Perdomo
+ * @date 2021-07-19
+ * @brief Contains the ManualMoveGenerator class memeber definitions. The ManualMoveGenerator class inherits from the MoveGenerator class. The class contains a propose_move function that checks if the block requested to move by the user exists and determines whether the manual move is VALID/ABORTED by the placer. If the manual move is determined VALID, the move is created. A manual move is ABORTED if the block requested is not found or movable and if there aren't any compatible subtiles.
+ */
+
+#include "manual_move_generator.h"
+#include "manual_moves.h"
+
+#ifndef NO_GRAPHICS
+# include "draw.h"
+#endif //NO_GRAPHICS
+
+//Manual Move Generator function
+e_create_move ManualMoveGenerator::propose_move(t_pl_blocks_to_be_moved& blocks_affected, e_move_type& /*move_type*/, float /*rlim*/, const t_placer_opts& /*placer_opts*/, const PlacerCriticalities* /*criticalities*/) {
+ int block_id = -1;
+ t_pl_loc to;
+
+#ifndef NO_GRAPHICS
+ t_draw_state* draw_state = get_draw_state_vars();
+ block_id = draw_state->manual_moves_state.manual_move_info.blockID;
+ to = draw_state->manual_moves_state.manual_move_info.to_location;
+#endif //NO_GRAPHICS
+
+ ClusterBlockId b_from = ClusterBlockId(block_id);
+
+ //Checking if the block was found
+ if (!b_from) {
+ return e_create_move::ABORT; //No movable block was found
+ }
+
+ auto& place_ctx = g_vpr_ctx.placement();
+ auto& cluster_ctx = g_vpr_ctx.clustering();
+ auto& device_ctx = g_vpr_ctx.device();
+
+ //Gets the current location of the block to move.
+ t_pl_loc from = place_ctx.block_locs[b_from].loc;
+ auto cluster_from_type = cluster_ctx.clb_nlist.block_type(b_from);
+ auto grid_from_type = device_ctx.grid[from.x][from.y].type;
+ VTR_ASSERT(is_tile_compatible(grid_from_type, cluster_from_type));
+
+ //Retrieving the compressed block grid for this block type
+ const auto& compressed_block_grid = place_ctx.compressed_block_grids[cluster_from_type->index];
+ //Checking if the block has a compatible subtile.
+ auto to_type = device_ctx.grid[to.x][to.y].type;
+ auto& compatible_subtiles = compressed_block_grid.compatible_sub_tiles_for_tile.at(to_type->index);
+
+ //No compatible subtile is found.
+ if (std::find(compatible_subtiles.begin(), compatible_subtiles.end(), to.sub_tile) == compatible_subtiles.end()) {
+ return e_create_move::ABORT;
+ }
+
+ e_create_move create_move = ::create_move(blocks_affected, b_from, to);
+ return create_move;
+}
diff --git a/vpr/src/place/manual_move_generator.h b/vpr/src/place/manual_move_generator.h
new file mode 100644
index 00000000000..863ebc71c8c
--- /dev/null
+++ b/vpr/src/place/manual_move_generator.h
@@ -0,0 +1,33 @@
+/*
+ * @file manual_move_generator.h
+ * @author Paula Perdomo
+ * @date 2021-07-19
+ * @brief Contains the ManualMoveGenerator class.
+ */
+
+#ifndef VPR_MANUAL_MOVE_GEN_H
+#define VPR_MANUAL_MOVE_GEN_H
+
+#include "move_generator.h"
+#include "median_move_generator.h"
+#include "weighted_median_move_generator.h"
+#include "weighted_centroid_move_generator.h"
+#include "feasible_region_move_generator.h"
+#include "uniform_move_generator.h"
+#include "critical_uniform_move_generator.h"
+#include "centroid_move_generator.h"
+#include "simpleRL_move_generator.h"
+#include
+
+/**
+ * @brief Manual Moves Generator, inherits from MoveGenerator class.
+ *
+ * Manual Move Generator, needed for swapping blocks requested by the user.
+ */
+class ManualMoveGenerator : public MoveGenerator {
+ public:
+ //Evaluates if move is successful and legal or unable to do.
+ e_create_move propose_move(t_pl_blocks_to_be_moved& blocks_affected, e_move_type& /*move_type*/, float /*rlim*/, const t_placer_opts& /*placer_opts*/, const PlacerCriticalities* /*criticalities*/);
+};
+
+#endif /*VPR_MANUAL_MOVE_GEN_H */
diff --git a/vpr/src/place/move_utils.cpp b/vpr/src/place/move_utils.cpp
index 84f34bf27d7..8822b8b8db3 100644
--- a/vpr/src/place/move_utils.cpp
+++ b/vpr/src/place/move_utils.cpp
@@ -5,6 +5,9 @@
#include "vtr_random.h"
+#include "draw_debug.h"
+#include "draw.h"
+
//f_placer_breakpoint_reached is used to stop the placer when a breakpoint is reached. When this flag is true, it stops the placer after the current perturbation. Thus, when a breakpoint is reached, this flag is set to true.
//Note: The flag is only effective if compiled with VTR_ENABLE_DEBUG_LOGGING
bool f_placer_breakpoint_reached = false;
@@ -728,14 +731,15 @@ bool find_to_loc_centroid(t_logical_block_type_ptr blk_type,
}
//Array of move type strings
-static const std::array move_type_strings = {
+static const std::array move_type_strings = {
"Uniform",
"Median",
"W. Centroid",
"Centroid",
"W. Median",
"Crit. Uniform",
- "Feasible Region"};
+ "Feasible Region",
+ "Manual Move"};
//To convert enum move type to string
std::string move_type_to_string(e_move_type move) {
@@ -843,3 +847,8 @@ bool find_compatible_compressed_loc_in_range(t_logical_block_type_ptr type, int
}
return legal;
}
+
+std::string e_move_result_to_string(e_move_result move_outcome) {
+ std::string move_result_to_string[] = {"Rejected", "Accepted", "Aborted"};
+ return move_result_to_string[move_outcome];
+}
diff --git a/vpr/src/place/move_utils.h b/vpr/src/place/move_utils.h
index 93e229615b7..3b0f01f9bcb 100644
--- a/vpr/src/place/move_utils.h
+++ b/vpr/src/place/move_utils.h
@@ -26,7 +26,8 @@ enum class e_move_type {
CENTROID,
W_MEDIAN,
CRIT_UNIFORM,
- FEASIBLE_REGION
+ FEASIBLE_REGION,
+ MANUAL_MOVE,
};
enum class e_create_move {
@@ -170,4 +171,6 @@ void compressed_grid_to_loc(t_logical_block_type_ptr blk_type, int cx, int cy, t
*/
bool find_compatible_compressed_loc_in_range(t_logical_block_type_ptr type, int min_cx, int max_cx, int min_cy, int max_cy, int delta_cx, int cx_from, int cy_from, int& cx_to, int& cy_to, bool is_median);
+std::string e_move_result_to_string(e_move_result move_outcome);
+
#endif
diff --git a/vpr/src/place/place.cpp b/vpr/src/place/place.cpp
index 356dcd99ef0..f07178e1541 100644
--- a/vpr/src/place/place.cpp
+++ b/vpr/src/place/place.cpp
@@ -4,6 +4,7 @@
#include
#include
#include
+#include
#include "vtr_assert.h"
#include "vtr_log.h"
@@ -39,9 +40,12 @@
#include "move_utils.h"
#include "read_place.h"
#include "place_constraints.h"
+#include "manual_moves.h"
+#include "buttons.h"
#include "static_move_generator.h"
#include "simpleRL_move_generator.h"
+#include "manual_move_generator.h"
#include "PlacementDelayCalculator.h"
#include "VprTimingGraphResolver.h"
@@ -58,6 +62,7 @@
* compared to the timing cost in the agent's reward function. The reward is calculated as *
* -1*(1.5-REWARD_BB_TIMING_RELATIVE_WEIGHT)*timing_cost + (1+REWARD_BB_TIMING_RELATIVE_WEIGHT)*bb_cost)
*/
+
#define REWARD_BB_TIMING_RELATIVE_WEIGHT 0.4
#ifdef VTR_ENABLE_DEBUG_LOGGING
@@ -148,14 +153,16 @@ static int num_ts_called = 0;
* Multiplied to bounding box of a net to better estimate wire length *
* for higher fanout nets. Each entry is the correction factor for the *
* fanout index-1 */
-static const float cross_count[50] = {/* [0..49] */ 1.0, 1.0, 1.0, 1.0828, 1.1536, 1.2206, 1.2823, 1.3385, 1.3991, 1.4493, 1.4974,
- 1.5455, 1.5937, 1.6418, 1.6899, 1.7304, 1.7709, 1.8114, 1.8519, 1.8924,
- 1.9288, 1.9652, 2.0015, 2.0379, 2.0743, 2.1061, 2.1379, 2.1698, 2.2016,
- 2.2334, 2.2646, 2.2958, 2.3271, 2.3583, 2.3895, 2.4187, 2.4479, 2.4772,
- 2.5064, 2.5356, 2.5610, 2.5864, 2.6117, 2.6371, 2.6625, 2.6887, 2.7148,
- 2.7410, 2.7671, 2.7933};
+static const float cross_count[50] = {/* [0..49] */ 1.0, 1.0, 1.0, 1.0828,
+ 1.1536, 1.2206, 1.2823, 1.3385, 1.3991, 1.4493, 1.4974, 1.5455, 1.5937,
+ 1.6418, 1.6899, 1.7304, 1.7709, 1.8114, 1.8519, 1.8924, 1.9288, 1.9652,
+ 2.0015, 2.0379, 2.0743, 2.1061, 2.1379, 2.1698, 2.2016, 2.2334, 2.2646,
+ 2.2958, 2.3271, 2.3583, 2.3895, 2.4187, 2.4479, 2.4772, 2.5064, 2.5356,
+ 2.5610, 2.5864, 2.6117, 2.6371, 2.6625, 2.6887, 2.7148, 2.7410, 2.7671,
+ 2.7933};
-std::unique_ptr f_move_stats_file(nullptr, vtr::fclose);
+std::unique_ptr f_move_stats_file(nullptr,
+ vtr::fclose);
#ifdef VTR_ENABLE_DEBUG_LOGGIING
# define LOG_MOVE_STATS_HEADER() \
@@ -256,6 +263,7 @@ static void reset_move_nets(int num_nets_affected);
static e_move_result try_swap(const t_annealing_state* state,
t_placer_costs* costs,
MoveGenerator& move_generator,
+ ManualMoveGenerator& manual_move_generator,
SetupTimingInfo* timing_info,
ClusteredPinTimingInvalidator* pin_timing_invalidator,
t_pl_blocks_to_be_moved& blocks_affected,
@@ -265,7 +273,8 @@ static e_move_result try_swap(const t_annealing_state* state,
const t_placer_opts& placer_opts,
MoveTypeStat& move_type_stat,
const t_place_algorithm& place_algorithm,
- float timing_bb_factor);
+ float timing_bb_factor,
+ bool manual_move_enabled);
static void check_place(const t_placer_costs& costs,
const PlaceDelayModel* delay_model,
@@ -281,18 +290,7 @@ static int check_placement_consistency();
static int check_block_placement_consistency();
static int check_macro_placement_consistency();
-static float starting_t(const t_annealing_state* state,
- t_placer_costs* costs,
- t_annealing_sched annealing_sched,
- const PlaceDelayModel* delay_model,
- PlacerCriticalities* criticalities,
- PlacerSetupSlacks* setup_slacks,
- SetupTimingInfo* timing_info,
- MoveGenerator& move_generator,
- ClusteredPinTimingInvalidator* pin_timing_invalidator,
- t_pl_blocks_to_be_moved& blocks_affected,
- const t_placer_opts& placer_opts,
- MoveTypeStat& move_type_stat);
+static float starting_t(const t_annealing_state* state, t_placer_costs* costs, t_annealing_sched annealing_sched, const PlaceDelayModel* delay_model, PlacerCriticalities* criticalities, PlacerSetupSlacks* setup_slacks, SetupTimingInfo* timing_info, MoveGenerator& move_generator, ManualMoveGenerator& manual_move_generator, ClusteredPinTimingInvalidator* pin_timing_invalidator, t_pl_blocks_to_be_moved& blocks_affected, const t_placer_opts& placer_opts, MoveTypeStat& move_type_stat);
static int count_connections();
@@ -302,11 +300,13 @@ static void commit_td_cost(const t_pl_blocks_to_be_moved& blocks_affected);
static void revert_td_cost(const t_pl_blocks_to_be_moved& blocks_affected);
-static void invalidate_affected_connections(const t_pl_blocks_to_be_moved& blocks_affected,
- ClusteredPinTimingInvalidator* pin_tedges_invalidator,
- TimingInfo* timing_info);
+static void invalidate_affected_connections(
+ const t_pl_blocks_to_be_moved& blocks_affected,
+ ClusteredPinTimingInvalidator* pin_tedges_invalidator,
+ TimingInfo* timing_info);
-static bool driven_by_moved_block(const ClusterNetId net, const t_pl_blocks_to_be_moved& blocks_affected);
+static bool driven_by_moved_block(const ClusterNetId net,
+ const t_pl_blocks_to_be_moved& blocks_affected);
static float analyze_setup_slack_cost(const PlacerSetupSlacks* setup_slacks);
@@ -316,12 +316,13 @@ static void get_non_updateable_bb(ClusterNetId net_id, t_bb* bb_coord_new);
static void update_bb(ClusterNetId net_id, t_bb* bb_coord_new, t_bb* bb_edge_new, int xold, int yold, int xnew, int ynew);
-static int find_affected_nets_and_update_costs(const t_place_algorithm& place_algorithm,
- const PlaceDelayModel* delay_model,
- const PlacerCriticalities* criticalities,
- t_pl_blocks_to_be_moved& blocks_affected,
- double& bb_delta_c,
- double& timing_delta_c);
+static int find_affected_nets_and_update_costs(
+ const t_place_algorithm& place_algorithm,
+ const PlaceDelayModel* delay_model,
+ const PlacerCriticalities* criticalities,
+ t_pl_blocks_to_be_moved& blocks_affected,
+ double& bb_delta_c,
+ double& timing_delta_c);
static void record_affected_net(const ClusterNetId net, int& num_affected_nets);
@@ -367,6 +368,7 @@ static void placement_inner_loop(const t_annealing_state* state,
PlacerCriticalities* criticalities,
PlacerSetupSlacks* setup_slacks,
MoveGenerator& move_generator,
+ ManualMoveGenerator& manual_move_generator,
t_pl_blocks_to_be_moved& blocks_affected,
SetupTimingInfo* timing_info,
const t_place_algorithm& place_algorithm,
@@ -384,7 +386,12 @@ static void generate_post_place_timing_reports(const t_placer_opts& placer_opts,
const PlacementDelayCalculator& delay_calc);
//calculate the agent's reward and the total process outcome
-static void calculate_reward_and_process_outcome(const t_placer_opts& placer_opts, const MoveOutcomeStats& move_outcome_stats, const double& delta_c, float timing_bb_factor, MoveGenerator& move_generator);
+static void calculate_reward_and_process_outcome(
+ const t_placer_opts& placer_opts,
+ const MoveOutcomeStats& move_outcome_stats,
+ const double& delta_c,
+ float timing_bb_factor,
+ MoveGenerator& move_generator);
static void print_place_status_header();
@@ -400,7 +407,8 @@ static void print_resources_utilization();
static void print_placement_swaps_stats(const t_annealing_state& state);
-static void print_placement_move_types_stats(const MoveTypeStat& move_type_stat);
+static void print_placement_move_types_stats(
+ const MoveTypeStat& move_type_stat);
/*****************************************************************************/
void try_place(const t_placer_opts& placer_opts,
@@ -426,7 +434,6 @@ void try_place(const t_placer_opts& placer_opts,
auto& timing_ctx = g_vpr_ctx.timing();
auto pre_place_timing_stats = timing_ctx.stats;
-
int tot_iter, moves_since_cost_recompute, width_fac, num_connections,
outer_crit_iter_count, inner_recompute_limit;
float first_crit_exponent, first_rlim, first_t;
@@ -449,12 +456,16 @@ void try_place(const t_placer_opts& placer_opts,
std::unique_ptr place_delay_model;
std::unique_ptr move_generator;
std::unique_ptr move_generator2;
+ std::unique_ptr manual_move_generator;
std::unique_ptr placer_setup_slacks;
std::unique_ptr placer_criticalities;
std::unique_ptr pin_timing_invalidator;
- t_pl_blocks_to_be_moved blocks_affected(cluster_ctx.clb_nlist.blocks().size());
+ manual_move_generator = std::make_unique();
+
+ t_pl_blocks_to_be_moved blocks_affected(
+ cluster_ctx.clb_nlist.blocks().size());
/* Allocated here because it goes into timing critical code where each memory allocation is expensive */
IntraLbPbPinLookup pb_gpin_lookup(device_ctx.logical_block_types);
@@ -467,15 +478,19 @@ void try_place(const t_placer_opts& placer_opts,
if (placer_opts.place_algorithm.is_timing_driven()) {
/*do this before the initial placement to avoid messing up the initial placement */
- place_delay_model = alloc_lookups_and_delay_model(chan_width_dist, placer_opts, router_opts, det_routing_arch, segment_inf, directs, num_directs);
+ place_delay_model = alloc_lookups_and_delay_model(chan_width_dist,
+ placer_opts, router_opts, det_routing_arch, segment_inf,
+ directs, num_directs);
if (isEchoFileEnabled(E_ECHO_PLACEMENT_DELTA_DELAY_MODEL)) {
- place_delay_model->dump_echo(getEchoFileName(E_ECHO_PLACEMENT_DELTA_DELAY_MODEL));
+ place_delay_model->dump_echo(
+ getEchoFileName(E_ECHO_PLACEMENT_DELTA_DELAY_MODEL));
}
}
int move_lim = 1;
- move_lim = (int)(annealing_sched.inner_num * pow(cluster_ctx.clb_nlist.blocks().size(), 1.3333));
+ move_lim = (int)(annealing_sched.inner_num
+ * pow(cluster_ctx.clb_nlist.blocks().size(), 1.3333));
//create the move generator based on the chosen strategy
create_move_generators(move_generator, move_generator2, placer_opts, move_lim);
@@ -495,7 +510,8 @@ void try_place(const t_placer_opts& placer_opts,
vtr::ScopedStartFinishTimer timer("Placement");
- initial_placement(placer_opts.pad_loc_type, placer_opts.constraints_file.c_str());
+ initial_placement(placer_opts.pad_loc_type,
+ placer_opts.constraints_file.c_str());
#ifdef ENABLE_ANALYTIC_PLACE
/*
@@ -516,7 +532,8 @@ void try_place(const t_placer_opts& placer_opts,
init_draw_coords((float)width_fac);
//Enables fast look-up of atom pins connect to CLB pins
- ClusteredPinAtomPinsLookup netlist_pin_lookup(cluster_ctx.clb_nlist, atom_ctx.nlist, pb_gpin_lookup);
+ ClusteredPinAtomPinsLookup netlist_pin_lookup(cluster_ctx.clb_nlist,
+ atom_ctx.nlist, pb_gpin_lookup);
/* Gets initial cost and loads bounding boxes. */
@@ -527,7 +544,8 @@ void try_place(const t_placer_opts& placer_opts,
num_connections = count_connections();
VTR_LOG("\n");
- VTR_LOG("There are %d point to point connections in this circuit.\n", num_connections);
+ VTR_LOG("There are %d point to point connections in this circuit.\n",
+ num_connections);
VTR_LOG("\n");
//Update the point-to-point delays from the initial placement
@@ -536,44 +554,50 @@ void try_place(const t_placer_opts& placer_opts,
/*
* Initialize timing analysis
*/
- placement_delay_calc = std::make_shared(atom_ctx.nlist, atom_ctx.lookup, p_timing_ctx.connection_delay);
- placement_delay_calc->set_tsu_margin_relative(placer_opts.tsu_rel_margin);
- placement_delay_calc->set_tsu_margin_absolute(placer_opts.tsu_abs_margin);
-
- timing_info = make_setup_timing_info(placement_delay_calc, placer_opts.timing_update_type);
-
- placer_setup_slacks = std::make_unique(cluster_ctx.clb_nlist, netlist_pin_lookup);
-
- placer_criticalities = std::make_unique(cluster_ctx.clb_nlist, netlist_pin_lookup);
-
- pin_timing_invalidator = std::make_unique(cluster_ctx.clb_nlist,
- netlist_pin_lookup,
- atom_ctx.nlist,
- atom_ctx.lookup,
- *timing_info->timing_graph());
+ placement_delay_calc = std::make_shared(
+ atom_ctx.nlist, atom_ctx.lookup, p_timing_ctx.connection_delay);
+ placement_delay_calc->set_tsu_margin_relative(
+ placer_opts.tsu_rel_margin);
+ placement_delay_calc->set_tsu_margin_absolute(
+ placer_opts.tsu_abs_margin);
+
+ timing_info = make_setup_timing_info(placement_delay_calc,
+ placer_opts.timing_update_type);
+
+ placer_setup_slacks = std::make_unique(
+ cluster_ctx.clb_nlist, netlist_pin_lookup);
+
+ placer_criticalities = std::make_unique(
+ cluster_ctx.clb_nlist, netlist_pin_lookup);
+
+ pin_timing_invalidator = std::make_unique(
+ cluster_ctx.clb_nlist, netlist_pin_lookup,
+ atom_ctx.nlist, atom_ctx.lookup,
+ *timing_info->timing_graph());
//First time compute timing and costs, compute from scratch
PlaceCritParams crit_params;
crit_params.crit_exponent = first_crit_exponent;
crit_params.crit_limit = placer_opts.place_crit_limit;
- initialize_timing_info(crit_params,
- place_delay_model.get(),
- placer_criticalities.get(),
- placer_setup_slacks.get(),
- pin_timing_invalidator.get(),
- timing_info.get(),
- &costs);
+ initialize_timing_info(crit_params, place_delay_model.get(),
+ placer_criticalities.get(), placer_setup_slacks.get(),
+ pin_timing_invalidator.get(), timing_info.get(), &costs);
critical_path = timing_info->least_slack_critical_path();
/* Write out the initial timing echo file */
if (isEchoFileEnabled(E_ECHO_INITIAL_PLACEMENT_TIMING_GRAPH)) {
- tatum::write_echo(getEchoFileName(E_ECHO_INITIAL_PLACEMENT_TIMING_GRAPH),
- *timing_ctx.graph, *timing_ctx.constraints, *placement_delay_calc, timing_info->analyzer());
-
- tatum::NodeId debug_tnode = id_or_pin_name_to_tnode(analysis_opts.echo_dot_timing_graph_node);
- write_setup_timing_graph_dot(getEchoFileName(E_ECHO_INITIAL_PLACEMENT_TIMING_GRAPH) + std::string(".dot"),
- *timing_info, debug_tnode);
+ tatum::write_echo(
+ getEchoFileName(E_ECHO_INITIAL_PLACEMENT_TIMING_GRAPH),
+ *timing_ctx.graph, *timing_ctx.constraints,
+ *placement_delay_calc, timing_info->analyzer());
+
+ tatum::NodeId debug_tnode = id_or_pin_name_to_tnode(
+ analysis_opts.echo_dot_timing_graph_node);
+ write_setup_timing_graph_dot(
+ getEchoFileName(E_ECHO_INITIAL_PLACEMENT_TIMING_GRAPH)
+ + std::string(".dot"),
+ *timing_info, debug_tnode);
}
outer_crit_iter_count = 1;
@@ -602,37 +626,47 @@ void try_place(const t_placer_opts& placer_opts,
}
//Sanity check that initial placement is legal
- check_place(costs, place_delay_model.get(), placer_criticalities.get(), placer_opts.place_algorithm);
+ check_place(costs, place_delay_model.get(), placer_criticalities.get(),
+ placer_opts.place_algorithm);
//Initial pacement statistics
- VTR_LOG("Initial placement cost: %g bb_cost: %g td_cost: %g\n",
- costs.cost, costs.bb_cost, costs.timing_cost);
+ VTR_LOG("Initial placement cost: %g bb_cost: %g td_cost: %g\n", costs.cost,
+ costs.bb_cost, costs.timing_cost);
if (placer_opts.place_algorithm.is_timing_driven()) {
- VTR_LOG("Initial placement estimated Critical Path Delay (CPD): %g ns\n",
- 1e9 * critical_path.delay());
- VTR_LOG("Initial placement estimated setup Total Negative Slack (sTNS): %g ns\n",
- 1e9 * timing_info->setup_total_negative_slack());
- VTR_LOG("Initial placement estimated setup Worst Negative Slack (sWNS): %g ns\n",
- 1e9 * timing_info->setup_worst_negative_slack());
+ VTR_LOG(
+ "Initial placement estimated Critical Path Delay (CPD): %g ns\n",
+ 1e9 * critical_path.delay());
+ VTR_LOG(
+ "Initial placement estimated setup Total Negative Slack (sTNS): %g ns\n",
+ 1e9 * timing_info->setup_total_negative_slack());
+ VTR_LOG(
+ "Initial placement estimated setup Worst Negative Slack (sWNS): %g ns\n",
+ 1e9 * timing_info->setup_worst_negative_slack());
VTR_LOG("\n");
VTR_LOG("Initial placement estimated setup slack histogram:\n");
- print_histogram(create_setup_slack_histogram(*timing_info->setup_analyzer()));
+ print_histogram(
+ create_setup_slack_histogram(*timing_info->setup_analyzer()));
}
size_t num_macro_members = 0;
for (auto& macro : g_vpr_ctx.placement().pl_macros) {
num_macro_members += macro.members.size();
}
- VTR_LOG("Placement contains %zu placement macros involving %zu blocks (average macro size %f)\n", g_vpr_ctx.placement().pl_macros.size(), num_macro_members, float(num_macro_members) / g_vpr_ctx.placement().pl_macros.size());
+ VTR_LOG(
+ "Placement contains %zu placement macros involving %zu blocks (average macro size %f)\n",
+ g_vpr_ctx.placement().pl_macros.size(), num_macro_members,
+ float(num_macro_members) / g_vpr_ctx.placement().pl_macros.size());
VTR_LOG("\n");
- sprintf(msg, "Initial Placement. Cost: %g BB Cost: %g TD Cost %g \t Channel Factor: %d",
+ sprintf(msg,
+ "Initial Placement. Cost: %g BB Cost: %g TD Cost %g \t Channel Factor: %d",
costs.cost, costs.bb_cost, costs.timing_cost, width_fac);
//Draw the initial placement
update_screen(ScreenUpdatePriority::MAJOR, msg, PLACEMENT, timing_info);
if (placer_opts.placement_saves_per_temperature >= 1) {
- std::string filename = vtr::string_fmt("placement_%03d_%03d.place", 0, 0);
+ std::string filename = vtr::string_fmt("placement_%03d_%03d.place", 0,
+ 0);
VTR_LOG("Saving initial placement to file: %s\n", filename.c_str());
print_place(nullptr, nullptr, filename.c_str());
}
@@ -640,7 +674,9 @@ void try_place(const t_placer_opts& placer_opts,
first_move_lim = get_initial_move_lim(placer_opts, annealing_sched);
if (placer_opts.inner_loop_recompute_divider != 0) {
- inner_recompute_limit = (int)(0.5 + (float)first_move_lim / (float)placer_opts.inner_loop_recompute_divider);
+ inner_recompute_limit = (int)(0.5
+ + (float)first_move_lim
+ / (float)placer_opts.inner_loop_recompute_divider);
} else {
/*don't do an inner recompute */
inner_recompute_limit = first_move_lim + 1;
@@ -650,7 +686,9 @@ void try_place(const t_placer_opts& placer_opts,
* the commandline option quench_recompute_divider */
int quench_recompute_limit;
if (placer_opts.quench_recompute_divider != 0) {
- quench_recompute_limit = (int)(0.5 + (float)move_lim / (float)placer_opts.quench_recompute_divider);
+ quench_recompute_limit = (int)(0.5
+ + (float)move_lim
+ / (float)placer_opts.quench_recompute_divider);
} else {
/*don't do an quench recompute */
quench_recompute_limit = first_move_lim + 1;
@@ -662,36 +700,36 @@ void try_place(const t_placer_opts& placer_opts,
//allocate move type statistics vectors
MoveTypeStat move_type_stat;
- move_type_stat.num_moves.resize(placer_opts.place_static_move_prob.size(), 0);
- move_type_stat.accepted_moves.resize(placer_opts.place_static_move_prob.size(), 0);
- move_type_stat.aborted_moves.resize(placer_opts.place_static_move_prob.size(), 0);
+ move_type_stat.num_moves.resize(placer_opts.place_static_move_prob.size() + 1,
+ 0);
+ move_type_stat.accepted_moves.resize(
+ placer_opts.place_static_move_prob.size() + 1, 0);
+ move_type_stat.aborted_moves.resize(
+ placer_opts.place_static_move_prob.size() + 1, 0);
/* Get the first range limiter */
- first_rlim = (float)max(device_ctx.grid.width() - 1, device_ctx.grid.height() - 1);
+ first_rlim = (float)max(device_ctx.grid.width() - 1,
+ device_ctx.grid.height() - 1);
place_move_ctx.first_rlim = first_rlim;
/* Set the temperature high so essentially all swaps will be accepted */
/* when trying to determine the starting temp for placement inner loop. */
first_t = HUGE_POSITIVE_FLOAT;
- t_annealing_state state(annealing_sched, first_t, first_rlim, first_move_lim, first_crit_exponent);
+ t_annealing_state state(annealing_sched, first_t, first_rlim,
+ first_move_lim, first_crit_exponent);
/* Update the starting temperature for placement annealing to a more appropriate value */
- state.t = starting_t(&state,
- &costs,
- annealing_sched,
- place_delay_model.get(),
- placer_criticalities.get(),
- placer_setup_slacks.get(),
- timing_info.get(),
- *move_generator,
- pin_timing_invalidator.get(),
- blocks_affected,
- placer_opts,
- move_type_stat);
+ state.t = starting_t(&state, &costs, annealing_sched,
+ place_delay_model.get(), placer_criticalities.get(),
+ placer_setup_slacks.get(), timing_info.get(), *move_generator,
+ *manual_move_generator, pin_timing_invalidator.get(),
+ blocks_affected, placer_opts, move_type_stat);
if (!placer_opts.move_stats_file.empty()) {
- f_move_stats_file = std::unique_ptr(vtr::fopen(placer_opts.move_stats_file.c_str(), "w"), vtr::fclose);
+ f_move_stats_file = std::unique_ptr(
+ vtr::fopen(placer_opts.move_stats_file.c_str(), "w"),
+ vtr::fclose);
LOG_MOVE_STATS_HEADER();
}
@@ -724,15 +762,10 @@ void try_place(const t_placer_opts& placer_opts,
do {
vtr::Timer temperature_timer;
- outer_loop_update_timing_info(placer_opts,
- &costs,
- num_connections,
- state.crit_exponent,
- &outer_crit_iter_count,
- place_delay_model.get(),
- placer_criticalities.get(),
- placer_setup_slacks.get(),
- pin_timing_invalidator.get(),
+ outer_loop_update_timing_info(placer_opts, &costs, num_connections,
+ state.crit_exponent, &outer_crit_iter_count,
+ place_delay_model.get(), placer_criticalities.get(),
+ placer_setup_slacks.get(), pin_timing_invalidator.get(),
timing_info.get());
if (placer_opts.place_algorithm.is_timing_driven()) {
@@ -742,38 +775,39 @@ void try_place(const t_placer_opts& placer_opts,
//see if we should save the current placement solution as a checkpoint
- if (placer_opts.place_checkpointing && agent_state == LATE_IN_THE_ANNEAL) {
- save_placement_checkpoint_if_needed(placement_checkpoint, timing_info, costs, critical_path.delay());
+ if (placer_opts.place_checkpointing
+ && agent_state == LATE_IN_THE_ANNEAL) {
+ save_placement_checkpoint_if_needed(placement_checkpoint,
+ timing_info, costs, critical_path.delay());
}
}
//move the appropoiate move_generator to be the current used move generator
- assign_current_move_generator(move_generator, move_generator2, agent_state, placer_opts, false, current_move_generator);
+ assign_current_move_generator(move_generator, move_generator2,
+ agent_state, placer_opts, false, current_move_generator);
//do a complete inner loop iteration
- placement_inner_loop(&state, placer_opts,
- inner_recompute_limit, &stats,
- &costs,
- &moves_since_cost_recompute,
- pin_timing_invalidator.get(),
- place_delay_model.get(),
- placer_criticalities.get(),
- placer_setup_slacks.get(),
- *current_move_generator,
- blocks_affected,
- timing_info.get(),
- placer_opts.place_algorithm,
- move_type_stat,
+ placement_inner_loop(&state, placer_opts, inner_recompute_limit,
+ &stats, &costs, &moves_since_cost_recompute,
+ pin_timing_invalidator.get(), place_delay_model.get(),
+ placer_criticalities.get(), placer_setup_slacks.get(),
+ *current_move_generator, *manual_move_generator,
+ blocks_affected, timing_info.get(),
+ placer_opts.place_algorithm, move_type_stat,
timing_bb_factor);
//move the update used move_generator to its original variable
- update_move_generator(move_generator, move_generator2, agent_state, placer_opts, false, current_move_generator);
+ update_move_generator(move_generator, move_generator2, agent_state,
+ placer_opts, false, current_move_generator);
tot_iter += state.move_lim;
++state.num_temps;
- print_place_status(state, stats, temperature_timer.elapsed_sec(), critical_path.delay(), sTNS, sWNS, tot_iter);
- if (placer_opts.place_algorithm.is_timing_driven() && placer_opts.place_agent_multistate && agent_state == EARLY_IN_THE_ANNEAL) {
+ print_place_status(state, stats, temperature_timer.elapsed_sec(),
+ critical_path.delay(), sTNS, sWNS, tot_iter);
+ if (placer_opts.place_algorithm.is_timing_driven()
+ && placer_opts.place_agent_multistate
+ && agent_state == EARLY_IN_THE_ANNEAL) {
if (state.alpha < 0.85 && state.alpha > 0.6) {
agent_state = LATE_IN_THE_ANNEAL;
VTR_LOG("Agent's 2nd state: \n");
@@ -782,14 +816,16 @@ void try_place(const t_placer_opts& placer_opts,
sprintf(msg, "Cost: %g BB Cost %g TD Cost %g Temperature: %g",
costs.cost, costs.bb_cost, costs.timing_cost, state.t);
- update_screen(ScreenUpdatePriority::MINOR, msg, PLACEMENT, timing_info);
+ update_screen(ScreenUpdatePriority::MINOR, msg, PLACEMENT,
+ timing_info);
#ifdef VERBOSE
if (getEchoEnabled()) {
print_clb_placement("first_iteration_clb_placement.echo");
}
#endif
- } while (state.outer_loop_update(stats.success_rate, costs, placer_opts, annealing_sched));
+ } while (state.outer_loop_update(stats.success_rate, costs, placer_opts,
+ annealing_sched));
/* Outer loop of the simmulated annealing ends */
} //skip_anneal ends
@@ -802,39 +838,30 @@ void try_place(const t_placer_opts& placer_opts,
vtr::ScopedFinishTimer temperature_timer("Placement Quench");
- outer_loop_update_timing_info(placer_opts,
- &costs,
- num_connections,
- state.crit_exponent,
- &outer_crit_iter_count,
- place_delay_model.get(),
- placer_criticalities.get(),
- placer_setup_slacks.get(),
- pin_timing_invalidator.get(),
+ outer_loop_update_timing_info(placer_opts, &costs, num_connections,
+ state.crit_exponent, &outer_crit_iter_count,
+ place_delay_model.get(), placer_criticalities.get(),
+ placer_setup_slacks.get(), pin_timing_invalidator.get(),
timing_info.get());
//move the appropoiate move_generator to be the current used move generator
- assign_current_move_generator(move_generator, move_generator2, agent_state, placer_opts, true, current_move_generator);
+ assign_current_move_generator(move_generator, move_generator2,
+ agent_state, placer_opts, true, current_move_generator);
/* Run inner loop again with temperature = 0 so as to accept only swaps
* which reduce the cost of the placement */
- placement_inner_loop(&state, placer_opts,
- quench_recompute_limit, &stats,
- &costs,
- &moves_since_cost_recompute,
- pin_timing_invalidator.get(),
- place_delay_model.get(),
- placer_criticalities.get(),
- placer_setup_slacks.get(),
- *current_move_generator,
- blocks_affected,
- timing_info.get(),
- placer_opts.place_quench_algorithm,
- move_type_stat,
+ placement_inner_loop(&state, placer_opts, quench_recompute_limit,
+ &stats, &costs, &moves_since_cost_recompute,
+ pin_timing_invalidator.get(), place_delay_model.get(),
+ placer_criticalities.get(), placer_setup_slacks.get(),
+ *current_move_generator, *manual_move_generator,
+ blocks_affected, timing_info.get(),
+ placer_opts.place_quench_algorithm, move_type_stat,
timing_bb_factor);
//move the update used move_generator to its original variable
- update_move_generator(move_generator, move_generator2, agent_state, placer_opts, true, current_move_generator);
+ update_move_generator(move_generator, move_generator2, agent_state,
+ placer_opts, true, current_move_generator);
tot_iter += state.move_lim;
++state.num_temps;
@@ -845,7 +872,8 @@ void try_place(const t_placer_opts& placer_opts,
sWNS = timing_info->setup_worst_negative_slack();
}
- print_place_status(state, stats, temperature_timer.elapsed_sec(), critical_path.delay(), sTNS, sWNS, tot_iter);
+ print_place_status(state, stats, temperature_timer.elapsed_sec(),
+ critical_path.delay(), sTNS, sWNS, tot_iter);
}
auto post_quench_timing_stats = timing_ctx.stats;
@@ -855,22 +883,22 @@ void try_place(const t_placer_opts& placer_opts,
crit_params.crit_limit = placer_opts.place_crit_limit;
if (placer_opts.place_algorithm.is_timing_driven()) {
- perform_full_timing_update(crit_params,
- place_delay_model.get(),
- placer_criticalities.get(),
- placer_setup_slacks.get(),
- pin_timing_invalidator.get(),
- timing_info.get(),
- &costs);
- VTR_LOG("post-quench CPD = %g (ns) \n", 1e9 * timing_info->least_slack_critical_path().delay());
+ perform_full_timing_update(crit_params, place_delay_model.get(),
+ placer_criticalities.get(), placer_setup_slacks.get(),
+ pin_timing_invalidator.get(), timing_info.get(), &costs);
+ VTR_LOG("post-quench CPD = %g (ns) \n",
+ 1e9 * timing_info->least_slack_critical_path().delay());
}
//See if our latest checkpoint is better than the current placement solution
if (placer_opts.place_checkpointing)
- restore_best_placement(placement_checkpoint, timing_info, costs, placer_criticalities, placer_setup_slacks, place_delay_model, pin_timing_invalidator, crit_params);
+ restore_best_placement(placement_checkpoint, timing_info, costs,
+ placer_criticalities, placer_setup_slacks, place_delay_model,
+ pin_timing_invalidator, crit_params);
if (placer_opts.placement_saves_per_temperature >= 1) {
- std::string filename = vtr::string_fmt("placement_%03d_%03d.place", state.num_temps + 1, 0);
+ std::string filename = vtr::string_fmt("placement_%03d_%03d.place",
+ state.num_temps + 1, 0);
VTR_LOG("Saving final placement to file: %s\n", filename.c_str());
print_place(nullptr, nullptr, filename.c_str());
}
@@ -884,7 +912,8 @@ void try_place(const t_placer_opts& placer_opts,
}
#endif
- check_place(costs, place_delay_model.get(), placer_criticalities.get(), placer_opts.place_algorithm);
+ check_place(costs, place_delay_model.get(), placer_criticalities.get(),
+ placer_opts.place_algorithm);
//Some stats
VTR_LOG("\n");
@@ -898,28 +927,33 @@ void try_place(const t_placer_opts& placer_opts,
critical_path = timing_info->least_slack_critical_path();
if (isEchoFileEnabled(E_ECHO_FINAL_PLACEMENT_TIMING_GRAPH)) {
- tatum::write_echo(getEchoFileName(E_ECHO_FINAL_PLACEMENT_TIMING_GRAPH),
- *timing_ctx.graph, *timing_ctx.constraints, *placement_delay_calc, timing_info->analyzer());
-
- tatum::NodeId debug_tnode = id_or_pin_name_to_tnode(analysis_opts.echo_dot_timing_graph_node);
- write_setup_timing_graph_dot(getEchoFileName(E_ECHO_FINAL_PLACEMENT_TIMING_GRAPH) + std::string(".dot"),
- *timing_info, debug_tnode);
+ tatum::write_echo(
+ getEchoFileName(E_ECHO_FINAL_PLACEMENT_TIMING_GRAPH),
+ *timing_ctx.graph, *timing_ctx.constraints,
+ *placement_delay_calc, timing_info->analyzer());
+
+ tatum::NodeId debug_tnode = id_or_pin_name_to_tnode(
+ analysis_opts.echo_dot_timing_graph_node);
+ write_setup_timing_graph_dot(
+ getEchoFileName(E_ECHO_FINAL_PLACEMENT_TIMING_GRAPH)
+ + std::string(".dot"),
+ *timing_info, debug_tnode);
}
- generate_post_place_timing_reports(placer_opts,
- analysis_opts,
- *timing_info,
- *placement_delay_calc);
+ generate_post_place_timing_reports(placer_opts, analysis_opts,
+ *timing_info, *placement_delay_calc);
/* Print critical path delay metrics */
VTR_LOG("\n");
- print_setup_timing_summary(*timing_ctx.constraints, *timing_info->setup_analyzer(), "Placement estimated ");
+ print_setup_timing_summary(*timing_ctx.constraints,
+ *timing_info->setup_analyzer(), "Placement estimated ");
}
- sprintf(msg, "Placement. Cost: %g bb_cost: %g td_cost: %g Channel Factor: %d",
+ sprintf(msg,
+ "Placement. Cost: %g bb_cost: %g td_cost: %g Channel Factor: %d",
costs.cost, costs.bb_cost, costs.timing_cost, width_fac);
- VTR_LOG("Placement cost: %g, bb_cost: %g, td_cost: %g, \n",
- costs.cost, costs.bb_cost, costs.timing_cost);
+ VTR_LOG("Placement cost: %g, bb_cost: %g, td_cost: %g, \n", costs.cost,
+ costs.bb_cost, costs.timing_cost);
update_screen(ScreenUpdatePriority::MAJOR, msg, PLACEMENT, timing_info);
// Print out swap statistics
print_resources_utilization();
@@ -931,15 +965,16 @@ void try_place(const t_placer_opts& placer_opts,
free_placement_structs(placer_opts);
free_try_swap_arrays();
- print_timing_stats("Placement Quench", post_quench_timing_stats, pre_quench_timing_stats);
- print_timing_stats("Placement Total ", timing_ctx.stats, pre_place_timing_stats);
+ print_timing_stats("Placement Quench", post_quench_timing_stats,
+ pre_quench_timing_stats);
+ print_timing_stats("Placement Total ", timing_ctx.stats,
+ pre_place_timing_stats);
- VTR_LOG(
- "update_td_costs: connections %g nets %g sum_nets %g total %g\n",
- p_runtime_ctx.f_update_td_costs_connections_elapsed_sec,
- p_runtime_ctx.f_update_td_costs_nets_elapsed_sec,
- p_runtime_ctx.f_update_td_costs_sum_nets_elapsed_sec,
- p_runtime_ctx.f_update_td_costs_total_elapsed_sec);
+ VTR_LOG("update_td_costs: connections %g nets %g sum_nets %g total %g\n",
+ p_runtime_ctx.f_update_td_costs_connections_elapsed_sec,
+ p_runtime_ctx.f_update_td_costs_nets_elapsed_sec,
+ p_runtime_ctx.f_update_td_costs_sum_nets_elapsed_sec,
+ p_runtime_ctx.f_update_td_costs_total_elapsed_sec);
}
/* Function to update the setup slacks and criticalities before the inner loop of the annealing/quench */
@@ -972,13 +1007,8 @@ static void outer_loop_update_timing_info(const t_placer_opts& placer_opts,
crit_params.crit_limit = placer_opts.place_crit_limit;
//Update all timing related classes
- perform_full_timing_update(crit_params,
- delay_model,
- criticalities,
- setup_slacks,
- pin_timing_invalidator,
- timing_info,
- costs);
+ perform_full_timing_update(crit_params, delay_model, criticalities,
+ setup_slacks, pin_timing_invalidator, timing_info, costs);
*outer_crit_iter_count = 0;
}
@@ -1000,6 +1030,7 @@ static void placement_inner_loop(const t_annealing_state* state,
PlacerCriticalities* criticalities,
PlacerSetupSlacks* setup_slacks,
MoveGenerator& move_generator,
+ ManualMoveGenerator& manual_move_generator,
t_pl_blocks_to_be_moved& blocks_affected,
SetupTimingInfo* timing_info,
const t_place_algorithm& place_algorithm,
@@ -1013,21 +1044,14 @@ static void placement_inner_loop(const t_annealing_state* state,
inner_crit_iter_count = 1;
+ bool manual_move_enabled = false;
+
/* Inner loop begins */
for (inner_iter = 0; inner_iter < state->move_lim; inner_iter++) {
- e_move_result swap_result = try_swap(state,
- costs,
- move_generator,
- timing_info,
- pin_timing_invalidator,
- blocks_affected,
- delay_model,
- criticalities,
- setup_slacks,
- placer_opts,
- move_type_stat,
- place_algorithm,
- timing_bb_factor);
+ e_move_result swap_result = try_swap(state, costs, move_generator,
+ manual_move_generator, timing_info, pin_timing_invalidator,
+ blocks_affected, delay_model, criticalities, setup_slacks,
+ placer_opts, move_type_stat, place_algorithm, timing_bb_factor, manual_move_enabled);
if (swap_result == ACCEPTED) {
/* Move was accepted. Update statistics that are useful for the annealing schedule. */
@@ -1056,13 +1080,9 @@ static void placement_inner_loop(const t_annealing_state* state,
crit_params.crit_limit = placer_opts.place_crit_limit;
//Update all timing related classes
- perform_full_timing_update(crit_params,
- delay_model,
- criticalities,
- setup_slacks,
- pin_timing_invalidator,
- timing_info,
- costs);
+ perform_full_timing_update(crit_params, delay_model,
+ criticalities, setup_slacks, pin_timing_invalidator,
+ timing_info, costs);
}
inner_crit_iter_count++;
}
@@ -1081,15 +1101,21 @@ static void placement_inner_loop(const t_annealing_state* state,
*/
++(*moves_since_cost_recompute);
if (*moves_since_cost_recompute > MAX_MOVES_BEFORE_RECOMPUTE) {
- recompute_costs_from_scratch(placer_opts, delay_model, criticalities, costs);
+ recompute_costs_from_scratch(placer_opts, delay_model,
+ criticalities, costs);
*moves_since_cost_recompute = 0;
}
- if (placer_opts.placement_saves_per_temperature >= 1
- && inner_iter > 0
- && (inner_iter + 1) % (state->move_lim / placer_opts.placement_saves_per_temperature) == 0) {
- std::string filename = vtr::string_fmt("placement_%03d_%03d.place", state->num_temps + 1, inner_placement_save_count);
- VTR_LOG("Saving placement to file at temperature move %d / %d: %s\n", inner_iter, state->move_lim, filename.c_str());
+ if (placer_opts.placement_saves_per_temperature >= 1 && inner_iter > 0
+ && (inner_iter + 1)
+ % (state->move_lim
+ / placer_opts.placement_saves_per_temperature)
+ == 0) {
+ std::string filename = vtr::string_fmt("placement_%03d_%03d.place",
+ state->num_temps + 1, inner_placement_save_count);
+ VTR_LOG(
+ "Saving placement to file at temperature move %d / %d: %s\n",
+ inner_iter, state->move_lim, filename.c_str());
print_place(nullptr, nullptr, filename.c_str());
++inner_placement_save_count;
}
@@ -1105,8 +1131,9 @@ static void recompute_costs_from_scratch(const t_placer_opts& placer_opts,
t_placer_costs* costs) {
double new_bb_cost = recompute_bb_cost();
if (fabs(new_bb_cost - costs->bb_cost) > costs->bb_cost * ERROR_TOL) {
- std::string msg = vtr::string_fmt("in recompute_costs_from_scratch: new_bb_cost = %g, old bb_cost = %g\n",
- new_bb_cost, costs->bb_cost);
+ std::string msg = vtr::string_fmt(
+ "in recompute_costs_from_scratch: new_bb_cost = %g, old bb_cost = %g\n",
+ new_bb_cost, costs->bb_cost);
VPR_ERROR(VPR_ERROR_PLACE, msg.c_str());
}
costs->bb_cost = new_bb_cost;
@@ -1114,9 +1141,13 @@ static void recompute_costs_from_scratch(const t_placer_opts& placer_opts,
if (placer_opts.place_algorithm.is_timing_driven()) {
double new_timing_cost = 0.;
comp_td_costs(delay_model, *criticalities, &new_timing_cost);
- if (fabs(new_timing_cost - costs->timing_cost) > costs->timing_cost * ERROR_TOL) {
- std::string msg = vtr::string_fmt("in recompute_costs_from_scratch: new_timing_cost = %g, old timing_cost = %g, ERROR_TOL = %g\n",
- new_timing_cost, costs->timing_cost, ERROR_TOL);
+ if (fabs(
+ new_timing_cost
+ - costs->timing_cost)
+ > costs->timing_cost * ERROR_TOL) {
+ std::string msg = vtr::string_fmt(
+ "in recompute_costs_from_scratch: new_timing_cost = %g, old timing_cost = %g, ERROR_TOL = %g\n",
+ new_timing_cost, costs->timing_cost, ERROR_TOL);
VPR_ERROR(VPR_ERROR_PLACE, msg.c_str());
}
costs->timing_cost = new_timing_cost;
@@ -1143,18 +1174,7 @@ static int count_connections() {
}
///@brief Find the starting temperature for the annealing loop.
-static float starting_t(const t_annealing_state* state,
- t_placer_costs* costs,
- t_annealing_sched annealing_sched,
- const PlaceDelayModel* delay_model,
- PlacerCriticalities* criticalities,
- PlacerSetupSlacks* setup_slacks,
- SetupTimingInfo* timing_info,
- MoveGenerator& move_generator,
- ClusteredPinTimingInvalidator* pin_timing_invalidator,
- t_pl_blocks_to_be_moved& blocks_affected,
- const t_placer_opts& placer_opts,
- MoveTypeStat& move_type_stat) {
+static float starting_t(const t_annealing_state* state, t_placer_costs* costs, t_annealing_sched annealing_sched, const PlaceDelayModel* delay_model, PlacerCriticalities* criticalities, PlacerSetupSlacks* setup_slacks, SetupTimingInfo* timing_info, MoveGenerator& move_generator, ManualMoveGenerator& manual_move_generator, ClusteredPinTimingInvalidator* pin_timing_invalidator, t_pl_blocks_to_be_moved& blocks_affected, const t_placer_opts& placer_opts, MoveTypeStat& move_type_stat) {
if (annealing_sched.type == USER_SCHED) {
return (annealing_sched.init_t);
}
@@ -1168,23 +1188,26 @@ static float starting_t(const t_annealing_state* state,
double av = 0., sum_of_squares = 0.;
/* Determines the block swap loop count. */
- int move_lim = std::min(state->move_lim_max, (int)cluster_ctx.clb_nlist.blocks().size());
+ int move_lim = std::min(state->move_lim_max,
+ (int)cluster_ctx.clb_nlist.blocks().size());
+
+ bool manual_move_enabled = false;
for (int i = 0; i < move_lim; i++) {
+#ifndef NO_GRAPHICS
+ //Checks manual move flag for manual move feature
+ t_draw_state* draw_state = get_draw_state_vars();
+ if (draw_state->show_graphics) {
+ manual_move_enabled = manual_move_is_selected();
+ }
+#endif /*NO_GRAPHICS*/
+
//Will not deploy setup slack analysis, so omit crit_exponenet and setup_slack
- e_move_result swap_result = try_swap(state,
- costs,
- move_generator,
- timing_info,
- pin_timing_invalidator,
- blocks_affected,
- delay_model,
- criticalities,
- setup_slacks,
- placer_opts,
- move_type_stat,
- placer_opts.place_algorithm,
- REWARD_BB_TIMING_RELATIVE_WEIGHT);
+ e_move_result swap_result = try_swap(state, costs, move_generator,
+ manual_move_generator, timing_info, pin_timing_invalidator,
+ blocks_affected, delay_model, criticalities, setup_slacks,
+ placer_opts, move_type_stat, placer_opts.place_algorithm,
+ REWARD_BB_TIMING_RELATIVE_WEIGHT, manual_move_enabled);
if (swap_result == ACCEPTED) {
num_accepted++;
@@ -1206,7 +1229,8 @@ static float starting_t(const t_annealing_state* state,
/* Print warning if not all swaps are accepted. */
if (num_accepted != move_lim) {
- VTR_LOG_WARN("Starting t: %d of %d configurations accepted.\n", num_accepted, move_lim);
+ VTR_LOG_WARN("Starting t: %d of %d configurations accepted.\n",
+ num_accepted, move_lim);
}
#ifdef VERBOSE
@@ -1224,7 +1248,8 @@ static void update_move_nets(int num_nets_affected) {
auto& cluster_ctx = g_vpr_ctx.clustering();
auto& place_move_ctx = g_placer_ctx.mutable_move();
- for (int inet_affected = 0; inet_affected < num_nets_affected; inet_affected++) {
+ for (int inet_affected = 0; inet_affected < num_nets_affected;
+ inet_affected++) {
ClusterNetId net_id = ts_nets_to_update[inet_affected];
place_move_ctx.bb_coords[net_id] = ts_bb_coord_new[net_id];
@@ -1241,7 +1266,8 @@ static void update_move_nets(int num_nets_affected) {
static void reset_move_nets(int num_nets_affected) {
/* Reset the net cost function flags first. */
- for (int inet_affected = 0; inet_affected < num_nets_affected; inet_affected++) {
+ for (int inet_affected = 0; inet_affected < num_nets_affected;
+ inet_affected++) {
ClusterNetId net_id = ts_nets_to_update[inet_affected];
proposed_net_cost[net_id] = -1;
bb_updated_before[net_id] = NOT_UPDATED_YET;
@@ -1267,6 +1293,7 @@ static void reset_move_nets(int num_nets_affected) {
static e_move_result try_swap(const t_annealing_state* state,
t_placer_costs* costs,
MoveGenerator& move_generator,
+ ManualMoveGenerator& manual_move_generator,
SetupTimingInfo* timing_info,
ClusteredPinTimingInvalidator* pin_timing_invalidator,
t_pl_blocks_to_be_moved& blocks_affected,
@@ -1276,7 +1303,8 @@ static e_move_result try_swap(const t_annealing_state* state,
const t_placer_opts& placer_opts,
MoveTypeStat& move_type_stat,
const t_place_algorithm& place_algorithm,
- float timing_bb_factor) {
+ float timing_bb_factor,
+ bool manual_move_enabled) {
/* Picks some block and moves it to another spot. If this spot is *
* occupied, switch the blocks. Assess the change in cost function. *
* rlim is the range limiter. *
@@ -1312,8 +1340,17 @@ static e_move_result try_swap(const t_annealing_state* state,
rlim = state->rlim;
}
- //Generate a new move (perturbation) used to explore the space of possible placements
- e_create_move create_move_outcome = move_generator.propose_move(blocks_affected, move_type, rlim, placer_opts, criticalities);
+ e_create_move create_move_outcome;
+
+ //When manual move toggle button is active, the manual move window asks the user for input.
+ if (manual_move_enabled) {
+#ifndef NO_GRAPHICS
+ create_move_outcome = manual_move_display_and_propose(manual_move_generator, blocks_affected, move_type, rlim, placer_opts, criticalities);
+#endif //NO_GRAPHICS
+ } else {
+ //Generate a new move (perturbation) used to explore the space of possible placements
+ create_move_outcome = move_generator.propose_move(blocks_affected, move_type, rlim, placer_opts, criticalities);
+ }
++move_type_stat.num_moves[(int)move_type];
LOG_MOVE_STATS_PROPOSED(t, blocks_affected);
@@ -1323,8 +1360,8 @@ static e_move_result try_swap(const t_annealing_state* state,
if (create_move_outcome == e_create_move::ABORT) {
LOG_MOVE_STATS_OUTCOME(std::numeric_limits::quiet_NaN(),
std::numeric_limits::quiet_NaN(),
- std::numeric_limits::quiet_NaN(),
- "ABORTED", "illegal move");
+ std::numeric_limits::quiet_NaN(), "ABORTED",
+ "illegal move");
move_outcome = ABORTED;
@@ -1352,12 +1389,9 @@ static e_move_result try_swap(const t_annealing_state* state,
//
//Also find all the pins affected by the swap, and calculates new connection
//delays and timing costs and store them in proposed_* data structures.
- int num_nets_affected = find_affected_nets_and_update_costs(place_algorithm,
- delay_model,
- criticalities,
- blocks_affected,
- bb_delta_c,
- timing_delta_c);
+ int num_nets_affected = find_affected_nets_and_update_costs(
+ place_algorithm, delay_model, criticalities, blocks_affected,
+ bb_delta_c, timing_delta_c);
//For setup slack analysis, we first do a timing analysis to get the newest
//slack values resulted from the proposed block moves. If the move turns out
@@ -1366,8 +1400,7 @@ static e_move_result try_swap(const t_annealing_state* state,
if (place_algorithm == SLACK_TIMING_PLACE) {
/* Invalidates timing of modified connections for incremental timing updates. */
invalidate_affected_connections(blocks_affected,
- pin_timing_invalidator,
- timing_info);
+ pin_timing_invalidator, timing_info);
/* Update the connection_timing_cost and connection_delay *
* values from the temporary values. */
@@ -1383,11 +1416,8 @@ static e_move_result try_swap(const t_annealing_state* state,
* we need to revert block moves and restore the timing values. */
criticalities->disable_update();
setup_slacks->enable_update();
- update_timing_classes(crit_params,
- timing_info,
- criticalities,
- setup_slacks,
- pin_timing_invalidator);
+ update_timing_classes(crit_params, timing_info, criticalities,
+ setup_slacks, pin_timing_invalidator);
/* Get the setup slack analysis cost */
//TODO: calculate a weighted average of the slack cost and wiring cost
@@ -1396,7 +1426,8 @@ static e_move_result try_swap(const t_annealing_state* state,
/* Take delta_c as a combination of timing and wiring cost. In
* addition to `timing_tradeoff`, we normalize the cost values */
delta_c = (1 - timing_tradeoff) * bb_delta_c * costs->bb_cost_norm
- + timing_tradeoff * timing_delta_c * costs->timing_cost_norm;
+ + timing_tradeoff * timing_delta_c
+ * costs->timing_cost_norm;
} else {
VTR_ASSERT_SAFE(place_algorithm == BOUNDING_BOX_PLACE);
delta_c = bb_delta_c;
@@ -1405,6 +1436,13 @@ static e_move_result try_swap(const t_annealing_state* state,
/* 1 -> move accepted, 0 -> rejected. */
move_outcome = assess_swap(delta_c, state->t);
+ //Updates the manual_move_state members and displays costs to the user to decide whether to ACCEPT/REJECT manual move.
+#ifndef NO_GRAPHICS
+ if (manual_move_enabled) {
+ move_outcome = pl_do_manual_move(delta_c, timing_delta_c, bb_delta_c, move_outcome);
+ }
+#endif //NO_GRAPHICS
+
if (move_outcome == ACCEPTED) {
costs->cost += delta_c;
costs->bb_cost += bb_delta_c;
@@ -1425,8 +1463,7 @@ static e_move_result try_swap(const t_annealing_state* state,
* timing updates. These invalidations are accumulated for a *
* big timing update in the outer loop. */
invalidate_affected_connections(blocks_affected,
- pin_timing_invalidator,
- timing_info);
+ pin_timing_invalidator, timing_info);
/* Update the connection_timing_cost and connection_delay *
* values from the temporary values. */
@@ -1440,6 +1477,14 @@ static e_move_result try_swap(const t_annealing_state* state,
commit_move_blocks(blocks_affected);
++move_type_stat.accepted_moves[(int)move_type];
+
+ //Highlights the new block when manual move is selected.
+#ifndef NO_GRAPHICS
+ if (manual_move_enabled) {
+ manual_move_highlight_new_block_location();
+ }
+#endif //NO_GRAPHICS
+
} else {
VTR_ASSERT_SAFE(move_outcome == REJECTED);
@@ -1460,15 +1505,11 @@ static e_move_result try_swap(const t_annealing_state* state,
* move is rejected, and the same blocks are reverted to *
* their original positions. */
invalidate_affected_connections(blocks_affected,
- pin_timing_invalidator,
- timing_info);
+ pin_timing_invalidator, timing_info);
/* Revert the timing update */
- update_timing_classes(crit_params,
- timing_info,
- criticalities,
- setup_slacks,
- pin_timing_invalidator);
+ update_timing_classes(crit_params, timing_info, criticalities,
+ setup_slacks, pin_timing_invalidator);
VTR_ASSERT_SAFE_MSG(
verify_connection_setup_slacks(setup_slacks),
@@ -1482,8 +1523,10 @@ static e_move_result try_swap(const t_annealing_state* state,
}
move_outcome_stats.delta_cost_norm = delta_c;
- move_outcome_stats.delta_bb_cost_norm = bb_delta_c * costs->bb_cost_norm;
- move_outcome_stats.delta_timing_cost_norm = timing_delta_c * costs->timing_cost_norm;
+ move_outcome_stats.delta_bb_cost_norm = bb_delta_c
+ * costs->bb_cost_norm;
+ move_outcome_stats.delta_timing_cost_norm = timing_delta_c
+ * costs->timing_cost_norm;
move_outcome_stats.delta_bb_cost_abs = bb_delta_c;
move_outcome_stats.delta_timing_cost_abs = timing_delta_c;
@@ -1493,7 +1536,8 @@ static e_move_result try_swap(const t_annealing_state* state,
}
move_outcome_stats.outcome = move_outcome;
- calculate_reward_and_process_outcome(placer_opts, move_outcome_stats, delta_c, timing_bb_factor, move_generator);
+ calculate_reward_and_process_outcome(placer_opts, move_outcome_stats,
+ delta_c, timing_bb_factor, move_generator);
#ifdef VTR_ENABLE_DEBUG_LOGGING
# ifndef NO_GRAPHICS
@@ -1535,12 +1579,13 @@ static e_move_result try_swap(const t_annealing_state* state,
*
* @return The number of affected nets.
*/
-static int find_affected_nets_and_update_costs(const t_place_algorithm& place_algorithm,
- const PlaceDelayModel* delay_model,
- const PlacerCriticalities* criticalities,
- t_pl_blocks_to_be_moved& blocks_affected,
- double& bb_delta_c,
- double& timing_delta_c) {
+static int find_affected_nets_and_update_costs(
+ const t_place_algorithm& place_algorithm,
+ const PlaceDelayModel* delay_model,
+ const PlacerCriticalities* criticalities,
+ t_pl_blocks_to_be_moved& blocks_affected,
+ double& bb_delta_c,
+ double& timing_delta_c) {
VTR_ASSERT_SAFE(bb_delta_c == 0.);
VTR_ASSERT_SAFE(timing_delta_c == 0.);
auto& cluster_ctx = g_vpr_ctx.clustering();
@@ -1554,7 +1599,8 @@ static int find_affected_nets_and_update_costs(const t_place_algorithm& place_al
/* Go through all the pins in the moved block. */
for (ClusterPinId blk_pin : cluster_ctx.clb_nlist.block_pins(blk)) {
ClusterNetId net_id = cluster_ctx.clb_nlist.pin_net(blk_pin);
- VTR_ASSERT_SAFE_MSG(net_id, "Only valid nets should be found in compressed netlist block pins");
+ VTR_ASSERT_SAFE_MSG(net_id,
+ "Only valid nets should be found in compressed netlist block pins");
if (cluster_ctx.clb_nlist.net_is_ignored(net_id))
//TODO: Do we require anyting special here for global nets?
@@ -1569,17 +1615,20 @@ static int find_affected_nets_and_update_costs(const t_place_algorithm& place_al
if (place_algorithm.is_timing_driven()) {
/* Determine the change in connection delay and timing cost. */
- update_td_delta_costs(delay_model, *criticalities, net_id, blk_pin, blocks_affected, timing_delta_c);
+ update_td_delta_costs(delay_model, *criticalities, net_id,
+ blk_pin, blocks_affected, timing_delta_c);
}
}
}
/* Now update the bounding box costs (since the net bounding *
* boxes are up-to-date). The cost is only updated once per net. */
- for (int inet_affected = 0; inet_affected < num_affected_nets; inet_affected++) {
+ for (int inet_affected = 0; inet_affected < num_affected_nets;
+ inet_affected++) {
ClusterNetId net_id = ts_nets_to_update[inet_affected];
- proposed_net_cost[net_id] = get_net_cost(net_id, &ts_bb_coord_new[net_id]);
+ proposed_net_cost[net_id] = get_net_cost(net_id,
+ &ts_bb_coord_new[net_id]);
bb_delta_c += proposed_net_cost[net_id] - net_cost[net_id];
}
@@ -1587,7 +1636,8 @@ static int find_affected_nets_and_update_costs(const t_place_algorithm& place_al
}
///@brief Record effected nets.
-static void record_affected_net(const ClusterNetId net, int& num_affected_nets) {
+static void record_affected_net(const ClusterNetId net,
+ int& num_affected_nets) {
/* Record effected nets. */
if (proposed_net_cost[net] < 0.) {
/* Net not marked yet. */
@@ -1627,12 +1677,13 @@ static void update_net_bb(const ClusterNetId net,
int pin_height_offset = blk_type->pin_height_offset[iblk_pin];
//Incremental bounding box update
- update_bb(net, &ts_bb_coord_new[net],
- &ts_bb_edge_new[net],
+ update_bb(net, &ts_bb_coord_new[net], &ts_bb_edge_new[net],
blocks_affected.moved_blocks[iblk].old_loc.x + pin_width_offset,
- blocks_affected.moved_blocks[iblk].old_loc.y + pin_height_offset,
+ blocks_affected.moved_blocks[iblk].old_loc.y
+ + pin_height_offset,
blocks_affected.moved_blocks[iblk].new_loc.x + pin_width_offset,
- blocks_affected.moved_blocks[iblk].new_loc.y + pin_height_offset);
+ blocks_affected.moved_blocks[iblk].new_loc.y
+ + pin_height_offset);
}
}
@@ -1681,8 +1732,10 @@ static void update_td_delta_costs(const PlaceDelayModel* delay_model,
if (cluster_ctx.clb_nlist.pin_type(pin) == PinType::DRIVER) {
/* This pin is a net driver on a moved block. */
/* Recompute all point to point connection delays for the net sinks. */
- for (size_t ipin = 1; ipin < cluster_ctx.clb_nlist.net_pins(net).size(); ipin++) {
- float temp_delay = comp_td_single_connection_delay(delay_model, net, ipin);
+ for (size_t ipin = 1; ipin < cluster_ctx.clb_nlist.net_pins(net).size();
+ ipin++) {
+ float temp_delay = comp_td_single_connection_delay(delay_model, net,
+ ipin);
/* If the delay hasn't changed, do not mark this pin as affected */
if (temp_delay == connection_delay[net][ipin]) {
continue;
@@ -1692,7 +1745,8 @@ static void update_td_delta_costs(const PlaceDelayModel* delay_model,
proposed_connection_delay[net][ipin] = temp_delay;
proposed_connection_timing_cost[net][ipin] = criticalities.criticality(net, ipin) * temp_delay;
- delta_timing_cost += proposed_connection_timing_cost[net][ipin] - connection_timing_cost[net][ipin];
+ delta_timing_cost += proposed_connection_timing_cost[net][ipin]
+ - connection_timing_cost[net][ipin];
/* Record this connection in blocks_affected.affected_pins */
ClusterPinId sink_pin = cluster_ctx.clb_nlist.net_pin(net, ipin);
@@ -1707,7 +1761,8 @@ static void update_td_delta_costs(const PlaceDelayModel* delay_model,
/* Get the sink pin index in the net */
int ipin = cluster_ctx.clb_nlist.pin_net_index(pin);
- float temp_delay = comp_td_single_connection_delay(delay_model, net, ipin);
+ float temp_delay = comp_td_single_connection_delay(delay_model, net,
+ ipin);
/* If the delay hasn't changed, do not mark this pin as affected */
if (temp_delay == connection_delay[net][ipin]) {
return;
@@ -1717,7 +1772,8 @@ static void update_td_delta_costs(const PlaceDelayModel* delay_model,
proposed_connection_delay[net][ipin] = temp_delay;
proposed_connection_timing_cost[net][ipin] = criticalities.criticality(net, ipin) * temp_delay;
- delta_timing_cost += proposed_connection_timing_cost[net][ipin] - connection_timing_cost[net][ipin];
+ delta_timing_cost += proposed_connection_timing_cost[net][ipin]
+ - connection_timing_cost[net][ipin];
/* Record this connection in blocks_affected.affected_pins */
blocks_affected.affected_pins.push_back(pin);
@@ -1759,7 +1815,8 @@ static float analyze_setup_slack_cost(const PlacerSetupSlacks* setup_slacks) {
size_t ipin = clb_nlist.pin_net_index(clb_pin);
original_setup_slacks.push_back(connection_setup_slack[net_id][ipin]);
- proposed_setup_slacks.push_back(setup_slacks->setup_slack(net_id, ipin));
+ proposed_setup_slacks.push_back(
+ setup_slacks->setup_slack(net_id, ipin));
}
//Sort in ascending order, from the worse slack value to the best
@@ -1769,7 +1826,8 @@ static float analyze_setup_slack_cost(const PlacerSetupSlacks* setup_slacks) {
//Check the first pair of slack values that are different
//If found, return their difference
for (size_t idiff = 0; idiff < original_setup_slacks.size(); ++idiff) {
- float slack_diff = original_setup_slacks[idiff] - proposed_setup_slacks[idiff];
+ float slack_diff = original_setup_slacks[idiff]
+ - proposed_setup_slacks[idiff];
if (slack_diff != 0) {
return slack_diff;
@@ -1882,9 +1940,10 @@ static void revert_td_cost(const t_pl_blocks_to_be_moved& blocks_affected) {
* Invalidate all the timing graph edges associated with these connections via
* the ClusteredPinTimingInvalidator class.
*/
-static void invalidate_affected_connections(const t_pl_blocks_to_be_moved& blocks_affected,
- ClusteredPinTimingInvalidator* pin_tedges_invalidator,
- TimingInfo* timing_info) {
+static void invalidate_affected_connections(
+ const t_pl_blocks_to_be_moved& blocks_affected,
+ ClusteredPinTimingInvalidator* pin_tedges_invalidator,
+ TimingInfo* timing_info) {
VTR_ASSERT_SAFE(timing_info);
VTR_ASSERT_SAFE(pin_tedges_invalidator);
@@ -1895,10 +1954,12 @@ static void invalidate_affected_connections(const t_pl_blocks_to_be_moved& block
}
//Returns true if 'net' is driven by one of the blocks in 'blocks_affected'
-static bool driven_by_moved_block(const ClusterNetId net, const t_pl_blocks_to_be_moved& blocks_affected) {
+static bool driven_by_moved_block(const ClusterNetId net,
+ const t_pl_blocks_to_be_moved& blocks_affected) {
auto& cluster_ctx = g_vpr_ctx.clustering();
- ClusterBlockId net_driver_block = cluster_ctx.clb_nlist.net_driver_block(net);
+ ClusterBlockId net_driver_block = cluster_ctx.clb_nlist.net_driver_block(
+ net);
for (int iblk = 0; iblk < blocks_affected.num_moved_blocks; iblk++) {
if (net_driver_block == blocks_affected.moved_blocks[iblk].block_num) {
return true;
@@ -1925,23 +1986,28 @@ static double comp_bb_cost(e_cost_methods method) {
if (!cluster_ctx.clb_nlist.net_is_ignored(net_id)) { /* Do only if not ignored. */
/* Small nets don't use incremental updating on their bounding boxes, *
* so they can use a fast bounding box calculator. */
- if (cluster_ctx.clb_nlist.net_sinks(net_id).size() >= SMALL_NET && method == NORMAL) {
+ if (cluster_ctx.clb_nlist.net_sinks(net_id).size() >= SMALL_NET
+ && method == NORMAL) {
get_bb_from_scratch(net_id, &place_move_ctx.bb_coords[net_id],
&place_move_ctx.bb_num_on_edges[net_id]);
} else {
- get_non_updateable_bb(net_id, &place_move_ctx.bb_coords[net_id]);
+ get_non_updateable_bb(net_id,
+ &place_move_ctx.bb_coords[net_id]);
}
- net_cost[net_id] = get_net_cost(net_id, &place_move_ctx.bb_coords[net_id]);
+ net_cost[net_id] = get_net_cost(net_id,
+ &place_move_ctx.bb_coords[net_id]);
cost += net_cost[net_id];
if (method == CHECK)
- expected_wirelength += get_net_wirelength_estimate(net_id, &place_move_ctx.bb_coords[net_id]);
+ expected_wirelength += get_net_wirelength_estimate(net_id,
+ &place_move_ctx.bb_coords[net_id]);
}
}
if (method == CHECK) {
VTR_LOG("\n");
- VTR_LOG("BB estimate of min-dist (placement) wire length: %.0f\n", expected_wirelength);
+ VTR_LOG("BB estimate of min-dist (placement) wire length: %.0f\n",
+ expected_wirelength);
}
return cost;
}
@@ -1975,23 +2041,30 @@ static void alloc_and_load_placement_structs(float place_cost_exp,
/* Allocate structures associated with timing driven placement */
/* [0..cluster_ctx.clb_nlist.nets().size()-1][1..num_pins-1] */
- p_timing_ctx.connection_delay = make_net_pins_matrix(cluster_ctx.clb_nlist, 0.f);
- p_timing_ctx.proposed_connection_delay = make_net_pins_matrix(cluster_ctx.clb_nlist, 0.f);
+ p_timing_ctx.connection_delay = make_net_pins_matrix(
+ cluster_ctx.clb_nlist, 0.f);
+ p_timing_ctx.proposed_connection_delay = make_net_pins_matrix(
+ cluster_ctx.clb_nlist, 0.f);
- p_timing_ctx.connection_setup_slack = make_net_pins_matrix(cluster_ctx.clb_nlist, std::numeric_limits::infinity());
+ p_timing_ctx.connection_setup_slack = make_net_pins_matrix(
+ cluster_ctx.clb_nlist, std::numeric_limits::infinity());
- p_timing_ctx.connection_timing_cost = PlacerTimingCosts(cluster_ctx.clb_nlist);
- p_timing_ctx.proposed_connection_timing_cost = make_net_pins_matrix(cluster_ctx.clb_nlist, 0.);
+ p_timing_ctx.connection_timing_cost = PlacerTimingCosts(
+ cluster_ctx.clb_nlist);
+ p_timing_ctx.proposed_connection_timing_cost = make_net_pins_matrix<
+ double>(cluster_ctx.clb_nlist, 0.);
p_timing_ctx.net_timing_cost.resize(num_nets, 0.);
for (auto net_id : cluster_ctx.clb_nlist.nets()) {
- for (ipin = 1; ipin < cluster_ctx.clb_nlist.net_pins(net_id).size(); ipin++) {
+ for (ipin = 1; ipin < cluster_ctx.clb_nlist.net_pins(net_id).size();
+ ipin++) {
p_timing_ctx.connection_delay[net_id][ipin] = 0;
p_timing_ctx.proposed_connection_delay[net_id][ipin] = INVALID_DELAY;
p_timing_ctx.proposed_connection_timing_cost[net_id][ipin] = INVALID_DELAY;
- if (cluster_ctx.clb_nlist.net_is_ignored(net_id)) continue;
+ if (cluster_ctx.clb_nlist.net_is_ignored(net_id))
+ continue;
p_timing_ctx.connection_timing_cost[net_id][ipin] = INVALID_DELAY;
}
@@ -2085,8 +2158,10 @@ static void get_bb_from_scratch(ClusterNetId net_id, t_bb* coords, t_bb* num_on_
ClusterBlockId bnum = cluster_ctx.clb_nlist.net_driver_block(net_id);
pnum = net_pin_to_tile_pin_index(net_id, 0);
VTR_ASSERT(pnum >= 0);
- x = place_ctx.block_locs[bnum].loc.x + physical_tile_type(bnum)->pin_width_offset[pnum];
- y = place_ctx.block_locs[bnum].loc.y + physical_tile_type(bnum)->pin_height_offset[pnum];
+ x = place_ctx.block_locs[bnum].loc.x
+ + physical_tile_type(bnum)->pin_width_offset[pnum];
+ y = place_ctx.block_locs[bnum].loc.y
+ + physical_tile_type(bnum)->pin_height_offset[pnum];
x = max(min(x, grid.width() - 2), 1);
y = max(min(y, grid.height() - 2), 1);
@@ -2103,8 +2178,10 @@ static void get_bb_from_scratch(ClusterNetId net_id, t_bb* coords, t_bb* num_on_
for (auto pin_id : cluster_ctx.clb_nlist.net_sinks(net_id)) {
bnum = cluster_ctx.clb_nlist.pin_block(pin_id);
pnum = tile_pin_index(pin_id);
- x = place_ctx.block_locs[bnum].loc.x + physical_tile_type(bnum)->pin_width_offset[pnum];
- y = place_ctx.block_locs[bnum].loc.y + physical_tile_type(bnum)->pin_height_offset[pnum];
+ x = place_ctx.block_locs[bnum].loc.x
+ + physical_tile_type(bnum)->pin_width_offset[pnum];
+ y = place_ctx.block_locs[bnum].loc.y
+ + physical_tile_type(bnum)->pin_height_offset[pnum];
/* Code below counts IO blocks as being within the 1..grid.width()-2, 1..grid.height()-2 clb array. *
* This is because channels do not go out of the 0..grid.width()-2, 0..grid.height()-2 range, and *
@@ -2174,7 +2251,8 @@ static double get_net_wirelength_estimate(ClusterNetId net_id, t_bb* bbptr) {
double ncost, crossing;
auto& cluster_ctx = g_vpr_ctx.clustering();
- crossing = wirelength_crossing_count(cluster_ctx.clb_nlist.net_pins(net_id).size());
+ crossing = wirelength_crossing_count(
+ cluster_ctx.clb_nlist.net_pins(net_id).size());
/* Could insert a check for xmin == xmax. In that case, assume *
* connection will be made with no bends and hence no x-cost. *
@@ -2197,7 +2275,8 @@ static double get_net_cost(ClusterNetId net_id, t_bb* bbptr) {
double ncost, crossing;
auto& cluster_ctx = g_vpr_ctx.clustering();
- crossing = wirelength_crossing_count(cluster_ctx.clb_nlist.net_pins(net_id).size());
+ crossing = wirelength_crossing_count(
+ cluster_ctx.clb_nlist.net_pins(net_id).size());
/* Could insert a check for xmin == xmax. In that case, assume *
* connection will be made with no bends and hence no x-cost. *
@@ -2234,8 +2313,10 @@ static void get_non_updateable_bb(ClusterNetId net_id, t_bb* bb_coord_new) {
ClusterBlockId bnum = cluster_ctx.clb_nlist.net_driver_block(net_id);
pnum = net_pin_to_tile_pin_index(net_id, 0);
- x = place_ctx.block_locs[bnum].loc.x + physical_tile_type(bnum)->pin_width_offset[pnum];
- y = place_ctx.block_locs[bnum].loc.y + physical_tile_type(bnum)->pin_height_offset[pnum];
+ x = place_ctx.block_locs[bnum].loc.x
+ + physical_tile_type(bnum)->pin_width_offset[pnum];
+ y = place_ctx.block_locs[bnum].loc.y
+ + physical_tile_type(bnum)->pin_height_offset[pnum];
xmin = x;
ymin = y;
@@ -2245,8 +2326,10 @@ static void get_non_updateable_bb(ClusterNetId net_id, t_bb* bb_coord_new) {
for (auto pin_id : cluster_ctx.clb_nlist.net_sinks(net_id)) {
bnum = cluster_ctx.clb_nlist.pin_block(pin_id);
pnum = tile_pin_index(pin_id);
- x = place_ctx.block_locs[bnum].loc.x + physical_tile_type(bnum)->pin_width_offset[pnum];
- y = place_ctx.block_locs[bnum].loc.y + physical_tile_type(bnum)->pin_height_offset[pnum];
+ x = place_ctx.block_locs[bnum].loc.x
+ + physical_tile_type(bnum)->pin_width_offset[pnum];
+ y = place_ctx.block_locs[bnum].loc.y
+ + physical_tile_type(bnum)->pin_height_offset[pnum];
if (x < xmin) {
xmin = x;
@@ -2289,7 +2372,6 @@ static void update_bb(ClusterNetId net_id, t_bb* bb_coord_new, t_bb* bb_edge_new
* The x and y coordinates are the pin's x and y coordinates. */
/* IO blocks are considered to be one cell in for simplicity. */
//TODO: account for multiple physical pin instances per logical pin
-
const t_bb *curr_bb_edge, *curr_bb_coord;
auto& device_ctx = g_vpr_ctx.device();
@@ -2501,11 +2583,13 @@ static void alloc_and_load_for_fast_cost_update(float place_cost_exp) {
* subhigh must be greater than or equal to sublow, we only need to *
* allocate storage for the lower half of a matrix. */
- chanx_place_cost_fac = (float**)vtr::malloc((device_ctx.grid.height()) * sizeof(float*));
+ chanx_place_cost_fac = (float**)vtr::malloc(
+ (device_ctx.grid.height()) * sizeof(float*));
for (size_t i = 0; i < device_ctx.grid.height(); i++)
chanx_place_cost_fac[i] = (float*)vtr::malloc((i + 1) * sizeof(float));
- chany_place_cost_fac = (float**)vtr::malloc((device_ctx.grid.width() + 1) * sizeof(float*));
+ chany_place_cost_fac = (float**)vtr::malloc(
+ (device_ctx.grid.width() + 1) * sizeof(float*));
for (size_t i = 0; i < device_ctx.grid.width(); i++)
chany_place_cost_fac[i] = (float*)vtr::malloc((i + 1) * sizeof(float));
@@ -2517,7 +2601,8 @@ static void alloc_and_load_for_fast_cost_update(float place_cost_exp) {
for (size_t high = 1; high < device_ctx.grid.height(); high++) {
chanx_place_cost_fac[high][high] = device_ctx.chan_width.x_list[high];
for (size_t low = 0; low < high; low++) {
- chanx_place_cost_fac[high][low] = chanx_place_cost_fac[high - 1][low] + device_ctx.chan_width.x_list[high];
+ chanx_place_cost_fac[high][low] = chanx_place_cost_fac[high - 1][low]
+ + device_ctx.chan_width.x_list[high];
}
}
@@ -2543,7 +2628,9 @@ static void alloc_and_load_for_fast_cost_update(float place_cost_exp) {
chanx_place_cost_fac[high][low] = (high - low + 1.)
/ chanx_place_cost_fac[high][low];
- chanx_place_cost_fac[high][low] = pow((double)chanx_place_cost_fac[high][low], (double)place_cost_exp);
+ chanx_place_cost_fac[high][low] = pow(
+ (double)chanx_place_cost_fac[high][low],
+ (double)place_cost_exp);
}
/* Now do the same thing for the y-directed channels. First get the *
@@ -2554,7 +2641,8 @@ static void alloc_and_load_for_fast_cost_update(float place_cost_exp) {
for (size_t high = 1; high < device_ctx.grid.width(); high++) {
chany_place_cost_fac[high][high] = device_ctx.chan_width.y_list[high];
for (size_t low = 0; low < high; low++) {
- chany_place_cost_fac[high][low] = chany_place_cost_fac[high - 1][low] + device_ctx.chan_width.y_list[high];
+ chany_place_cost_fac[high][low] = chany_place_cost_fac[high - 1][low]
+ + device_ctx.chan_width.y_list[high];
}
}
@@ -2575,7 +2663,9 @@ static void alloc_and_load_for_fast_cost_update(float place_cost_exp) {
chany_place_cost_fac[high][low] = (high - low + 1.)
/ chany_place_cost_fac[high][low];
- chany_place_cost_fac[high][low] = pow((double)chany_place_cost_fac[high][low], (double)place_cost_exp);
+ chany_place_cost_fac[high][low] = pow(
+ (double)chany_place_cost_fac[high][low],
+ (double)place_cost_exp);
}
}
@@ -2592,7 +2682,8 @@ static void check_place(const t_placer_costs& costs,
int error = 0;
error += check_placement_consistency();
- error += check_placement_costs(costs, delay_model, criticalities, place_algorithm);
+ error += check_placement_costs(costs, delay_model, criticalities,
+ place_algorithm);
error += check_placement_floorplanning();
if (error == 0) {
@@ -2617,17 +2708,22 @@ static int check_placement_costs(const t_placer_costs& costs,
bb_cost_check = comp_bb_cost(CHECK);
if (fabs(bb_cost_check - costs.bb_cost) > costs.bb_cost * ERROR_TOL) {
- VTR_LOG_ERROR("bb_cost_check: %g and bb_cost: %g differ in check_place.\n",
- bb_cost_check, costs.bb_cost);
+ VTR_LOG_ERROR(
+ "bb_cost_check: %g and bb_cost: %g differ in check_place.\n",
+ bb_cost_check, costs.bb_cost);
error++;
}
if (place_algorithm.is_timing_driven()) {
comp_td_costs(delay_model, *criticalities, &timing_cost_check);
//VTR_LOG("timing_cost recomputed from scratch: %g\n", timing_cost_check);
- if (fabs(timing_cost_check - costs.timing_cost) > costs.timing_cost * ERROR_TOL) {
- VTR_LOG_ERROR("timing_cost_check: %g and timing_cost: %g differ in check_place.\n",
- timing_cost_check, costs.timing_cost);
+ if (fabs(
+ timing_cost_check
+ - costs.timing_cost)
+ > costs.timing_cost * ERROR_TOL) {
+ VTR_LOG_ERROR(
+ "timing_cost_check: %g and timing_cost: %g differ in check_place.\n",
+ timing_cost_check, costs.timing_cost);
error++;
}
}
@@ -2635,7 +2731,8 @@ static int check_placement_costs(const t_placer_costs& costs,
}
static int check_placement_consistency() {
- return check_block_placement_consistency() + check_macro_placement_consistency();
+ return check_block_placement_consistency()
+ + check_macro_placement_consistency();
}
static int check_block_placement_consistency() {
@@ -2645,14 +2742,18 @@ static int check_block_placement_consistency() {
auto& place_ctx = g_vpr_ctx.placement();
auto& device_ctx = g_vpr_ctx.device();
- vtr::vector bdone(cluster_ctx.clb_nlist.blocks().size(), 0);
+ vtr::vector bdone(
+ cluster_ctx.clb_nlist.blocks().size(), 0);
/* Step through device grid and placement. Check it against blocks */
for (size_t i = 0; i < device_ctx.grid.width(); i++)
for (size_t j = 0; j < device_ctx.grid.height(); j++) {
- if (place_ctx.grid_blocks[i][j].usage > device_ctx.grid[i][j].type->capacity) {
- VTR_LOG_ERROR("%d blocks were placed at grid location (%zu,%zu), but location capacity is %d.\n",
- place_ctx.grid_blocks[i][j].usage, i, j, device_ctx.grid[i][j].type->capacity);
+ if (place_ctx.grid_blocks[i][j].usage
+ > device_ctx.grid[i][j].type->capacity) {
+ VTR_LOG_ERROR(
+ "%d blocks were placed at grid location (%zu,%zu), but location capacity is %d.\n",
+ place_ctx.grid_blocks[i][j].usage, i, j,
+ device_ctx.grid[i][j].type->capacity);
error++;
}
int usage_check = 0;
@@ -2665,24 +2766,29 @@ static int check_block_placement_consistency() {
auto physical_tile = device_ctx.grid[i][j].type;
if (physical_tile_type(bnum) != physical_tile) {
- VTR_LOG_ERROR("Block %zu type (%s) does not match grid location (%zu,%zu) type (%s).\n",
- size_t(bnum), logical_block->name, i, j, physical_tile->name);
+ VTR_LOG_ERROR(
+ "Block %zu type (%s) does not match grid location (%zu,%zu) type (%s).\n",
+ size_t(bnum), logical_block->name, i, j,
+ physical_tile->name);
error++;
}
auto& loc = place_ctx.block_locs[bnum].loc;
- if (loc.x != int(i) || loc.y != int(j) || !is_sub_tile_compatible(physical_tile, logical_block, loc.sub_tile)) {
- VTR_LOG_ERROR("Block %zu's location is (%d,%d,%d) but found in grid at (%zu,%zu,%d).\n",
- size_t(bnum), loc.x, loc.y, loc.sub_tile,
- i, j, k);
+ if (loc.x != int(i) || loc.y != int(j)
+ || !is_sub_tile_compatible(physical_tile, logical_block,
+ loc.sub_tile)) {
+ VTR_LOG_ERROR(
+ "Block %zu's location is (%d,%d,%d) but found in grid at (%zu,%zu,%d).\n",
+ size_t(bnum), loc.x, loc.y, loc.sub_tile, i, j, k);
error++;
}
++usage_check;
bdone[bnum]++;
}
if (usage_check != place_ctx.grid_blocks[i][j].usage) {
- VTR_LOG_ERROR("%d block(s) were placed at location (%zu,%zu), but location contains %d block(s).\n",
- place_ctx.grid_blocks[i][j].usage, i, j, usage_check);
+ VTR_LOG_ERROR(
+ "%d block(s) were placed at location (%zu,%zu), but location contains %d block(s).\n",
+ place_ctx.grid_blocks[i][j].usage, i, j, usage_check);
error++;
}
}
@@ -2708,23 +2814,28 @@ int check_macro_placement_consistency() {
for (size_t imacro = 0; imacro < place_ctx.pl_macros.size(); imacro++) {
auto head_iblk = pl_macros[imacro].members[0].blk_index;
- for (size_t imember = 0; imember < pl_macros[imacro].members.size(); imember++) {
+ for (size_t imember = 0; imember < pl_macros[imacro].members.size();
+ imember++) {
auto member_iblk = pl_macros[imacro].members[imember].blk_index;
// Compute the suppossed member's x,y,z location
- t_pl_loc member_pos = place_ctx.block_locs[head_iblk].loc + pl_macros[imacro].members[imember].offset;
+ t_pl_loc member_pos = place_ctx.block_locs[head_iblk].loc
+ + pl_macros[imacro].members[imember].offset;
// Check the place_ctx.block_locs data structure first
if (place_ctx.block_locs[member_iblk].loc != member_pos) {
- VTR_LOG_ERROR("Block %zu in pl_macro #%zu is not placed in the proper orientation.\n",
- size_t(member_iblk), imacro);
+ VTR_LOG_ERROR(
+ "Block %zu in pl_macro #%zu is not placed in the proper orientation.\n",
+ size_t(member_iblk), imacro);
error++;
}
// Then check the place_ctx.grid data structure
- if (place_ctx.grid_blocks[member_pos.x][member_pos.y].blocks[member_pos.sub_tile] != member_iblk) {
- VTR_LOG_ERROR("Block %zu in pl_macro #%zu is not placed in the proper orientation.\n",
- size_t(member_iblk), imacro);
+ if (place_ctx.grid_blocks[member_pos.x][member_pos.y].blocks[member_pos.sub_tile]
+ != member_iblk) {
+ VTR_LOG_ERROR(
+ "Block %zu in pl_macro #%zu is not placed in the proper orientation.\n",
+ size_t(member_iblk), imacro);
error++;
}
} // Finish going through all the members
@@ -2762,12 +2873,16 @@ static void generate_post_place_timing_reports(const t_placer_opts& placer_opts,
auto& timing_ctx = g_vpr_ctx.timing();
auto& atom_ctx = g_vpr_ctx.atom();
- VprTimingGraphResolver resolver(atom_ctx.nlist, atom_ctx.lookup, *timing_ctx.graph, delay_calc);
+ VprTimingGraphResolver resolver(atom_ctx.nlist, atom_ctx.lookup,
+ *timing_ctx.graph, delay_calc);
resolver.set_detail_level(analysis_opts.timing_report_detail);
- tatum::TimingReporter timing_reporter(resolver, *timing_ctx.graph, *timing_ctx.constraints);
+ tatum::TimingReporter timing_reporter(resolver, *timing_ctx.graph,
+ *timing_ctx.constraints);
- timing_reporter.report_timing_setup(placer_opts.post_place_timing_report_file, *timing_info.setup_analyzer(), analysis_opts.timing_report_npaths);
+ timing_reporter.report_timing_setup(
+ placer_opts.post_place_timing_report_file,
+ *timing_info.setup_analyzer(), analysis_opts.timing_report_npaths);
}
#if 0
@@ -2782,10 +2897,14 @@ static void update_screen_debug() {
#endif
static void print_place_status_header() {
- VTR_LOG("---- ------ ------- ------- ---------- ---------- ------- ---------- -------- ------- ------- ------ -------- --------- ------\n");
- VTR_LOG("Tnum Time T Av Cost Av BB Cost Av TD Cost CPD sTNS sWNS Ac Rate Std Dev R lim Crit Exp Tot Moves Alpha\n");
- VTR_LOG(" (sec) (ns) (ns) (ns) \n");
- VTR_LOG("---- ------ ------- ------- ---------- ---------- ------- ---------- -------- ------- ------- ------ -------- --------- ------\n");
+ VTR_LOG(
+ "---- ------ ------- ------- ---------- ---------- ------- ---------- -------- ------- ------- ------ -------- --------- ------\n");
+ VTR_LOG(
+ "Tnum Time T Av Cost Av BB Cost Av TD Cost CPD sTNS sWNS Ac Rate Std Dev R lim Crit Exp Tot Moves Alpha\n");
+ VTR_LOG(
+ " (sec) (ns) (ns) (ns) \n");
+ VTR_LOG(
+ "---- ------ ------- ------- ---------- ---------- ------- ---------- -------- ------- ------- ------ -------- --------- ------\n");
}
static void print_place_status(const t_annealing_state& state,
@@ -2802,12 +2921,10 @@ static void print_place_status(const t_annealing_state& state,
"%7.3f %10.2f %-10.5g "
"%7.3f % 10.3g % 8.3f "
"%7.3f %7.4f %6.1f %8.2f",
- state.num_temps,
- elapsed_sec,
- state.t,
- stats.av_cost, stats.av_bb_cost, stats.av_timing_cost,
- 1e9 * cpd, 1e9 * sTNS, 1e9 * sWNS,
- stats.success_rate, stats.std_dev, state.rlim, state.crit_exponent);
+ state.num_temps, elapsed_sec, state.t,
+ stats.av_cost, stats.av_bb_cost, stats.av_timing_cost, 1e9 * cpd,
+ 1e9 * sTNS, 1e9 * sWNS, stats.success_rate, stats.std_dev,
+ state.rlim, state.crit_exponent);
pretty_print_uint(" ", tot_moves, 9, 3);
@@ -2825,7 +2942,9 @@ static void print_resources_utilization() {
//Record the resource requirement
std::map num_type_instances;
- std::map> num_placed_instances;
+ std::map>
+ num_placed_instances;
for (auto blk_id : cluster_ctx.clb_nlist.blocks()) {
auto block_loc = place_ctx.block_locs[blk_id];
auto loc = block_loc.loc;
@@ -2836,22 +2955,27 @@ static void print_resources_utilization() {
num_type_instances[logical_block]++;
num_placed_instances[logical_block][physical_tile]++;
- max_block_name = std::max(max_block_name, strlen(logical_block->name));
- max_tile_name = std::max(max_tile_name, strlen(physical_tile->name));
+ max_block_name = std::max(max_block_name,
+ strlen(logical_block->name));
+ max_tile_name = std::max(max_tile_name,
+ strlen(physical_tile->name));
}
VTR_LOG("\n");
VTR_LOG("Placement resource usage:\n");
for (auto logical_block : num_type_instances) {
for (auto physical_tile : num_placed_instances[logical_block.first]) {
- VTR_LOG(" %-*s implemented as %-*s: %d\n", max_block_name, logical_block.first->name, max_tile_name, physical_tile.first->name, physical_tile.second);
+ VTR_LOG(" %-*s implemented as %-*s: %d\n", max_block_name,
+ logical_block.first->name, max_tile_name,
+ physical_tile.first->name, physical_tile.second);
}
}
VTR_LOG("\n");
}
static void print_placement_swaps_stats(const t_annealing_state& state) {
- size_t total_swap_attempts = num_swap_rejected + num_swap_accepted + num_swap_aborted;
+ size_t total_swap_attempts = num_swap_rejected + num_swap_accepted
+ + num_swap_aborted;
VTR_ASSERT(total_swap_attempts > 0);
size_t num_swap_print_digits = ceil(log10(total_swap_attempts));
@@ -2859,15 +2983,21 @@ static void print_placement_swaps_stats(const t_annealing_state& state) {
float accept_rate = (float)num_swap_accepted / total_swap_attempts;
float abort_rate = (float)num_swap_aborted / total_swap_attempts;
VTR_LOG("Placement number of temperatures: %d\n", state.num_temps);
- VTR_LOG("Placement total # of swap attempts: %*d\n", num_swap_print_digits, total_swap_attempts);
- VTR_LOG("\tSwaps accepted: %*d (%4.1f %%)\n", num_swap_print_digits, num_swap_accepted, 100 * accept_rate);
- VTR_LOG("\tSwaps rejected: %*d (%4.1f %%)\n", num_swap_print_digits, num_swap_rejected, 100 * reject_rate);
- VTR_LOG("\tSwaps aborted : %*d (%4.1f %%)\n", num_swap_print_digits, num_swap_aborted, 100 * abort_rate);
+ VTR_LOG("Placement total # of swap attempts: %*d\n", num_swap_print_digits,
+ total_swap_attempts);
+ VTR_LOG("\tSwaps accepted: %*d (%4.1f %%)\n", num_swap_print_digits,
+ num_swap_accepted, 100 * accept_rate);
+ VTR_LOG("\tSwaps rejected: %*d (%4.1f %%)\n", num_swap_print_digits,
+ num_swap_rejected, 100 * reject_rate);
+ VTR_LOG("\tSwaps aborted : %*d (%4.1f %%)\n", num_swap_print_digits,
+ num_swap_aborted, 100 * abort_rate);
}
-static void print_placement_move_types_stats(const MoveTypeStat& move_type_stat) {
+static void print_placement_move_types_stats(
+ const MoveTypeStat& move_type_stat) {
float moves, accepted, rejected, aborted;
- float total_moves = std::accumulate(move_type_stat.num_moves.begin(), move_type_stat.num_moves.end(), 0.0);
+ float total_moves = std::accumulate(move_type_stat.num_moves.begin(),
+ move_type_stat.num_moves.end(), 0.0);
std::string move_name;
VTR_LOG("\n\nPercentage of different move types:\n");
@@ -2879,19 +3009,29 @@ static void print_placement_move_types_stats(const MoveTypeStat& move_type_stat)
aborted = move_type_stat.aborted_moves[i];
rejected = moves - (accepted + aborted);
move_name = move_type_to_string(e_move_type(i));
- VTR_LOG("\t%.17s move: %2.2f %% (acc=%2.2f %%, rej=%2.2f %%, aborted=%2.2f %%)\n", move_name.c_str(), 100 * moves / total_moves, 100 * accepted / moves, 100 * rejected / moves, 100 * aborted / moves);
+ VTR_LOG(
+ "\t%.17s move: %2.2f %% (acc=%2.2f %%, rej=%2.2f %%, aborted=%2.2f %%)\n",
+ move_name.c_str(), 100 * moves / total_moves,
+ 100 * accepted / moves, 100 * rejected / moves,
+ 100 * aborted / moves);
}
}
VTR_LOG("\n");
}
-static void calculate_reward_and_process_outcome(const t_placer_opts& placer_opts, const MoveOutcomeStats& move_outcome_stats, const double& delta_c, float timing_bb_factor, MoveGenerator& move_generator) {
+static void calculate_reward_and_process_outcome(
+ const t_placer_opts& placer_opts,
+ const MoveOutcomeStats& move_outcome_stats,
+ const double& delta_c,
+ float timing_bb_factor,
+ MoveGenerator& move_generator) {
std::string reward_fun_string = placer_opts.place_reward_fun;
e_reward_function reward_fun = string_to_reward(reward_fun_string);
if (reward_fun == BASIC) {
move_generator.process_outcome(-1 * delta_c, reward_fun);
- } else if (reward_fun == NON_PENALIZING_BASIC || reward_fun == RUNTIME_AWARE) {
+ } else if (reward_fun == NON_PENALIZING_BASIC
+ || reward_fun == RUNTIME_AWARE) {
if (delta_c < 0) {
move_generator.process_outcome(-1 * delta_c, reward_fun);
} else {
@@ -2899,7 +3039,12 @@ static void calculate_reward_and_process_outcome(const t_placer_opts& placer_opt
}
} else if (reward_fun == WL_BIASED_RUNTIME_AWARE) {
if (delta_c < 0) {
- float reward = -1 * (move_outcome_stats.delta_cost_norm + (0.5 - timing_bb_factor) * move_outcome_stats.delta_timing_cost_norm + timing_bb_factor * move_outcome_stats.delta_bb_cost_norm);
+ float reward = -1
+ * (move_outcome_stats.delta_cost_norm
+ + (0.5 - timing_bb_factor)
+ * move_outcome_stats.delta_timing_cost_norm
+ + timing_bb_factor
+ * move_outcome_stats.delta_bb_cost_norm);
move_generator.process_outcome(reward, reward_fun);
} else {
move_generator.process_outcome(0, reward_fun);
diff --git a/vpr/src/place/place.h b/vpr/src/place/place.h
index 514fe0e9306..4bd161ec64d 100644
--- a/vpr/src/place/place.h
+++ b/vpr/src/place/place.h
@@ -2,6 +2,7 @@
#define VPR_PLACE_H
#include "vpr_types.h"
+
void try_place(const t_placer_opts& placer_opts,
t_annealing_sched annealing_sched,
const t_router_opts& router_opts,
@@ -13,4 +14,5 @@ void try_place(const t_placer_opts& placer_opts,
int num_directs);
bool placer_needs_lookahead(const t_vpr_setup& vpr_setup);
+
#endif