1 #include <ot/timer/test.hpp>
2 #include <ot/timer/arc.hpp>
3 #include <ot/timer/pin.hpp>
4 
5 namespace ot {
6 
7 // ------------------------------------------------------------------------------------------------
8 
9 // Constructor
Test(Arc & arc)10 Test::Test(Arc& arc) : _arc {arc} {
11 }
12 
13 // Function: rat
rat(Split el,Tran rf) const14 std::optional<float> Test::rat(Split el, Tran rf) const {
15   return _rat[el][rf];
16 }
17 
18 // Function: constraint
constraint(Split el,Tran rf) const19 std::optional<float> Test::constraint(Split el, Tran rf) const {
20   return _constraint[el][rf];
21 }
22 
23 // Function: cppr_credit
cppr_credit(Split el,Tran rf) const24 std::optional<float> Test::cppr_credit(Split el, Tran rf) const {
25   return _cppr_credit[el][rf];
26 }
27 
28 // Function: slack
slack(Split el,Tran rf) const29 std::optional<float> Test::slack(Split el, Tran rf) const {
30   if(_arc._to._at[el][rf] && _rat[el][rf]) {
31     return (
32       el == MIN ? *_arc._to._at[el][rf] - *_rat[el][rf] :
33                   *_rat[el][rf] - *_arc._to._at[el][rf]
34     ) + (
35       _cppr_credit[el][rf] ? *_cppr_credit[el][rf] : 0.0f
36     );
37   }
38   else return std::nullopt;
39 }
40 
41 // Function: raw_slack
raw_slack(Split el,Tran rf) const42 std::optional<float> Test::raw_slack(Split el, Tran rf) const {
43   if(_arc._to._at[el][rf] && _rat[el][rf]) {
44     return (
45       el == MIN ? *_arc._to._at[el][rf] - *_rat[el][rf] :
46                   *_rat[el][rf] - *_arc._to._at[el][rf]
47     );
48   }
49   else return std::nullopt;
50 }
51 
52 // Function: arc
arc() const53 const Arc& Test::arc() const {
54   return _arc;
55 }
56 
57 // Function: constrained_pin
constrained_pin() const58 const Pin& Test::constrained_pin() const {
59   return _arc._to;
60 }
61 
62 // Function: related_pin
related_pin() const63 const Pin& Test::related_pin() const {
64   return _arc._from;
65 }
66 
67 // Function: _constrained_pin
_constrained_pin()68 Pin& Test::_constrained_pin() {
69   return _arc._to;
70 }
71 
72 // Function: _related_pin
_related_pin()73 Pin& Test::_related_pin() {
74   return _arc._from;
75 }
76 
77 // Procedure: _reset
_reset()78 void Test::_reset() {
79   FOR_EACH_EL_RF(el, rf) {
80     _rat[el][rf].reset();
81     _cppr_credit[el][rf].reset();
82     _constraint[el][rf].reset();
83     _related_at[el][rf].reset();
84   }
85 }
86 
87 // Procedure: _fprop_rat
_fprop_rat(float period)88 void Test::_fprop_rat(float period) {
89 
90   auto tv = _arc.timing_view();
91 
92   FOR_EACH_EL_RF_IF(el, rf, tv[el]) {
93 
94     // SLEW not defined at the constrained pin.
95     if(!(_arc._to._slew[el][rf])) {
96       continue;
97     }
98 
99     auto fel = (el == MIN ? MAX : MIN);
100     auto frf = tv[el]->is_rising_edge_triggered() ? RISE : FALL;
101 
102     if(frf == FALL && !tv[el]->is_falling_edge_triggered()) {
103       OT_LOGE("clock transition not found for test ", _arc.name());
104       continue;
105     }
106 
107     // AT/SLEW not defined at the arc._from
108     if(!(_arc._from._at[fel][frf]) || !(_arc._from._slew[fel][frf])) {
109       continue;
110     }
111 
112     if(el == MIN) {
113       _related_at[el][rf] = *_arc._from._at[fel][frf];
114     }
115     else {
116       _related_at[el][rf] = *_arc._from._at[fel][frf] + period;
117     }
118 
119     _constraint[el][rf] = tv[el]->constraint(
120       frf,
121       rf,
122       *_arc._from._slew[fel][frf],
123       *_arc._to._slew[el][rf]
124     );
125 
126     if(_constraint[el][rf] && _related_at[el][rf]) {
127       if(el == MIN) {
128         _rat[el][rf] = *_constraint[el][rf] + *_related_at[el][rf];
129       }
130       else {
131         _rat[el][rf] = *_related_at[el][rf] - *_constraint[el][rf];
132       }
133     }
134   }
135 }
136 
137 };  // end of namespace ot. -----------------------------------------------------------------------
138 
139 
140 
141 
142 
143 
144 
145 
146 
147 
148