Merge remote-tracking branch 'parallax_sta/master' into sta_update_latest_0505
This commit is contained in:
commit
ccce34fea5
|
|
@ -4,6 +4,13 @@ OpenSTA Timing Analyzer Release Notes
|
||||||
This file summarizes user visible changes for each release.
|
This file summarizes user visible changes for each release.
|
||||||
See ApiChangeLog.txt for changes to the STA api.
|
See ApiChangeLog.txt for changes to the STA api.
|
||||||
|
|
||||||
|
2026/05/01
|
||||||
|
----------
|
||||||
|
|
||||||
|
The write_sdc command supports a -mode argument.
|
||||||
|
|
||||||
|
read_sdc [-mode mode]
|
||||||
|
|
||||||
2026/03/23
|
2026/03/23
|
||||||
----------
|
----------
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -138,7 +138,7 @@ public:
|
||||||
void setCmdScene(Scene *scene);
|
void setCmdScene(Scene *scene);
|
||||||
SceneSeq makeSceneSeq(Scene *scene) const;
|
SceneSeq makeSceneSeq(Scene *scene) const;
|
||||||
|
|
||||||
Mode *cmdMode() const { return cmd_scene_->mode(); }
|
Mode *cmdMode() const { return cmd_mode_; }
|
||||||
const std::string &cmdModeName();
|
const std::string &cmdModeName();
|
||||||
void setCmdMode(std::string_view mode_name);
|
void setCmdMode(std::string_view mode_name);
|
||||||
Mode *findMode(std::string_view mode_name) const;
|
Mode *findMode(std::string_view mode_name) const;
|
||||||
|
|
@ -1042,6 +1042,13 @@ public:
|
||||||
const Scene *scene,
|
const Scene *scene,
|
||||||
const MinMax *min_max,
|
const MinMax *min_max,
|
||||||
int digits);
|
int digits);
|
||||||
|
void writeSdc(std::string_view filename,
|
||||||
|
std::string_view mode_name,
|
||||||
|
bool leaf,
|
||||||
|
bool native,
|
||||||
|
int digits,
|
||||||
|
bool gzip,
|
||||||
|
bool no_timestamp);
|
||||||
void writeSdc(const Sdc *sdc,
|
void writeSdc(const Sdc *sdc,
|
||||||
std::string_view filename,
|
std::string_view filename,
|
||||||
// Map hierarchical pins and instances to leaf pins and instances.
|
// Map hierarchical pins and instances to leaf pins and instances.
|
||||||
|
|
@ -1611,6 +1618,7 @@ protected:
|
||||||
void checkLibrarayPocv();
|
void checkLibrarayPocv();
|
||||||
|
|
||||||
Scene *cmd_scene_{nullptr};
|
Scene *cmd_scene_{nullptr};
|
||||||
|
Mode *cmd_mode_{nullptr};
|
||||||
CmdNamespace cmd_namespace_{CmdNamespace::sdc};
|
CmdNamespace cmd_namespace_{CmdNamespace::sdc};
|
||||||
Instance *current_instance_{nullptr};
|
Instance *current_instance_{nullptr};
|
||||||
SceneNameMap scene_name_map_;
|
SceneNameMap scene_name_map_;
|
||||||
|
|
|
||||||
14
sdc/Sdc.i
14
sdc/Sdc.i
|
|
@ -94,15 +94,15 @@ private:
|
||||||
|
|
||||||
void
|
void
|
||||||
write_sdc_cmd(std::string filename,
|
write_sdc_cmd(std::string filename,
|
||||||
bool leaf,
|
std::string mode_name,
|
||||||
bool compatible,
|
bool leaf,
|
||||||
int digits,
|
bool compatible,
|
||||||
bool gzip,
|
int digits,
|
||||||
bool no_timestamp)
|
bool gzip,
|
||||||
|
bool no_timestamp)
|
||||||
{
|
{
|
||||||
Sta *sta = Sta::sta();
|
Sta *sta = Sta::sta();
|
||||||
const Sdc *sdc = sta->cmdSdc();
|
sta->writeSdc(filename, mode_name, leaf, compatible, digits, gzip, no_timestamp);
|
||||||
sta->writeSdc(sdc, filename, leaf, compatible, digits, gzip, no_timestamp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
31
sdc/Sdc.tcl
31
sdc/Sdc.tcl
|
|
@ -42,31 +42,38 @@ proc_redirect read_sdc {
|
||||||
check_argc_eq1 "read_sdc" $args
|
check_argc_eq1 "read_sdc" $args
|
||||||
set echo [info exists flags(-echo)]
|
set echo [info exists flags(-echo)]
|
||||||
set filename [file nativename [lindex $args 0]]
|
set filename [file nativename [lindex $args 0]]
|
||||||
set mode_name {}
|
|
||||||
if { [info exists keys(-mode)] } {
|
if { [info exists keys(-mode)] } {
|
||||||
set mode_name $keys(-mode)
|
set mode_name $keys(-mode)
|
||||||
}
|
set prev_mode [cmd_mode_name]
|
||||||
set prev_mode [cmd_mode_name]
|
try {
|
||||||
try {
|
set_cmd_mode $mode_name
|
||||||
set_mode_cmd $mode_name
|
include_file $filename $echo 0
|
||||||
include_file $filename $echo 0
|
} finally {
|
||||||
} finally {
|
if { $prev_mode != "default" } {
|
||||||
if { $prev_mode != "default" } {
|
set_cmd_mode $prev_mode
|
||||||
set_mode_cmd $prev_mode
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
include_file $filename $echo 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
################################################################
|
################################################################
|
||||||
|
|
||||||
define_cmd_args "write_sdc" \
|
define_cmd_args "write_sdc" \
|
||||||
{[-map_hpins] [-digits digits] [-gzip] [-no_timestamp] filename}
|
{[-mode mode] [-map_hpins] [-digits digits] [-gzip] [-no_timestamp] filename}
|
||||||
|
|
||||||
proc write_sdc { args } {
|
proc write_sdc { args } {
|
||||||
parse_key_args "write_sdc" args keys {-digits -significant_digits} \
|
parse_key_args "write_sdc" args keys {-mode -digits} \
|
||||||
flags {-map_hpins -compatible -gzip -no_timestamp}
|
flags {-map_hpins -compatible -gzip -no_timestamp}
|
||||||
check_argc_eq1 "write_sdc" $args
|
check_argc_eq1 "write_sdc" $args
|
||||||
|
|
||||||
|
set mode [cmd_mode]
|
||||||
|
if { [info exists keys(-mode)] } {
|
||||||
|
set mode $keys(-mode)
|
||||||
|
}
|
||||||
|
|
||||||
set digits 4
|
set digits 4
|
||||||
if { [info exists keys(-digits)] } {
|
if { [info exists keys(-digits)] } {
|
||||||
set digits $keys(-digits)
|
set digits $keys(-digits)
|
||||||
|
|
@ -78,7 +85,7 @@ proc write_sdc { args } {
|
||||||
set no_timestamp [info exists flags(-no_timestamp)]
|
set no_timestamp [info exists flags(-no_timestamp)]
|
||||||
set map_hpins [info exists flags(-map_hpins)]
|
set map_hpins [info exists flags(-map_hpins)]
|
||||||
set native [expr ![info exists flags(-compatible)]]
|
set native [expr ![info exists flags(-compatible)]]
|
||||||
write_sdc_cmd $filename $map_hpins $native $digits $gzip $no_timestamp
|
write_sdc_cmd $filename $mode $map_hpins $native $digits $gzip $no_timestamp
|
||||||
}
|
}
|
||||||
|
|
||||||
################################################################
|
################################################################
|
||||||
|
|
|
||||||
|
|
@ -180,7 +180,7 @@ define_cmd_args "write_sdf" \
|
||||||
|
|
||||||
proc_redirect write_sdf {
|
proc_redirect write_sdf {
|
||||||
parse_key_args "write_sdf" args \
|
parse_key_args "write_sdf" args \
|
||||||
keys {-corner -scene -divider -digits -significant_digits} \
|
keys {-corner -scene -divider -digits} \
|
||||||
flags {-include_typ -gzip -no_timestamp -no_version}
|
flags {-include_typ -gzip -no_timestamp -no_version}
|
||||||
check_argc_eq1 "write_sdf" $args
|
check_argc_eq1 "write_sdf" $args
|
||||||
set scene [parse_scene keys]
|
set scene [parse_scene keys]
|
||||||
|
|
|
||||||
|
|
@ -818,8 +818,14 @@ cmd_mode_name()
|
||||||
return Sta::sta()->cmdMode()->name();
|
return Sta::sta()->cmdMode()->name();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Mode *
|
||||||
|
cmd_mode()
|
||||||
|
{
|
||||||
|
return Sta::sta()->cmdMode();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
set_mode_cmd(std::string mode_name)
|
set_cmd_mode(std::string mode_name)
|
||||||
{
|
{
|
||||||
Sta::sta()->setCmdMode(mode_name);
|
Sta::sta()->setCmdMode(mode_name);
|
||||||
}
|
}
|
||||||
|
|
@ -830,6 +836,12 @@ find_modes(std::string mode_name)
|
||||||
return Sta::sta()->findModes(mode_name);
|
return Sta::sta()->findModes(mode_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Mode *
|
||||||
|
find_mode(std::string mode_name)
|
||||||
|
{
|
||||||
|
return Sta::sta()->findMode(mode_name);
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
CheckErrorSeq &
|
CheckErrorSeq &
|
||||||
|
|
|
||||||
|
|
@ -570,30 +570,46 @@ Sta::clearNonSdc()
|
||||||
Sdc *
|
Sdc *
|
||||||
Sta::cmdSdc() const
|
Sta::cmdSdc() const
|
||||||
{
|
{
|
||||||
return cmdMode()->sdc();
|
return cmd_mode_->sdc();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Sta::setCmdMode(std::string_view mode_name)
|
Sta::setCmdMode(std::string_view mode_name)
|
||||||
{
|
{
|
||||||
if (!mode_name.empty()) {
|
Mode *mode = findKey(mode_name_map_, std::string(mode_name));
|
||||||
if (!mode_name_map_.contains(mode_name)) {
|
if (mode) {
|
||||||
if (modes_.size() == 1 && modes_[0]->name() == "default") {
|
// Sync scene with mode. Note that multiple scenes can share a mode.
|
||||||
// No need for default mode if one is defined.
|
Scene *mode_scene = nullptr;
|
||||||
delete modes_[0];
|
for (Scene *scene : scenes_) {
|
||||||
mode_name_map_.clear();
|
if (scene->mode() == mode) {
|
||||||
modes_.clear();
|
if (mode_scene) {
|
||||||
|
report_->warn(1556, "multiple scenes reference mode {}", mode_name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mode_scene = scene;
|
||||||
}
|
}
|
||||||
Mode *mode = new Mode(mode_name, mode_name_map_.size(), this);
|
|
||||||
mode_name_map_[std::string(mode_name)] = mode;
|
|
||||||
modes_.push_back(mode);
|
|
||||||
mode->sim()->setMode(mode);
|
|
||||||
mode->sim()->setObserver(new StaSimObserver(this));
|
|
||||||
|
|
||||||
if (scenes_.size() == 1 && scenes_[0]->name() == "default")
|
|
||||||
scenes_[0]->setMode(mode);
|
|
||||||
updateComponentsState();
|
|
||||||
}
|
}
|
||||||
|
if (mode_scene)
|
||||||
|
cmd_scene_ = mode_scene;
|
||||||
|
cmd_mode_ = mode;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (modes_.size() == 1 && modes_[0]->name() == "default") {
|
||||||
|
// No need for default mode if one is defined.
|
||||||
|
delete modes_[0];
|
||||||
|
mode_name_map_.clear();
|
||||||
|
modes_.clear();
|
||||||
|
}
|
||||||
|
Mode *mode = new Mode(mode_name, mode_name_map_.size(), this);
|
||||||
|
mode_name_map_[std::string(mode_name)] = mode;
|
||||||
|
modes_.push_back(mode);
|
||||||
|
mode->sim()->setMode(mode);
|
||||||
|
mode->sim()->setObserver(new StaSimObserver(this));
|
||||||
|
cmd_mode_ = mode;
|
||||||
|
|
||||||
|
if (scenes_.size() == 1 && scenes_[0]->name() == "default")
|
||||||
|
scenes_[0]->setMode(mode);
|
||||||
|
updateComponentsState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2190,6 +2206,22 @@ Sta::checkExceptionToPins(ExceptionTo *to,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Sta::writeSdc(std::string_view filename,
|
||||||
|
std::string_view mode_name,
|
||||||
|
bool leaf,
|
||||||
|
bool native,
|
||||||
|
int digits,
|
||||||
|
bool gzip,
|
||||||
|
bool no_timestamp)
|
||||||
|
{
|
||||||
|
Mode *mode = findMode(mode_name);
|
||||||
|
if (mode)
|
||||||
|
writeSdc(mode->sdc(), filename, leaf, native, digits, gzip, no_timestamp);
|
||||||
|
else
|
||||||
|
report_->warn(1561, "mode {} not found.", mode_name);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Sta::writeSdc(const Sdc *sdc,
|
Sta::writeSdc(const Sdc *sdc,
|
||||||
std::string_view filename,
|
std::string_view filename,
|
||||||
|
|
@ -2514,6 +2546,7 @@ Sta::makeDefaultScene()
|
||||||
makeScene(name, mode, parasitics);
|
makeScene(name, mode, parasitics);
|
||||||
|
|
||||||
cmd_scene_ = scenes_[0];
|
cmd_scene_ = scenes_[0];
|
||||||
|
cmd_mode_ = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
// define_corners (before read_liberty).
|
// define_corners (before read_liberty).
|
||||||
|
|
@ -2603,8 +2636,8 @@ Sta::makeScene(const std::string &name,
|
||||||
if (scenes_.size() == 1 && findScene("default"))
|
if (scenes_.size() == 1 && findScene("default"))
|
||||||
deleteScenes();
|
deleteScenes();
|
||||||
|
|
||||||
Scene *scene =
|
Scene *scene = new Scene(name, scenes_.size(), mode,
|
||||||
new Scene(name, scenes_.size(), mode, parasitics_min, parasitics_max);
|
parasitics_min, parasitics_max);
|
||||||
scene_name_map_[name] = scene;
|
scene_name_map_[name] = scene;
|
||||||
scenes_.push_back(scene);
|
scenes_.push_back(scene);
|
||||||
mode->addScene(scene);
|
mode->addScene(scene);
|
||||||
|
|
@ -2696,6 +2729,7 @@ void
|
||||||
Sta::setCmdScene(Scene *scene)
|
Sta::setCmdScene(Scene *scene)
|
||||||
{
|
{
|
||||||
cmd_scene_ = scene;
|
cmd_scene_ = scene;
|
||||||
|
cmd_mode_ = scene->mode();
|
||||||
}
|
}
|
||||||
|
|
||||||
SceneSeq
|
SceneSeq
|
||||||
|
|
@ -3529,7 +3563,7 @@ Sta::findRequired(Vertex *vertex)
|
||||||
search_->findAllArrivals();
|
search_->findAllArrivals();
|
||||||
if (search_->isEndpoint(vertex)
|
if (search_->isEndpoint(vertex)
|
||||||
// Need to include downstream required times if there is fanout.
|
// Need to include downstream required times if there is fanout.
|
||||||
&& !hasFanout(vertex, search_->searchAdj(), graph_, cmdMode()))
|
&& !hasFanout(vertex, search_->searchAdj(), graph_, cmd_mode_))
|
||||||
search_->seedRequired(vertex);
|
search_->seedRequired(vertex);
|
||||||
else
|
else
|
||||||
search_->findRequireds(vertex->level());
|
search_->findRequireds(vertex->level());
|
||||||
|
|
@ -3927,14 +3961,14 @@ Sta::findLogicConstants()
|
||||||
{
|
{
|
||||||
ensureGraph();
|
ensureGraph();
|
||||||
// Sdc independent constants so any mode should return the same values.
|
// Sdc independent constants so any mode should return the same values.
|
||||||
Sim *sim = cmdMode()->sim();
|
Sim *sim = cmd_mode_->sim();
|
||||||
sim->findLogicConstants();
|
sim->findLogicConstants();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Sta::clearLogicConstants()
|
Sta::clearLogicConstants()
|
||||||
{
|
{
|
||||||
Sim *sim = cmdMode()->sim();
|
Sim *sim = cmd_mode_->sim();
|
||||||
sim->clear();
|
sim->clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,7 @@ define_cmd_args "set_scene" {scene_name}
|
||||||
|
|
||||||
proc set_scene { args } {
|
proc set_scene { args } {
|
||||||
check_argc_eq1 "set_scene" $args
|
check_argc_eq1 "set_scene" $args
|
||||||
set_scene_cmd [lindex $args 0]
|
set_cmd_scene [lindex $args 0]
|
||||||
}
|
}
|
||||||
|
|
||||||
################################################################
|
################################################################
|
||||||
|
|
@ -141,7 +141,7 @@ define_cmd_args "set_mode" {mode_name}
|
||||||
|
|
||||||
proc set_mode { args } {
|
proc set_mode { args } {
|
||||||
check_argc_eq1 "set_mode" $args
|
check_argc_eq1 "set_mode" $args
|
||||||
set_mode_cmd [lindex $args 0]
|
set_cmd_mode [lindex $args 0]
|
||||||
}
|
}
|
||||||
|
|
||||||
################################################################
|
################################################################
|
||||||
|
|
|
||||||
|
|
@ -156,11 +156,8 @@ proc expand_tests { argv } {
|
||||||
lappend tests $test
|
lappend tests $test
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} elseif { [lsearch [group_tests "all"] $arg] != -1 } {
|
|
||||||
lappend tests $arg
|
|
||||||
} else {
|
} else {
|
||||||
puts "Error: test $arg not found."
|
lappend tests $arg
|
||||||
incr errors(no_cmd)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $tests
|
return $tests
|
||||||
|
|
@ -525,15 +522,11 @@ proc show_summary {} {
|
||||||
if { $valgrind_shared_lib_failure } {
|
if { $valgrind_shared_lib_failure } {
|
||||||
puts "WARNING: valgrind failed because the executable is not statically linked."
|
puts "WARNING: valgrind failed because the executable is not statically linked."
|
||||||
}
|
}
|
||||||
puts "See $result_dir for log files"
|
|
||||||
set test_count [llength $tests]
|
set test_count [llength $tests]
|
||||||
if { [found_errors] } {
|
if { [found_errors] } {
|
||||||
if { $errors(error) != 0 } {
|
if { $errors(error) != 0 } {
|
||||||
puts "Errored $errors(error)/$test_count"
|
puts "Errored $errors(error)/$test_count"
|
||||||
}
|
}
|
||||||
if { $errors(fail) != 0 } {
|
|
||||||
puts "Failed $errors(fail)/$test_count"
|
|
||||||
}
|
|
||||||
if { $errors(leak) != 0 } {
|
if { $errors(leak) != 0 } {
|
||||||
puts "Memory leaks in $errors(leak)/$test_count"
|
puts "Memory leaks in $errors(leak)/$test_count"
|
||||||
}
|
}
|
||||||
|
|
@ -547,7 +540,7 @@ proc show_summary {} {
|
||||||
puts "No cmd tcl file for $errors(no_cmd)/$test_count"
|
puts "No cmd tcl file for $errors(no_cmd)/$test_count"
|
||||||
}
|
}
|
||||||
if { $errors(fail) != 0 } {
|
if { $errors(fail) != 0 } {
|
||||||
puts "See $diff_file for differences"
|
puts "Failed $errors(fail)/$test_count"
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
puts "Passed $test_count"
|
puts "Passed $test_count"
|
||||||
|
|
|
||||||
|
|
@ -447,12 +447,13 @@ VerilogWriter::writeAssigns(const Instance *inst)
|
||||||
if (term) {
|
if (term) {
|
||||||
Net *net = network_->net(term);
|
Net *net = network_->net(term);
|
||||||
Port *port = network_->port(pin);
|
Port *port = network_->port(pin);
|
||||||
if (port
|
if (net
|
||||||
|
&& port
|
||||||
&& (include_pwr_gnd_
|
&& (include_pwr_gnd_
|
||||||
|| !(network_->isPower(net) || network_->isGround(net)))
|
|| !(network_->isPower(net) || network_->isGround(net)))
|
||||||
&& (network_->direction(port)->isAnyOutput()
|
&& (network_->direction(port)->isAnyOutput()
|
||||||
|| (include_pwr_gnd_ && network_->direction(port)->isPowerGround()))
|
|| (include_pwr_gnd_ && network_->direction(port)->isPowerGround()))
|
||||||
&& !stringEqual(network_->name(port), network_->name(net))) {
|
&& network_->name(port) != network_->name(net)) {
|
||||||
// Port name is different from net name.
|
// Port name is different from net name.
|
||||||
std::string port_vname = netVerilogName(std::string(network_->name(port)));
|
std::string port_vname = netVerilogName(std::string(network_->name(port)));
|
||||||
std::string net_vname = netVerilogName(std::string(network_->name(net)));
|
std::string net_vname = netVerilogName(std::string(network_->name(net)));
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue