Skip to content

Kinematic Tree

In JITX physical layout design, objects (pins, landpatterns, components, modules, etc.) can either be placed (given a pose and a board side) in code ("code-placed") or interactively using the graphical physical design interface. These placements are all specified with respect to the design hierarchy. Thus, a child objects placement is relative to its parent object, and these child-parent relationships form a kinematic tree which closely follows the design hierarchy. The behavior of objects with respect to when and how they move, whether independently or as a group, depends on whether they are code-placed or interactively-placed. This gives users the freedom to choose whether a component can move freely around the board during interactive layout (interactively-placed), or to have it tied to a parent object to make it easier to move a group of components in tandem.

Code Placement

Code-placed objects are objects whose placement is specified in code, using a place statement. These objects will be "fixed in place" in the board view, and their placement (relative to their parent object) cannot be changed. However, a code-placed object can still potentially move if it has a parent object which is free to move and its parent is moved. Code-placed objects are grouped together based on what they are tied to. All objects which share a common ancestor module which they are "fixed" to (i.e. every module in the ancestral chain is fixed to its parent) will be part of the same group, and they will move, rotate, flip, and switch board sides together as a group.

Frame of Reference

Poses are composed "inside-out". That means the final position of a child object's pose it determined by applying the pose transforms of its ancestors to its pose, in the order from closest to the child upwards to the top-level module's pose. Thus, the pose of a child object is specified in the "frame of reference" of its parent object, i.e. the X-axis and Y-axis for the pose may be shifted, rotated, or even flipped relative to the global X-axis and Y-axis if the parent object (or some other ancestor) is shifted, rotated, or flipped.

Board Side

The placement of objects requires specifying a board side, either Top or Bottom. This specification is the side the object should be on assuming its parent object is placed on the Top side. If the parent object is actually placed on the Bottom side, then the child object's board side will actually be the opposite of what is specified in the place statement. Thus, placing on Top should be thought of as placing the child object on the same side as its parent, and placing on Bottom should be thought of as placing on the opposite side as the object's parent.

Interactive Placement

Objects which do not have a code placement are free to move independently in the interactive physical layout. In other words, they are left detached from the kinematic tree. This means that even if their parent object is moved, rotated, flipped, or change board side, they will not be affected. This applies even if the parent is code-placed.

Proxy Placement

Control points (including single-ended control, pair control, and merge points) and non-code vias can be created interactively in the board view. These non-code-generated objects are called proxies, and they are linked to the parent component which they were created from (i.e. where the proxy was "dragged out" from). Or, if the proxy was created by dragging out from another proxy, they will share the same parent component. Proxies have the unique behavior that they will move when their parent component moves, however moving a proxy will not move its parent component. A proxy will move with its parent even if it is disconnected from its parent. See the following examples:

Proxy-only Move

Moving the proxy does not move its parent component.

Proxy Move

Moving the parent component does move the proxy.

Proxy Chain Move

Moving the parent component moves the entire chain of proxies.

Code Example

Here is some example code with a hierarchy of modules:

pcb-module module-a () :
  inst r1 : chip-resistor(50.0)
  place(r1) at loc(0.0, -2.0) on Top

  inst r2 : chip-resistor(100.0)
  place(r2) at loc(0.0, 2.0) on Top

  inst r3 : chip-resistor(200.0)

pcb-module module-b () :
  inst r4 : chip-resistor(500.0)
  place(r4) at loc(-2.0, 0.0) on Top

  inst r5 : chip-resistor(750.0)
  place(r5) at loc(2.0, 0.0) on Top

pcb-module module-c () :
  inst m1 : module-a()
  place(m1) at loc(0.0, 0.0) on Top

  inst m2 : module-b()

  inst r6 : chip-resistor(1000.0)
  place(r6) at loc(-5.0, 0.0) on Top

pcb-module top-module () :
  inst m3 : module-c()

There are 4 modules total, 3 if you exclude the top-level module which is used to instantiate the whole design. Based on the code-placements in the code, the following groups of instances will be tied together:

  • r1, r2, r6
    • r6 is tied to m3
    • r1 and r2 are tied to m1, which is in turn tied to m3
  • r4, r5
    • r4 and r5 are tied to m2

r3 is completely free to move independently. Note that r4 and r5 are not grouped with r1, r2, and r6 because m2 is not tied to m3.