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 Sta;
|
||||||
class PropertyValue;
|
class PropertyValue;
|
||||||
|
class Scene;
|
||||||
|
class Mode;
|
||||||
|
|
||||||
template<class TYPE>
|
template<class TYPE>
|
||||||
class PropertyRegistry
|
class PropertyRegistry
|
||||||
|
|
@ -86,6 +88,10 @@ public:
|
||||||
std::string_view property);
|
std::string_view property);
|
||||||
PropertyValue getProperty(const Clock *clk,
|
PropertyValue getProperty(const Clock *clk,
|
||||||
std::string_view property);
|
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,
|
PropertyValue getProperty(PathEnd *end,
|
||||||
std::string_view property);
|
std::string_view property);
|
||||||
PropertyValue getProperty(Path *path,
|
PropertyValue getProperty(Path *path,
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ proc_redirect read_sdc {
|
||||||
|
|
||||||
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]
|
set prev_mode [cmd_mode_name]
|
||||||
try {
|
try {
|
||||||
set_cmd_mode $mode_name
|
set_cmd_mode $mode_name
|
||||||
include_file $filename $echo 0
|
include_file $filename $echo 0
|
||||||
|
|
@ -69,7 +69,7 @@ proc write_sdc { args } {
|
||||||
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]
|
set mode [cmd_mode_name]
|
||||||
if { [info exists keys(-mode)] } {
|
if { [info exists keys(-mode)] } {
|
||||||
set mode $keys(-mode)
|
set mode $keys(-mode)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@
|
||||||
#include "Graph.hh"
|
#include "Graph.hh"
|
||||||
#include "Liberty.hh"
|
#include "Liberty.hh"
|
||||||
#include "MinMax.hh"
|
#include "MinMax.hh"
|
||||||
|
#include "Mode.hh"
|
||||||
#include "Network.hh"
|
#include "Network.hh"
|
||||||
#include "Path.hh"
|
#include "Path.hh"
|
||||||
#include "PathEnd.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
|
PropertyValue
|
||||||
Properties::getProperty(PathEnd *end,
|
Properties::getProperty(PathEnd *end,
|
||||||
std::string_view property)
|
std::string_view property)
|
||||||
|
|
|
||||||
|
|
@ -121,6 +121,22 @@ clock_property(Clock *clk,
|
||||||
return properties.getProperty(clk, property);
|
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
|
PropertyValue
|
||||||
path_end_property(PathEnd *end,
|
path_end_property(PathEnd *end,
|
||||||
const char *property)
|
const char *property)
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,20 @@ private:
|
||||||
~PathEnd();
|
~PathEnd();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class Scene
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
Scene();
|
||||||
|
~Scene();
|
||||||
|
};
|
||||||
|
|
||||||
|
class Mode
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
Mode();
|
||||||
|
~Mode();
|
||||||
|
};
|
||||||
|
|
||||||
%inline %{
|
%inline %{
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
|
||||||
|
|
@ -536,14 +536,23 @@ proc parse_scenes_or_all { keys_var } {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
proc find_scenes { scene_names } {
|
proc find_scenes { scenes_arg } {
|
||||||
set scenes {}
|
set scenes {}
|
||||||
foreach scene_name $scene_names {
|
foreach scene_arg $scenes_arg {
|
||||||
set scene [find_scene $scene_name]
|
if { [is_object $scene_arg] } {
|
||||||
if { $scene == "NULL" } {
|
set object_type [object_type $scene_arg]
|
||||||
sta_error 134 "$scene_name is not the name of a scene."
|
if { $object_type == "Scene" } {
|
||||||
|
lappend scenes $scene_arg
|
||||||
|
} else {
|
||||||
|
sta_error 135 "scene object type '$object_type' is not a scene."
|
||||||
|
}
|
||||||
} else {
|
} 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
|
return $scenes
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,10 @@ proc get_object_property { object prop } {
|
||||||
return [net_property $object $prop]
|
return [net_property $object $prop]
|
||||||
} elseif { $object_type == "Clock" } {
|
} elseif { $object_type == "Clock" } {
|
||||||
return [clock_property $object $prop]
|
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" } {
|
} elseif { $object_type == "Port" } {
|
||||||
return [port_property $object $prop]
|
return [port_property $object $prop]
|
||||||
} elseif { $object_type == "LibertyPort" } {
|
} 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 } {
|
proc set_scene { args } {
|
||||||
check_argc_eq1 "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 {
|
} else {
|
||||||
set scene_name [lindex $args 0]
|
set scene_name [lindex $args 0]
|
||||||
}
|
}
|
||||||
set mode_names {}
|
|
||||||
if { [info exists keys(-modes)] } {
|
if { [info exists keys(-modes)] } {
|
||||||
set mode_names $keys(-modes)
|
set modes {}
|
||||||
return [find_mode_scenes_matching $scene_name $mode_names]
|
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 {
|
} else {
|
||||||
return [find_scenes_matching $scene_name]
|
return [find_scenes_matching $scene_name]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1189,106 +1189,70 @@ using namespace sta;
|
||||||
$1 = tclListSetConstChar($input, interp);
|
$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* {
|
%typemap(out) Mode* {
|
||||||
const Mode *mode = $1;
|
Mode *mode = $1;
|
||||||
if (mode)
|
if (mode) {
|
||||||
Tcl_SetResult(interp, const_cast<char*>($1->name().c_str()), TCL_VOLATILE);
|
Tcl_Obj *obj = SWIG_NewInstanceObj(mode, SWIGTYPE_p_Mode, false);
|
||||||
|
Tcl_SetObjResult(interp, obj);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
Tcl_SetResult(interp, const_cast<char*>("NULL"), TCL_STATIC);
|
Tcl_SetResult(interp, const_cast<char*>("NULL"), TCL_STATIC);
|
||||||
}
|
}
|
||||||
|
|
||||||
%typemap(in) ModeSeq {
|
%typemap(in) ModeSeq {
|
||||||
Tcl_Size argc;
|
$1 = tclListSeq<Mode*>($input, SWIGTYPE_p_Mode, interp);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
%typemap(out) ModeSeq {
|
%typemap(out) ModeSeq {
|
||||||
Tcl_Obj *list = Tcl_NewListObj(0, nullptr);
|
seqTclList<ModeSeq, Mode>($1, SWIGTYPE_p_Mode, interp);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
%typemap(in) Scene* {
|
%typemap(in) Scene* {
|
||||||
sta::Sta *sta = Sta::sta();
|
|
||||||
Tcl_Size length;
|
Tcl_Size length;
|
||||||
std::string scene_name = Tcl_GetStringFromObj($input, &length);
|
const char *arg = Tcl_GetStringFromObj($input, &length);
|
||||||
// parse_scene_or_all support depreated 11/21/2025
|
if (stringEqual(arg, "NULL"))
|
||||||
if (scene_name == "NULL")
|
|
||||||
$1 = nullptr;
|
$1 = nullptr;
|
||||||
else {
|
else {
|
||||||
Scene *scene = sta->findScene(scene_name);
|
void *obj;
|
||||||
if (scene)
|
if (SWIG_ConvertPtr($input, &obj, SWIGTYPE_p_Scene, false) != TCL_OK) {
|
||||||
$1 = scene;
|
tclArgError(interp, 2173, "{} is not a scene object.", arg);
|
||||||
else {
|
|
||||||
tclArgError(interp, 2173, "scene {} not found.", scene_name.c_str());
|
|
||||||
return TCL_ERROR;
|
return TCL_ERROR;
|
||||||
}
|
}
|
||||||
|
$1 = reinterpret_cast<Scene*>(obj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
%typemap(out) Scene* {
|
%typemap(out) Scene* {
|
||||||
const Scene *scene = $1;
|
Scene *scene = $1;
|
||||||
if (scene)
|
if (scene) {
|
||||||
Tcl_SetResult(interp, const_cast<char*>($1->name().c_str()), TCL_VOLATILE);
|
Tcl_Obj *obj = SWIG_NewInstanceObj(scene, SWIGTYPE_p_Scene, false);
|
||||||
|
Tcl_SetObjResult(interp, obj);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
Tcl_SetResult(interp, const_cast<char*>("NULL"), TCL_STATIC);
|
Tcl_SetResult(interp, const_cast<char*>("NULL"), TCL_STATIC);
|
||||||
}
|
}
|
||||||
|
|
||||||
%typemap(in) SceneSeq {
|
%typemap(in) SceneSeq {
|
||||||
Tcl_Size argc;
|
$1 = tclListSeq<Scene*>($input, SWIGTYPE_p_Scene, interp);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
%typemap(out) SceneSeq {
|
%typemap(out) SceneSeq {
|
||||||
Tcl_Obj *list = Tcl_NewListObj(0, nullptr);
|
seqTclList<SceneSeq, Scene>($1, SWIGTYPE_p_Scene, interp);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
%typemap(in) PropertyValue {
|
%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_is_memory
|
||||||
get_lib_pins_of_objects
|
get_lib_pins_of_objects
|
||||||
get_noargs
|
get_noargs
|
||||||
|
get_scenes
|
||||||
get_objrefs
|
get_objrefs
|
||||||
input_delay_ref_pin_rebuild
|
input_delay_ref_pin_rebuild
|
||||||
liberty_arcs_one2one_1
|
liberty_arcs_one2one_1
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue