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:
parent
ef0b69091f
commit
f476e269b9
|
|
@ -284,6 +284,10 @@ protected:
|
||||||
PropertyValue::Type propertyType(std::string_view type);
|
PropertyValue::Type propertyType(std::string_view type);
|
||||||
PropertyValue coercePropertyValue(PropertyValue::Type type,
|
PropertyValue coercePropertyValue(PropertyValue::Type type,
|
||||||
std::string_view value);
|
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 Library*> registry_library_;
|
||||||
PropertyRegistry<const LibertyLibrary*> registry_liberty_library_;
|
PropertyRegistry<const LibertyLibrary*> registry_liberty_library_;
|
||||||
|
|
|
||||||
|
|
@ -643,6 +643,8 @@ Properties::getProperty(const Library *lib,
|
||||||
"library", sta_);
|
"library", sta_);
|
||||||
if (value.type() != PropertyValue::Type::none)
|
if (value.type() != PropertyValue::Type::none)
|
||||||
return value;
|
return value;
|
||||||
|
else if (isUserProperty("library", property))
|
||||||
|
return value;
|
||||||
else
|
else
|
||||||
throw PropertyUnknown("library", property);
|
throw PropertyUnknown("library", property);
|
||||||
}
|
}
|
||||||
|
|
@ -665,6 +667,8 @@ Properties::getProperty(const LibertyLibrary *lib,
|
||||||
sta_);
|
sta_);
|
||||||
if (value.type() != PropertyValue::Type::none)
|
if (value.type() != PropertyValue::Type::none)
|
||||||
return value;
|
return value;
|
||||||
|
else if (isUserProperty("liberty_library", property))
|
||||||
|
return value;
|
||||||
else
|
else
|
||||||
throw PropertyUnknown("liberty library", property);
|
throw PropertyUnknown("liberty library", property);
|
||||||
}
|
}
|
||||||
|
|
@ -696,6 +700,8 @@ Properties::getProperty(const Cell *cell,
|
||||||
"cell", sta_);
|
"cell", sta_);
|
||||||
if (value.type() != PropertyValue::Type::none)
|
if (value.type() != PropertyValue::Type::none)
|
||||||
return value;
|
return value;
|
||||||
|
else if (isUserProperty("cell", property))
|
||||||
|
return value;
|
||||||
else
|
else
|
||||||
throw PropertyUnknown("cell", property);
|
throw PropertyUnknown("cell", property);
|
||||||
}
|
}
|
||||||
|
|
@ -737,6 +743,8 @@ Properties::getProperty(const LibertyCell *cell,
|
||||||
"liberty_cell", sta_);
|
"liberty_cell", sta_);
|
||||||
if (value.type() != PropertyValue::Type::none)
|
if (value.type() != PropertyValue::Type::none)
|
||||||
return value;
|
return value;
|
||||||
|
else if (isUserProperty("liberty_cell", property))
|
||||||
|
return value;
|
||||||
else
|
else
|
||||||
throw PropertyUnknown("liberty cell", property);
|
throw PropertyUnknown("liberty cell", property);
|
||||||
}
|
}
|
||||||
|
|
@ -797,6 +805,8 @@ Properties::getProperty(const Port *port,
|
||||||
"port", sta_);
|
"port", sta_);
|
||||||
if (value.type() != PropertyValue::Type::none)
|
if (value.type() != PropertyValue::Type::none)
|
||||||
return value;
|
return value;
|
||||||
|
else if (isUserProperty("port", property))
|
||||||
|
return value;
|
||||||
else
|
else
|
||||||
throw PropertyUnknown("port", property);
|
throw PropertyUnknown("port", property);
|
||||||
}
|
}
|
||||||
|
|
@ -898,6 +908,8 @@ Properties::getProperty(const LibertyPort *port,
|
||||||
"liberty_port", sta_);
|
"liberty_port", sta_);
|
||||||
if (value.type() != PropertyValue::Type::none)
|
if (value.type() != PropertyValue::Type::none)
|
||||||
return value;
|
return value;
|
||||||
|
else if (isUserProperty("liberty_port", property))
|
||||||
|
return value;
|
||||||
else
|
else
|
||||||
throw PropertyUnknown("liberty port", property);
|
throw PropertyUnknown("liberty port", property);
|
||||||
}
|
}
|
||||||
|
|
@ -938,6 +950,8 @@ Properties::getProperty(const Instance *inst,
|
||||||
"instance", sta_);
|
"instance", sta_);
|
||||||
if (value.type() != PropertyValue::Type::none)
|
if (value.type() != PropertyValue::Type::none)
|
||||||
return value;
|
return value;
|
||||||
|
else if (isUserProperty("instance", property))
|
||||||
|
return value;
|
||||||
else
|
else
|
||||||
throw PropertyUnknown("instance", property);
|
throw PropertyUnknown("instance", property);
|
||||||
}
|
}
|
||||||
|
|
@ -1025,6 +1039,8 @@ Properties::getProperty(const Pin *pin,
|
||||||
PropertyValue value = registry_pin_.getProperty(pin, property, "pin", sta_);
|
PropertyValue value = registry_pin_.getProperty(pin, property, "pin", sta_);
|
||||||
if (value.type() != PropertyValue::Type::none)
|
if (value.type() != PropertyValue::Type::none)
|
||||||
return value;
|
return value;
|
||||||
|
else if (isUserProperty("pin", property))
|
||||||
|
return value;
|
||||||
else
|
else
|
||||||
throw PropertyUnknown("pin", property);
|
throw PropertyUnknown("pin", property);
|
||||||
}
|
}
|
||||||
|
|
@ -1086,6 +1102,8 @@ Properties::getProperty(const Net *net,
|
||||||
PropertyValue value = registry_net_.getProperty(net, property, "net", sta_);
|
PropertyValue value = registry_net_.getProperty(net, property, "net", sta_);
|
||||||
if (value.type() != PropertyValue::Type::none)
|
if (value.type() != PropertyValue::Type::none)
|
||||||
return value;
|
return value;
|
||||||
|
else if (isUserProperty("net", property))
|
||||||
|
return value;
|
||||||
else
|
else
|
||||||
throw PropertyUnknown("net", property);
|
throw PropertyUnknown("net", property);
|
||||||
}
|
}
|
||||||
|
|
@ -1191,6 +1209,8 @@ Properties::getProperty(const Clock *clk,
|
||||||
"clock", sta_);
|
"clock", sta_);
|
||||||
if (value.type() != PropertyValue::Type::none)
|
if (value.type() != PropertyValue::Type::none)
|
||||||
return value;
|
return value;
|
||||||
|
else if (isUserProperty("clock", property))
|
||||||
|
return value;
|
||||||
else
|
else
|
||||||
throw PropertyUnknown("clock", property);
|
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,
|
PropertyKey::PropertyKey(const void *object,
|
||||||
std::string_view property) :
|
std::string_view property) :
|
||||||
object_(object),
|
object_(object),
|
||||||
|
|
@ -1462,6 +1489,36 @@ template void Properties::defineProperty<Scene>(std::string_view,
|
||||||
template void Properties::defineProperty<Mode>(std::string_view,
|
template void Properties::defineProperty<Mode>(std::string_view,
|
||||||
std::string_view,
|
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
|
void
|
||||||
Properties::setProperty(const void *object,
|
Properties::setProperty(const void *object,
|
||||||
|
|
|
||||||
|
|
@ -149,6 +149,26 @@ define_property_cmd(const char *object_type,
|
||||||
properties.defineProperty<Scene>(object_type, property, type);
|
properties.defineProperty<Scene>(object_type, property, type);
|
||||||
else if (object_type_view == "mode")
|
else if (object_type_view == "mode")
|
||||||
properties.defineProperty<Mode>(object_type, property, type);
|
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
|
else
|
||||||
Sta::sta()->report()->error(2209, "define_property -object_type {} not supported.",
|
Sta::sta()->report()->error(2209, "define_property -object_type {} not supported.",
|
||||||
object_type);
|
object_type);
|
||||||
|
|
@ -166,6 +186,26 @@ set_property_cmd(void *object,
|
||||||
properties.setProperty(object, "scene", property, value);
|
properties.setProperty(object, "scene", property, value);
|
||||||
else if (object_type_view == "Mode")
|
else if (object_type_view == "Mode")
|
||||||
properties.setProperty(object, "mode", property, value);
|
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
|
else
|
||||||
Sta::sta()->report()->error(2214, "set_property unsupported object type {}.",
|
Sta::sta()->report()->error(2214, "set_property unsupported object type {}.",
|
||||||
object_type);
|
object_type);
|
||||||
|
|
|
||||||
|
|
@ -121,7 +121,7 @@ proc get_property_object_type { object_type object_name quiet } {
|
||||||
}
|
}
|
||||||
|
|
||||||
define_cmd_args "define_property" \
|
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 } {
|
proc define_property { args } {
|
||||||
parse_key_args "define_property" args keys {-object_type -type} flags {}
|
parse_key_args "define_property" args keys {-object_type -type} flags {}
|
||||||
|
|
|
||||||
|
|
@ -168,6 +168,7 @@ record_public_tests {
|
||||||
report_json1
|
report_json1
|
||||||
report_json2
|
report_json2
|
||||||
suppress_msg
|
suppress_msg
|
||||||
|
user_properties
|
||||||
verilog_attribute
|
verilog_attribute
|
||||||
verilog_well_supplies
|
verilog_well_supplies
|
||||||
verilog_specify
|
verilog_specify
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
@ -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
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue