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.