Extend user-defined properties to all basic object types (#479)

* support for filter in get_scene/mode

Signed-off-by: dsengupta0628 <dsengupta@precisioninno.com>

* extend user defined property to all 10 objects

Signed-off-by: dsengupta0628 <dsengupta@precisioninno.com>

* address reviews

Signed-off-by: dsengupta0628 <dsengupta@precisioninno.com>

---------

Signed-off-by: dsengupta0628 <dsengupta@precisioninno.com>
This commit is contained in:
Deepashree Sengupta 2026-07-27 15:50:40 +00:00 committed by GitHub
parent ef0b69091f
commit f476e269b9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 164 additions and 1 deletions

View File

@ -284,6 +284,10 @@ protected:
PropertyValue::Type propertyType(std::string_view type);
PropertyValue coercePropertyValue(PropertyValue::Type type,
std::string_view value);
// True if a user-defined property of this name was declared (via
// defineProperty) on this object type.
bool isUserProperty(std::string_view object_type,
std::string_view property);
PropertyRegistry<const Library*> registry_library_;
PropertyRegistry<const LibertyLibrary*> registry_liberty_library_;

View File

@ -643,6 +643,8 @@ Properties::getProperty(const Library *lib,
"library", sta_);
if (value.type() != PropertyValue::Type::none)
return value;
else if (isUserProperty("library", property))
return value;
else
throw PropertyUnknown("library", property);
}
@ -665,6 +667,8 @@ Properties::getProperty(const LibertyLibrary *lib,
sta_);
if (value.type() != PropertyValue::Type::none)
return value;
else if (isUserProperty("liberty_library", property))
return value;
else
throw PropertyUnknown("liberty library", property);
}
@ -696,6 +700,8 @@ Properties::getProperty(const Cell *cell,
"cell", sta_);
if (value.type() != PropertyValue::Type::none)
return value;
else if (isUserProperty("cell", property))
return value;
else
throw PropertyUnknown("cell", property);
}
@ -737,6 +743,8 @@ Properties::getProperty(const LibertyCell *cell,
"liberty_cell", sta_);
if (value.type() != PropertyValue::Type::none)
return value;
else if (isUserProperty("liberty_cell", property))
return value;
else
throw PropertyUnknown("liberty cell", property);
}
@ -797,6 +805,8 @@ Properties::getProperty(const Port *port,
"port", sta_);
if (value.type() != PropertyValue::Type::none)
return value;
else if (isUserProperty("port", property))
return value;
else
throw PropertyUnknown("port", property);
}
@ -898,6 +908,8 @@ Properties::getProperty(const LibertyPort *port,
"liberty_port", sta_);
if (value.type() != PropertyValue::Type::none)
return value;
else if (isUserProperty("liberty_port", property))
return value;
else
throw PropertyUnknown("liberty port", property);
}
@ -938,6 +950,8 @@ Properties::getProperty(const Instance *inst,
"instance", sta_);
if (value.type() != PropertyValue::Type::none)
return value;
else if (isUserProperty("instance", property))
return value;
else
throw PropertyUnknown("instance", property);
}
@ -1025,6 +1039,8 @@ Properties::getProperty(const Pin *pin,
PropertyValue value = registry_pin_.getProperty(pin, property, "pin", sta_);
if (value.type() != PropertyValue::Type::none)
return value;
else if (isUserProperty("pin", property))
return value;
else
throw PropertyUnknown("pin", property);
}
@ -1086,6 +1102,8 @@ Properties::getProperty(const Net *net,
PropertyValue value = registry_net_.getProperty(net, property, "net", sta_);
if (value.type() != PropertyValue::Type::none)
return value;
else if (isUserProperty("net", property))
return value;
else
throw PropertyUnknown("net", property);
}
@ -1191,6 +1209,8 @@ Properties::getProperty(const Clock *clk,
"clock", sta_);
if (value.type() != PropertyValue::Type::none)
return value;
else if (isUserProperty("clock", property))
return value;
else
throw PropertyUnknown("clock", property);
}
@ -1420,6 +1440,13 @@ Properties::coercePropertyValue(PropertyValue::Type type,
}
}
bool
Properties::isUserProperty(std::string_view object_type,
std::string_view property)
{
return prop_types_.contains({std::string(object_type), std::string(property)});
}
PropertyKey::PropertyKey(const void *object,
std::string_view property) :
object_(object),
@ -1462,6 +1489,36 @@ template void Properties::defineProperty<Scene>(std::string_view,
template void Properties::defineProperty<Mode>(std::string_view,
std::string_view,
std::string_view);
template void Properties::defineProperty<Library>(std::string_view,
std::string_view,
std::string_view);
template void Properties::defineProperty<LibertyLibrary>(std::string_view,
std::string_view,
std::string_view);
template void Properties::defineProperty<Cell>(std::string_view,
std::string_view,
std::string_view);
template void Properties::defineProperty<LibertyCell>(std::string_view,
std::string_view,
std::string_view);
template void Properties::defineProperty<Port>(std::string_view,
std::string_view,
std::string_view);
template void Properties::defineProperty<LibertyPort>(std::string_view,
std::string_view,
std::string_view);
template void Properties::defineProperty<Instance>(std::string_view,
std::string_view,
std::string_view);
template void Properties::defineProperty<Pin>(std::string_view,
std::string_view,
std::string_view);
template void Properties::defineProperty<Net>(std::string_view,
std::string_view,
std::string_view);
template void Properties::defineProperty<Clock>(std::string_view,
std::string_view,
std::string_view);
void
Properties::setProperty(const void *object,

View File

@ -149,6 +149,26 @@ define_property_cmd(const char *object_type,
properties.defineProperty<Scene>(object_type, property, type);
else if (object_type_view == "mode")
properties.defineProperty<Mode>(object_type, property, type);
else if (object_type_view == "library")
properties.defineProperty<Library>(object_type, property, type);
else if (object_type_view == "liberty_library")
properties.defineProperty<LibertyLibrary>(object_type, property, type);
else if (object_type_view == "cell")
properties.defineProperty<Cell>(object_type, property, type);
else if (object_type_view == "liberty_cell")
properties.defineProperty<LibertyCell>(object_type, property, type);
else if (object_type_view == "port")
properties.defineProperty<Port>(object_type, property, type);
else if (object_type_view == "liberty_port")
properties.defineProperty<LibertyPort>(object_type, property, type);
else if (object_type_view == "instance")
properties.defineProperty<Instance>(object_type, property, type);
else if (object_type_view == "pin")
properties.defineProperty<Pin>(object_type, property, type);
else if (object_type_view == "net")
properties.defineProperty<Net>(object_type, property, type);
else if (object_type_view == "clock")
properties.defineProperty<Clock>(object_type, property, type);
else
Sta::sta()->report()->error(2209, "define_property -object_type {} not supported.",
object_type);
@ -166,6 +186,26 @@ set_property_cmd(void *object,
properties.setProperty(object, "scene", property, value);
else if (object_type_view == "Mode")
properties.setProperty(object, "mode", property, value);
else if (object_type_view == "Library")
properties.setProperty(object, "library", property, value);
else if (object_type_view == "LibertyLibrary")
properties.setProperty(object, "liberty_library", property, value);
else if (object_type_view == "Cell")
properties.setProperty(object, "cell", property, value);
else if (object_type_view == "LibertyCell")
properties.setProperty(object, "liberty_cell", property, value);
else if (object_type_view == "Port")
properties.setProperty(object, "port", property, value);
else if (object_type_view == "LibertyPort")
properties.setProperty(object, "liberty_port", property, value);
else if (object_type_view == "Instance")
properties.setProperty(object, "instance", property, value);
else if (object_type_view == "Pin")
properties.setProperty(object, "pin", property, value);
else if (object_type_view == "Net")
properties.setProperty(object, "net", property, value);
else if (object_type_view == "Clock")
properties.setProperty(object, "clock", property, value);
else
Sta::sta()->report()->error(2214, "set_property unsupported object type {}.",
object_type);

View File

@ -121,7 +121,7 @@ proc get_property_object_type { object_type object_name quiet } {
}
define_cmd_args "define_property" \
{-object_type scene|mode -type bool|float|string property}
{-object_type scene|mode|library|liberty_library|cell|liberty_cell|port|liberty_port|instance|pin|net|clock -type bool|float|string property}
proc define_property { args } {
parse_key_args "define_property" args keys {-object_type -type} flags {}

View File

@ -168,6 +168,7 @@ record_public_tests {
report_json1
report_json2
suppress_msg
user_properties
verilog_attribute
verilog_well_supplies
verilog_specify

17
test/user_properties.ok Normal file
View File

@ -0,0 +1,17 @@
[get_property u1/Z owner]
alice
[get_property u2/ZN owner] (unset)
<>
[get_property r1q weight]
3.500000
[get_property u1z weight] (unset)
<>
[get_property u2 crit]
1
[get_property u1 crit] (unset)
<>
[get_property clk1 grp]
main
[get_pins -filter {owner == alice} *]
Z
Error: pin objects do not have a no_such_prop property.

44
test/user_properties.tcl Normal file
View File

@ -0,0 +1,44 @@
# User-defined properties on pin/net/instance/clock object types.
read_liberty ../examples/nangate45_typ.lib.gz
read_verilog ../examples/example1.v
link_design top
create_clock -name clk1 -period 10 {clk1}
# pin: string property, set on one pin, left unset on another.
define_property -object_type pin -type string owner
set_property [get_pins u1/Z] owner alice
puts {[get_property u1/Z owner]}
puts [get_property [get_pins u1/Z] owner]
puts {[get_property u2/ZN owner] (unset)}
puts "<[get_property [get_pins u2/ZN] owner]>"
# net: float property.
define_property -object_type net -type float weight
set_property [get_nets r1q] weight 3.5
puts {[get_property r1q weight]}
puts [get_property [get_nets r1q] weight]
puts {[get_property u1z weight] (unset)}
puts "<[get_property [get_nets u1z] weight]>"
# instance: bool property.
define_property -object_type instance -type bool crit
set_property [get_cells u2] crit true
puts {[get_property u2 crit]}
puts [get_property [get_cells u2] crit]
puts {[get_property u1 crit] (unset)}
puts "<[get_property [get_cells u1] crit]>"
# clock: string property.
define_property -object_type clock -type string grp
set_property [get_clocks clk1] grp main
puts {[get_property clk1 grp]}
puts [get_property [get_clocks clk1] grp]
# -filter skips objects the property was never set on (no error).
puts {[get_pins -filter {owner == alice} *]}
report_object_names [get_pins -filter {owner == alice} *]
# An undefined property still errors.
if {[catch {get_property [get_pins u1/Z] no_such_prop} msg]} {
puts $msg
}