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 #pragma once
18 
19 #include "DisallowCopyAssign.hh"
20 #include "Vector.hh"
21 #include "Set.hh"
22 #include "Transition.hh"
23 #include "SdcClass.hh"
24 #include "SearchClass.hh"
25 #include "PathRef.hh"
26 
27 namespace sta {
28 
29 // Tags are used to distinguish multiple paths that hold
30 // arrival/required times on a vertex.
31 //
32 // Each tag corresponds to a different path on the vertex thru a
33 // set of exceptions.
34 //
35 // Clock paths are distinguished from non-clock paths using separate
36 // tags. This is because clocks pins can also have input arrivals wrt
37 // other clocks.
38 //
39 // When common clock reconvergence pessimism removal is enabled the
40 // tag ClkInfo includes the last clock driver pin so that distinct
41 // paths are used for paths from different sources of min/max clock
42 // arrivals.
43 
44 class Tag
45 {
46 public:
47   Tag(TagIndex index,
48       int tr_index,
49       PathAPIndex path_ap_index,
50       ClkInfo *clk_info,
51       bool is_clk,
52       InputDelay *input_delay,
53       bool is_segment_start,
54       ExceptionStateSet *states,
55       bool own_states,
56       const StaState *sta);
57   ~Tag();
58   const char *asString(const StaState *sta) const;
59   const char *asString(bool report_index,
60 		       bool report_rf_min_max,
61 		       const StaState *sta) const;
clkInfo() const62   ClkInfo *clkInfo() const { return clk_info_; }
isClock() const63   bool isClock() const { return is_clk_; }
64   ClockEdge *clkEdge() const;
65   Clock *clock() const;
66   const Pin *clkSrc() const;
trIndex() const67   int trIndex() const { return tr_index_; }
68   const RiseFall *transition() const;
69   PathAnalysisPt *pathAnalysisPt(const StaState *sta) const;
pathAPIndex() const70   PathAPIndex pathAPIndex() const { return path_ap_index_; }
index() const71   TagIndex index() const { return index_; }
states() const72   ExceptionStateSet *states() const { return states_; }
73   void setStates(ExceptionStateSet *states);
74   bool isGenClkSrcPath() const;
75   Clock *genClkSrcPathClk(const StaState *sta) const;
76   // Input delay at search startpoint (not propagated).
inputDelay() const77   InputDelay *inputDelay() const { return input_delay_; }
isLoop() const78   bool isLoop() const { return is_loop_; }
isFilter() const79   bool isFilter() const { return is_filter_; }
isSegmentStart() const80   bool isSegmentStart() const { return is_segment_start_; }
hash() const81   size_t hash() const { return hash_; }
82   size_t matchHash(bool match_crpr_clk_pin) const;
83 
84 protected:
85   void findHash();
86 
87 private:
88   DISALLOW_COPY_AND_ASSIGN(Tag);
89 
90   ClkInfo *clk_info_;
91   InputDelay *input_delay_;
92   ExceptionStateSet *states_;
93   size_t hash_;
94   size_t match_hash_;
95   bool is_clk_:1;
96   bool is_filter_:1;
97   bool is_loop_:1;
98   bool is_segment_start_:1;
99   // Indicates that states_ is owned by the tag.
100   bool own_states_:1;
101   TagIndex index_:tag_index_bits;
102   unsigned int tr_index_:RiseFall::index_bit_count;
103   unsigned int path_ap_index_:path_ap_index_bit_count;
104 };
105 
106 class TagLess
107 {
108 public:
109   bool operator()(const Tag *tag1,
110 		  const Tag *tag2) const;
111 };
112 
113 class TagIndexLess
114 {
115 public:
116   bool operator()(const Tag *tag1,
117 		  const Tag *tag2) const;
118 };
119 
120 class TagHash
121 {
122 public:
123   size_t operator()(const Tag *tag);
124 };
125 
126 class TagEqual
127 {
128 public:
129   bool operator()(const Tag *tag1,
130 		  const Tag *tag2);
131 };
132 
133 int
134 tagCmp(const Tag *tag1,
135        const Tag *tag2,
136        bool cmp_rf);
137 
138 // Match tag clock edge, clock driver and exception states but not clk info.
139 bool
140 tagMatch(const Tag *tag1,
141 	 const Tag *tag2,
142 	 const StaState *sta);
143 bool
144 tagMatch(const Tag *tag1,
145 	 const Tag *tag2,
146  	 bool match_crpr_clk_pin,
147 	 const StaState *sta);
148 bool
149 tagStateEqual(const Tag *tag1,
150 	      const Tag *tag2);
151 bool
152 tagMatchNoCrpr(const Tag *tag1,
153 	       const Tag *tag2);
154 int
155 tagMatchCmp(const Tag *tag1,
156 	    const Tag *tag2,
157 	    bool match_clk_clk_pin,
158 	    const StaState *sta);
159 
160 bool
161 tagMatchNoPathAp(const Tag *tag1,
162 		 const Tag *tag2);
163 bool
164 tagMatchCrpr(const Tag *tag1,
165 	     const Tag *tag2);
166 
167 } // namespace
168