1 #ifndef OT_TIMER_TIMER_HPP_
2 #define OT_TIMER_TIMER_HPP_
3 
4 #include <ot/timer/gate.hpp>
5 #include <ot/timer/pin.hpp>
6 #include <ot/timer/arc.hpp>
7 #include <ot/timer/net.hpp>
8 #include <ot/timer/test.hpp>
9 #include <ot/timer/clock.hpp>
10 #include <ot/timer/endpoint.hpp>
11 #include <ot/timer/path.hpp>
12 #include <ot/timer/sfxt.hpp>
13 #include <ot/timer/pfxt.hpp>
14 #include <ot/timer/cppr.hpp>
15 #include <ot/timer/scc.hpp>
16 #include <ot/static/logger.hpp>
17 #include <ot/spef/spef.hpp>
18 #include <ot/verilog/verilog.hpp>
19 #include <ot/sdc/sdc.hpp>
20 #include <ot/tau/tau15.hpp>
21 
22 namespace ot {
23 
24 // Class: Timer
25 class Timer {
26 
27   friend class Shell;
28 
29   constexpr static int FULL_TIMING   = 0x01;
30   constexpr static int EPTS_UPDATED  = 0x02;
31   constexpr static int AREA_UPDATED  = 0x04;
32   constexpr static int POWER_UPDATED = 0x08;
33 
34   public:
35 
36     // Builder
37     Timer& set_num_threads(unsigned);
38     Timer& read_celllib(std::filesystem::path, std::optional<Split> = {});
39     Timer& read_verilog(std::filesystem::path);
40     Timer& read_spef(std::filesystem::path);
41     Timer& read_sdc(std::filesystem::path);
42     Timer& read_timing(std::filesystem::path);
43     Timer& insert_net(std::string);
44     Timer& insert_gate(std::string, std::string);
45     Timer& repower_gate(std::string, std::string);
46     Timer& remove_net(std::string);
47     Timer& remove_gate(std::string);
48     Timer& disconnect_pin(std::string);
49     Timer& connect_pin(std::string, std::string);
50     Timer& insert_primary_input(std::string);
51     Timer& insert_primary_output(std::string);
52     Timer& set_at(std::string, Split, Tran, std::optional<float>);
53     Timer& set_rat(std::string, Split, Tran, std::optional<float>);
54     Timer& set_slew(std::string, Split, Tran, std::optional<float>);
55     Timer& set_load(std::string, Split, Tran, std::optional<float>);
56     Timer& create_clock(std::string, float);
57     Timer& create_clock(std::string, std::string, float);
58     Timer& cppr(bool);
59     Timer& set_time_unit(second_t);
60     Timer& set_capacitance_unit(farad_t);
61     Timer& set_resistance_unit(ohm_t);
62     Timer& set_voltage_unit(volt_t);
63     Timer& set_power_unit(watt_t);
64     Timer& set_current_unit(ampere_t);
65 
66     // Action.
67     void update_timing();
68 
69     std::optional<float> report_at(const std::string&, Split, Tran);
70     std::optional<float> report_rat(const std::string&, Split, Tran);
71     std::optional<float> report_slew(const std::string&, Split, Tran);
72     std::optional<float> report_slack(const std::string&, Split, Tran);
73     std::optional<float> report_load(const std::string&, Split, Tran);
74     std::optional<float> report_area();
75     std::optional<float> report_leakage_power();
76     std::optional<float> report_tns(std::optional<Split> = {}, std::optional<Tran> = {});
77     std::optional<float> report_wns(std::optional<Split> = {}, std::optional<Tran> = {});
78     std::optional<size_t> report_fep(std::optional<Split> = {}, std::optional<Tran> = {});
79 
80     std::vector<Path> report_timing(size_t);
81     std::vector<Path> report_timing(size_t, Split);
82     std::vector<Path> report_timing(size_t, Tran);
83     std::vector<Path> report_timing(size_t, Split, Tran);
84     std::vector<Path> report_timing(PathGuide);
85 
86     // Accessor
87     void dump_graph(std::ostream&) const;
88     void dump_taskflow(std::ostream&) const;
89     void dump_cell(std::ostream&, const std::string&, Split) const;
90     void dump_celllib(std::ostream&, Split) const;
91     void dump_net_load(std::ostream&) const;
92     void dump_pin_cap(std::ostream&) const;
93     void dump_at(std::ostream&) const;
94     void dump_rat(std::ostream&) const;
95     void dump_slew(std::ostream&) const;
96     void dump_slack(std::ostream&) const;
97     void dump_timer(std::ostream&) const;
98     void dump_verilog(std::ostream&, const std::string&) const;
99     void dump_spef(std::ostream&) const;
100     void dump_rctree(std::ostream&) const;
101 
102     inline auto num_primary_inputs() const;
103     inline auto num_primary_outputs() const;
104     inline auto num_pins() const;
105     inline auto num_nets() const;
106     inline auto num_arcs() const;
107     inline auto num_gates() const;
108     inline auto num_tests() const;
109     inline auto num_sccs() const;
110     inline auto time_unit() const;
111     inline auto power_unit() const;
112     inline auto resistance_unit() const;
113     inline auto current_unit() const;
114     inline auto voltage_unit() const;
115     inline auto capacitance_unit() const;
116 
117     inline const auto& primary_inputs() const;
118     inline const auto& primary_outputs() const;
119     inline const auto& pins() const;
120     inline const auto& nets() const;
121     inline const auto& gates() const;
122     inline const auto& clocks() const;
123     inline const auto& tests() const;
124     inline const auto& arcs() const;
125 
126   private:
127 
128     mutable std::shared_mutex _mutex;
129 
130     tf::Taskflow _taskflow;
131     tf::Executor _executor;
132 
133     int _state {0};
134 
135     bool _scc_analysis {false};
136 
137     std::optional<tf::Task> _lineage;
138     std::optional<CpprAnalysis> _cppr_analysis;
139     std::optional<second_t> _time_unit;
140     std::optional<watt_t> _power_unit;
141     std::optional<ohm_t> _resistance_unit;
142     std::optional<farad_t> _capacitance_unit;
143     std::optional<ampere_t> _current_unit;
144     std::optional<volt_t> _voltage_unit;
145 
146     TimingData<std::optional<Celllib>, MAX_SPLIT> _celllib;
147 
148     std::unordered_map<std::string, PrimaryInput> _pis;
149     std::unordered_map<std::string, PrimaryOutput> _pos;
150     std::unordered_map<std::string, Pin> _pins;
151     std::unordered_map<std::string, Net> _nets;
152     std::unordered_map<std::string, Gate> _gates;
153     std::unordered_map<std::string, Clock> _clocks;
154 
155     std::list<Test> _tests;
156     std::list<Arc> _arcs;
157     std::list<Pin*> _frontiers;
158     std::list<SCC> _sccs;
159 
160     TimingData<std::vector<Endpoint>, MAX_SPLIT, MAX_TRAN> _endpoints;
161     TimingData<std::optional<float>,  MAX_SPLIT, MAX_TRAN> _wns;
162     TimingData<std::optional<float>,  MAX_SPLIT, MAX_TRAN> _tns;
163     TimingData<std::optional<size_t>, MAX_SPLIT, MAX_TRAN> _fep;
164 
165     std::optional<float> _area;
166     std::optional<float> _leakage_power;
167 
168     std::deque<Pin*> _fprop_cands;
169     std::deque<Pin*> _bprop_cands;
170 
171     IndexGenerator<size_t> _pin_idx_gen {0u};
172     IndexGenerator<size_t> _arc_idx_gen {0u};
173 
174     std::vector<Pin*> _scc_cands;
175     std::vector<Pin*> _idx2pin;
176     std::vector<Arc*> _idx2arc;
177 
178     std::vector<Endpoint*> _worst_endpoints(size_t);
179     std::vector<Endpoint*> _worst_endpoints(size_t, Split);
180     std::vector<Endpoint*> _worst_endpoints(size_t, Tran);
181     std::vector<Endpoint*> _worst_endpoints(size_t, Split, Tran);
182     std::vector<Endpoint*> _worst_endpoints(const PathGuide&);
183 
184     std::vector<Path> _report_timing(std::vector<Endpoint*>&&, size_t);
185 
186     bool _is_redundant_timing(const Timing&, Split) const;
187 
188     void _to_time_unit(const second_t&);
189     void _to_capacitance_unit(const farad_t&);
190     void _to_resistance_unit(const ohm_t&);
191     void _to_power_unit(const watt_t&);
192     void _to_current_unit(const ampere_t&);
193     void _to_voltage_unit(const volt_t&);
194     void _add_to_lineage(tf::Task);
195     void _rebase_unit(Celllib&);
196     void _rebase_unit(spef::Spef&);
197     void _update_timing();
198     void _update_endpoints();
199     void _update_area();
200     void _update_power();
201     void _fprop_rc_timing(Pin&);
202     void _fprop_slew(Pin&);
203     void _fprop_delay(Pin&);
204     void _fprop_at(Pin&);
205     void _fprop_test(Pin&);
206     void _bprop_rat(Pin&);
207     void _build_prop_cands();
208     void _build_fprop_cands(Pin&);
209     void _build_bprop_cands(Pin&);
210     void _build_prop_tasks();
211     void _clear_prop_tasks();
212     void _read_spef(spef::Spef&);;
213     void _verilog(vlog::Module&);
214     void _timing(tau15::Timing&);
215     void _read_sdc(sdc::SDC&);
216     void _read_sdc(sdc::SetInputDelay&);
217     void _read_sdc(sdc::SetInputTransition&);
218     void _read_sdc(sdc::SetOutputDelay&);
219     void _read_sdc(sdc::SetLoad&);
220     void _read_sdc(sdc::CreateClock&);
221     void _connect_pin(Pin&, Net&);
222     void _disconnect_pin(Pin&);
223     void _insert_frontier(Pin&);
224     void _remove_frontier(Pin&);
225     void _remove_scc(SCC&);
226     void _clear_frontiers();
227     void _insert_primary_output(const std::string&);
228     void _insert_primary_input(const std::string&);
229     void _insert_gate(const std::string&, const std::string&);
230     void _insert_gate_arcs(Gate&);
231     void _remove_gate_arcs(Gate&);
232     void _repower_gate(const std::string&, const std::string&);
233     void _remove_gate(Gate&);
234     void _remove_net(Net&);
235     void _remove_pin(Pin&);
236     void _remove_arc(Arc&);
237     void _remove_test(Test&);
238     void _set_at(PrimaryInput&, Split, Tran, std::optional<float>);
239     void _set_slew(PrimaryInput&, Split, Tran, std::optional<float>);
240     void _set_rat(PrimaryOutput&, Split, Tran, std::optional<float>);
241     void _set_load(PrimaryOutput&, Split, Tran, std::optional<float>);
242     void _cppr(bool);
243     void _topologize(SfxtCache&, size_t) const;
244     void _spfa(SfxtCache&) const;
245     void _spdp(SfxtCache&) const;
246     void _recover_prefix(Path&, const SfxtCache&, size_t) const;
247     void _recover_datapath(Path&, const SfxtCache&) const;
248     void _recover_datapath(Path&, const SfxtCache&, const PfxtNode*, size_t) const;
249     void _enable_full_timing_update();
250     void _merge_celllib(Celllib&, Split);
251     void _insert_full_timing_frontiers();
252     void _spur(Endpoint&, size_t, PathHeap&) const;
253     void _spur(PfxtCache&, const PfxtNode&) const;
254     void _dump_graph(std::ostream&) const;
255     void _dump_taskflow(std::ostream&) const;
256     void _dump_cell(std::ostream&, const std::string&, Split) const;
257     void _dump_celllib(std::ostream&, Split) const;
258     void _dump_net_load(std::ostream&) const;
259     void _dump_pin_cap(std::ostream&) const;
260     void _dump_slew(std::ostream&) const;
261     void _dump_slack(std::ostream&) const;
262     void _dump_at(std::ostream&) const;
263     void _dump_rat(std::ostream&) const;
264     void _dump_timer(std::ostream&) const;
265     void _dump_timing(std::ostream&) const;
266     void _dump_verilog(std::ostream&, const std::string&) const;
267     void _dump_spef(std::ostream&) const;
268     void _dump_rctree(std::ostream&) const;
269 
270     template <typename... T, std::enable_if_t<(sizeof...(T)>1), void>* = nullptr >
271     void _insert_frontier(T&&...);
272 
273     SfxtCache _sfxt_cache(const Endpoint&) const;
274     SfxtCache _sfxt_cache(const PrimaryOutput&, Split, Tran) const;
275     SfxtCache _sfxt_cache(const Test&, Split, Tran) const;
276     CpprCache _cppr_cache(const Test&, Split, Tran) const;
277     PfxtCache _pfxt_cache(const SfxtCache&) const;
278 
279     Net& _insert_net(const std::string&);
280     Pin& _insert_pin(const std::string&);
281     Arc& _insert_arc(Pin&, Pin&, Net&);
282     Arc& _insert_arc(Pin&, Pin&, Test&);
283     Arc& _insert_arc(Pin&, Pin&, TimingView);
284     SCC& _insert_scc(std::vector<Pin*>&);
285     Test& _insert_test(Arc&);
286     Clock& _create_clock(const std::string&, Pin&, float);
287     Clock& _create_clock(const std::string&, float);
288 
289     std::optional<float> _report_at(const std::string&, Split, Tran);
290     std::optional<float> _report_rat(const std::string&, Split, Tran);
291     std::optional<float> _report_slew(const std::string&, Split, Tran);
292     std::optional<float> _report_slack(const std::string&, Split, Tran);
293     std::optional<float> _report_load(const std::string&, Split, Tran);
294     std::optional<float> _cppr_credit(const Test&, Split, Tran) const;
295     std::optional<float> _cppr_credit(const CpprCache&, Pin&, Split, Tran) const;
296     std::optional<float> _cppr_offset(const CpprCache&, Pin&, Split, Tran) const;
297     std::optional<float> _sfxt_offset(const SfxtCache&, size_t) const;
298 
299     size_t _max_pin_name_size() const;
300     size_t _max_net_name_size() const;
301 
302     inline auto _encode_pin(Pin&, Tran) const;
303     inline auto _decode_pin(size_t) const;
304     inline auto _encode_arc(Arc&, Tran, Tran) const;
305     inline auto _decode_arc(size_t) const;
306     inline auto _has_state(int) const;
307     inline auto _insert_state(int);
308     inline auto _remove_state(int = 0);
309 
310 };
311 
312 // Procedure: _insert_frontier
313 template <typename... T, std::enable_if_t<(sizeof...(T)>1), void>*>
_insert_frontier(T &&...pins)314 void Timer::_insert_frontier(T&&... pins) {
315   (_insert_frontier(pins), ...);
316 }
317 
318 // Function: num_primary_inputs
num_primary_inputs() const319 inline auto Timer::num_primary_inputs() const {
320   return _pis.size();
321 }
322 
323 // Function: num_primary_outputs
num_primary_outputs() const324 inline auto Timer::num_primary_outputs() const {
325   return _pos.size();
326 }
327 
328 // Function: num_pins
num_pins() const329 inline auto Timer::num_pins() const {
330   return _pins.size();
331 }
332 
333 // Function: num_nets
num_nets() const334 inline auto Timer::num_nets() const {
335   return _nets.size();
336 }
337 
338 // Function: num_arcs
num_arcs() const339 inline auto Timer::num_arcs() const {
340   return _arcs.size();
341 }
342 
343 // Function: num_gates
num_gates() const344 inline auto Timer::num_gates() const {
345   return _gates.size();
346 }
347 
348 // Function: num_tests
num_tests() const349 inline auto Timer::num_tests() const {
350   return _tests.size();
351 }
352 
353 // Function: num_sccs
num_sccs() const354 inline auto Timer::num_sccs() const {
355   return _sccs.size();
356 }
357 
358 // Function: time_unit
time_unit() const359 inline auto Timer::time_unit() const {
360   return _time_unit;
361 }
362 
363 // Function: power_unit
power_unit() const364 inline auto Timer::power_unit() const {
365   return _power_unit;
366 }
367 
368 // Function: resistance_unit
resistance_unit() const369 inline auto Timer::resistance_unit() const {
370   return _resistance_unit;
371 }
372 
373 // Function: current_unit
current_unit() const374 inline auto Timer::current_unit() const {
375   return _current_unit;
376 }
377 
378 // Function: voltage_unit
voltage_unit() const379 inline auto Timer::voltage_unit() const {
380   return _voltage_unit;
381 }
382 
383 // Function: capacitance_unit
capacitance_unit() const384 inline auto Timer::capacitance_unit() const {
385   return _capacitance_unit;
386 }
387 
388 // Function: primary_inputs
389 // expose the primary input data structure to users
primary_inputs() const390 inline const auto& Timer::primary_inputs() const {
391   return _pis;
392 }
393 
394 // Function: primary_outputs
395 // Expose the primary output data structure to users
primary_outputs() const396 inline const auto& Timer::primary_outputs() const {
397   return _pos;
398 }
399 
400 // Function: pins
401 // Expose the pin data structure to users
pins() const402 inline const auto& Timer::pins() const {
403   return _pins;
404 }
405 
406 // Function: nets
407 // Expose the net data structure to users
nets() const408 inline const auto& Timer::nets() const {
409   return _nets;
410 }
411 
412 // Function: gates
413 // Expose the gate data structure to users
gates() const414 inline const auto& Timer::gates() const {
415   return _gates;
416 }
417 
418 // Function: clocks
419 // Expose the clock data structure to users
clocks() const420 inline const auto& Timer::clocks() const {
421   return _clocks;
422 }
423 
424 // Function: tests
425 // Expose the test data structure to users
tests() const426 inline const auto& Timer::tests() const {
427   return _tests;
428 }
429 
430 // Function: arcs
431 // Expose the arc data structure to users
arcs() const432 inline const auto& Timer::arcs() const {
433   return _arcs;
434 }
435 
436 // Function: _encode_pin
_encode_pin(Pin & pin,Tran rf) const437 inline auto Timer::_encode_pin(Pin& pin, Tran rf) const {
438   return rf == RISE ? pin._idx : pin._idx + _idx2pin.size();
439 }
440 
441 // Function: _decode_pin
_decode_pin(size_t idx) const442 inline auto Timer::_decode_pin(size_t idx) const {
443   return std::make_tuple(_idx2pin[idx%_idx2pin.size()], idx<_idx2pin.size() ? RISE : FALL);
444 }
445 
446 // Function: _encode_arc
_encode_arc(Arc & arc,Tran frf,Tran trf) const447 inline auto Timer::_encode_arc(Arc& arc, Tran frf, Tran trf) const {
448   if(frf == RISE) {
449     return arc._idx + (trf == RISE ? 0 : _idx2arc.size());
450   }
451   else {
452     return arc._idx + (trf == RISE ? _idx2arc.size()*2 : _idx2arc.size()*3);
453   }
454 }
455 
456 // Function: _decode_arc
_decode_arc(size_t idx) const457 inline auto Timer::_decode_arc(size_t idx) const {
458   if(auto s = _idx2arc.size(); idx < s) {
459     return std::make_tuple(_idx2arc[idx % s], RISE, RISE);
460   }
461   else if(idx < 2*s) {
462     return std::make_tuple(_idx2arc[idx % s], RISE, FALL);
463   }
464   else if(idx < 3*s) {
465     return std::make_tuple(_idx2arc[idx % s], FALL, RISE);
466   }
467   else {
468     return std::make_tuple(_idx2arc[idx % s], FALL, FALL);
469   }
470 }
471 
472 // Function: _has_state
_has_state(int s) const473 inline auto Timer::_has_state(int s) const {
474   return _state & s;
475 }
476 
477 // Procedure: _insert_state
_insert_state(int s)478 inline auto Timer::_insert_state(int s) {
479   _state |= s;
480 }
481 
482 // Procedure: _remove_state
_remove_state(int s)483 inline auto Timer::_remove_state(int s) {
484   if(s == 0) _state = 0;
485   else {
486     _state &= ~s;
487   }
488 }
489 
490 };  // end of namespace ot ------------------------------------------------------------------------
491 
492 #endif
493 
494 
495 
496 
497