Merge remote-tracking branch 'upstream/master' into sta_latest_0629

This commit is contained in:
dsengupta0628 2026-06-30 17:11:41 +00:00
commit 5c68ce6b54
15 changed files with 1488 additions and 1392 deletions

File diff suppressed because it is too large Load Diff

View File

@ -42,6 +42,8 @@ class PropertyValue;
class Sta;
class PropertyValue;
class Scene;
class Mode;
template<class TYPE>
class PropertyRegistry
@ -86,6 +88,10 @@ public:
std::string_view property);
PropertyValue getProperty(const Clock *clk,
std::string_view property);
PropertyValue getProperty(const Scene *scene,
std::string_view property);
PropertyValue getProperty(const Mode *mode,
std::string_view property);
PropertyValue getProperty(PathEnd *end,
std::string_view property);
PropertyValue getProperty(Path *path,

View File

@ -1518,6 +1518,7 @@ protected:
bool infer_latches);
void delayCalcPreamble();
void delaysInvalidFrom(const Port *port);
void delaysInvalidFromFanin(const Port *port);
void deleteEdge(Edge *edge);
void netParasiticCaps(Net *net,
const RiseFall *rf,

View File

@ -45,7 +45,7 @@ proc_redirect read_sdc {
if { [info exists keys(-mode)] } {
set mode_name $keys(-mode)
set prev_mode [cmd_mode]
set prev_mode [cmd_mode_name]
try {
set_cmd_mode $mode_name
include_file $filename $echo 0
@ -69,7 +69,7 @@ proc write_sdc { args } {
flags {-map_hpins -compatible -gzip -no_timestamp}
check_argc_eq1 "write_sdc" $args
set mode [cmd_mode]
set mode [cmd_mode_name]
if { [info exists keys(-mode)] } {
set mode $keys(-mode)
}

View File

@ -33,6 +33,7 @@
#include "Graph.hh"
#include "Liberty.hh"
#include "MinMax.hh"
#include "Mode.hh"
#include "Network.hh"
#include "Path.hh"
#include "PathEnd.hh"
@ -1196,6 +1197,32 @@ Properties::getProperty(const Clock *clk,
////////////////////////////////////////////////////////////////
PropertyValue
Properties::getProperty(const Scene *scene,
std::string_view property)
{
if (property == "name"
|| property == "full_name")
return PropertyValue(scene->name());
else
throw PropertyUnknown("scene", property);
}
////////////////////////////////////////////////////////////////
PropertyValue
Properties::getProperty(const Mode *mode,
std::string_view property)
{
if (property == "name"
|| property == "full_name")
return PropertyValue(mode->name());
else
throw PropertyUnknown("mode", property);
}
////////////////////////////////////////////////////////////////
PropertyValue
Properties::getProperty(PathEnd *end,
std::string_view property)

View File

@ -121,6 +121,22 @@ clock_property(Clock *clk,
return properties.getProperty(clk, property);
}
PropertyValue
scene_property(Scene *scene,
const char *property)
{
Properties &properties = Sta::sta()->properties();
return properties.getProperty(scene, property);
}
PropertyValue
mode_property(Mode *mode,
const char *property)
{
Properties &properties = Sta::sta()->properties();
return properties.getProperty(mode, property);
}
PropertyValue
path_end_property(PathEnd *end,
const char *property)

View File

@ -72,6 +72,20 @@ private:
~PathEnd();
};
class Scene
{
private:
Scene();
~Scene();
};
class Mode
{
private:
Mode();
~Mode();
};
%inline %{
using std::string;

View File

@ -3992,7 +3992,7 @@ Sta::setPortExtPinCap(const Port *port,
for (const MinMax *mm : min_max->range())
sdc->setPortExtPinCap(port, rf1, mm, cap);
}
delaysInvalidFrom(port);
delaysInvalidFromFanin(port);
}
void
@ -4047,7 +4047,7 @@ Sta::setPortExtWireCap(const Port *port,
for (const MinMax *mm : min_max->range())
sdc->setPortExtWireCap(port, rf1, mm, cap);
}
delaysInvalidFrom(port);
delaysInvalidFromFanin(port);
}
void
@ -4065,7 +4065,7 @@ Sta::setPortExtFanout(const Port *port,
{
for (const MinMax *mm : min_max->range())
sdc->setPortExtFanout(port, mm, fanout);
delaysInvalidFrom(port);
delaysInvalidFromFanin(port);
}
void
@ -5050,6 +5050,20 @@ Sta::delaysInvalidFrom(Vertex *vertex)
graph_delay_calc_->delayInvalid(vertex);
}
void
Sta::delaysInvalidFromFanin(const Port *port)
{
if (graph_) {
Instance *top_inst = network_->topInstance();
Pin *pin = network_->findPin(top_inst, port);
Vertex *vertex, *bidirect_drvr_vertex;
graph_->pinVertices(pin, vertex, bidirect_drvr_vertex);
delaysInvalidFromFanin(vertex);
if (bidirect_drvr_vertex)
delaysInvalidFromFanin(bidirect_drvr_vertex);
}
}
void
Sta::delaysInvalidFromFanin(const Pin *pin)
{

View File

@ -536,14 +536,23 @@ proc parse_scenes_or_all { keys_var } {
}
}
proc find_scenes { scene_names } {
proc find_scenes { scenes_arg } {
set scenes {}
foreach scene_name $scene_names {
set scene [find_scene $scene_name]
if { $scene == "NULL" } {
sta_error 134 "$scene_name is not the name of a scene."
foreach scene_arg $scenes_arg {
if { [is_object $scene_arg] } {
set object_type [object_type $scene_arg]
if { $object_type == "Scene" } {
lappend scenes $scene_arg
} else {
sta_error 135 "scene object type '$object_type' is not a scene."
}
} else {
lappend scenes $scene
set scene [find_scene $scene_arg]
if { $scene == "NULL" } {
sta_error 134 "$scene_arg is not the name of a scene."
} else {
lappend scenes $scene
}
}
}
return $scenes

View File

@ -57,6 +57,10 @@ proc get_object_property { object prop } {
return [net_property $object $prop]
} elseif { $object_type == "Clock" } {
return [clock_property $object $prop]
} elseif { $object_type == "Scene" } {
return [scene_property $object $prop]
} elseif { $object_type == "Mode" } {
return [mode_property $object $prop]
} elseif { $object_type == "Port" } {
return [port_property $object $prop]
} elseif { $object_type == "LibertyPort" } {

View File

@ -102,7 +102,12 @@ define_cmd_args "set_scene" {scene_name}
proc set_scene { args } {
check_argc_eq1 "set_scene" $args
set_cmd_scene [lindex $args 0]
set scene_name [lindex $args 0]
set scene [find_scene $scene_name]
if { $scene == "NULL" } {
sta_error 578 "$scene_name is not the name of a scene."
}
set_cmd_scene $scene
}
################################################################
@ -118,10 +123,16 @@ proc get_scenes { args } {
} else {
set scene_name [lindex $args 0]
}
set mode_names {}
if { [info exists keys(-modes)] } {
set mode_names $keys(-modes)
return [find_mode_scenes_matching $scene_name $mode_names]
set modes {}
foreach mode_name $keys(-modes) {
set mode [find_mode $mode_name]
if { $mode == "NULL" } {
sta_error 579 "$mode_name is not the name of a mode."
}
lappend modes $mode
}
return [find_mode_scenes_matching $scene_name $modes]
} else {
return [find_scenes_matching $scene_name]
}

View File

@ -1189,106 +1189,70 @@ using namespace sta;
$1 = tclListSetConstChar($input, interp);
}
%typemap(in) Mode* {
Tcl_Size length;
const char *arg = Tcl_GetStringFromObj($input, &length);
if (stringEqual(arg, "NULL"))
$1 = nullptr;
else {
void *obj;
if (SWIG_ConvertPtr($input, &obj, SWIGTYPE_p_Mode, false) != TCL_OK) {
tclArgError(interp, 2174, "{} is not a mode object.", arg);
return TCL_ERROR;
}
$1 = reinterpret_cast<Mode*>(obj);
}
}
%typemap(out) Mode* {
const Mode *mode = $1;
if (mode)
Tcl_SetResult(interp, const_cast<char*>($1->name().c_str()), TCL_VOLATILE);
Mode *mode = $1;
if (mode) {
Tcl_Obj *obj = SWIG_NewInstanceObj(mode, SWIGTYPE_p_Mode, false);
Tcl_SetObjResult(interp, obj);
}
else
Tcl_SetResult(interp, const_cast<char*>("NULL"), TCL_STATIC);
}
%typemap(in) ModeSeq {
Tcl_Size argc;
Tcl_Obj **argv;
Sta *sta = Sta::sta();
std::vector<Mode*> seq;
if (Tcl_ListObjGetElements(interp, $input, &argc, &argv) == TCL_OK
&& argc > 0) {
for (int i = 0; i < argc; i++) {
Tcl_Size length;
const char *mode_name = Tcl_GetStringFromObj(argv[i], &length);
Mode *mode = sta->findMode(mode_name);
if (mode)
seq.push_back(mode);
else {
tclArgError(interp, 2174, "mode {} not found.", mode_name);
return TCL_ERROR;
}
}
}
$1 = seq;
$1 = tclListSeq<Mode*>($input, SWIGTYPE_p_Mode, interp);
}
%typemap(out) ModeSeq {
Tcl_Obj *list = Tcl_NewListObj(0, nullptr);
ModeSeq &modes = $1;
for (Mode *mode : modes) {
const std::string &mode_name = mode->name();
Tcl_Obj *obj = Tcl_NewStringObj(mode_name.c_str(), mode_name.size());
Tcl_ListObjAppendElement(interp, list, obj);
}
Tcl_SetObjResult(interp, list);
seqTclList<ModeSeq, Mode>($1, SWIGTYPE_p_Mode, interp);
}
%typemap(in) Scene* {
sta::Sta *sta = Sta::sta();
Tcl_Size length;
std::string scene_name = Tcl_GetStringFromObj($input, &length);
// parse_scene_or_all support depreated 11/21/2025
if (scene_name == "NULL")
const char *arg = Tcl_GetStringFromObj($input, &length);
if (stringEqual(arg, "NULL"))
$1 = nullptr;
else {
Scene *scene = sta->findScene(scene_name);
if (scene)
$1 = scene;
else {
tclArgError(interp, 2173, "scene {} not found.", scene_name.c_str());
void *obj;
if (SWIG_ConvertPtr($input, &obj, SWIGTYPE_p_Scene, false) != TCL_OK) {
tclArgError(interp, 2173, "{} is not a scene object.", arg);
return TCL_ERROR;
}
$1 = reinterpret_cast<Scene*>(obj);
}
}
%typemap(out) Scene* {
const Scene *scene = $1;
if (scene)
Tcl_SetResult(interp, const_cast<char*>($1->name().c_str()), TCL_VOLATILE);
Scene *scene = $1;
if (scene) {
Tcl_Obj *obj = SWIG_NewInstanceObj(scene, SWIGTYPE_p_Scene, false);
Tcl_SetObjResult(interp, obj);
}
else
Tcl_SetResult(interp, const_cast<char*>("NULL"), TCL_STATIC);
}
%typemap(in) SceneSeq {
Tcl_Size argc;
Tcl_Obj **argv;
Sta *sta = Sta::sta();
std::vector<Scene*> seq;
if (Tcl_ListObjGetElements(interp, $input, &argc, &argv) == TCL_OK
&& argc > 0) {
for (int i = 0; i < argc; i++) {
Tcl_Size length;
const char *scene_name = Tcl_GetStringFromObj(argv[i], &length);
Scene *scene = sta->findScene(scene_name);
if (scene)
seq.push_back(scene);
else {
tclArgError(interp, 2172, "scene {} not found.", scene_name);
return TCL_ERROR;
}
}
}
$1 = seq;
$1 = tclListSeq<Scene*>($input, SWIGTYPE_p_Scene, interp);
}
%typemap(out) SceneSeq {
Tcl_Obj *list = Tcl_NewListObj(0, nullptr);
SceneSeq &scenes = $1;
for (Scene *scene : scenes) {
const std::string &scene_name = scene->name();
Tcl_Obj *obj = Tcl_NewStringObj(scene_name.c_str(), scene_name.size());
Tcl_ListObjAppendElement(interp, list, obj);
}
Tcl_SetObjResult(interp, list);
seqTclList<SceneSeq, Scene>($1, SWIGTYPE_p_Scene, interp);
}
%typemap(in) PropertyValue {

6
test/get_scenes.ok Normal file
View File

@ -0,0 +1,6 @@
[get_scenes *]
scene1
scene2
[get_modes *]
mode1
mode2

20
test/get_scenes.tcl Normal file
View File

@ -0,0 +1,20 @@
# get_scenes / get_modes return objects
read_liberty ../examples/asap7_small_ff.lib.gz
read_liberty ../examples/asap7_small_ss.lib.gz
read_verilog ../examples/reg1_asap7.v
link_design top
read_sdc -mode mode1 ../examples/mcmm2_mode1.sdc
read_sdc -mode mode2 ../examples/mcmm2_mode2.sdc
read_spef -name reg1_ff ../examples/reg1_asap7.spef
read_spef -name reg1_ss ../examples/reg1_asap7_ss.spef
define_scene scene1 -mode mode1 -liberty asap7_small_ff -spef reg1_ff
define_scene scene2 -mode mode2 -liberty asap7_small_ss -spef reg1_ss
puts {[get_scenes *]}
report_object_names [get_scenes *]
puts {[get_modes *]}
report_object_names [get_modes *]

View File

@ -147,6 +147,7 @@ record_public_tests {
get_is_memory
get_lib_pins_of_objects
get_noargs
get_scenes
get_objrefs
input_delay_ref_pin_rebuild
liberty_arcs_one2one_1