FEATURE: Implement `set_max_dynamic_power` and `set_max_leakage_power` (#471)
* Implement set_max_dynamic_power and set_max_leakage_power. Store max dynamic/leakage power like max area, expose getters through Sta, write them in write_sdc, and document that they are ignored during timing. Co-authored-by: Cursor <cursoragent@cursor.com> * Drop get_max_* Tcl wrappers; use SWIG accessors in tests. James pointed out the get_max_* commands duplicate existing SWIG accessors; remove them and call sta::max_* from the regression. Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
ecdef77537
commit
d0526b524b
|
|
@ -11986,7 +11986,7 @@
|
|||
</table:table-cell>
|
||||
</table:table-row>
|
||||
</table:table>
|
||||
<text:p text:style-name="Body_20_first">The <text:span text:style-name="Command">set_max_dynamic_power</text:span> command is ignored.</text:p>
|
||||
<text:p text:style-name="Body_20_first">The <text:span text:style-name="Command">set_max_dynamic_power</text:span> command is ignored during timing but is included in SDC files that are written.</text:p>
|
||||
<table:table table:name="Table102" table:style-name="Table102">
|
||||
<table:table-column table:style-name="Table102.A"/>
|
||||
<table:table-column table:style-name="Table102.B"/>
|
||||
|
|
@ -12028,7 +12028,7 @@
|
|||
</table:table-cell>
|
||||
</table:table-row>
|
||||
</table:table>
|
||||
<text:p text:style-name="Body_20_first">The <text:span text:style-name="Command">set_max_leakage_power</text:span> command is ignored.</text:p>
|
||||
<text:p text:style-name="Body_20_first">The <text:span text:style-name="Command">set_max_leakage_power</text:span> command is ignored during timing but is included in SDC files that are written.</text:p>
|
||||
<table:table table:name="Table104" table:style-name="Table104">
|
||||
<table:table-column table:style-name="Table104.A"/>
|
||||
<table:table-column table:style-name="Table104.B"/>
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
26
sdc/Sdc.cc
26
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 *
|
||||
|
|
|
|||
37
sdc/Sdc.i
37
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,
|
||||
|
|
|
|||
|
|
@ -3599,7 +3599,9 @@ 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
|
||||
}
|
||||
|
||||
################################################################
|
||||
|
|
@ -3607,7 +3609,9 @@ 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
|
||||
}
|
||||
|
||||
################################################################
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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 [sta::max_area]"
|
||||
puts "max_dynamic_power [sta::max_dynamic_power]"
|
||||
puts "max_leakage_power [sta::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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue