make mode/scene pass as tcl objects (#454)
* make mode/scene pass as tcl objects Signed-off-by: dsengupta0628 <dsengupta@precisioninno.com> * address review comments Signed-off-by: dsengupta0628 <dsengupta@precisioninno.com> * address review comments take 2 Signed-off-by: dsengupta0628 <dsengupta@precisioninno.com> * revert to using cmd mode name Signed-off-by: dsengupta0628 <dsengupta@precisioninno.com> --------- Signed-off-by: dsengupta0628 <dsengupta@precisioninno.com>
This commit is contained in:
parent
310107acd8
commit
998806cb13
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -72,6 +72,20 @@ private:
|
|||
~PathEnd();
|
||||
};
|
||||
|
||||
class Scene
|
||||
{
|
||||
private:
|
||||
Scene();
|
||||
~Scene();
|
||||
};
|
||||
|
||||
class Mode
|
||||
{
|
||||
private:
|
||||
Mode();
|
||||
~Mode();
|
||||
};
|
||||
|
||||
%inline %{
|
||||
|
||||
using std::string;
|
||||
|
|
|
|||
|
|
@ -536,16 +536,25 @@ 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]
|
||||
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 {
|
||||
set scene [find_scene $scene_arg]
|
||||
if { $scene == "NULL" } {
|
||||
sta_error 134 "$scene_name is not the name of a scene."
|
||||
sta_error 134 "$scene_arg is not the name of a scene."
|
||||
} else {
|
||||
lappend scenes $scene
|
||||
}
|
||||
}
|
||||
}
|
||||
return $scenes
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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" } {
|
||||
|
|
|
|||
19
tcl/Sta.tcl
19
tcl/Sta.tcl
|
|
@ -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]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
[get_scenes *]
|
||||
scene1
|
||||
scene2
|
||||
[get_modes *]
|
||||
mode1
|
||||
mode2
|
||||
|
|
@ -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 *]
|
||||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue