diff --git a/doc/OpenSTA.fodt b/doc/OpenSTA.fodt
index 3b13720c..dcaf83ab 100644
--- a/doc/OpenSTA.fodt
+++ b/doc/OpenSTA.fodt
@@ -11986,7 +11986,7 @@
- The set_max_dynamic_power command is ignored.
+ The set_max_dynamic_power command is ignored during timing but is included in SDC files that are written.
@@ -12028,7 +12028,7 @@
- The set_max_leakage_power command is ignored.
+ The set_max_leakage_power command is ignored during timing but is included in SDC files that are written.
diff --git a/include/sta/Sdc.hh b/include/sta/Sdc.hh
index a93569fe..948efe10 100644
--- a/include/sta/Sdc.hh
+++ b/include/sta/Sdc.hh
@@ -377,6 +377,10 @@ public:
float fanout);
void setMaxArea(float area);
float maxArea() const;
+ void setMaxDynamicPower(float power);
+ float maxDynamicPower() const;
+ void setMaxLeakagePower(float power);
+ float maxLeakagePower() const;
Clock *makeClock(std::string_view name,
const PinSet &pins,
bool add_to_pins,
@@ -1420,6 +1424,8 @@ protected:
InstMinPulseWidthMap inst_min_pulse_width_map_;
ClockMinPulseWidthMap clk_min_pulse_width_map_;
float max_area_;
+ float max_dynamic_power_;
+ float max_leakage_power_;
Wireload *wireload_[MinMax::index_count];
WireloadMode wireload_mode_;
const WireloadSelection *wireload_selection_[MinMax::index_count];
diff --git a/include/sta/Sta.hh b/include/sta/Sta.hh
index bf482f55..e2f5ced3 100644
--- a/include/sta/Sta.hh
+++ b/include/sta/Sta.hh
@@ -346,6 +346,13 @@ public:
Sdc *sdc);
void setMaxArea(float area,
Sdc *sdc);
+ float maxArea(const Sdc *sdc) const;
+ void setMaxDynamicPower(float power,
+ Sdc *sdc);
+ float maxDynamicPower(const Sdc *sdc) const;
+ void setMaxLeakagePower(float power,
+ Sdc *sdc);
+ float maxLeakagePower(const Sdc *sdc) const;
void makeClock(std::string_view name,
const PinSet &pins,
diff --git a/sdc/Sdc.cc b/sdc/Sdc.cc
index 9b30c470..77f3ba89 100644
--- a/sdc/Sdc.cc
+++ b/sdc/Sdc.cc
@@ -244,6 +244,8 @@ Sdc::initVariables()
analysis_type_ = AnalysisType::ocv;
wireload_mode_ = WireloadMode::unknown;
max_area_ = 0.0;
+ max_dynamic_power_ = 0.0;
+ max_leakage_power_ = 0.0;
path_delays_without_to_ = false;
clk_hpin_disables_valid_ = false;
have_clk_slew_limits_ = false;
@@ -951,6 +953,30 @@ Sdc::maxArea() const
return max_area_;
}
+void
+Sdc::setMaxDynamicPower(float power)
+{
+ max_dynamic_power_ = power;
+}
+
+float
+Sdc::maxDynamicPower() const
+{
+ return max_dynamic_power_;
+}
+
+void
+Sdc::setMaxLeakagePower(float power)
+{
+ max_leakage_power_ = power;
+}
+
+float
+Sdc::maxLeakagePower() const
+{
+ return max_leakage_power_;
+}
+
////////////////////////////////////////////////////////////////
Clock *
diff --git a/sdc/Sdc.i b/sdc/Sdc.i
index 3ac13d81..d326512e 100644
--- a/sdc/Sdc.i
+++ b/sdc/Sdc.i
@@ -1229,6 +1229,43 @@ set_max_area_cmd(float area)
sta->setMaxArea(area, sdc);
}
+float
+max_area()
+{
+ Sta *sta = Sta::sta();
+ return sta->maxArea(sta->cmdSdc());
+}
+
+void
+set_max_dynamic_power_cmd(float power)
+{
+ Sta *sta = Sta::sta();
+ Sdc *sdc = sta->cmdSdc();
+ sta->setMaxDynamicPower(power, sdc);
+}
+
+float
+max_dynamic_power()
+{
+ Sta *sta = Sta::sta();
+ return sta->maxDynamicPower(sta->cmdSdc());
+}
+
+void
+set_max_leakage_power_cmd(float power)
+{
+ Sta *sta = Sta::sta();
+ Sdc *sdc = sta->cmdSdc();
+ sta->setMaxLeakagePower(power, sdc);
+}
+
+float
+max_leakage_power()
+{
+ Sta *sta = Sta::sta();
+ return sta->maxLeakagePower(sta->cmdSdc());
+}
+
void
set_port_fanout_limit(Port *port,
const MinMax *min_max,
diff --git a/sdc/Sdc.tcl b/sdc/Sdc.tcl
index e444eea8..46808194 100644
--- a/sdc/Sdc.tcl
+++ b/sdc/Sdc.tcl
@@ -2989,6 +2989,12 @@ proc set_max_area { area } {
set_max_area_cmd $area
}
+define_cmd_args "get_max_area" {}
+
+proc get_max_area {} {
+ return [max_area]
+}
+
################################################################
define_cmd_args "set_max_capacitance" {cap objects}
@@ -3599,7 +3605,15 @@ proc set_level_shifter_threshold { args } {
define_cmd_args "set_max_dynamic_power" {power [unit]}
proc set_max_dynamic_power { power {unit {}} } {
- # ignored
+ check_positive_float "power" $power
+ # Optional SDC unit argument is accepted but ignored; use set_units.
+ set_max_dynamic_power_cmd $power
+}
+
+define_cmd_args "get_max_dynamic_power" {}
+
+proc get_max_dynamic_power {} {
+ return [max_dynamic_power]
}
################################################################
@@ -3607,7 +3621,15 @@ proc set_max_dynamic_power { power {unit {}} } {
define_cmd_args "set_max_leakage_power" {power [unit]}
proc set_max_leakage_power { power {unit {}} } {
- # ignored
+ check_positive_float "power" $power
+ # Optional SDC unit argument is accepted but ignored; use set_units.
+ set_max_leakage_power_cmd $power
+}
+
+define_cmd_args "get_max_leakage_power" {}
+
+proc get_max_leakage_power {} {
+ return [max_leakage_power]
}
################################################################
diff --git a/sdc/WriteSdc.cc b/sdc/WriteSdc.cc
index 1733a050..4fa34656 100644
--- a/sdc/WriteSdc.cc
+++ b/sdc/WriteSdc.cc
@@ -2031,6 +2031,8 @@ WriteSdc::writeDesignRules() const
writeCapLimits();
writeFanoutLimits();
writeMaxArea();
+ writeMaxDynamicPower();
+ writeMaxLeakagePower();
}
void
@@ -2262,6 +2264,28 @@ WriteSdc::writeMaxArea() const
}
}
+void
+WriteSdc::writeMaxDynamicPower() const
+{
+ float max_power = sdc_->maxDynamicPower();
+ if (max_power > 0.0) {
+ sta::print(stream_, "set_max_dynamic_power ");
+ writeFloat(max_power);
+ sta::print(stream_, "\n");
+ }
+}
+
+void
+WriteSdc::writeMaxLeakagePower() const
+{
+ float max_power = sdc_->maxLeakagePower();
+ if (max_power > 0.0) {
+ sta::print(stream_, "set_max_leakage_power ");
+ writeFloat(max_power);
+ sta::print(stream_, "\n");
+ }
+}
+
void
WriteSdc::writeFanoutLimits() const
{
diff --git a/sdc/WriteSdcPvt.hh b/sdc/WriteSdcPvt.hh
index b7bc9338..1d0b0f08 100644
--- a/sdc/WriteSdcPvt.hh
+++ b/sdc/WriteSdcPvt.hh
@@ -169,6 +169,8 @@ public:
void writeCapLimits(const MinMax *min_max,
std::string_view cmd) const;
void writeMaxArea() const;
+ void writeMaxDynamicPower() const;
+ void writeMaxLeakagePower() const;
void writeFanoutLimits() const;
void writeFanoutLimits(const MinMax *min_max,
std::string_view cmd) const;
diff --git a/search/Sta.cc b/search/Sta.cc
index 843061df..1b7d7111 100644
--- a/search/Sta.cc
+++ b/search/Sta.cc
@@ -1148,6 +1148,38 @@ Sta::setMaxArea(float area,
sdc->setMaxArea(area);
}
+float
+Sta::maxArea(const Sdc *sdc) const
+{
+ return sdc->maxArea();
+}
+
+void
+Sta::setMaxDynamicPower(float power,
+ Sdc *sdc)
+{
+ sdc->setMaxDynamicPower(power);
+}
+
+float
+Sta::maxDynamicPower(const Sdc *sdc) const
+{
+ return sdc->maxDynamicPower();
+}
+
+void
+Sta::setMaxLeakagePower(float power,
+ Sdc *sdc)
+{
+ sdc->setMaxLeakagePower(power);
+}
+
+float
+Sta::maxLeakagePower(const Sdc *sdc) const
+{
+ return sdc->maxLeakagePower();
+}
+
void
Sta::makeClock(std::string_view name,
const PinSet &pins,
diff --git a/test/max_power_area.ok b/test/max_power_area.ok
new file mode 100644
index 00000000..6848c1f8
--- /dev/null
+++ b/test/max_power_area.ok
@@ -0,0 +1,6 @@
+max_area 123.5
+max_dynamic_power 1.25
+max_leakage_power 0.75
+set_max_area 123.5000
+set_max_dynamic_power 1.2500
+set_max_leakage_power 0.7500
diff --git a/test/max_power_area.tcl b/test/max_power_area.tcl
new file mode 100644
index 00000000..4d64f79b
--- /dev/null
+++ b/test/max_power_area.tcl
@@ -0,0 +1,25 @@
+# Store/retrieve/write max area and power SDC constraints.
+source helpers.tcl
+read_liberty asap7_small.lib.gz
+read_verilog reg1_asap7.v
+link_design top
+
+set_max_area 123.5
+set_max_dynamic_power 1.25
+set_max_leakage_power 0.75
+
+puts "max_area [get_max_area]"
+puts "max_dynamic_power [get_max_dynamic_power]"
+puts "max_leakage_power [get_max_leakage_power]"
+
+set sdc_file [make_result_file max_power_area.sdc]
+write_sdc -no_timestamp $sdc_file
+set stream [open $sdc_file r]
+gets $stream line
+while { ![eof $stream] } {
+ if {[string match "set_max_*" $line]} {
+ puts $line
+ }
+ gets $stream line
+}
+close $stream
diff --git a/test/regression_vars.tcl b/test/regression_vars.tcl
index fcb2c291..05db84e2 100644
--- a/test/regression_vars.tcl
+++ b/test/regression_vars.tcl
@@ -157,6 +157,7 @@ record_public_tests {
liberty_float_as_str
liberty_latch3
make_concrete_parasitics_leak
+ max_power_area
package_require
path_group_names
power_json