1 <!DOCTYPE html PUBLIC
"-//W3C//DTD XHTML 1.0 Transitional//EN"
2 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5 <link rel=
"stylesheet" media=
"screen" type=
"text/css" href=
"./style.css" />
6 <link rel=
"stylesheet" media=
"screen" type=
"text/css" href=
"./design.css" />
7 <link rel=
"stylesheet" media=
"print" type=
"text/css" href=
"./print.css" />
9 <meta http-equiv=
"Content-Type" content=
"text/html; charset=utf-8" />
13 <h2 id=
"connectionlookup">Connection Lookup
</h2>
17 The connection lookup algorithm starts at an object and looks for any objects that touch the starting object or any object touching the starting object. This code is implemented in find.c and used throughout the code base for a variety of purposes.
21 The connection lookup process starts at an object (pins/pads only?) and searches for intersecting objects. For each object it finds, it sets a specified flag. (todo: eventually this should build a list of objects instead). These flags are used in a convoluted way to identify things that have already been found, and if the algorithm should continue looking for more objects.
25 One of the tricks that the algorithm uses to restore the state of the flags in some cases is to use ClearFlagOnAllObjects to wipe out a flag (an undoable operation), then do everything without adding operations to the Undo stack, run ClearFlagsOnAllObjects a second time (without undo), and then Undo the first one. I guess the point of this is to prevent the undo system from sucking up resources during these operations? This has led to a global variable
"User
" which has the effect of causing flag change operations to be added to the undo list. I think this is absolutely horrid. This variable needs to die. I think a better way of accomplishing this goal is by locking the undo system.
29 In a number of places, the
"andRats
" parameter is used. This indicates that rat lines should be considered when looking for overlaps. This way, you can highlight an entire net, even if all the pieces aren
't connected with copper. It
's important to preserve this functionality.
33 Objects are broken into two categories,
"layer objects
" (LO) and pins and vias (PV). The tests then get split into four categories, PV to PV, LO to PV, LO to LO, and PV to LO.
38 <h2 id=
"detailedalgorithm">Detailed Algorithm
</h2>
41 <li class=
"level1"><div class=
"li"> Initialize the lists
</div>
43 <li class=
"level1"><div class=
"li"> Add seed object
</div>
45 <li class=
"level1"><div class=
"li"> Initialize global variables
</div>
47 <li class=
"level1 node"><div class=
"li"> Search lists for new connections
</div>
49 <li class=
"level2 node"><div class=
"li"> Check the PV list for new PV connections (LookupPVConnectionsToPVList)
</div>
51 <li class=
"level3"><div class=
"li"> rsearch the pin tree calling pv_pv_callback
</div>
53 <li class=
"level3 node"><div class=
"li"> rsearch the via tree calling pv_pv_callback
</div>
55 <li class=
"level4"><div class=
"li"> check that the pvs are on intersecting layers
</div>
57 <li class=
"level4"><div class=
"li"> check that it
's not already in the list
</div>
59 <li class=
"level4"><div class=
"li"> check that they touch
</div>
61 <li class=
"level4"><div class=
"li"> check that neither is just a hole
</div>
63 <li class=
"level4"><div class=
"li"> add the new pv to the list
</div>
69 <li class=
"level2 node"><div class=
"li"> Check the PV list for new LO connections
</div>
71 <li class=
"level3"><div class=
"li"> rsearch the pad tree calling LOCtoPVpad_callback
</div>
73 <li class=
"level3 node"><div class=
"li"> For each copper layer
</div>
75 <li class=
"level4"><div class=
"li"> rsearch the line tree calling LOCtoPVline_callback
</div>
77 <li class=
"level4"><div class=
"li"> rsearch the arc tree calling LOCtoPVarc_callback
</div>
79 <li class=
"level4"><div class=
"li"> rsearch the polygon tree calling LOCtoPVpoly_callback
</div>
89 <li class=
"level1 node"><div class=
"li"> InitConnectionLookup()
</div>
91 <li class=
"level2 node"><div class=
"li"> InitComponentLookup()
</div>
93 <li class=
"level3"><div class=
"li"> Compute the number of pads on each side of the pcb
</div>
95 <li class=
"level3"><div class=
"li"> Allocate enough memory for the PadLists to hold pointers to all of them, and initialize the list structures.
</div>
99 <li class=
"level2 node"><div class=
"li"> InitLayoutLookup()
</div>
101 <li class=
"level3"><div class=
"li"> For each copper layer, allocate enough memory for each list (lines, arcs, polygons) to hold pointers to all of the objects on the layer, and initialize the list structures.
</div>
103 <li class=
"level3"><div class=
"li"> Allocate enough memory for the pin and via combined list, and initialize it.
</div>
105 <li class=
"level3"><div class=
"li"> Allocate enough memory for the rats list to hold all of the rats.
</div>
111 <li class=
"level1 node"><div class=
"li"> ListStart(type, ptr1, ptr2, ptr3)
</div>
113 <li class=
"level2"><div class=
"li"> Add the seed object to the lists.
</div>
117 <li class=
"level1 node"><div class=
"li"> DoIt(flag, bloat, AndRats, AndDraw, is_drc)
</div>
119 <li class=
"level2"><div class=
"li"> Set the global drc flag and bloat value
</div>
121 <li class=
"level2"><div class=
"li"> Update layer
"no_drc
" flags
</div>
123 <li class=
"level2 node"><div class=
"li"> Lookup connection loop:
</div>
125 <li class=
"level3"><div class=
"li"> Note that if any of the four lookup functions returns true, it will likely short-circuit the rest of the tests.
</div>
127 <li class=
"level3 node"><div class=
"li"> LookupPVConnectionsToPVList(flag)
</div>
129 <li class=
"level4"><div class=
"li"> Save our current position in the PV list
</div>
131 <li class=
"level4 node"><div class=
"li"> If our current position is not the last item in the list:
</div>
133 <li class=
"level5"><div class=
"li"> Get the current list item
</div>
135 <li class=
"level5"><div class=
"li"> Expand the bounding box by the global bloat for the search
</div>
137 <li class=
"level5 node"><div class=
"li"> Set a jump point, and do an r_search on the via tree around the current PV (pv_pv_callback)
</div>
139 <li class=
"level6"><div class=
"li"> If the vias are buried and the layers don
't intersect, return and continue the search.
</div>
141 <li class=
"level6 node"><div class=
"li"> If the new PV hasn
't been marked yet, and the new one overlaps with the current one,
</div>
143 <li class=
"level7"><div class=
"li"> If it
's just a hole (no copper annulus), throw a warning and continue the search
</div>
145 <li class=
"level7 node"><div class=
"li"> Otherwise, add the new PV to the list (add_object_to_list)
</div>
147 <li class=
"level8"><div class=
"li"> If this is a DRC and the selected flag wasn
't set, long jump back to LookupPVConnectionsToPVList
</div>
149 <li class=
"level8"><div class=
"li"> Otherwise, continue the search
</div>
157 <li class=
"level5"><div class=
"li"> If we returned via a long jump, return true (found something/want to stop lookup up objects)
</div>
159 <li class=
"level5"><div class=
"li"> Otherwise check the pin tree (repeat via tree steps)
</div>
161 <li class=
"level5"><div class=
"li"> If we returned via a long jump, return true (found something/want to stop lookup up objects)
</div>
163 <li class=
"level5"><div class=
"li"> Otherwise, keep looking through the PV list until we get to the end.
</div>
167 <li class=
"level4"><div class=
"li"> Restore the list position (why? Probably so that LookupLOConnectionsToPVList can iterate over the same group of objects)
</div>
169 <li class=
"level4"><div class=
"li"> Return false (no new objects/we want to keep looking up objects)
</div>
173 <li class=
"level3 node"><div class=
"li"> LookupLOConnectionsToPVList(flag, AndRats)
</div>
175 <li class=
"level4 node"><div class=
"li"> If our current position is not the last item in the list:
</div>
177 <li class=
"level5"><div class=
"li"> Get the current list item
</div>
179 <li class=
"level5"><div class=
"li"> Expand the bounding box by the global bloat for the search
</div>
181 <li class=
"level5 node"><div class=
"li"> Set a jump point, and do an r_search on the pad tree around the current PV (LOCtoPVpad_callback)
</div>
183 <li class=
"level6"><div class=
"li"> If the PV doesn
't intersect the pad layer (top or bottom), return false (keep looking for objects)
</div>
185 <li class=
"level6"><div class=
"li"> If we haven
't already flagged the pad, the PV and pad intersect, and the PV isn
't just a hole, add the pad to the list, and longjmp back to LookupLOConnectionToPVList
</div>
187 <li class=
"level6"><div class=
"li"> Otherwise, return
0 (keep looking for objects)
</div>
191 <li class=
"level5 node"><div class=
"li"> For each layer:
</div>
193 <li class=
"level6"><div class=
"li"> if the no_drc flag is set, skip this layer
</div>
195 <li class=
"level6 node"><div class=
"li"> Set a jump point, and do an r_search on the layer
's line tree around the via (LOCtoPVline_callback)
</div>
197 <li class=
"level7"><div class=
"li"> Repeat the pad procedure here
</div>
201 <li class=
"level6"><div class=
"li"> If we returned via long jump, return true (abort search)
</div>
203 <li class=
"level6 node"><div class=
"li"> Otherwise, set a jump point and do an r_search on the layer
's arc tree around the via (LOCtoPVarc_callback)
</div>
205 <li class=
"level7"><div class=
"li"> Repeat the pad procedure here
</div>
209 <li class=
"level6"><div class=
"li"> If we returned via long jump, return true (abort search)
</div>
211 <li class=
"level6 node"><div class=
"li"> Otherwise, set a jump point and do an r_search on the layer
's polygon tree around the via (LOCtoPVpoly_callback)
</div>
213 <li class=
"level7"><div class=
"li"> If the PV doesn
't intersect the polygon layer, return
0 (continue search)
</div>
215 <li class=
"level7 node"><div class=
"li"> If we haven
't yet flagged the polygon and the PV isn
't just a hole...
</div>
217 <li class=
"level8"><div class=
"li"> If there
's no thermal and the polygon is clearing, return
0 (continue search)
</div>
219 <li class=
"level8 node"><div class=
"li"> Otherwise...
</div>
221 <li class=
"level9"><div class=
"li"> compute the width of the search box
</div>
223 <li class=
"level9 node"><div class=
"li"> if the pv has the square flag set,
</div>
225 <li class=
"level10"><div class=
"li"> compute the corner points
</div>
227 <li class=
"level10"><div class=
"li"> if the rectangle is in the polygon (IsRectangleInPolygon) add it to the list (... ends up in add_object_to_list)
</div>
229 <li class=
"level10"><div class=
"li"> if we
're doing the drc and the object didn
't have the selected flag set, long jump back to to LookupLOConnectionToPVList
</div>
231 <li class=
"level10"><div class=
"li"> otherwise return
0 (continue search)
</div>
235 <li class=
"level9 node"><div class=
"li"> otherwise, if the pv has the octagon flag set...
</div>
237 <li class=
"level10"><div class=
"li"> create a dummy octagon polygon
</div>
239 <li class=
"level10"><div class=
"li"> if the dummy octagon and the polygon intersect (isects), add it to the list
</div>
241 <li class=
"level10"><div class=
"li"> if we
're doing the drc and the object didn
't have the selected flag set, long jump back to to LookupLOConnectionToPVList
</div>
245 <li class=
"level9 node"><div class=
"li"> otherwise, pv is round, and if intersects the polygon (IsPointInPolygon)
</div>
247 <li class=
"level10"><div class=
"li"> add it to the list
</div>
249 <li class=
"level10"><div class=
"li"> if we
're doing the drc and the object didn
't have the selected flag set, long jump back to LookupLOConnectionToPVList
</div>
257 <li class=
"level7"><div class=
"li"> return
0 (continue search)
</div>
261 <li class=
"level6"><div class=
"li"> Move on to the next layer
</div>
265 <li class=
"level5 node"><div class=
"li"> If we
're following rats, set a jump point and do an r_search on the rat tree (LOCtoPVrat_callback)
</div>
267 <li class=
"level6"><div class=
"li"> If we haven
't already found the rat, add it to the list, and long jump back to LookupLOConnectionToPVList
</div>
271 <li class=
"level5"><div class=
"li"> Increment the position in the list and check the next PV
</div>
275 <li class=
"level4"><div class=
"li"> Return false (continue search)
</div>
279 <li class=
"level3"><div class=
"li"> LookupLOConnectionsToLOList(flag, AndRats)
</div>
289 <h3 id=
"usesoftheconnectionlookupalgorithm">Uses of the Connection Lookup Algorithm
</h3>
294 <h4 id=
"drc">DRC
</h4>
298 The DRC uses the connection lookup code in combination with the
"Bloat
" and
"Shrink
" settings to detect places with insufficient spacing and overlap.
303 <h4 id=
"notifyline">NotifyLine
</h4>
312 <h4 id=
"notifymode">NotifyMode
</h4>
321 <h4 id=
"actionconnection">ActionConnection
</h4>
330 <h4 id=
"actiondisplay">ActionDisplay
</h4>
339 <h4 id=
"actionsaveto">ActionSaveTo
</h4>
348 <h4 id=
"ipcdhid">IPCD HID
</h4>
353 <h4 id=
"gtkhid">GTK HID
</h4>
362 <h4 id=
"netlistc">netlist.c
</h4>
367 <h4 id=
"reportc">report.c
</h4>
372 <h4 id=
"placesthatcalldoit">Places that call DoIt
</h4>
377 <h5 id=
"notesfrom20180810">Notes from
20180810</h5>
381 Saves list of unused pins and pads:
382 ActionSaveTo:action.c:
5752
383 LookupUnusedPins:find.c:
2464
384 PrintAndSelectUnusedPinsAndPadsOfElement:find.c:
1982
385 DoIt:find.c:
2000,
2044
389 Saves list of element connections
390 ActionSaveTo:action.c:
5752
391 LookupElementConnections:find.c:
2255
392 PrintElementConnections:find.c:
2120
393 DoIt:find.c:
2136,
2161
397 There are quite a few of these.
398 (action.c:
905,
906,
1366,
2314,
2315,
2789,
2792) LookupConnection:find.c:
2376
399 (netlist.c:
171,
180) LookupConnection:find.c:
2376
400 (report.c:
598) LookupConnection:find.c:
2376
405 (ipcd356.c:
493,
514,
538) LookupConnectionByPin:find.c:
2431
410 (gsvit.c:
433) RatFindHook:find.c:
2450
411 (lesstif/netlist.c:
140) RatFindHook:find.c:
2450
412 (gtk/gui-netlist-window.c:
543) RatFindHook:find.c:
2450
413 (rats.c:
474) RatFindHook:find.c:
2450
414 (select.c:
996) RatFindHook:find.c:
2450
419 start_do_it_and_dump:find.c:
2681