Merge branch 'master' of https://github.com/The-OpenROAD-Project-private/OpenSTA into secure-sta-test-by-opus
This commit is contained in:
commit
1b97c9c9b4
16
BUILD
16
BUILD
|
|
@ -3,8 +3,8 @@
|
|||
|
||||
load("@rules_cc//cc:cc_binary.bzl", "cc_binary")
|
||||
load("@rules_cc//cc:cc_library.bzl", "cc_library")
|
||||
load("@rules_hdl//dependency_support/com_github_westes_flex:flex.bzl", "genlex")
|
||||
load("@rules_hdl//dependency_support/org_gnu_bison:bison.bzl", "genyacc")
|
||||
load("//bazel:bison.bzl", "genyacc")
|
||||
load("//bazel:flex.bzl", "genlex")
|
||||
load("//bazel:tcl_encode_sta.bzl", "tcl_encode_sta")
|
||||
load("//bazel:tcl_wrap_cc.bzl", "tcl_wrap_cc")
|
||||
|
||||
|
|
@ -177,8 +177,9 @@ tcl_encode_sta(
|
|||
genrule(
|
||||
name = "StaConfig",
|
||||
srcs = [],
|
||||
outs = ["util/StaConfig.hh"],
|
||||
outs = ["include/sta/StaConfig.hh"],
|
||||
cmd = """echo -e '
|
||||
#pragma once
|
||||
#define STA_VERSION "2.7.0"
|
||||
#define STA_GIT_SHA1 "f21d4a3878e2531e3af4930818d9b5968aad9416"
|
||||
#define SSTA 0
|
||||
|
|
@ -296,7 +297,7 @@ cc_binary(
|
|||
deps = [
|
||||
":opensta_lib",
|
||||
"@rules_cc//cc/runfiles",
|
||||
"@tk_tcl//:tcl",
|
||||
"@tcl_lang//:tcl",
|
||||
],
|
||||
)
|
||||
|
||||
|
|
@ -390,14 +391,17 @@ cc_library(
|
|||
"util",
|
||||
"verilog",
|
||||
],
|
||||
textual_hdrs = ["util/MachineLinux.cc"],
|
||||
textual_hdrs = select({
|
||||
"@platforms//os:osx": ["util/MachineApple.cc"],
|
||||
"//conditions:default": ["util/MachineLinux.cc"],
|
||||
}),
|
||||
visibility = ["//:__subpackages__"],
|
||||
deps = [
|
||||
"@cudd",
|
||||
"@eigen",
|
||||
"@openmp",
|
||||
"@rules_flex//flex:current_flex_toolchain",
|
||||
"@tk_tcl//:tcl",
|
||||
"@tcl_lang//:tcl",
|
||||
"@zlib",
|
||||
],
|
||||
)
|
||||
|
|
|
|||
|
|
@ -3,6 +3,13 @@ OpenSTA Timing Analyzer Release Notes
|
|||
|
||||
This file summarizes user visible changes for each release.
|
||||
|
||||
2025/02/24
|
||||
----------
|
||||
|
||||
The define_scene -library argument now takes a the library name or a
|
||||
library filename. If a filename is used, it must be the same as the
|
||||
filename used to read the library with read_liberty.
|
||||
|
||||
Release 3.0.0 2025/11/26
|
||||
------------------------
|
||||
|
||||
|
|
|
|||
2584
doc/OpenSTA.fodt
2584
doc/OpenSTA.fodt
File diff suppressed because it is too large
Load Diff
BIN
doc/OpenSTA.pdf
BIN
doc/OpenSTA.pdf
Binary file not shown.
|
|
@ -9,9 +9,9 @@ set_timing_derate -late 1.1
|
|||
create_clock -name clk -period 10 {clk1 clk2 clk3}
|
||||
set_input_delay -clock clk 0 {in1 in2}
|
||||
|
||||
define_scene ss -liberty nangate45_slow
|
||||
define_scene tt -liberty nangate45_typ
|
||||
define_scene ff -liberty nangate45_fast
|
||||
define_scene ss -liberty NangateOpenCellLibrary_slow
|
||||
define_scene tt -liberty NangateOpenCellLibrary
|
||||
define_scene ff -liberty NangateOpenCellLibrary_fast
|
||||
|
||||
# report all scenes
|
||||
report_checks -path_delay min_max
|
||||
|
|
|
|||
|
|
@ -408,7 +408,7 @@ void
|
|||
sort(Range& r,
|
||||
Comp comp = Comp{})
|
||||
{
|
||||
std::sort(std::ranges::begin(r), std::ranges::end(r), comp);
|
||||
std::stable_sort(std::ranges::begin(r), std::ranges::end(r), comp);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -423,7 +423,7 @@ void
|
|||
sort(Range* r,
|
||||
Comp comp = Comp{})
|
||||
{
|
||||
std::sort(std::ranges::begin(*r), std::ranges::end(*r), comp);
|
||||
std::stable_sort(std::ranges::begin(*r), std::ranges::end(*r), comp);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
|
|||
|
|
@ -1596,9 +1596,8 @@ protected:
|
|||
void setThreadCount1(int thread_count);
|
||||
void updateLibertyScenes();
|
||||
void updateSceneLiberty(Scene *scene,
|
||||
const StdStringSeq &liberty_files,
|
||||
const MinMax *min_max);
|
||||
LibertyLibrary *findLibertyFileBasename(const std::string &filename) const;
|
||||
const StdStringSeq &liberty_min_files,
|
||||
const StdStringSeq &liberty_max_files);
|
||||
|
||||
Scene *makeScene(const std::string &name,
|
||||
Mode *mode,
|
||||
|
|
|
|||
|
|
@ -208,7 +208,6 @@ Network::checkNetworkLibertyScenes()
|
|||
}
|
||||
}
|
||||
|
||||
// Only used by Sta::setMinLibrary so linear search is acceptable.
|
||||
LibertyLibrary *
|
||||
Network::findLibertyFilename(const char *filename)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -88,15 +88,12 @@ staToVerilog(const char *sta_name)
|
|||
for (const char *s = sta_name; *s ; s++) {
|
||||
char ch = s[0];
|
||||
if (ch == verilog_escape) {
|
||||
escaped = true;
|
||||
char next_ch = s[1];
|
||||
if (next_ch == verilog_escape) {
|
||||
escaped_name += ch;
|
||||
escaped_name += next_ch;
|
||||
s++;
|
||||
}
|
||||
else
|
||||
// Skip escape.
|
||||
escaped = true;
|
||||
}
|
||||
else {
|
||||
if ((!(isalnum(ch) || ch == '_')))
|
||||
|
|
@ -126,15 +123,12 @@ staToVerilog2(const char *sta_name)
|
|||
for (const char *s = sta_name; *s ; s++) {
|
||||
char ch = s[0];
|
||||
if (ch == verilog_escape) {
|
||||
escaped = true;
|
||||
char next_ch = s[1];
|
||||
if (next_ch == verilog_escape) {
|
||||
escaped_name += ch;
|
||||
escaped_name += next_ch;
|
||||
s++;
|
||||
}
|
||||
else
|
||||
// Skip escape.
|
||||
escaped = true;
|
||||
}
|
||||
else {
|
||||
bool is_brkt = (ch == bus_brkt_left || ch == bus_brkt_right);
|
||||
|
|
|
|||
|
|
@ -162,14 +162,14 @@ ClkLatency::findClkDelays(ConstClockSeq &clks,
|
|||
VertexPathIterator path_iter(clk_vertex, this);
|
||||
while (path_iter.hasNext()) {
|
||||
Path *path = path_iter.next();
|
||||
const ClockEdge *path_clk_edge = path->clkEdge(this);
|
||||
const Scene *path_scene = path->scene(this);
|
||||
if (path_clk_edge
|
||||
const Clock *path_clk = path->clock(this);
|
||||
if (path_clk
|
||||
&& scenes.contains(path_scene)
|
||||
&& clk_set.contains(path_clk_edge->clock())) {
|
||||
const Clock *path_clk = path_clk_edge->clock();
|
||||
&& clk_set.contains(path_clk)) {
|
||||
auto delays_itr = clk_delay_map.find(path_clk);
|
||||
if (delays_itr != clk_delay_map.end()) {
|
||||
const ClockEdge *path_clk_edge = path->clkEdge(this);
|
||||
ClkDelays &clk_delays = delays_itr->second;
|
||||
const RiseFall *clk_rf = path_clk_edge->transition();
|
||||
const MinMax *min_max = path->minMax(this);
|
||||
|
|
|
|||
|
|
@ -436,8 +436,10 @@ PathGroups::pathGroups(const PathEnd *path_end) const
|
|||
// GroupPaths have precedence.
|
||||
else if (!group_paths.empty()) {
|
||||
for (ExceptionPath *group_path : group_paths) {
|
||||
if (group_path->isDefault())
|
||||
path_groups.push_back(path_delay_[mm_index]);
|
||||
if (group_path->isDefault()) {
|
||||
if (path_delay_[mm_index])
|
||||
path_groups.push_back(path_delay_[mm_index]);
|
||||
}
|
||||
else {
|
||||
const char *group_name = group_path->name();
|
||||
PathGroup *group = findPathGroup(group_name, min_max);
|
||||
|
|
|
|||
|
|
@ -2498,27 +2498,30 @@ Sta::makeScene(const std::string &name,
|
|||
const std::string &spef_max_file)
|
||||
{
|
||||
Mode *mode = findMode(mode_name);
|
||||
Parasitics *parasitics_default = findParasitics("default");
|
||||
Parasitics *parasitics_min = parasitics_default;
|
||||
Parasitics *parasitics_max = parasitics_default;
|
||||
if (!spef_min_file.empty() && !spef_max_file.empty()) {
|
||||
parasitics_min = findParasitics(spef_min_file);
|
||||
parasitics_max = findParasitics(spef_max_file);
|
||||
if (parasitics_min == nullptr)
|
||||
report_->error(1558, "Spef file %s not found.", spef_min_file.c_str());
|
||||
if (parasitics_max == nullptr
|
||||
&& spef_max_file != spef_min_file)
|
||||
report_->error(1559, "Spef file %s not found.", spef_max_file.c_str());
|
||||
}
|
||||
if (mode) {
|
||||
Parasitics *parasitics_default = findParasitics("default");
|
||||
Parasitics *parasitics_min = parasitics_default;
|
||||
Parasitics *parasitics_max = parasitics_default;
|
||||
if (!spef_min_file.empty() && !spef_max_file.empty()) {
|
||||
parasitics_min = findParasitics(spef_min_file);
|
||||
parasitics_max = findParasitics(spef_max_file);
|
||||
if (parasitics_min == nullptr)
|
||||
report_->error(1558, "Spef file %s not found.", spef_min_file.c_str());
|
||||
if (parasitics_max == nullptr
|
||||
&& spef_max_file != spef_min_file)
|
||||
report_->error(1559, "Spef file %s not found.", spef_max_file.c_str());
|
||||
}
|
||||
|
||||
mode->sdc()->makeSceneBefore();
|
||||
Scene *scene = makeScene(name, mode, parasitics_min, parasitics_max);
|
||||
updateComponentsState();
|
||||
if (graph_)
|
||||
graph_->makeSceneAfter();
|
||||
updateSceneLiberty(scene, liberty_min_files, MinMax::min());
|
||||
updateSceneLiberty(scene, liberty_max_files, MinMax::max());
|
||||
cmd_scene_ = scene;
|
||||
mode->sdc()->makeSceneBefore();
|
||||
Scene *scene = makeScene(name, mode, parasitics_min, parasitics_max);
|
||||
updateComponentsState();
|
||||
if (graph_)
|
||||
graph_->makeSceneAfter();
|
||||
updateSceneLiberty(scene, liberty_min_files, liberty_max_files);
|
||||
cmd_scene_ = scene;
|
||||
}
|
||||
else
|
||||
report_->error(1572, "mode %s not found.", mode_name.c_str());
|
||||
}
|
||||
|
||||
Scene *
|
||||
|
|
@ -2597,34 +2600,27 @@ Sta::findScenes(const std::string &name,
|
|||
|
||||
void
|
||||
Sta::updateSceneLiberty(Scene *scene,
|
||||
const StdStringSeq &liberty_files,
|
||||
const MinMax *min_max)
|
||||
const StdStringSeq &liberty_min_files,
|
||||
const StdStringSeq &liberty_max_files)
|
||||
{
|
||||
for (const std::string &lib_file : liberty_files) {
|
||||
LibertyLibrary *lib = findLibertyFileBasename(lib_file);
|
||||
if (lib)
|
||||
LibertyLibrary::makeSceneMap(lib, scene->libertyIndex(min_max),
|
||||
network_, report_);
|
||||
else
|
||||
report_->warn(1555, "liberty filename %s not found.", lib_file.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
LibertyLibrary *
|
||||
Sta::findLibertyFileBasename(const std::string &filename) const
|
||||
{
|
||||
LibertyLibraryIterator *lib_iter = network_->libertyLibraryIterator();
|
||||
while (lib_iter->hasNext()) {
|
||||
LibertyLibrary *lib = lib_iter->next();
|
||||
auto lib_file = std::filesystem::path(lib->filename()).filename().stem();
|
||||
auto stem = lib_file.stem();
|
||||
if (stem.string() == filename) {
|
||||
delete lib_iter;
|
||||
return lib;
|
||||
StdStringSet warned_files;
|
||||
for (const MinMax *min_max : MinMax::range()) {
|
||||
const StdStringSeq &liberty_files = min_max == MinMax::min()
|
||||
? liberty_min_files
|
||||
: liberty_max_files;
|
||||
for (const std::string &lib_file : liberty_files) {
|
||||
LibertyLibrary *lib = network_->findLiberty(lib_file.c_str());
|
||||
if (lib == nullptr)
|
||||
lib = network_->findLibertyFilename(lib_file.c_str());
|
||||
if (lib)
|
||||
LibertyLibrary::makeSceneMap(lib, scene->libertyIndex(min_max),
|
||||
network_, report_);
|
||||
else if (!warned_files.contains(lib_file)) {
|
||||
report_->warn(1555, "liberty name/filename %s not found.", lib_file.c_str());
|
||||
warned_files.insert(lib_file);
|
||||
}
|
||||
}
|
||||
}
|
||||
delete lib_iter;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -3128,7 +3124,7 @@ Sta::required(Vertex *vertex,
|
|||
|
||||
Slack
|
||||
Sta::slack(const Net *net,
|
||||
const MinMax *min_max)
|
||||
const MinMax *min_max)
|
||||
{
|
||||
ensureGraph();
|
||||
Slack min_slack = MinMax::min()->initValue();
|
||||
|
|
@ -3150,7 +3146,7 @@ Slack
|
|||
Sta::slack(const Pin *pin,
|
||||
const RiseFallBoth *rf,
|
||||
const SceneSeq &scenes,
|
||||
const MinMax *min_max)
|
||||
const MinMax *min_max)
|
||||
{
|
||||
ensureGraph();
|
||||
Vertex *vertex, *bidirect_drvr_vertex;
|
||||
|
|
|
|||
|
|
@ -165,6 +165,7 @@ record_public_tests {
|
|||
suppress_msg
|
||||
verilog_attribute
|
||||
verilog_specify
|
||||
verilog_write_escape
|
||||
}
|
||||
|
||||
define_test_group fast [group_tests all]
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
module multi_sink (clk);
|
||||
input clk;
|
||||
|
||||
wire \alu_adder_result_ex[0] ;
|
||||
|
||||
hier_block \h1\x (.childclk(clk),
|
||||
.\Y[2:1] ({\alu_adder_result_ex[0] ,
|
||||
\alu_adder_result_ex[0] }));
|
||||
endmodule
|
||||
module hier_block (childclk,
|
||||
\Y[2:1] );
|
||||
input childclk;
|
||||
output [1:0] \Y[2:1] ;
|
||||
|
||||
|
||||
BUFx2_ASAP7_75t_R \abuf_$100 (.A(childclk));
|
||||
BUFx2_ASAP7_75t_R \ff0/name (.A(childclk));
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
# Check if "h1\x" and \Y[2:1] are correctly processed from input to output of Verilog
|
||||
read_liberty gf180mcu_sram.lib.gz
|
||||
read_liberty asap7_small.lib.gz
|
||||
read_verilog verilog_write_escape.v
|
||||
link_design multi_sink
|
||||
set output_file "verilog_write_escape_out.v"
|
||||
write_verilog $output_file
|
||||
set fp [open $output_file r]
|
||||
while {[gets $fp line] >= 0} {
|
||||
puts $line
|
||||
}
|
||||
close $fp
|
||||
read_verilog $output_file
|
||||
file delete $output_file
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
module \multi_sink (clk);
|
||||
input clk;
|
||||
wire \alu_adder_result_ex[0] ;
|
||||
\hier_block \h1\x (.childclk(clk), .\Y[2:1] ({ \alu_adder_result_ex[0] , \alu_adder_result_ex[0] }) );
|
||||
endmodule // multi_sink
|
||||
|
||||
module \hier_block (childclk, \Y[2:1] );
|
||||
input childclk;
|
||||
output [1:0] \Y[2:1] ;
|
||||
wire [1:0] \Y[2:1] ;
|
||||
BUFx2_ASAP7_75t_R \abuf_$100 (.A(childclk));
|
||||
BUFx2_ASAP7_75t_R \ff0/name (.A(childclk));
|
||||
endmodule // hier_block1
|
||||
|
|
@ -389,7 +389,8 @@ VerilogWriter::writeInstBusPin(const Instance *inst,
|
|||
if (!first_port)
|
||||
fprintf(stream_, ",\n ");
|
||||
|
||||
fprintf(stream_, ".%s({", network_->name(port));
|
||||
string port_vname = portVerilogName(network_->name(port));
|
||||
fprintf(stream_, ".%s({", port_vname.c_str());
|
||||
first_port = false;
|
||||
bool first_member = true;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue