From 27cc8f1614fc94b744d509acf9516880c10fab98 Mon Sep 17 00:00:00 2001 From: James Cherry Date: Mon, 6 Jul 2020 15:18:13 -0700 Subject: [PATCH] report_path -format json --- include/sta/Network.hh | 7 +++++ include/sta/SearchClass.hh | 3 +- network/Network.cc | 11 +++++++ search/ReportPath.cc | 62 ++++++++++++++++++++++++++++++++++++++ search/ReportPath.hh | 5 +++ tcl/Search.tcl | 2 +- tcl/StaTcl.i | 2 ++ 7 files changed, 90 insertions(+), 2 deletions(-) diff --git a/include/sta/Network.hh b/include/sta/Network.hh index 4a6e092e..879ad2c5 100644 --- a/include/sta/Network.hh +++ b/include/sta/Network.hh @@ -323,6 +323,13 @@ public: virtual VertexId vertexId(const Pin *pin) const = 0; virtual void setVertexId(Pin *pin, VertexId id) = 0; + // Return the physical X/Y coordinates of the pin. + virtual void location(const Pin *pin, + // Return values. + double x, + double y, + bool exists) const; + int pinCount(); int pinCount(Instance *inst); int leafPinCount(); diff --git a/include/sta/SearchClass.hh b/include/sta/SearchClass.hh index 2eaae23c..c6f49dd3 100644 --- a/include/sta/SearchClass.hh +++ b/include/sta/SearchClass.hh @@ -119,7 +119,8 @@ enum class ReportPathFormat { full, shorter, endpoint, summary, - slack_only + slack_only, + json }; static const int tag_index_bits = 24; diff --git a/network/Network.cc b/network/Network.cc index 8ac29711..535566f9 100644 --- a/network/Network.cc +++ b/network/Network.cc @@ -935,6 +935,17 @@ Network::findInstPinsMatching(const Instance *instance, } } +void +Network::location(const Pin *pin, + // Return values. + double x, + double y, + bool exists) const +{ + x = y = 0.0; + exists = false; +} + int Network::instanceCount(Instance *inst) { diff --git a/search/ReportPath.cc b/search/ReportPath.cc index 456cb2fd..09c2443c 100644 --- a/search/ReportPath.cc +++ b/search/ReportPath.cc @@ -2503,6 +2503,27 @@ ReportPath::reportPath(const PathEnd *end, void ReportPath::reportPath(const Path *path, string &result) +{ + switch (format_) { + case ReportPathFormat::full: + case ReportPathFormat::full_clock: + case ReportPathFormat::full_clock_expanded: + reportPathFull(path, result); + break; + case ReportPathFormat::json: + reportPathJson(path, result); + break; + case ReportPathFormat::summary: + case ReportPathFormat::slack_only: + default: + internalError("unsupported path type"); + break; + } +} + +void +ReportPath::reportPathFull(const Path *path, + string &result) { reportPathHeader(result); PathExpanded expanded(path, this); @@ -2510,6 +2531,47 @@ ReportPath::reportPath(const Path *path, false, result); } +void +ReportPath::reportPathJson(const Path *path, + string &result) +{ + result += "{ \"path\": [\n"; + PathExpanded expanded(path, this); + for (auto i = expanded.startIndex(); i < expanded.size(); i++) { + PathRef *path = expanded.path(i); + const Pin *pin = path->vertex(this)->pin(); + result += " {\n"; + result += " \"pin\": \""; + result += network_->pathName(pin); + result += "\",\n"; + + double x, y; + bool exists; + string tmp; + network_->location(pin, x, y, exists); + if (exists) { + result += " \"x\": "; + stringPrint(tmp, "%.3f", x); + result += tmp + ",\n"; + result += " \"y\": "; + stringPrint(tmp, "%.3f", y); + result += tmp + "\n"; + } + + result += " \"arrival\": "; + stringPrint(tmp, "%.3e", path->arrival(this)); + result += tmp + ",\n"; + + result += " \"slew\": "; + stringPrint(tmp, "%.3e", path->slew(this)); + result += tmp + ",\n"; + + result += " }\n"; + } + result += " ]\n"; + result += "}\n"; +} + void ReportPath::reportPath1(const Path *path, PathExpanded &expanded, diff --git a/search/ReportPath.hh b/search/ReportPath.hh index c7ae2e75..3fda967c 100644 --- a/search/ReportPath.hh +++ b/search/ReportPath.hh @@ -63,6 +63,7 @@ public: void reportPathEnd(PathEnd *end, PathEnd *prev_end); void reportPathEnds(PathEndSeq *ends); + // for debugging void reportPath(const Path *path); void reportShort(const PathEndUnconstrained *end, @@ -341,6 +342,10 @@ protected: string &result); void reportPath(const Path *path, string &result); + void reportPathFull(const Path *path, + string &result); + void reportPathJson(const Path *path, + string &result); void reportPathHeader(string &result); void reportPath1(const Path *path, PathExpanded &expanded, diff --git a/tcl/Search.tcl b/tcl/Search.tcl index 23a06b0e..41491223 100644 --- a/tcl/Search.tcl +++ b/tcl/Search.tcl @@ -227,7 +227,7 @@ proc parse_report_path_options { cmd args_var default_format if [info exists path_options(-format)] { set format $path_options(-format) set formats {full full_clock full_clock_expanded short \ - end slack_only summary} + end slack_only summary json} if { [lsearch $formats $format] == -1 } { sta_error "-format $format not recognized." } diff --git a/tcl/StaTcl.i b/tcl/StaTcl.i index 8e6ff2e1..4500e3a6 100644 --- a/tcl/StaTcl.i +++ b/tcl/StaTcl.i @@ -1065,6 +1065,8 @@ using namespace sta; $1 = ReportPathFormat::summary; else if (stringEq(arg, "slack_only")) $1 = ReportPathFormat::slack_only; + else if (stringEq(arg, "json")) + $1 = ReportPathFormat::json; else { tclError(interp, "Error: unknown path type %s.", arg); return TCL_ERROR;