1 #ifndef OT_TIMER_PIN_HPP_
2 #define OT_TIMER_PIN_HPP_
3 
4 #include <ot/liberty/celllib.hpp>
5 
6 namespace ot {
7 
8 // Forward declaration
9 class Timer;
10 class Net;
11 class Gate;
12 class RctNode;
13 class Arc;
14 class Pin;
15 class Test;
16 class SCC;
17 
18 // ------------------------------------------------------------------------------------------------
19 
20 // PrimayInput
21 class PrimaryInput {
22 
23   friend class Timer;
24   friend class Pin;
25 
26   public:
27 
28     PrimaryInput(Pin&);
29 
30   private:
31 
32     Pin& _pin;
33 
34     TimingData<std::optional<float>, MAX_SPLIT, MAX_TRAN> _slew;
35     TimingData<std::optional<float>, MAX_SPLIT, MAX_TRAN> _at;
36 
37     void _scale_time(float s);
38     void _scale_capacitance(float s);
39 };
40 
41 // ------------------------------------------------------------------------------------------------
42 
43 // PrimaryOutput
44 class PrimaryOutput {
45 
46   friend class Timer;
47   friend class Pin;
48 
49   public:
50 
51     PrimaryOutput(Pin&);
52 
53     std::optional<float> rat(Split, Tran) const;
54     std::optional<float> slack(Split, Tran) const;
55 
56   private:
57 
58     Pin& _pin;
59 
60     TimingData<float, MAX_SPLIT, MAX_TRAN> _load {{{.0f, .0f}, {.0f, .0f}}};
61     TimingData<std::optional<float>, MAX_SPLIT, MAX_TRAN> _rat;
62 
63     void _scale_time(float);
64     void _scale_capacitance(float);
65 };
66 
67 // ------------------------------------------------------------------------------------------------
68 
69 // Class: Pin
70 class Pin {
71 
72   // At storage
73   struct At {
74     Arc*  pi_arc {nullptr};
75     Split pi_el;
76     Tran  pi_rf;
77     float numeric;
78     At(Arc*, Split, Tran, float);
79     inline operator float () const;
80     inline auto pi() const;
81   };
82 
83   // Slew storage.
84   struct Slew {
85     Arc*  pi_arc {nullptr};
86     Split pi_el;
87     Tran  pi_rf;
88     float numeric;
89     Slew(Arc*, Split, Tran, float);
90     inline operator float () const;
91     inline auto pi() const;
92   };
93 
94   // Rat storage
95   struct Rat {
96     Arc*  pi_arc {nullptr};
97     Split pi_el;
98     Tran  pi_rf;
99     float numeric;
100     Rat(Arc*, Split, Tran, float);
101     inline operator float () const;
102     inline auto pi() const;
103   };
104 
105   friend class Timer;
106   friend class Net;
107   friend class Arc;
108   friend class Gate;
109   friend class Test;
110   friend class PrimaryOutput;
111   friend class PrimaryInput;
112   friend class SCC;
113 
114   friend struct Point;
115   friend struct Path;
116 
117   constexpr static int FPROP_CAND       = 0x01;
118   constexpr static int BPROP_CAND       = 0x02;
119   constexpr static int IN_FPROP_STACK   = 0x04;
120   constexpr static int IN_BPROP_STACK   = 0x08;
121   constexpr static int UNLOOP_CAND      = 0x10;
122   constexpr static int IN_UNLOOP_STACK  = 0x20;
123 
124   public:
125 
126     Pin(const std::string&);
127 
128     inline const std::string& name() const;
129     inline const PrimaryInput* primary_input() const;
130     inline const PrimaryOutput* primary_output() const;
131     inline const Cellpin* cellpin(Split) const;
132     inline const Net* net() const;
133     inline const Gate* gate() const;
134 
135     bool is_input() const;
136     bool is_output() const;
137     bool is_rct_root() const;
138     bool is_datapath_source() const;
139     bool has_self_loop() const;
140 
141     std::optional<float> slew(Split, Tran) const;
142     std::optional<float> at(Split, Tran) const;
143     std::optional<float> rat(Split, Tran) const;
144     std::optional<float> slack(Split, Tran) const;
145 
146     float cap(Split, Tran) const;
147 
148     inline size_t num_fanouts() const;
149     inline size_t num_fanins() const;
150     inline size_t idx() const;
151 
152   private:
153 
154     std::string _name;
155 
156     size_t _idx;
157 
158     Net*  _net  {nullptr};
159     SCC*  _scc  {nullptr};
160     Gate* _gate {nullptr};
161 
162     std::variant<PrimaryInput*, PrimaryOutput*, CellpinView> _handle;
163 
164     std::list<Arc*> _fanout;
165     std::list<Arc*> _fanin;
166     std::list<Test*> _tests;
167 
168     std::optional<std::list<Pin*>::iterator> _frontier_satellite;
169     std::optional<std::list<Pin*>::iterator> _net_satellite;
170 
171     TimingData<std::optional<Slew>, MAX_SPLIT, MAX_TRAN> _slew;
172     TimingData<std::optional<Rat >, MAX_SPLIT, MAX_TRAN> _rat;
173     TimingData<std::optional<At  >, MAX_SPLIT, MAX_TRAN> _at;
174 
175     int _state {0};
176 
177     std::optional<tf::Task> _ftask;
178     std::optional<tf::Task> _btask;
179 
180     bool _has_state(int) const;
181     bool _has_no_state(int) const;
182 
183     void _insert_fanout(Arc&);
184     void _insert_fanin(Arc&);
185     void _remove_fanout(Arc&);
186     void _remove_fanin(Arc&);
187     void _remap_cellpin(Split, const Cellpin*);
188     void _remap_cellpin(Split, const Cellpin&);
189     void _reset_slew();
190     void _reset_at();
191     void _reset_rat();
192     void _relax_slew(Arc*, Split, Tran, Split, Tran, float);
193     void _relax_at(Arc*, Split, Tran, Split, Tran, float);
194     void _relax_rat(Arc*, Split, Tran, Split, Tran, float);
195     void _insert_state(int);
196     void _remove_state(int = 0);
197 
198     Arc* _find_fanin(Pin&);
199     Arc* _find_fanout(Pin&);
200 
201     inline PrimaryOutput* _primary_output();
202     inline PrimaryInput* _primary_input();
203 
204     std::optional<float> _delta_at(Split, Tran, Split, Tran) const;
205     std::optional<float> _delta_slew(Split, Tran, Split, Tran) const;
206     std::optional<float> _delta_rat(Split, Tran, Split, Tran) const;
207 };
208 
209 // ------------------------------------------------------------------------------------------------
210 
211 // Operator
operator float() const212 inline Pin::At::operator float () const {
213   return numeric;
214 }
215 
216 // Function: pi
pi() const217 inline auto Pin::At::pi() const {
218   return std::make_tuple(pi_arc, pi_el, pi_rf);
219 }
220 
221 // ------------------------------------------------------------------------------------------------
222 
223 // Operator
operator float() const224 inline Pin::Slew::operator float () const {
225   return numeric;
226 }
227 
228 // Function: pi
pi() const229 inline auto Pin::Slew::pi() const {
230   return std::make_tuple(pi_arc, pi_el, pi_rf);
231 }
232 
233 // ------------------------------------------------------------------------------------------------
234 
235 // Operator
operator float() const236 inline Pin::Rat::operator float () const {
237   return numeric;
238 }
239 
240 // Function: pi
pi() const241 inline auto Pin::Rat::pi() const {
242   return std::make_tuple(pi_arc, pi_el, pi_rf);
243 }
244 
245 // ------------------------------------------------------------------------------------------------
246 
247 // Function: name
name() const248 inline const std::string& Pin::name() const {
249   return _name;
250 }
251 
252 // Function: idx
idx() const253 inline size_t Pin::idx() const {
254   return _idx;
255 }
256 
257 // Function: _pi
_primary_input()258 inline PrimaryInput* Pin::_primary_input() {
259   if(auto ptr = std::get_if<PrimaryInput*>(&_handle)) {
260     return *ptr;
261   }
262   return nullptr;
263 }
264 
265 // Function: pi
primary_input() const266 inline const PrimaryInput* Pin::primary_input() const {
267   if(auto ptr = std::get_if<PrimaryInput*>(&_handle)) {
268     return *ptr;
269   }
270   return nullptr;
271 }
272 
273 // Function: _po
_primary_output()274 inline PrimaryOutput* Pin::_primary_output() {
275   if(auto ptr = std::get_if<PrimaryOutput*>(&_handle)) {
276     return *ptr;
277   }
278   return nullptr;
279 }
280 
281 // Function: po
primary_output() const282 inline const PrimaryOutput* Pin::primary_output() const {
283   if(auto ptr = std::get_if<PrimaryOutput*>(&_handle)) {
284     return *ptr;
285   }
286   return nullptr;
287 }
288 
289 // Function: gate
gate() const290 inline const Gate* Pin::gate() const {
291   return _gate;
292 }
293 
294 // Function: cellpin
cellpin(Split m) const295 inline const Cellpin* Pin::cellpin(Split m) const {
296   if(auto cp = std::get_if<CellpinView>(&_handle); cp) {
297     return (*cp)[m];
298   }
299   return nullptr;
300 }
301 
302 // Function: net
net() const303 inline const Net* Pin::net() const {
304   return _net;
305 }
306 
num_fanins() const307 inline size_t Pin::num_fanins() const {
308   return _fanin.size();
309 }
310 
num_fanouts() const311 inline size_t Pin::num_fanouts() const {
312   return _fanout.size();
313 }
314 
315 };  // end of namespace ot. -----------------------------------------------------------------------
316 
317 #endif
318 
319 
320 
321 
322 
323 
324