Eugeny KhanchinCreating Forms in SKILL Code: A Practical Guide
Why should we create graphical user interfaces (GUIs) for our tools?
GUIs offer a user-friendly and intuitive way to interact with software, making complex tasks more accessible and efficient. They provide visual feedback and structured workflows, reducing errors and enhancing productivity, allowing users to focus on their work rather than memorizing commands. GUIs also simplify training, making it easier for new users to explore features without extensive documentation.
SKILL code offers powerful ways to develop GUIs (or forms) within the Virtuoso environment. Cadence provides comprehensive documentation for all their hi* functions, which handle form development, along with examples of various features:
- Worked example using all available SKILL UI fields (Cadence Support Portal)
- Advanced GUI building using dynamically resizable layout forms (Cadence Support Portal)
In this guide, we'll walk through the GUI development process using a practical example. We'll use layout forms and define several callbacks, with the full code attached at the end.
1. Layout Forms
There are two main approaches for field placement in a GUI: using pixels (hiCreateAppForm()) and using layout forms (hiCreateLayoutForm()). Placing fields using pixels gives you freedom in choosing exact x, y coordinates and a size for your fields. Despite the fact that it’s intuitive, the major problem with this approach is it’s not scalable. The more complex the GUI is, the harder it’s to add a new field to it. Imagine you have to add a new field to a complex GUI such this:

Complex GUI example
In the by-pixel approach, in addition to a new field, you’ll have to change the location of other fields manually. Which will end up in long and tedious work. A more modern and scalable approach is using layout forms. At first, it’s not as intuitive as defining locations by pixels, but after you get hold of it, it turns into a powerful skill in GUI development. Layout forms allow you to build GUIs with container layouts (like Lego). When you have to add a new field, you just add it to the required layout and other fields will move automatically.
So for scalable and robust GUIs it is recommended to use layout forms approach.
Now, let’s get to our practical example.
2. GUI Template
Start by building a GUI template. Our GUI will receive the top cell's library, cell, and view names as input and display library and cell names used in the top cell's hierarchy.
1/*
2Create layout form.
3A practical example of creating layout forms and adding callbacks.
4
5Usage example:
6 form = createLibrariesCellsInUseForm()
7 hiDisplayForm(form)
8
9
10Author: Eugeny Khanchin
11Source: AnalogHub.ie
12*/
13
14
15procedure( createLibrariesCellsInUseForm()
16
17 ;Creates a form for displaying and interacting with library, cell, and
18 ;view information.
19
20 ;@return formObject
21 ; The created form object for libraries and cells in use.
22
23 let( (libraryLabel libraryStringField cellLabel cellStringField viewLabel
24 viewStringField topGridLayout browseButton horizontalLayout
25 infoReportField getInfoButton verticalLayout)
26
27 libraryLabel = hiCreateLabel(
28 ?name 'libraryLabel
29 ?labelText "Library"
30 ?justification 'right
31 )
32
33 libraryStringField = hiCreateStringField(
34 ?name 'libraryStringField
35 ?modifyCallback 'libraryNameModifyCB
36 )
37
38 cellLabel = hiCreateLabel(
39 ?name 'cellLabel
40 ?labelText "Cell"
41 ?justification 'right
42 )
43
44 cellStringField = hiCreateStringField(
45 ?name 'cellStringField
46 )
47
48 viewLabel = hiCreateLabel(
49 ?name 'viewLabel
50 ?labelText "View"
51 ?justification 'right
52 )
53
54 viewStringField = hiCreateStringField(
55 ?name 'viewStringField
56 )
57
58 topGridLayout = hiCreateGridLayout(
59 'topGridLayout
60 ?spacing 10
61 ?items list(
62 list(libraryLabel 'row 0 'col 0)
63 list(libraryStringField 'row 0 'col 1)
64 list(cellLabel 'row 1 'col 0)
65 list(cellStringField 'row 1 'col 1)
66 list(viewLabel 'row 2 'col 0)
67 list(viewStringField 'row 2 'col 1)
68 list('col_stretch 0 0)
69 list('col_stretch 1 1)
70 )
71 )
72
73 browseButton = hiCreateButton(
74 ?name 'browseButton
75 ?buttonText "Browse"
76 ?callback "browseLibraryCellViewCB(hiGetCurrentForm())"
77 )
78
79 horizontalLayout = hiCreateHorizontalBoxLayout(
80 'horizontalLayout
81 ?frame "Top Cell Info"
82 ?spacing 10
83 ?items list(
84 list(topGridLayout 'stretch 1)
85 list(browseButton 'stretch 0)
86 )
87 )
88
89 infoReportField = hiCreateReportField(
90 ?name 'infoReportField
91 ?title "Hierarchy Info"
92 ?headers list(
93 list("Library" 100 'left 'string t)
94 list("Cell" 100 'left 'string t)
95 )
96 )
97
98 getInfoButton = hiCreateButton(
99 ?name 'getInfoButton
100 ?buttonText "Get Hierarchy Info"
101 ?callback "getUsedLibrariesCellsCB(hiGetCurrentForm())"
102 )
103
104 verticalLayout = hiCreateVerticalBoxLayout(
105 'verticalLayout
106 ?items list(horizontalLayout infoReportField getInfoButton)
107 )
108
109 hiCreateLayoutForm(
110 'librariesCellsInUseForm
111 "Libraries Cells in Use"
112 verticalLayout
113 ?buttonLayout 'Empty
114 ?mapCB 'librariesCellsInUseFormMapCB
115 )
116 );let
117);procedure
118
119
120procedure( librariesCellsInUseFormMapCB(form)
121
122 ;Map callback function for initializing the Libraries Cells In Use
123 ;form fields.
124
125 ;@param form formObject
126 ; The form object being instantiated.
127
128 let( (cellView)
129
130 hiInstantiateForm(form)
131 hiSetFieldMinSize(form 'browseButton ?widgetHeight 25)
132 hiSetFieldMinSize(form 'getInfoButton ?widgetHeight 35)
133
134 cellView = geGetEditCellView()
135 when( cellView
136 form~>libraryStringField~>value = cellView~>libName
137 form~>cellStringField~>value = cellView~>cellName
138 form~>viewStringField~>value = cellView~>viewName
139 );when
140 );let
141);procedure
142
143
144procedure( libraryNameModifyCB(field scope latestTextValue sourceOfChange)
145
146 ;Modify callback function for validating and highlighting the library
147 ;name field.
148
149 ;@param field formField
150 ; The form field being modified.
151 ;@param scope formObject
152 ; The form object containing the field.
153 ;@param latestTextValue string
154 ; The latest text value entered in the field.
155 ;@param sourceOfChange any
156 ; The source of the change, indicating whether the modification
157 ; was user-initiated.
158 ;@return t boolean
159 ; Returns t to allow the changes made to the field.
160
161 let( (libraryObject)
162 when( sourceOfChange
163 libraryObject = ddGetObj(latestTextValue)
164 if( !libraryObject
165 then
166 hiHighlightField(scope field~>hiFieldSym 'error)
167 else
168 hiHighlightField(scope field~>hiFieldSym 'background)
169 );if
170 );when
171
172 t
173 );let
174);procedure
175
176
177procedure( browseLibraryCellViewCB(form)
178
179 ;Callback function for synchronizing library, cell, and view fields with
180 ;the form.
181
182 ;@param form formObject
183 ; The form object containing the fields to be synchronized.
184
185 ddsSyncWithForm(form 'browse 'libraryStringField 'cellStringField
186 'viewStringField)
187);procedure
188
189
190procedure( getUsedLibrariesCellsCB(form)
191
192 ;Callback function to extract and display used libraries and cells from a
193 ;specified cell view.
194
195 ;@param form formObject
196 ; The form object containing the input fields and report field.
197
198 prog( (libName cellName viewName cellView usedLibrariesCellsTable choices)
199
200 ; Get input
201 libName = form~>libraryStringField~>value
202 cellName = form~>cellStringField~>value
203 viewName = form~>viewStringField~>value
204
205 ; Check input
206 unless( checkInput(libName cellName viewName)
207 return()
208 );unless
209
210 ; Pre-process input
211 cellView = dbOpenCellViewByType(libName cellName viewName)
212
213 ; Run the libraries and cells extraction function
214 usedLibrariesCellsTable = getLibrariesCellsUsedIn(cellView)
215
216 ; Post-process output
217 foreach( library usedLibrariesCellsTable
218 foreach( cell usedLibrariesCellsTable[library]
219 choices = cons(list(library cell) choices)
220 );foreach
221 );foreach
222
223 ; Show output in a table
224 form~>infoReportField~>choices = choices
225
226 return(t)
227 );prog
228);procedure
229
230
231procedure( checkInput(libName cellName viewName)
232
233 ;Validates the existence of a specified library, cell, and view
234 ;combination.
235
236 ;@param libName string
237 ; The name of the library to check.
238 ;@param cellName string
239 ; The name of the cell to check.
240 ;@param viewName string
241 ; The name of the view to check.
242 ;@return boolean
243 ; Returns t if the library, cell, and view exist; otherwise,
244 ; displays an error dialog and returns nil.
245
246 prog( (viewObject)
247
248 viewObject = ddGetObj(libName cellName viewName)
249 unless( viewObject
250 hiDisplayAppDBox(
251 ?name 'errorAppDBox
252 ?dboxBanner "*ERROR* Libraries Cells in Use"
253 ?dboxText "Selected library, cell or view don't exist!"
254 ?dialogType hicErrorDialog
255 ?buttonLayout 'Close
256 )
257
258 return()
259 );unless
260
261 return(t)
262 );prog
263);procedure
264
265
266procedure( getLibrariesCellsUsedIn(cellView
267 @optional (usedLibrariesCellsTable nil))
268
269 ;Retrieves all libraries and cells used in the hierarchy of a given
270 ;cell view.
271
272 ;@param cellView dbObject
273 ;The cell view object from which to retrieve the hierarchy.
274
275 ;@param usedLibrariesCellsTable table
276 ;Optional. A table to keep track of used libraries and cells.
277 ;If not provided, a new table is created.
278
279 ;@return table
280 ;A table containing libraries as keys and tables of cell names as
281 ;values, representing the hierarchy.
282
283 let( (cellTable libName cellName cellObject message viewName nextCellView)
284
285 ; First initialization
286 unless( usedLibrariesCellsTable
287 usedLibrariesCellsTable = makeTable('usedLibrariesCellsTable nil)
288 cellTable = makeTable('cellTable nil)
289 cellTable[cellView~>cellName] = t
290 usedLibrariesCellsTable[cellView~>libName] = cellTable
291 );unless
292
293 foreach( instance cellView~>instHeaders
294 libName = instance~>libName
295 cellName = instance~>cellName
296 cellObject = ddGetObj(libName cellName)
297
298 if( !cellObject
299 then
300 message = strcat("[getLibrariesCellsUsedIn] " libName "/"
301 cellName " cell doesn't exist in your Library Manager")
302 warn(message)
303 else
304 ; Creates cells' table for a library
305 unless( usedLibrariesCellsTable[libName]
306 cellTable = makeTable('cellTable nil)
307 usedLibrariesCellsTable[libName] = cellTable
308 );unless
309
310 unless( usedLibrariesCellsTable[libName][cellName]
311 ; This cell is not in table yet
312 usedLibrariesCellsTable[libName][cellName] = t
313
314 ; Gets instance's cell view
315 viewName = mapViewName(instance~>viewName)
316 nextCellView = dbOpenCellViewByType(libName cellName viewName)
317 when( nextCellView
318 usedLibrariesCellsTable = getLibrariesCellsUsedIn(nextCellView
319 usedLibrariesCellsTable)
320 );when
321 );unless
322 );if
323 );foreach
324
325 usedLibrariesCellsTable
326 );let
327);procedure
328
329
330procedure( mapViewName(viewName)
331 ; Maps a view name to a common view name that includes 'instances'
332 ;for hierarchy traversal.
333
334 ;@param viewName string
335 ;The name of the view to be mapped.
336
337 ;@return string
338 ;The mapped view name.
339
340
341 if( viewName == "symbol" ; Symbol's cell view doesn't have ~>instances
342 then
343 "schematic"
344 else
345 viewName
346 );if
347);procedureHere, we define labels, string fields, buttons and a report field, and use form layouts to organize the fields into sections. To display the GUI in SKILL, create the form and display it with these two commands:
1form = createLibrariesCellsInUseForm()
2hiDisplayForm(form)

Display GUI in SKILL
Tip: If you change anything in the form’s creation function, you have to re-create the form to see the changes. Re-run the two functions above.
3. Map Callback
Map callbacks are used to perform additional setup or customization when a form is instantiated and displayed. They are particularly useful for initializing form fields, setting default values, adjusting field sizes, or performing any other setup tasks that need to occur when the form is first displayed.
Define a map callback for our GUI to change the size of "Browse" and "Get Hierarchy Info" buttons and initialize top cell info fields if a cell view is currently open.
1procedure( librariesCellsInUseFormMapCB(form)
2;Map callback function for initializing the Libraries Cells In Use
3;form fields.
4
5;@param form formObject
6;The form object being instantiated.
7
8let( (cv)
9
10hiInstantiateForm(form)
11hiSetFieldMinSize(form 'browseButton ?widgetHeight 25)
12hiSetFieldMinSize(form 'getInfoButton ?widgetHeight 35)
13
14cv = geGetEditCellView()
15when( cv
16form~>libraryStringField~>value = cv~>libName
17form~>cellStringField~>value = cv~>cellName
18form~>viewStringField~>value = cv~>viewName
19);when
20);let
21);procedureHere, we must instantiate the form before modifying its fields’ sizes. Additionally, we assign values to our string fields. Set the function as a map callback by adding the ?mapCB keyword to the hiCreateLayoutForm() function.
1hiCreateLayoutForm(
2'librariesCellsInUseForm
3"Libraries Cells in Use"
4verticalLayout
5?buttonLayout 'Empty
6?mapCB 'librariesCellsInUseFormMapCB
7)Note: You can define field callbacks either as a symbol, like 'myFunc, or as a string, such as "myFunc()". Using a symbol automatically passes default arguments to the function based on the field, with each field's callback having its own set of default arguments. In case of the ?mapCB, it sends the current form object as an argument. Setting callbacks as strings is useful when you need to pass different arguments to a function.

Callback example
4. Modify Callback
A modify callback in SKILL is a function that is triggered whenever the user changes the value of a string field, such as by typing a new value. This callback is executed immediately when a change is detected in the field, but before the change is displayed.
The modify callback function can return one of three values:
- t: If the function returns t, the changes made to the field are allowed and displayed as they are entered.
- nil: If the function returns nil, the changes are not allowed, and the original value of the field is retained.
- value: If the function returns a string, this value replaces the current value of the field.
This mechanism provides a powerful way to validate input, update other fields, or trigger additional logic based on the new value, enabling dynamic and responsive interactions within SKILL forms.
Add a modify callback to the library string field to validate the entered name and highlight the field if incorrect.
1procedure( libraryNameModifyCB(field scope latestTextValue sourceOfChange)
2;Modify callback function for validating and highlighting the library
3;name field.
4;
5;@param field formField
6; The form field being modified.
7;@param scope formObject
8; The form object contains the field.
9;@param latestTextValue string
10; The latest text value entered in the field.
11;@param sourceOfChange any
12; The source of the change, indicating whether the modification
13; was user-initiated.
14;@return t boolean
15; Returns t to allow the changes made to the field.
16
17let( (libraryObject)
18when( sourceOfChange
19libraryObject = ddGetObj(latestTextValue)
20if( !libraryObject
21then
22hiHighlightField(scope field~>hiFieldSym 'error)
23else
24hiHighlightField(scope field~>hiFieldSym 'background)
25);if
26);when
27
28t
29);let
30);procedureHere, we attempt to retrieve a library object using its name and adjust the string field's highlight based on the result. Set the function as a modify callback by adding the ?modifyCallback keyword to the library's hiCreateStringField() function.
1libraryStringField = hiCreateStringField(
2?name 'libraryStringField
3?modifyCallback 'libraryNameModifyCB
4)

Note: To practice, you can add modify callbacks to the cell and view string fields.
5. Button Callback - Browse
Instead of manually entering library/cell/view names, we can define a callback to invoke the Library Manager for selection.
1procedure( browseLibraryCellViewCB(form)
2;Callback function for synchronizing library, cell, and view fields with
3;the form.
4
5;@param form formObject
6;The form object containing the fields to be synchronized.
7ddsSyncWithForm(form 'browse 'libraryStringField 'cellStringField
8'viewStringField)
9);procedureHere, we use the built-in ddsSyncWithForm() function, which requires a form, an action to perform, and fields’ symbols to update when selection is done.
Add this function to the browse button as a callback. Use the string approach this time, as we want to send only the form as an argument.
1browseButton = hiCreateButton(
2?name 'browseButton
3?buttonText "Browse"
4?callback "browseLibraryCellViewCB(hiGetCurrentForm())"
5)

6. Button Callback - Run
The run button executes the main algorithm. Here, we’ll use the getLibrariesCellsUsedIn() function, described in the “Extracting Library and Cell Names from a Top Cell Hierarchy Using SKILL Code” guide.
Define a function to run the algorithm, get results, and display them in a table.
1procedure( getUsedLibrariesCellsCB(form)
2;Callback function to extract and display used libraries and cells from a
3;specified cell view.
4;
5;@param form formObject
6;The form object containing the input fields and report field.
7prog( (libName cellName viewName cellView usedLibrariesCellsTable choices)
8
9; Get input
10libName = form~>libraryStringField~>value
11cellName = form~>cellStringField~>value
12viewName = form~>viewStringField~>value
13
14; Check input
15unless( checkInput(libName cellName viewName)
16return()
17);unless
18
19; Pre-process input
20cellView = dbOpenCellViewByType(libName cellName viewName)
21
22; Run the libraries and cells extraction function
23usedLibrariesCellsTable = getLibrariesCellsUsedIn(cellView)
24
25; Post-process output
26foreach( library usedLibrariesCellsTable
27foreach( cell usedLibrariesCellsTable[library]
28choices = cons(list(library cell) choices)
29);foreach
30);foreach
31
32; Show output in a table
33form~>infoReportField~>choices = choices
34
35return(t)
36);prog
37);procedureHere, first of all, we check the input, and if it’s incorrect we exit the function in an early stage by return(). To use the return() function to exit your function at a desired stage, you’ll have to wrap your code in the prog() scope, instead of the let(). Next, we get the cell view object, using the provided library/cell/view names.
After this, we use the cell view object to get libraries and cells names that are in use in this cell view’s hierarchy. When we get the result, we need to process it to be able to add to the report field, our results table. And finally, we add the processed results to the report field.
Add this function to the run button as a callback.
1getInfoButton = hiCreateButton(
2?name 'getInfoButton
3?buttonText "Get Hierarchy Info"
4?callback "getUsedLibrariesCellsCB(hiGetCurrentForm())"
5)Now, when you provide correct library/cell/view names and click the run button, you'll see the extracted results in the report field.

7. Conclusion
In this guide, we've explored how to use layout forms, define various callbacks, highlight string fields, display error messages, invoke the Library Manager, and utilize let() and prog() scopes. To further explore, check out Cadence guides on creating forms and experiment with different fields and parameters.
8. Full code
1procedure( createLibrariesCellsInUseForm()
2
3;Creates a form for displaying and interacting with library, cell, and
4;view information.
5
6;@return formObject
7;The created form object for libraries and cells in use.
8
9let( (libraryLabel libraryStringField cellLabel cellStringField viewLabel
10 viewStringField topGridLayout browseButton horizontalLayout
11 infoReportField getInfoButton verticalLayout)
12
13libraryLabel = hiCreateLabel(
14?name 'libraryLabel
15?labelText "Library"
16?justification 'right
17)
18
19libraryStringField = hiCreateStringField(
20?name 'libraryStringField
21?modifyCallback 'libraryNameModifyCB
22)
23
24cellLabel = hiCreateLabel(
25?name 'cellLabel
26?labelText "Cell"
27?justification 'right
28)
29
30cellStringField = hiCreateStringField(
31?name 'cellStringField
32)
33
34viewLabel = hiCreateLabel(
35?name 'viewLabel
36?labelText "View"
37?justification 'right
38)
39
40viewStringField = hiCreateStringField(
41?name 'viewStringField
42)
43
44topGridLayout = hiCreateGridLayout(
45'topGridLayout
46?spacing 10
47?items list(
48list(libraryLabel 'row 0 'col 0)
49list(libraryStringField 'row 0 'col 1)
50list(cellLabel 'row 1 'col 0)
51list(cellStringField 'row 1 'col 1)
52list(viewLabel 'row 2 'col 0)
53list(viewStringField 'row 2 'col 1)
54list('col_stretch 0 0)
55list('col_stretch 1 1)
56)
57)
58
59browseButton = hiCreateButton(
60?name 'browseButton
61?buttonText "Browse"
62?callback "browseLibraryCellViewCB(hiGetCurrentForm())"
63)
64
65horizontalLayout = hiCreateHorizontalBoxLayout(
66'horizontalLayout
67?frame "Top Cell Info"
68?spacing 10
69?items list(
70list(topGridLayout 'stretch 1)
71list(browseButton 'stretch 0)
72)
73)
74
75infoReportField = hiCreateReportField(
76?name 'infoReportField
77?title "Hierarchy Info"
78?headers list(
79list("Library" 100 'left 'string t)
80list("Cell" 100 'left 'string t)
81)
82)
83
84getInfoButton = hiCreateButton(
85?name 'getInfoButton
86?buttonText "Get Hierarchy Info"
87?callback "getUsedLibrariesCellsCB(hiGetCurrentForm())"
88)
89
90verticalLayout = hiCreateVerticalBoxLayout(
91'verticalLayout
92?items list(horizontalLayout infoReportField getInfoButton)
93)
94
95hiCreateLayoutForm(
96'librariesCellsInUseForm
97"Libraries Cells in Use"
98verticalLayout
99?buttonLayout 'Empty
100?mapCB 'librariesCellsInUseFormMapCB
101)
102);let
103);procedure
104
105
106procedure( librariesCellsInUseFormMapCB(form)
107
108;Map callback function for initializing the Libraries Cells In Use
109;form fields.
110
111;@param form formObject
112;The form object being instantiated.
113
114let( (cellView)
115
116hiInstantiateForm(form)
117hiSetFieldMinSize(form 'browseButton ?widgetHeight 25)
118hiSetFieldMinSize(form 'getInfoButton ?widgetHeight 35)
119
120cellView = geGetEditCellView()
121when( cellView
122form~>libraryStringField~>value = cellView~>libName
123form~>cellStringField~>value = cellView~>cellName
124form~>viewStringField~>value = cellView~>viewName
125);when
126);let
127);procedure
128
129
130procedure( libraryNameModifyCB(field scope latestTextValue sourceOfChange)
131
132;Modify callback function for validating and highlighting the library
133;name field.
134
135;@param field formField
136; The form field being modified.
137;@param scope formObject
138; The form object containing the field.
139;@param latestTextValue string
140; The latest text value entered in the field.
141;@param sourceOfChange any
142;The source of the change, indicating whether the modification
143;was user-initiated.
144;@return t boolean
145;Returns t to allow the changes made to the field.
146
147let( (libraryObject)
148when( sourceOfChange
149libraryObject = ddGetObj(latestTextValue)
150if( !libraryObject
151then
152hiHighlightField(scope field~>hiFieldSym 'error)
153else
154hiHighlightField(scope field~>hiFieldSym 'background)
155);if
156);when
157
158t
159);let
160);procedure
161
162
163procedure( browseLibraryCellViewCB(form)
164
165;Callback function for synchronizing library, cell, and view fields with
166;the form.
167
168;@param form formObject
169;The form object containing the fields to be synchronized.
170
171ddsSyncWithForm(form 'browse 'libraryStringField 'cellStringField
172'viewStringField)
173);procedure
174
175
176procedure( getUsedLibrariesCellsCB(form)
177
178;Callback function to extract and display used libraries and cells from a
179;specified cell view.
180
181;@param form formObject
182;The form object containing the input fields and report field.
183
184prog( (libName cellName viewName cellView usedLibrariesCellsTable choices)
185
186; Get input
187libName = form~>libraryStringField~>value
188cellName = form~>cellStringField~>value
189viewName = form~>viewStringField~>value
190
191; Check input
192unless( checkInput(libName cellName viewName)
193return()
194);unless
195
196; Pre-process input
197cellView = dbOpenCellViewByType(libName cellName viewName)
198
199; Run the libraries and cells extraction function
200usedLibrariesCellsTable = getLibrariesCellsUsedIn(cellView)
201
202; Post-process output
203foreach( library usedLibrariesCellsTable
204foreach( cell usedLibrariesCellsTable[library]
205choices = cons(list(library cell) choices)
206);foreach
207);foreach
208
209; Show output in a table
210form~>infoReportField~>choices = choices
211
212return(t)
213);prog
214);procedure
215
216
217procedure( checkInput(libName cellName viewName)
218
219;Validates the existence of a specified library, cell, and view
220;combination.
221
222;@param libName string
223; The name of the library to check.
224;@param cellName string
225; The name of the cell to check.
226;@param viewName string
227; The name of the view to check.
228;@return boolean
229; Returns t if the library, cell, and view exist; otherwise,
230; displays an error dialog and returns nil.
231
232prog( (viewObject)
233
234viewObject = ddGetObj(libName cellName viewName)
235unless( viewObject
236hiDisplayAppDBox(
237?name 'errorAppDBox
238?dboxBanner "*ERROR* Libraries Cells in Use"
239?dboxText "Selected library, cell or view don't exist!"
240?dialogType hicErrorDialog
241?buttonLayout 'Close
242)
243
244return()
245);unless
246
247return(t)
248);prog
249);procedure
250
251
252procedure( getLibrariesCellsUsedIn(cellView
253 @optional (usedLibrariesCellsTable nil))
254
255 ;Retrieves all libraries and cells used in the hierarchy of a given
256 ;cell view.
257
258 ;@param cellView dbObject
259 ;The cell view object from which to retrieve the hierarchy.
260
261 ;@param usedLibrariesCellsTable table
262 ;Optional. A table to keep track of used libraries and cells.
263 ;If not provided, a new table is created.
264
265 ;@return table
266 ;A table containing libraries as keys and tables of cell names as
267 ;values, representing the hierarchy.
268
269 let( (cellTable libName cellName cellObject message viewName nextCellView)
270
271 ; First initialization
272 unless( usedLibrariesCellsTable
273 usedLibrariesCellsTable = makeTable('usedLibrariesCellsTable nil)
274 cellTable = makeTable('cellTable nil)
275 cellTable[cellView~>cellName] = t
276 usedLibrariesCellsTable[cellView~>libName] = cellTable
277 );unless
278
279 foreach( instance cellView~>instHeaders
280 libName = instance~>libName
281 cellName = instance~>cellName
282 cellObject = ddGetObj(libName cellName)
283
284 if( !cellObject
285 then
286 message = strcat("[getLibrariesCellsUsedIn] " libName "/"
287 cellName " cell doesn't exist in your Library Manager")
288 warn(message)
289 else
290 ; Creates cells' table for a library
291 unless( usedLibrariesCellsTable[libName]
292 cellTable = makeTable('cellTable nil)
293 usedLibrariesCellsTable[libName] = cellTable
294 );unless
295
296 unless( usedLibrariesCellsTable[libName][cellName]
297 ; This cell is not in table yet
298 usedLibrariesCellsTable[libName][cellName] = t
299
300 ; Gets instance's cell view
301 viewName = mapViewName(instance~>viewName)
302 nextCellView = dbOpenCellViewByType(libName cellName viewName)
303 when( nextCellView
304 usedLibrariesCellsTable = getLibrariesCellsUsedIn(nextCellView
305 usedLibrariesCellsTable)
306 );when
307 );unless
308 );if
309 );foreach
310
311 usedLibrariesCellsTable
312 );let
313);procedure
314
315
316procedure( mapViewName(viewName)
317 ; Maps a view name to a common view name that includes 'instances'
318 ;for hierarchy traversal.
319
320 ;@param viewName string
321 ;The name of the view to be mapped.
322
323 ;@return string
324 ;The mapped view name.
325
326
327 if( viewName == "symbol" ; Symbol's cell view doesn't have ~>instances
328 then
329 "schematic"
330 else
331 viewName
332 );if
333);procedure