Index: drc_query/index.html =================================================================== --- drc_query/index.html (revision 30145) +++ drc_query/index.html (revision 30146) @@ -105,3 +105,84 @@ a check depends only on properties of the single padstack object and constants. There is only one iterator used, @, which iterates on all objects of the board. +

Rule scripts

+

+However, in some situations a DRC violation depends on two or more objects, +thus iterations need to be done on pairs (or tuplets) of objects. It is +done by: +

+

+Example 2 demonstrates a simple case of pair-wise iteration: first a list called +A is set up; it will contain all objects of the board whose type is PSTK. +Then list A is copied to B in the second let. +

+Note: the second argument of a let is always an expression. In +the first case it is more trivial: (@.type==PSTK). When this expression is +true, the last evaluated object (the current iteration with @) is appended +to the destination list (specified in the first argument). The second +let "copies" the list by expression (A). It really means: +having the iterator run on each item of A, evaluating each; they +will all be true (since they are existing objects); once an item is true, +the last evaluated object (the same that caused the expression to be true) +is appended to the left side-list B. The part that may be confusing +is this: on the left side, there's a list name, on the right side +there is an expression. Referencing a list within an expression +will always result in iteration and is always substituted by a single item +of the list. +

+Once the lists are set up, an assert is specified with an expression +that uses both A and B. This makes the query engine iterate +in nested loops for items of A and B, which means the expression +is evaluated to every possible pair of items in list A and list B. +

+Or in other words, any possible pair of padstacks on the board - including +the case of a virtual pair of the same padstack twice (since every padstack +is present on both lists). For example if the board has three padstacks +p1, p2 and p3, then A is [p1, p2, p3] and B is [p1, p2, p3] +too. The first iteration will take the first item of A and the +first item of B, so the pairing is p1 vs. p1. Avoiding such +false checks is easy by starting the assert expession by (A != B), +which will make the whole expression false for the virtual pair case. +

+Note: query has lazy evaluation so when the left side of an && if +false, the right side is not evaluated. This it makes execution more +efficient to add such simple checks that limit the number of objects or +combinations to deal with as early as possible in the expression. +

+With that, we would be checking the same pairs twice still: p1 vs. p2 +and then p2 vs. p1. The easiest way to avoid that is to consider +that each object has an unique integer ID that can be compared, which +allows us to write (A.ID > B.ID) instead od (A != B). This ensures +only 'ordered pairs' are considered, at about the same low cost of +check. +

+The left side of the && filters duplicates and self-overlaps. The +right side is the actual check: it calculates the distance of the hole +centers using the distance() builtin function and compares the result +to the expected minimum distance which is the sum of the radii of the two +holes. Since a hole is always at the origin of the padstack, the hole's +center coordinate matches the padstack's coordinate. When A.x is written +in the expression, that really means: "take the object from list A +for the current iteration and extract its x property", which for +a padstack means the x coordinate of the padstack placement. +

+When both the left side and the right side of the && evaluates to +true, that means the pair is valid and unique and the holes overlap. At +this point drc_query could already indicate the DRC violation, but it would +use the last evaulated object for indicating the location. Which means +the indication would mark only one of the two padstacks participating in the +overlap. +

+The thus keyword changes this: when the left side of thus +evaluates to true, instead of returning true, the right side is evaluated +and returned. The right side is a function call to the builtin function +mklist, which will create a new list of objects, inserting the current +iteration object from list A and list B. In other words, it's +a list of the two padstack objects participating in the overlap. When a +list-of-two-objects is returned, drc_query will automatically put the two +objects in the two offender group for marking (red and blue groups). +