1 // OpenSTA, Static Timing Analyzer
2 // Copyright (c) 2020, 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 "Map.hh"
22 #include "StringUtil.hh"
23 #include "NetworkClass.hh"
24 
25 // The classes defined in this file are a contrete implementation of
26 // the library API.  They can be used by a reader to construct classes
27 // that implement the library portion of the network API.
28 
29 namespace sta {
30 
31 class ConcreteLibrary;
32 class ConcreteCell;
33 class ConcretePort;
34 class ConcreteCellPortBitIterator;
35 class PatternMatch;
36 class LibertyCell;
37 class LibertyPort;
38 
39 typedef Map<const char*, ConcreteCell*, CharPtrLess> ConcreteCellMap;
40 typedef Vector<ConcretePort*> ConcretePortSeq;
41 typedef Map<const char*, ConcretePort*, CharPtrLess> ConcretePortMap;
42 typedef ConcreteCellMap::ConstIterator ConcreteLibraryCellIterator;
43 typedef ConcretePortSeq::ConstIterator ConcreteCellPortIterator;
44 typedef ConcretePortSeq::ConstIterator ConcretePortMemberIterator;
45 
46 class ConcreteLibrary
47 {
48 public:
49   explicit ConcreteLibrary(const char *name,
50 			   const char *filename,
51 			   bool is_liberty);
52   virtual ~ConcreteLibrary();
name() const53   const char *name() const { return name_; }
54   void setName(const char *name);
isLiberty() const55   bool isLiberty() const { return is_liberty_; }
filename() const56   const char *filename() const { return filename_; }
57   void addCell(ConcreteCell *cell);
58   ConcreteCell *makeCell(const char *name,
59 			 bool is_leaf,
60 			 const char *filename);
61   void deleteCell(ConcreteCell *cell);
62   ConcreteLibraryCellIterator *cellIterator() const;
63   ConcreteCell *findCell(const char *name) const;
64   void findCellsMatching(const PatternMatch *pattern,
65 			 CellSeq *cells) const;
busBrktLeft()66   char busBrktLeft() { return bus_brkt_left_; }
busBrktRight()67   char busBrktRight() { return bus_brkt_right_; }
68   void setBusBrkts(char left,
69 		   char right);
70 
71 protected:
72   void renameCell(ConcreteCell *cell,
73 		  const char *cell_name);
74 
75   const char *name_;
76   const char *filename_;
77   bool is_liberty_;
78   char bus_brkt_left_;
79   char bus_brkt_right_;
80   ConcreteCellMap cell_map_;
81 
82 private:
83   DISALLOW_COPY_AND_ASSIGN(ConcreteLibrary);
84 
85   friend class ConcreteCell;
86 };
87 
88 class ConcreteCell
89 {
90 public:
91   // Use ConcreteLibrary::deleteCell.
92   virtual ~ConcreteCell();
library() const93   ConcreteLibrary *library() const { return library_; }
name() const94   const char *name() const { return name_; }
filename() const95   const char *filename() const { return filename_; }
libertyCell() const96   LibertyCell *libertyCell() const { return liberty_cell_; }
97   void setLibertyCell(LibertyCell *cell);
extCell() const98   void *extCell() const { return ext_cell_; }
99   void setExtCell(void *ext_cell);
portBitCount() const100   int portBitCount() const { return port_bit_count_; }
101   ConcretePort *findPort(const char *name) const;
102   void findPortsMatching(const PatternMatch *pattern,
103 			 PortSeq *ports) const;
104   ConcreteCellPortIterator *portIterator() const;
105   ConcreteCellPortBitIterator *portBitIterator() const;
isLeaf() const106   bool isLeaf() const { return is_leaf_; }
107   void setIsLeaf(bool is_leaf);
108 
109   // Cell acts as port factory.
110   ConcretePort *makePort(const char *name);
111   // Bus port.
112   ConcretePort *makeBusPort(const char *name,
113 			    int from_index,
114 			    int to_index);
115   // Bundle port.
116   ConcretePort *makeBundlePort(const char *name,
117 			       ConcretePortSeq *members);
118   // Group previously defined bus bit ports together.
119   void groupBusPorts(const char bus_brkt_left,
120 		     const char bus_brkt_right);
121   size_t portCount() const;
122   void setName(const char *name);
123   void addPort(ConcretePort *port);
124   void addPortBit(ConcretePort *port);
125 
126 protected:
127   ConcreteCell(ConcreteLibrary *library,
128 	       const char *name,
129 	       bool is_leaf,
130 	       const char *filename);
131   ConcretePort *makeBusPort(const char *name,
132 			    int from_index,
133 			    int to_index,
134 			    ConcretePortSeq *members);
135   void makeBusPortBits(ConcretePort *bus_port,
136 		       const char *name,
137 		       int from_index,
138 		       int to_index);
139   // Bus port bit (internal to makeBusPortBits).
140   ConcretePort *makePort(const char *bit_name,
141 			 int bit_index);
142   void makeBusPortBit(ConcretePort *bus_port,
143 		      const char *name,
144 		      int index);
145 
146   ConcreteLibrary *library_;
147   const char *name_;
148   // Filename is optional.
149   const char *filename_;
150   LibertyCell *liberty_cell_;
151   // External application cell.
152   void *ext_cell_;
153   // Non-bus and bus ports (but no expanded bus bit ports).
154   ConcretePortSeq ports_;
155   ConcretePortMap port_map_;
156   // Port bit count (expanded buses).
157   int port_bit_count_;
158   bool is_leaf_;
159 
160 private:
161   DISALLOW_COPY_AND_ASSIGN(ConcreteCell);
162 
163   friend class ConcreteLibrary;
164   friend class ConcreteCellPortBitIterator;
165 };
166 
167 class ConcretePort
168 {
169 public:
170   virtual ~ConcretePort();
name() const171   const char *name() const { return name_; }
172   const char *busName() const;
173   Cell *cell() const;
library() const174   ConcreteLibrary *library() const { return cell_->library(); }
direction() const175   PortDirection *direction() const { return direction_; }
libertyPort() const176   LibertyPort *libertyPort() const { return liberty_port_; }
177   void setLibertyPort(LibertyPort *port);
178   // External application port.
extPort() const179   void *extPort() const { return ext_port_; }
180   void setExtPort(void *port);
181   void setDirection(PortDirection *dir);
182   // Bundles are groups of related ports that do not use
183   // bus notation.
isBundle() const184   bool isBundle() const { return is_bundle_; }
isBus() const185   bool isBus() const { return is_bus_; }
186   // Index of cell bit ports.
187   // Bus/bundle ports do not have an pin index.
pinIndex() const188   int pinIndex() const { return pin_index_; }
189   void setPinIndex(int index);
190   // Size is the bus/bundle member count (1 for non-bus/bundle ports).
191   int size() const;
fromIndex() const192   int fromIndex() const { return from_index_; }
toIndex() const193   int toIndex() const { return to_index_; }
194   // Bus member, bus[subscript].
195   ConcretePort *findBusBit(int index) const;
196   // Predicate to determine if subscript is within bus range.
197   //     (toIndex > fromIndex) && fromIndex <= subscript <= toIndex
198   //  || (fromIndex > toIndex) && fromIndex >= subscript >= toIndex
199   bool busIndexInRange(int index) const;
200   // A port has members if it is a bundle or bus.
201   bool hasMembers() const;
202   ConcretePort *findMember(int index) const;
203   ConcretePortMemberIterator *memberIterator() const;
204   void setBusBitIndex(int index);
205 
206   // Bus bit port functions.
207   // Bus bit is one bit of a bus port.
208   bool isBusBit() const;
209   // Bit index within bus port.
210   // The bit index of A[3] is 3.
busBitIndex() const211   int busBitIndex() const { return to_index_; }
memberPorts() const212   ConcretePortSeq *memberPorts() const { return member_ports_; }
213   void addPortBit(ConcretePort *port);
214 
215 protected:
216   // Constructors for factory in cell class.
217   ConcretePort(ConcreteCell *cell,
218 	       const char *name,
219 	       bool is_bus,
220 	       int from_index,
221 	       int to_index,
222 	       bool is_bundle,
223 	       ConcretePortSeq *member_ports);
224 
225   const char *name_;
226   ConcreteCell *cell_;
227   PortDirection *direction_;
228   LibertyPort *liberty_port_;
229   // External application port.
230   void *ext_port_;
231   int pin_index_;
232   bool is_bundle_;
233   bool is_bus_;
234   int from_index_;
235   int to_index_;
236   // Expanded bus bit ports (ordered by from_index_ to to_index_)
237   // or bundle member ports.
238   ConcretePortSeq *member_ports_;
239 
240 private:
241   DISALLOW_COPY_AND_ASSIGN(ConcretePort);
242 
243   friend class ConcreteCell;
244 };
245 
246 class ConcreteCellPortBitIterator : public Iterator<ConcretePort*>
247 {
248 public:
249   explicit ConcreteCellPortBitIterator(const ConcreteCell *cell);
250   virtual bool hasNext();
251   virtual ConcretePort *next();
252 
253 private:
254   DISALLOW_COPY_AND_ASSIGN(ConcreteCellPortBitIterator);
255   void findNext();
256 
257   ConcretePortSeq::ConstIterator port_iter_;
258   ConcretePortMemberIterator *member_iter_;
259   ConcretePort *next_;
260 };
261 
262 } // Namespace
263