1 // OpenSTA, Static Timing Analyzer
2 // Copyright (c) 2021, Parallax Software, Inc.
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program.  If not, see <https://www.gnu.org/licenses/>.
16 
17 #include "DeratingFactors.hh"
18 
19 namespace sta {
20 
21 inline int
TimingDerateIndex(TimingDerateType type)22 TimingDerateIndex(TimingDerateType type)
23 {
24   return int(type);
25 }
26 
DeratingFactors()27 DeratingFactors::DeratingFactors()
28 {
29   clear();
30 }
31 
32 void
setFactor(PathClkOrData clk_data,const RiseFallBoth * rf,const EarlyLate * early_late,float factor)33 DeratingFactors::setFactor(PathClkOrData clk_data,
34 			   const RiseFallBoth *rf,
35 			   const EarlyLate *early_late,
36 			   float factor)
37 {
38   for (auto tr1 : rf->range())
39     factors_[int(clk_data)].setValue(tr1, early_late, factor);
40 }
41 
42 void
factor(PathClkOrData clk_data,const RiseFall * rf,const EarlyLate * early_late,float & factor,bool & exists) const43 DeratingFactors::factor(PathClkOrData clk_data,
44 			const RiseFall *rf,
45 			const EarlyLate *early_late,
46 			float &factor,
47 			bool &exists) const
48 {
49   factors_[int(clk_data)].value(rf, early_late, factor, exists);
50 }
51 
52 void
clear()53 DeratingFactors::clear()
54 {
55   for (int clk_data = 0; clk_data < path_clk_or_data_count;clk_data++)
56     factors_[int(clk_data)].clear();
57 }
58 
59 void
isOneValue(const EarlyLate * early_late,bool & is_one_value,float & value) const60 DeratingFactors::isOneValue(const EarlyLate *early_late,
61 			    bool &is_one_value,
62 			    float &value) const
63 {
64   bool is_one_value0, is_one_value1;
65   float value0, value1;
66   is_one_value0 = factors_[0].isOneValue(early_late, value0);
67   is_one_value1 = factors_[1].isOneValue(early_late, value1);
68   is_one_value = is_one_value0
69     && is_one_value1
70     && value0 == value1;
71   value = value1;
72 }
73 
74 void
isOneValue(PathClkOrData clk_data,const EarlyLate * early_late,bool & is_one_value,float & value) const75 DeratingFactors::isOneValue(PathClkOrData clk_data,
76 			    const EarlyLate *early_late,
77 			    bool &is_one_value,
78 			    float &value) const
79 {
80   is_one_value = factors_[int(clk_data)].isOneValue(early_late, value);
81 }
82 
83 bool
hasValue() const84 DeratingFactors::hasValue() const
85 {
86   return factors_[0].hasValue()
87     || factors_[1].hasValue();
88 }
89 
90 ////////////////////////////////////////////////////////////////
91 
DeratingFactorsGlobal()92 DeratingFactorsGlobal::DeratingFactorsGlobal()
93 {
94   clear();
95 }
96 
97 void
setFactor(TimingDerateType type,PathClkOrData clk_data,const RiseFallBoth * rf,const EarlyLate * early_late,float factor)98 DeratingFactorsGlobal::setFactor(TimingDerateType type,
99 				 PathClkOrData clk_data,
100 				 const RiseFallBoth *rf,
101 				 const EarlyLate *early_late,
102 				 float factor)
103 {
104   factors_[TimingDerateIndex(type)].setFactor(clk_data, rf, early_late, factor);
105 }
106 
107 void
factor(TimingDerateType type,PathClkOrData clk_data,const RiseFall * rf,const EarlyLate * early_late,float & factor,bool & exists) const108 DeratingFactorsGlobal::factor(TimingDerateType type,
109 			      PathClkOrData clk_data,
110 			      const RiseFall *rf,
111 			      const EarlyLate *early_late,
112 			      float &factor,
113 			      bool &exists) const
114 {
115   factors_[TimingDerateIndex(type)].factor(clk_data, rf, early_late, factor, exists);
116 }
117 
118 void
clear()119 DeratingFactorsGlobal::clear()
120 {
121   for (int type = 0; type < timing_derate_type_count; type++)
122     factors_[type].clear();
123 }
124 
125 DeratingFactors *
factors(TimingDerateType type)126 DeratingFactorsGlobal::factors(TimingDerateType type)
127 {
128   return &factors_[TimingDerateIndex(type)];
129 }
130 
131 ////////////////////////////////////////////////////////////////
132 
DeratingFactorsCell()133 DeratingFactorsCell::DeratingFactorsCell()
134 {
135   clear();
136 }
137 
138 void
setFactor(TimingDerateType type,PathClkOrData clk_data,const RiseFallBoth * rf,const EarlyLate * early_late,float factor)139 DeratingFactorsCell::setFactor(TimingDerateType type,
140 			       PathClkOrData clk_data,
141 			       const RiseFallBoth *rf,
142 			       const EarlyLate *early_late,
143 			       float factor)
144 {
145   factors_[TimingDerateIndex(type)].setFactor(clk_data, rf, early_late, factor);
146 }
147 
148 void
factor(TimingDerateType type,PathClkOrData clk_data,const RiseFall * rf,const EarlyLate * early_late,float & factor,bool & exists) const149 DeratingFactorsCell::factor(TimingDerateType type,
150 			    PathClkOrData clk_data,
151 			    const RiseFall *rf,
152 			    const EarlyLate *early_late,
153 			    float &factor,
154 			    bool &exists) const
155 {
156   factors_[TimingDerateIndex(type)].factor(clk_data, rf, early_late, factor, exists);
157 }
158 
159 void
clear()160 DeratingFactorsCell::clear()
161 {
162   for (int type = 0; type < timing_derate_cell_type_count; type++)
163     factors_[type].clear();
164 }
165 
166 DeratingFactors *
factors(TimingDerateType type)167 DeratingFactorsCell::factors(TimingDerateType type)
168 {
169   return &factors_[TimingDerateIndex(type)];
170 }
171 
172 void
isOneValue(const EarlyLate * early_late,bool & is_one_value,float & value) const173 DeratingFactorsCell::isOneValue(const EarlyLate *early_late,
174 				bool &is_one_value,
175 				float &value) const
176 {
177   bool is_one_value1, is_one_value2;
178   float value1, value2;
179   factors_[TimingDerateIndex(TimingDerateType::cell_delay)]
180     .isOneValue(early_late, is_one_value1, value1);
181   factors_[TimingDerateIndex(TimingDerateType::cell_check)]
182     .isOneValue(early_late, is_one_value2, value2);
183   is_one_value = is_one_value1
184     && is_one_value2
185     && value1 == value2;
186   value = value1;
187 }
188 
189 ////////////////////////////////////////////////////////////////
190 
DeratingFactorsNet()191 DeratingFactorsNet::DeratingFactorsNet()
192 {
193 }
194 
195 } // namespace
196