diff --git a/vpr/src/base/vpr_context.h b/vpr/src/base/vpr_context.h index 137a1527246..ca644ae7edd 100644 --- a/vpr/src/base/vpr_context.h +++ b/vpr/src/base/vpr_context.h @@ -565,6 +565,9 @@ struct NocContext : public Context { class ServerContext : public Context { public: + bool is_enabled() const { return is_enabled_; } + void set_enabled(bool is_enabled) { is_enabled_ = is_enabled; } + const Server& server() const { return server_; } Server& server() { return server_; } @@ -587,6 +590,7 @@ class ServerContext : public Context { const std::shared_ptr& hold_timing_info() const { return hold_timing_info_; } private: + bool is_enabled_ = false; Server server_; TaskResolver task_resolver_; diff --git a/vpr/src/draw/draw.cpp b/vpr/src/draw/draw.cpp index 3bb135eedfb..83d4e814842 100644 --- a/vpr/src/draw/draw.cpp +++ b/vpr/src/draw/draw.cpp @@ -238,6 +238,7 @@ void init_graphics_state(bool show_graphics_val, draw_state->is_flat = is_flat; if (server) { + g_vpr_ctx.server_ctx().set_enabled(true); g_vpr_ctx.server_ctx().server().setPortNum(port_num); g_timeout_add(200, redraw_callback, &application); } diff --git a/vpr/src/draw/draw_basic.cpp b/vpr/src/draw/draw_basic.cpp index 831093201cd..f5e60b14ae2 100644 --- a/vpr/src/draw/draw_basic.cpp +++ b/vpr/src/draw/draw_basic.cpp @@ -951,20 +951,31 @@ void draw_crit_path(ezgl::renderer* g) { return; //No timing to draw } - ServerContext& server_ctx = g_vpr_ctx.server_ctx(); // shortcut - calcCritPath(server_ctx.critical_path_num(), server_ctx.path_type()); + if (g_vpr_ctx.server_ctx().is_enabled()) { + ServerContext& server_ctx = g_vpr_ctx.server_ctx(); // shortcut - const auto& paths = server_ctx.crit_paths(); // shortcut + auto paths = server_ctx.crit_paths(); - // check path index - if (server_ctx.crit_path_index() >= static_cast(paths.size())) { - server_ctx.set_crit_path_index(-1); - } - if (server_ctx.crit_path_index() == -1) { - return; + // check path index + if (server_ctx.crit_path_index() >= static_cast(paths.size())) { + server_ctx.set_crit_path_index(-1); + } + if (server_ctx.crit_path_index() != -1) { + tatum::TimingPath path = paths[server_ctx.crit_path_index()]; + draw_crit_path(path, g); + } + } else { + const int crit_path_index = 0; + auto paths = calcSetupCritPaths(1); + if (paths.size()>0) { + auto path = paths[crit_path_index]; + draw_crit_path(path, g); + } } +} - tatum::TimingPath path = paths[server_ctx.crit_path_index()]; +void draw_crit_path(const tatum::TimingPath& path, ezgl::renderer* g) { + t_draw_state* draw_state = get_draw_state_vars(); //Walk through the timing path drawing each edge tatum::NodeId prev_node; diff --git a/vpr/src/draw/draw_basic.h b/vpr/src/draw/draw_basic.h index 4b2fad749c2..0c391a49bbe 100644 --- a/vpr/src/draw/draw_basic.h +++ b/vpr/src/draw/draw_basic.h @@ -86,6 +86,8 @@ void draw_routing_util(ezgl::renderer* g); */ void draw_crit_path(ezgl::renderer* g); +void draw_crit_path(const tatum::TimingPath& path, ezgl::renderer* g); + /* Draws critical path shown as flylines. Takes in start and end coordinates, time delay, & renderer.*/ void draw_flyline_timing_edge(ezgl::point2d start, ezgl::point2d end, float incr_delay, ezgl::renderer* g); diff --git a/vpr/src/server/pathhelper.cpp b/vpr/src/server/pathhelper.cpp index 3deacb06f9e..92f5251a577 100644 --- a/vpr/src/server/pathhelper.cpp +++ b/vpr/src/server/pathhelper.cpp @@ -44,31 +44,25 @@ std::string getPathsStr(const std::vector& paths, const std:: return ss.str(); } -void calcCritPath(int numMax, const std::string& type) +std::vector calcSetupCritPaths(int numMax) { - ServerContext& server_ctx = g_vpr_ctx.server_ctx(); // shortcut + tatum::TimingPathCollector path_collector; - server_ctx.set_critical_path_num(numMax); - server_ctx.set_path_type(type); + t_draw_state* draw_state = get_draw_state_vars(); + auto& timing_ctx = g_vpr_ctx.timing(); + return path_collector.collect_worst_setup_timing_paths( + *timing_ctx.graph, + *(draw_state->setup_timing_info->setup_analyzer()), numMax); +} + +std::vector calcHoldCritPaths(int numMax, const std::shared_ptr& hold_timing_info) +{ tatum::TimingPathCollector path_collector; - t_draw_state* draw_state = get_draw_state_vars(); auto& timing_ctx = g_vpr_ctx.timing(); - if (type == "setup") { - auto paths = path_collector.collect_worst_setup_timing_paths( - *timing_ctx.graph, - *(draw_state->setup_timing_info->setup_analyzer()), numMax); - server_ctx.set_crit_paths(paths); - } else if (type == "hold") { - if (server_ctx.hold_timing_info()) { - auto paths = path_collector.collect_worst_hold_timing_paths( - *timing_ctx.graph, - *(server_ctx.hold_timing_info()->hold_analyzer()), numMax); - server_ctx.set_crit_paths(paths); - } else { - std::cerr << "g_vpr_ctx.hold_timing_info is nullptr" << std::endl; - } - } + return path_collector.collect_worst_hold_timing_paths( + *timing_ctx.graph, + *(hold_timing_info->hold_analyzer()), numMax); } \ No newline at end of file diff --git a/vpr/src/server/pathhelper.h b/vpr/src/server/pathhelper.h index 3623b16ee40..b7e43ab2cff 100644 --- a/vpr/src/server/pathhelper.h +++ b/vpr/src/server/pathhelper.h @@ -3,10 +3,15 @@ #include #include +#include #include "tatum/report/TimingPath.hpp" +class SetupHoldTimingInfo; + std::string getPathsStr(const std::vector& paths, const std::string& detailesLevel, bool is_flat_routing); -void calcCritPath(int numMax, const std::string& type); + +std::vector calcSetupCritPaths(int numMax); +std::vector calcHoldCritPaths(int numMax, const std::shared_ptr& hold_timing_info); #endif diff --git a/vpr/src/server/taskresolver.cpp b/vpr/src/server/taskresolver.cpp index 110403d645a..fa1f6dcf74b 100644 --- a/vpr/src/server/taskresolver.cpp +++ b/vpr/src/server/taskresolver.cpp @@ -56,19 +56,41 @@ bool TaskResolver::update(ezgl::application* app) if (task.cmd() == CMD_GET_PATH_LIST_ID) { options.validateNamePresence({OPTION_PATH_NUM, OPTION_PATH_TYPE, OPTION_DETAILS_LEVEL, OPTION_IS_FLOAT_ROUTING}); int nCriticalPathNum = options.getInt(OPTION_PATH_NUM, 1); - std::string typePath = options.getString(OPTION_PATH_TYPE); + std::string pathType = options.getString(OPTION_PATH_TYPE); std::string detailsLevel = options.getString(OPTION_DETAILS_LEVEL); bool isFlat = options.getBool(OPTION_IS_FLOAT_ROUTING, false); if (!options.hasErrors()) { - if (typePath != server_ctx.path_type()) { + if (pathType != server_ctx.path_type()) { server_ctx.set_crit_path_index(-1); } - calcCritPath(nCriticalPathNum, typePath); - std::string msg = getPathsStr(server_ctx.crit_paths(), detailsLevel, isFlat); - server_ctx.set_path_type(typePath); // duplicated - task.success(msg); + + server_ctx.set_path_type(pathType); + server_ctx.set_critical_path_num(nCriticalPathNum); + if (pathType == "setup") { + auto paths = calcSetupCritPaths(nCriticalPathNum); + server_ctx.set_crit_paths(paths); + } else if (pathType == "hold") { + auto hold_timing_info = server_ctx.hold_timing_info(); + if (hold_timing_info) { + auto paths = calcHoldCritPaths(nCriticalPathNum, hold_timing_info); + server_ctx.set_crit_paths(paths); + } else { + std::string msg{"cannot calculate hold critical path due to hold_timing_info nullptr"}; + std::cerr << msg << std::endl; + task.fail(msg); + } + } else { + std::string msg{"unknown path type " + pathType}; + std::cerr << msg << std::endl; + task.fail(msg); + } + + if (!task.hasError()) { + std::string msg{getPathsStr(server_ctx.crit_paths(), detailsLevel, isFlat)}; + task.success(msg); + } } else { - std::string msg = "options errors in get crit path list telegram: " + options.errorsStr(); + std::string msg{"options errors in get crit path list telegram: " + options.errorsStr()}; std::cerr << msg << std::endl; task.fail(msg); } @@ -92,7 +114,7 @@ bool TaskResolver::update(ezgl::application* app) task.fail(msg); } } else { - std::string msg = "selectedIndex=" + std::to_string(pathIndex) + " is out of range [0-" + std::to_string(static_cast(server_ctx.crit_paths().size())-1) + "]"; + std::string msg{"selectedIndex=" + std::to_string(pathIndex) + " is out of range [0-" + std::to_string(static_cast(server_ctx.crit_paths().size())-1) + "]"}; std::cerr << msg << std::endl; task.fail(msg); }