report_checks -format json
commit d4337917f790d90d7e16d068a19d9d9f8f44b760
Author: James Cherry <cherry@parallaxsw.com>
Date: Mon Sep 16 16:42:19 2024 -0700
report json
Signed-off-by: James Cherry <cherry@parallaxsw.com>
commit a2707db7210437e4afc7b6af2c0b1e5cbdc0fa2a
Author: James Cherry <cherry@parallaxsw.com>
Date: Mon Sep 16 15:45:08 2024 -0700
report json
Signed-off-by: James Cherry <cherry@parallaxsw.com>
commit f9d511250046a5d3c5105299e42cdc4d75ccdfef
Author: James Cherry <cherry@parallaxsw.com>
Date: Sun Sep 15 18:42:39 2024 -0700
report json
Signed-off-by: James Cherry <cherry@parallaxsw.com>
commit 82d4d5002e9d134396d199e56d47ea3fdee08a16
Author: James Cherry <cherry@parallaxsw.com>
Date: Sat Sep 14 20:44:45 2024 -0700
report json
Signed-off-by: James Cherry <cherry@parallaxsw.com>
Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
parent
d2ffbffe2e
commit
bae1afcb11
BIN
doc/OpenSTA.odt
BIN
doc/OpenSTA.odt
Binary file not shown.
BIN
doc/OpenSTA.pdf
BIN
doc/OpenSTA.pdf
Binary file not shown.
|
|
@ -40,7 +40,7 @@ public:
|
|||
size_t size() const { return paths_.size(); }
|
||||
// path(0) is the startpoint.
|
||||
// path(size()-1) is the endpoint.
|
||||
PathRef *path(size_t index);
|
||||
const PathRef *path(size_t index) const;
|
||||
TimingArc *prevArc(size_t index);
|
||||
// Returns the path start point.
|
||||
// Register/Latch Q pin
|
||||
|
|
|
|||
|
|
@ -905,9 +905,9 @@ public:
|
|||
// Previous path end is used to detect path group changes
|
||||
// so headers are reported by group.
|
||||
void reportPathEnd(PathEnd *end,
|
||||
PathEnd *prev_end);
|
||||
PathEnd *prev_end,
|
||||
bool last);
|
||||
void reportPathEnd(PathEnd *end);
|
||||
void reportPathEnds(PathEndSeq *ends);
|
||||
ReportPath *reportPath() { return report_path_; }
|
||||
void reportPath(Path *path);
|
||||
|
||||
|
|
|
|||
|
|
@ -169,6 +169,11 @@ void
|
|||
stringPrint(string &str,
|
||||
const char *fmt,
|
||||
...) __attribute__((format (printf, 2, 3)));
|
||||
// Formated append to std::string.
|
||||
void
|
||||
stringAppend(string &str,
|
||||
const char *fmt,
|
||||
...) __attribute__((format (printf, 2, 3)));
|
||||
|
||||
// Print to a temporary string.
|
||||
char *
|
||||
|
|
|
|||
|
|
@ -146,8 +146,8 @@ PathExpanded::startIndex() const
|
|||
return pathsIndex(start_index_);
|
||||
}
|
||||
|
||||
PathRef *
|
||||
PathExpanded::path(size_t index)
|
||||
const PathRef *
|
||||
PathExpanded::path(size_t index) const
|
||||
{
|
||||
if (index < paths_.size())
|
||||
return &paths_[pathsIndex(index)];
|
||||
|
|
|
|||
|
|
@ -1260,7 +1260,7 @@ getProperty(PathEnd *end,
|
|||
PathExpanded expanded(end->path(), sta);
|
||||
PathRefSeq paths;
|
||||
for (auto i = expanded.startIndex(); i < expanded.size(); i++) {
|
||||
PathRef *path = expanded.path(i);
|
||||
const PathRef *path = expanded.path(i);
|
||||
paths.push_back(*path);
|
||||
}
|
||||
return PropertyValue(&paths);
|
||||
|
|
|
|||
|
|
@ -269,58 +269,16 @@ ReportPath::setReportSigmas(bool report)
|
|||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
void
|
||||
ReportPath::reportPathEndHeader()
|
||||
{
|
||||
switch (format_) {
|
||||
case ReportPathFormat::full:
|
||||
case ReportPathFormat::full_clock:
|
||||
case ReportPathFormat::full_clock_expanded:
|
||||
case ReportPathFormat::shorter:
|
||||
case ReportPathFormat::endpoint:
|
||||
break;
|
||||
case ReportPathFormat::summary:
|
||||
reportSummaryHeader();
|
||||
break;
|
||||
case ReportPathFormat::slack_only:
|
||||
reportSlackOnlyHeader();
|
||||
break;
|
||||
default:
|
||||
report_->critical(1470, "unsupported path type");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ReportPath::reportPathEndFooter()
|
||||
{
|
||||
string header;
|
||||
switch (format_) {
|
||||
case ReportPathFormat::full:
|
||||
case ReportPathFormat::full_clock:
|
||||
case ReportPathFormat::full_clock_expanded:
|
||||
case ReportPathFormat::shorter:
|
||||
break;
|
||||
case ReportPathFormat::endpoint:
|
||||
case ReportPathFormat::summary:
|
||||
case ReportPathFormat::slack_only:
|
||||
reportBlankLine();
|
||||
break;
|
||||
default:
|
||||
report_->critical(1471, "unsupported path type");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ReportPath::reportPathEnd(PathEnd *end)
|
||||
{
|
||||
reportPathEnd(end, nullptr);
|
||||
reportPathEnd(end, nullptr, true);
|
||||
}
|
||||
|
||||
void
|
||||
ReportPath::reportPathEnd(PathEnd *end,
|
||||
PathEnd *prev_end)
|
||||
PathEnd *prev_end,
|
||||
bool last)
|
||||
{
|
||||
switch (format_) {
|
||||
case ReportPathFormat::full:
|
||||
|
|
@ -345,8 +303,8 @@ ReportPath::reportPathEnd(PathEnd *end,
|
|||
case ReportPathFormat::slack_only:
|
||||
reportSlackOnly(end);
|
||||
break;
|
||||
default:
|
||||
report_->critical(1473, "unsupported path type");
|
||||
case ReportPathFormat::json:
|
||||
reportJson(end, last);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -367,6 +325,49 @@ ReportPath::reportPathEnds(PathEndSeq *ends)
|
|||
reportPathEndFooter();
|
||||
}
|
||||
|
||||
void
|
||||
ReportPath::reportPathEndHeader()
|
||||
{
|
||||
switch (format_) {
|
||||
case ReportPathFormat::full:
|
||||
case ReportPathFormat::full_clock:
|
||||
case ReportPathFormat::full_clock_expanded:
|
||||
case ReportPathFormat::shorter:
|
||||
case ReportPathFormat::endpoint:
|
||||
break;
|
||||
case ReportPathFormat::summary:
|
||||
reportSummaryHeader();
|
||||
break;
|
||||
case ReportPathFormat::slack_only:
|
||||
reportSlackOnlyHeader();
|
||||
break;
|
||||
case ReportPathFormat::json:
|
||||
reportJsonHeader();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ReportPath::reportPathEndFooter()
|
||||
{
|
||||
string header;
|
||||
switch (format_) {
|
||||
case ReportPathFormat::full:
|
||||
case ReportPathFormat::full_clock:
|
||||
case ReportPathFormat::full_clock_expanded:
|
||||
case ReportPathFormat::shorter:
|
||||
break;
|
||||
case ReportPathFormat::endpoint:
|
||||
case ReportPathFormat::summary:
|
||||
case ReportPathFormat::slack_only:
|
||||
reportBlankLine();
|
||||
break;
|
||||
case ReportPathFormat::json:
|
||||
reportJsonFooter();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ReportPath::reportEndpointHeader(PathEnd *end,
|
||||
PathEnd *prev_end)
|
||||
|
|
@ -1043,6 +1044,146 @@ ReportPath::pathEndpoint(PathEnd *end)
|
|||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
void
|
||||
ReportPath::reportJsonHeader()
|
||||
{
|
||||
report_->reportLine("{\"checks\": [");
|
||||
}
|
||||
|
||||
void
|
||||
ReportPath::reportJsonFooter()
|
||||
{
|
||||
report_->reportLine("]");
|
||||
report_->reportLine("}");
|
||||
}
|
||||
|
||||
void
|
||||
ReportPath::reportJson(const PathEnd *end,
|
||||
bool last)
|
||||
{
|
||||
string result;
|
||||
result += "{\n";
|
||||
stringAppend(result, " \"type\": \"%s\",\n", end->typeName());
|
||||
stringAppend(result, " \"path_group\": \"%s\",\n",
|
||||
search_->pathGroup(end)->name());
|
||||
stringAppend(result, " \"path_type\": \"%s\",\n",
|
||||
end->minMax(this)->asString());
|
||||
|
||||
PathExpanded expanded(end->path(), this);
|
||||
const Pin *startpoint = expanded.startPath()->vertex(this)->pin();
|
||||
const Pin *endpoint = expanded.endPath()->vertex(this)->pin();
|
||||
stringAppend(result, " \"startpoint\": \"%s\",\n",
|
||||
network_->pathName(startpoint));
|
||||
stringAppend(result, " \"endpoint\": \"%s\",\n",
|
||||
network_->pathName(endpoint));
|
||||
|
||||
const ClockEdge *src_clk_edge = end->sourceClkEdge(this);
|
||||
const PathVertex *tgt_clk_path = end->targetClkPath();
|
||||
if (src_clk_edge) {
|
||||
stringAppend(result, " \"source_clock\": \"%s\",\n",
|
||||
src_clk_edge->clock()->name());
|
||||
stringAppend(result, " \"source_clock_edge\": \"%s\",\n",
|
||||
src_clk_edge->transition()->name());
|
||||
}
|
||||
reportJson(expanded, "source_path", 2, !end->isUnconstrained(), result);
|
||||
|
||||
const ClockEdge *tgt_clk_edge = end->targetClkEdge(this);
|
||||
if (tgt_clk_edge) {
|
||||
stringAppend(result, " \"target_clock\": \"%s\",\n",
|
||||
tgt_clk_edge->clock()->name());
|
||||
stringAppend(result, " \"target_clock_edge\": \"%s\",\n",
|
||||
tgt_clk_edge->transition()->name());
|
||||
}
|
||||
if (tgt_clk_path)
|
||||
reportJson(end->targetClkPath(), "target_clock_path", 2, true, result);
|
||||
|
||||
if (end->checkRole(this)) {
|
||||
stringAppend(result, " \"data_arrival_time\": %.3e,\n",
|
||||
end->dataArrivalTimeOffset(this));
|
||||
|
||||
const MultiCyclePath *mcp = end->multiCyclePath();
|
||||
if (mcp)
|
||||
stringAppend(result, " \"multi_cycle_path\": %d,\n",
|
||||
mcp->pathMultiplier());
|
||||
|
||||
PathDelay *path_delay = end->pathDelay();
|
||||
if (path_delay)
|
||||
stringAppend(result, " \"path_delay\": %.3e,\n",
|
||||
path_delay->delay());
|
||||
|
||||
stringAppend(result, " \"crpr\": %.3e,\n", end->checkCrpr(this));
|
||||
stringAppend(result, " \"margin\": %.3e,\n", end->margin(this));
|
||||
stringAppend(result, " \"required_time\": %.3e,\n",
|
||||
end->requiredTimeOffset(this));
|
||||
stringAppend(result, " \"slack\": %.3e\n", end->slack(this));
|
||||
}
|
||||
result += "}";
|
||||
if (!last)
|
||||
result += ",";
|
||||
report_->reportLineString(result);
|
||||
}
|
||||
|
||||
void
|
||||
ReportPath::reportJson(const Path *path)
|
||||
{
|
||||
string result;
|
||||
result += "{\n";
|
||||
reportJson(path, "path", 0, false, result);
|
||||
result += "}\n";
|
||||
report_->reportLineString(result);
|
||||
}
|
||||
|
||||
void
|
||||
ReportPath::reportJson(const Path *path,
|
||||
const char *path_name,
|
||||
int indent,
|
||||
bool trailing_comma,
|
||||
string &result)
|
||||
{
|
||||
PathExpanded expanded(path, this);
|
||||
reportJson(expanded, path_name, indent, trailing_comma, result);
|
||||
}
|
||||
|
||||
void
|
||||
ReportPath::reportJson(const PathExpanded &expanded,
|
||||
const char *path_name,
|
||||
int indent,
|
||||
bool trailing_comma,
|
||||
string &result)
|
||||
{
|
||||
stringAppend(result, "%*s\"%s\": [\n", indent, "", path_name);
|
||||
for (size_t i = 0; i < expanded.size(); i++) {
|
||||
const PathRef *path = expanded.path(i);
|
||||
const Pin *pin = path->vertex(this)->pin();
|
||||
stringAppend(result, "%*s {\n", indent, "");
|
||||
stringAppend(result, "%*s \"pin\": \"%s\",\n",
|
||||
indent, "",
|
||||
network_->pathName(pin));
|
||||
double x, y;
|
||||
bool exists;
|
||||
network_->location(pin, x, y, exists);
|
||||
if (exists) {
|
||||
stringAppend(result, "%*s \"x\": %.9f,\n", indent, "", x);
|
||||
stringAppend(result, "%*s \"y\": %.9f,\n", indent, "", y);
|
||||
}
|
||||
|
||||
stringAppend(result, "%*s \"arrival\": %.3e,\n",
|
||||
indent, "",
|
||||
delayAsFloat(path->arrival(this)));
|
||||
stringAppend(result, "%*s \"slew\": %.3e\n",
|
||||
indent, "",
|
||||
delayAsFloat(path->slew(this)));
|
||||
stringAppend(result, "%*s }%s\n",
|
||||
indent, "",
|
||||
(i < expanded.size() - 1) ? "," : "");
|
||||
}
|
||||
stringAppend(result, "%*s]%s\n",
|
||||
indent, "",
|
||||
trailing_comma ? "," : "");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
void
|
||||
ReportPath::reportSlackOnlyHeader()
|
||||
{
|
||||
|
|
@ -2365,12 +2506,13 @@ ReportPath::reportPath(const Path *path)
|
|||
reportPathFull(path);
|
||||
break;
|
||||
case ReportPathFormat::json:
|
||||
reportPathJson(path);
|
||||
reportJson(path);
|
||||
break;
|
||||
case ReportPathFormat::shorter:
|
||||
case ReportPathFormat::endpoint:
|
||||
case ReportPathFormat::summary:
|
||||
case ReportPathFormat::slack_only:
|
||||
default:
|
||||
report_->critical(1474, "unsupported path type");
|
||||
report_->reportLine("Format not supported.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -2383,54 +2525,7 @@ ReportPath::reportPathFull(const Path *path)
|
|||
reportSrcClkAndPath(path, expanded, 0.0, delay_zero, delay_zero, false);
|
||||
}
|
||||
|
||||
void
|
||||
ReportPath::reportPathJson(const Path *path)
|
||||
{
|
||||
report_->reportLine("{ \"path\": [");
|
||||
PathExpanded expanded(path, this);
|
||||
for (auto i = expanded.startIndex(); i < expanded.size(); i++) {
|
||||
string line;
|
||||
PathRef *path = expanded.path(i);
|
||||
const Pin *pin = path->vertex(this)->pin();
|
||||
report_->reportLine(" {");
|
||||
line = " \"pin\": \"";
|
||||
line += network_->pathName(pin);
|
||||
line += "\",";
|
||||
report_->reportLineString(line);
|
||||
|
||||
double x, y;
|
||||
bool exists;
|
||||
string tmp;
|
||||
network_->location(pin, x, y, exists);
|
||||
if (exists) {
|
||||
line = " \"x\": ";
|
||||
stringPrint(tmp, "%.9f", x);
|
||||
line += tmp + ",\n";
|
||||
line += " \"y\": ";
|
||||
stringPrint(tmp, "%.9f", y);
|
||||
line += tmp + ",";
|
||||
report_->reportLineString(line);
|
||||
}
|
||||
|
||||
line = " \"arrival\": ";
|
||||
stringPrint(tmp, "%.3e", delayAsFloat(path->arrival(this)));
|
||||
line += tmp;
|
||||
line += ",";
|
||||
report_->reportLineString(line);
|
||||
|
||||
line = " \"slew\": ";
|
||||
stringPrint(tmp, "%.3e", delayAsFloat(path->slew(this)));
|
||||
line += tmp;
|
||||
report_->reportLineString(line);
|
||||
|
||||
line = " }";
|
||||
if (i < expanded.size() - 1)
|
||||
line += ",";
|
||||
report_->reportLineString(line);
|
||||
}
|
||||
report_->reportLine(" ]");
|
||||
report_->reportLine("}");
|
||||
}
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
void
|
||||
ReportPath::reportPath1(const Path *path,
|
||||
|
|
@ -2517,7 +2612,7 @@ ReportPath::reportPath4(const Path *path,
|
|||
Arrival prev_time(0.0);
|
||||
if (skip_first_path) {
|
||||
path_first_index = 1;
|
||||
PathRef *start = expanded.path(0);
|
||||
const PathRef *start = expanded.path(0);
|
||||
prev_time = start->arrival(this) + time_offset;
|
||||
}
|
||||
size_t path_last_index = expanded.size() - 1;
|
||||
|
|
@ -2551,7 +2646,7 @@ ReportPath::reportPath5(const Path *path,
|
|||
expanded.clkPath(clk_path);
|
||||
Vertex *clk_start = clk_path.vertex(this);
|
||||
for (size_t i = path_first_index; i <= path_last_index; i++) {
|
||||
PathRef *path1 = expanded.path(i);
|
||||
const PathRef *path1 = expanded.path(i);
|
||||
TimingArc *prev_arc = expanded.prevArc(i);
|
||||
Vertex *vertex = path1->vertex(this);
|
||||
Pin *pin = vertex->pin();
|
||||
|
|
|
|||
|
|
@ -61,7 +61,8 @@ public:
|
|||
// Previous path end is used to detect path group changes
|
||||
// so headers are reported by group.
|
||||
void reportPathEnd(PathEnd *end,
|
||||
PathEnd *prev_end);
|
||||
PathEnd *prev_end,
|
||||
bool last);
|
||||
void reportPathEnds(PathEndSeq *ends);
|
||||
void reportPath(const Path *path);
|
||||
|
||||
|
|
@ -81,6 +82,22 @@ public:
|
|||
void reportFull(const PathEndGatedClock *end);
|
||||
void reportFull(const PathEndDataCheck *end);
|
||||
|
||||
void reportJsonHeader();
|
||||
void reportJsonFooter();
|
||||
void reportJson(const PathEnd *end,
|
||||
bool last);
|
||||
void reportJson(const Path *path);
|
||||
void reportJson(const Path *path,
|
||||
const char *path_name,
|
||||
int indent,
|
||||
bool trailing_comma,
|
||||
string &result);
|
||||
void reportJson(const PathExpanded &expanded,
|
||||
const char *path_name,
|
||||
int indent,
|
||||
bool trailing_comma,
|
||||
string &result);
|
||||
|
||||
void reportEndHeader();
|
||||
void reportEndLine(PathEnd *end);
|
||||
|
||||
|
|
@ -264,7 +281,6 @@ protected:
|
|||
void reportPath(const PathEnd *end,
|
||||
PathExpanded &expanded);
|
||||
void reportPathFull(const Path *path);
|
||||
void reportPathJson(const Path *path);
|
||||
void reportPathHeader();
|
||||
void reportPath1(const Path *path,
|
||||
PathExpanded &expanded,
|
||||
|
|
|
|||
|
|
@ -480,9 +480,10 @@ report_path_end(PathEnd *end)
|
|||
|
||||
void
|
||||
report_path_end2(PathEnd *end,
|
||||
PathEnd *prev_end)
|
||||
PathEnd *prev_end,
|
||||
bool last)
|
||||
{
|
||||
Sta::sta()->reportPathEnd(end, prev_end);
|
||||
Sta::sta()->reportPathEnd(end, prev_end, last);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -1069,9 +1069,12 @@ proc parse_path_group_arg { group_names } {
|
|||
proc report_path_ends { path_ends } {
|
||||
report_path_end_header
|
||||
set prev_end "NULL"
|
||||
set end_count [llength $path_ends]
|
||||
set i 0
|
||||
foreach path_end $path_ends {
|
||||
report_path_end2 $path_end $prev_end
|
||||
report_path_end2 $path_end $prev_end [expr $i == ($end_count - 1)]
|
||||
set prev_end $path_end
|
||||
incr i
|
||||
}
|
||||
report_path_end_footer
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2518,12 +2518,6 @@ Sta::setReportPathSigmas(bool report_sigmas)
|
|||
report_path_->setReportSigmas(report_sigmas);
|
||||
}
|
||||
|
||||
void
|
||||
Sta::reportPathEnds(PathEndSeq *ends)
|
||||
{
|
||||
report_path_->reportPathEnds(ends);
|
||||
}
|
||||
|
||||
void
|
||||
Sta::reportPathEndHeader()
|
||||
{
|
||||
|
|
@ -2544,9 +2538,10 @@ Sta::reportPathEnd(PathEnd *end)
|
|||
|
||||
void
|
||||
Sta::reportPathEnd(PathEnd *end,
|
||||
PathEnd *prev_end)
|
||||
PathEnd *prev_end,
|
||||
bool last)
|
||||
{
|
||||
report_path_->reportPathEnd(end, prev_end);
|
||||
report_path_->reportPathEnd(end, prev_end, last);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -84,10 +84,10 @@ private:
|
|||
float maxTime();
|
||||
float pathMaxTime();
|
||||
void writeMeasureDelayStmt(Stage stage,
|
||||
Path *from_path,
|
||||
Path *to_path);
|
||||
const Path *from_path,
|
||||
const Path *to_path);
|
||||
void writeMeasureSlewStmt(Stage stage,
|
||||
Path *path);
|
||||
const Path *path);
|
||||
void writeInputWaveform();
|
||||
void writeClkWaveform();
|
||||
|
||||
|
|
@ -110,9 +110,9 @@ private:
|
|||
int stageGateInputPathIndex(Stage stage);
|
||||
int stageDrvrPathIndex(Stage stage);
|
||||
int stageLoadPathIndex(Stage stage);
|
||||
PathRef *stageGateInputPath(Stage stage);
|
||||
PathRef *stageDrvrPath(Stage stage);
|
||||
PathRef *stageLoadPath(Stage stage);
|
||||
const PathRef *stageGateInputPath(Stage stage);
|
||||
const PathRef *stageDrvrPath(Stage stage);
|
||||
const PathRef *stageLoadPath(Stage stage);
|
||||
TimingArc *stageGateArc(Stage stage);
|
||||
TimingArc *stageWireArc(Stage stage);
|
||||
Edge *stageGateEdge(Stage stage);
|
||||
|
|
@ -128,8 +128,8 @@ private:
|
|||
LibertyCell *stageLibertyCell(Stage stage);
|
||||
Instance *stageInstance(Stage stage);
|
||||
|
||||
float findSlew(Path *path);
|
||||
float findSlew(Path *path,
|
||||
float findSlew(const Path *path);
|
||||
float findSlew(const Path *path,
|
||||
const RiseFall *rf,
|
||||
TimingArc *next_arc);
|
||||
Path *path_;
|
||||
|
|
@ -240,7 +240,7 @@ float
|
|||
WritePathSpice::maxTime()
|
||||
{
|
||||
Stage input_stage = stageFirst();
|
||||
PathRef *input_path = stageDrvrPath(input_stage);
|
||||
const PathRef *input_path = stageDrvrPath(input_stage);
|
||||
if (input_path->isClock(this)) {
|
||||
const Clock *clk = input_path->clock(this);
|
||||
float period = clk->period();
|
||||
|
|
@ -258,7 +258,7 @@ WritePathSpice::pathMaxTime()
|
|||
{
|
||||
float max_time = 0.0;
|
||||
for (size_t i = 0; i < path_expanded_.size(); i++) {
|
||||
PathRef *path = path_expanded_.path(i);
|
||||
const PathRef *path = path_expanded_.path(i);
|
||||
const RiseFall *rf = path->transition(this);
|
||||
Vertex *vertex = path->vertex(this);
|
||||
float path_max_slew = railToRailSlew(findSlew(vertex,rf,nullptr), rf);
|
||||
|
|
@ -315,7 +315,7 @@ WritePathSpice::writeInputSource()
|
|||
streamPrint(spice_stream_, "**************\n\n");
|
||||
|
||||
Stage input_stage = stageFirst();
|
||||
PathRef *input_path = stageDrvrPath(input_stage);
|
||||
const PathRef *input_path = stageDrvrPath(input_stage);
|
||||
if (input_path->isClock(this))
|
||||
writeClkWaveform();
|
||||
else
|
||||
|
|
@ -327,7 +327,7 @@ void
|
|||
WritePathSpice::writeInputWaveform()
|
||||
{
|
||||
Stage input_stage = stageFirst();
|
||||
PathRef *input_path = stageDrvrPath(input_stage);
|
||||
const PathRef *input_path = stageDrvrPath(input_stage);
|
||||
const RiseFall *rf = input_path->transition(this);
|
||||
TimingArc *next_arc = stageGateArc(input_stage + 1);
|
||||
float slew0 = findSlew(input_path, rf, next_arc);
|
||||
|
|
@ -352,7 +352,7 @@ void
|
|||
WritePathSpice::writeClkWaveform()
|
||||
{
|
||||
Stage input_stage = stageFirst();
|
||||
PathRef *input_path = stageDrvrPath(input_stage);
|
||||
const PathRef *input_path = stageDrvrPath(input_stage);
|
||||
TimingArc *next_arc = stageGateArc(input_stage + 1);
|
||||
const ClockEdge *clk_edge = input_path->clkEdge(this);
|
||||
|
||||
|
|
@ -387,7 +387,7 @@ WritePathSpice::writeClkWaveform()
|
|||
}
|
||||
|
||||
float
|
||||
WritePathSpice::findSlew(Path *path)
|
||||
WritePathSpice::findSlew(const Path *path)
|
||||
{
|
||||
Vertex *vertex = path->vertex(this);
|
||||
const RiseFall *rf = path->transition(this);
|
||||
|
|
@ -395,7 +395,7 @@ WritePathSpice::findSlew(Path *path)
|
|||
}
|
||||
|
||||
float
|
||||
WritePathSpice::findSlew(Path *path,
|
||||
WritePathSpice::findSlew(const Path *path,
|
||||
const RiseFall *rf,
|
||||
TimingArc *next_arc)
|
||||
{
|
||||
|
|
@ -413,9 +413,9 @@ WritePathSpice::writeMeasureStmts()
|
|||
streamPrint(spice_stream_, "********************\n\n");
|
||||
|
||||
for (Stage stage = stageFirst(); stage <= stageLast(); stage++) {
|
||||
PathRef *gate_input_path = stageGateInputPath(stage);
|
||||
PathRef *drvr_path = stageDrvrPath(stage);
|
||||
PathRef *load_path = stageLoadPath(stage);
|
||||
const PathRef *gate_input_path = stageGateInputPath(stage);
|
||||
const PathRef *drvr_path = stageDrvrPath(stage);
|
||||
const PathRef *load_path = stageLoadPath(stage);
|
||||
if (gate_input_path) {
|
||||
// gate input -> gate output
|
||||
writeMeasureSlewStmt(stage, gate_input_path);
|
||||
|
|
@ -432,8 +432,8 @@ WritePathSpice::writeMeasureStmts()
|
|||
|
||||
void
|
||||
WritePathSpice::writeMeasureDelayStmt(Stage stage,
|
||||
Path *from_path,
|
||||
Path *to_path)
|
||||
const Path *from_path,
|
||||
const Path *to_path)
|
||||
{
|
||||
writeMeasureDelayStmt(from_path->pin(this), from_path->transition(this),
|
||||
to_path->pin(this), to_path->transition(this),
|
||||
|
|
@ -442,7 +442,7 @@ WritePathSpice::writeMeasureDelayStmt(Stage stage,
|
|||
|
||||
void
|
||||
WritePathSpice::writeMeasureSlewStmt(Stage stage,
|
||||
Path *path)
|
||||
const Path *path)
|
||||
{
|
||||
const Pin *pin = path->pin(this);
|
||||
const RiseFall *rf = path->transition(this);
|
||||
|
|
@ -514,7 +514,7 @@ WritePathSpice::writeGateStage(Stage stage)
|
|||
drvr_port->name());
|
||||
writeSubcktInst(inst);
|
||||
|
||||
PathRef *drvr_path = stageDrvrPath(stage);
|
||||
const PathRef *drvr_path = stageDrvrPath(stage);
|
||||
const RiseFall *drvr_rf = drvr_path->transition(this);
|
||||
Edge *gate_edge = stageGateEdge(stage);
|
||||
|
||||
|
|
@ -544,7 +544,7 @@ WritePathSpice::writeGateStage(Stage stage)
|
|||
void
|
||||
WritePathSpice::writeStageParasitics(Stage stage)
|
||||
{
|
||||
PathRef *drvr_path = stageDrvrPath(stage);
|
||||
const PathRef *drvr_path = stageDrvrPath(stage);
|
||||
DcalcAnalysisPt *dcalc_ap = drvr_path->dcalcAnalysisPt(this);
|
||||
ParasiticAnalysisPt *parasitic_ap = dcalc_ap->parasiticAnalysisPt();
|
||||
const Pin *drvr_pin = stageDrvrPin(stage);
|
||||
|
|
@ -637,21 +637,21 @@ WritePathSpice::stageLoadPathIndex(Stage stage)
|
|||
return stage * 2 - 1;
|
||||
}
|
||||
|
||||
PathRef *
|
||||
const PathRef *
|
||||
WritePathSpice::stageGateInputPath(Stage stage)
|
||||
{
|
||||
int path_index = stageGateInputPathIndex(stage);
|
||||
return path_expanded_.path(path_index);
|
||||
}
|
||||
|
||||
PathRef *
|
||||
const PathRef *
|
||||
WritePathSpice::stageDrvrPath(Stage stage)
|
||||
{
|
||||
int path_index = stageDrvrPathIndex(stage);
|
||||
return path_expanded_.path(path_index);
|
||||
}
|
||||
|
||||
PathRef *
|
||||
const PathRef *
|
||||
WritePathSpice::stageLoadPath(Stage stage)
|
||||
{
|
||||
int path_index = stageLoadPathIndex(stage);
|
||||
|
|
@ -678,7 +678,7 @@ WritePathSpice::stageWireArc(Stage stage)
|
|||
Edge *
|
||||
WritePathSpice::stageGateEdge(Stage stage)
|
||||
{
|
||||
PathRef *path = stageDrvrPath(stage);
|
||||
const PathRef *path = stageDrvrPath(stage);
|
||||
TimingArc *arc = stageGateArc(stage);
|
||||
return path->prevEdge(arc, this);
|
||||
}
|
||||
|
|
@ -686,7 +686,7 @@ WritePathSpice::stageGateEdge(Stage stage)
|
|||
Edge *
|
||||
WritePathSpice::stageWireEdge(Stage stage)
|
||||
{
|
||||
PathRef *path = stageLoadPath(stage);
|
||||
const PathRef *path = stageLoadPath(stage);
|
||||
TimingArc *arc = stageWireArc(stage);
|
||||
return path->prevEdge(arc, this);
|
||||
}
|
||||
|
|
@ -694,7 +694,7 @@ WritePathSpice::stageWireEdge(Stage stage)
|
|||
Pin *
|
||||
WritePathSpice::stageGateInputPin(Stage stage)
|
||||
{
|
||||
PathRef *path = stageGateInputPath(stage);
|
||||
const PathRef *path = stageGateInputPath(stage);
|
||||
return path->pin(this);
|
||||
}
|
||||
|
||||
|
|
@ -708,7 +708,7 @@ WritePathSpice::stageGateInputPort(Stage stage)
|
|||
Pin *
|
||||
WritePathSpice::stageDrvrPin(Stage stage)
|
||||
{
|
||||
PathRef *path = stageDrvrPath(stage);
|
||||
const PathRef *path = stageDrvrPath(stage);
|
||||
return path->pin(this);
|
||||
}
|
||||
|
||||
|
|
@ -722,7 +722,7 @@ WritePathSpice::stageDrvrPort(Stage stage)
|
|||
Pin *
|
||||
WritePathSpice::stageLoadPin(Stage stage)
|
||||
{
|
||||
PathRef *path = stageLoadPath(stage);
|
||||
const PathRef *path = stageLoadPath(stage);
|
||||
return path->pin(this);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -341,21 +341,20 @@ proc sta_unknown { args } {
|
|||
}
|
||||
if { $ret != 0 } {
|
||||
return -code $ret -errorcode $errorCode \
|
||||
"error in unknown while checking if \"$name\" is a unique command abbreviation: $msg"
|
||||
"Error in unknown while checking if \"$name\" is a unique command abbreviation: $msg."
|
||||
}
|
||||
if { [llength $cmds] == 1 } {
|
||||
return [uplevel 1 [lreplace $args 0 0 $cmds]]
|
||||
}
|
||||
if { [llength $cmds] > 1 } {
|
||||
if {[string equal $name ""]} {
|
||||
return -code error "empty command name \"\""
|
||||
return -code error "Empty command name \"\""
|
||||
} else {
|
||||
return -code error \
|
||||
"ambiguous command name \"$name\": [lsort $cmds]"
|
||||
"Ambiguous command name \"$name\": [lsort $cmds]."
|
||||
}
|
||||
}
|
||||
|
||||
::unknown {*}$args
|
||||
return [uplevel 1 [::unknown {*}$args]]
|
||||
}
|
||||
|
||||
proc is_bus_subscript { subscript } {
|
||||
|
|
|
|||
|
|
@ -76,6 +76,20 @@ stringPrint(string &str,
|
|||
str = tmp;
|
||||
}
|
||||
|
||||
void
|
||||
stringAppend(string &str,
|
||||
const char *fmt,
|
||||
...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
char *tmp;
|
||||
size_t tmp_length;
|
||||
stringPrintTmp(fmt, args, tmp, tmp_length);
|
||||
va_end(args);
|
||||
str += tmp;
|
||||
}
|
||||
|
||||
string
|
||||
stdstrPrint(const char *fmt,
|
||||
...)
|
||||
|
|
|
|||
Loading…
Reference in New Issue