# Analyze a Design

This tutorial shows how to create data for electrical checks by analyzing a design. Our goal here is to automate a large amount of analysis, even if our design does not contain enough information to run something like a SPICE simulation on every component.

It will cover:

• Assigning `voltage`
• Running passes on a `pcb-module`
• Calculating operating points.

## voltage

We enable analysis of our design by assign a `voltage` property to nets in our design whose voltage we know. e.g.

``````net P3V3 (mcu.vdd, ldo.vout)
property(P3V3.voltage) = tol%(3.3, 2.0)
``````

`voltage` is a Toleranced value that represents the range of voltage we expect on this net during normal operation. Defining `voltage` for nets like power rails enables many checks to run automatically.

Here's a small design setting the voltage on the two pins of a resistor and trying to run checks to check that the operating point of the resistor does not exceed its derated limits.

``````#use-added-syntax(jitx)
defpackage analysis :
import core
import jitx
import jitx/commands
import ocdb/utils/generic-components
import ocdb/utils/checks

pcb-module design :

inst r : chip-resistor(100.0)

net vdd (r.p[1])
net gnd (r.p[2])

property(vdd.voltage) = tol%(3.3, 5.0)
property(gnd.voltage) = typ(0.0)

ocdb/utils/checks/check-design(self)

set-main-module(design)
run-checks("checks.txt")
``````

When we run this design, we get a failed check prompting us to add information:

``````r is missing properties: operating-point
``````

Even through we set a `voltage` on the each net that attaches to the resistor pins:

1. The pins of the resistor do not automatically inherit the `voltage` from the nets they are attached to
2. The voltage and current across the resistor are not automatically calculated, so the `operating-point` is missing.

We use a pass named `run-final-passes` to perform these analysis operations.

## Running passes on a pcb-module

We can use passes to do many things, including performing analysis on our designs. A pass takes an `Instantiable` like a `pcb-module` definition, and returns a transformed version (see transform-module). OCDB has a standard analysis pass named `run-final-passes`. We use it to transform our design module into an analyzed module with voltages propagated from nets to pins, and `operating-point` calculated when the necessary information exists.

We call the `run-final-passes` like this:

``````val analyzed-design = ocdb/utils/generator-utils/run-final-passes(design) ; Analyze design with a pass
``````

Note that we now need to use `analyzed-design` as the main-module, so our checks will run on the new transformed version and not the pre-analyzed version. All together the design looks like this:

``````#use-added-syntax(jitx)
defpackage analysis :
import core
import jitx
import jitx/commands
import ocdb/utils/generic-components

pcb-module design :

inst r : chip-resistor(100.0)

net vdd (r.p[1])
net gnd (r.p[2])

property(gnd.voltage) = typ(0.0)
property(vdd.voltage) = tol%(3.3, 5.0)

ocdb/utils/checks/check-design(self)

val analyzed-design = ocdb/utils/generator-utils/run-final-passes(design)
set-main-module(analyzed-design)
run-checks("checks.txt")
``````

Now when we see `missing operating-point` show up, it often means we need to add a `voltage` property to another net in our design.