Supports

Support statements are used as part of the pin assignment solver. We use supports to describe valid ways pins could be assigned.

Often supports are used to describe pin mappings on a processor (e.g. this i2c IP can have pins here or here). The support mechanism is very flexible and can be used more generally.

Syntax

The general syntax supports a pcb-bundle on a set of pins:

supports my-bundle:
  bundle.pin-1 => supporting-pin-1
  bundle.pin-2 => supporting-pin-2
  bundle.pin-3 => supporting-pin-3
  ...

We can later tap this support using a require statement like require something:my-bundle from supporting-inst.

More examples:

import ocdb/utils/bundles

pcb-component my-component :
  port sys : i2c
  port PA : pin[10]

  supports i2c :
    i2c.sda => sys.sda
    i2c.scl => sys.scl

  supports gpio :
    gpio.gpio => PA[0]

  supports gpio :
    option :
      gpio.gpio => PA[1]
    option :
      gpio.gpio => PA[4]

  pcb-bundle io-pin : (pin p)
  for i in 5 to 10 do:
    supports io-pin :
      io-pin.p => PA[i]

  supports uart([UART-DTR UART-RX UART-TX]) :
    require pins:io-pin[3]
    uart([UART-DTR UART-RX UART-TX]).tx => pins[0].p
    uart([UART-DTR UART-RX UART-TX]).rx => pins[1].p
    uart([UART-DTR UART-RX UART-TX]).dtr => pins[2].p

pcb-module my-module :
  inst c : my-component

  supports i2c : 
    i2c.sda => c.PA[2]
    i2c.scl => c.PA[3]

Description

  supports i2c :
    i2c.sda => sys.sda
    i2c.scl => sys.scl

This component supports i2c on the port named sys that is also of type i2c.

  supports gpio :
    gpio.gpio => PA[0]
    property(PA[0].is-gpio?) = true

Pin PA[0] of this component supports a gpio bundle. A property is-gpio? is set on this pin only if this support statement is trigged. i.e. if PA[0] is used as a gpio by the pin solver, then the property is-gpio? is set, but not otherwise.

  supports gpio :
    option :
      gpio.gpio => PA[1]
    option :
      gpio.gpio => PA[4]

Another gpio bundle is supported on pin PA[1] or PA[4], but not both.

  pcb-bundle io-pin : (pin p)
  for i in 5 to 10 do:
    supports io-pin :
      io-pin.p => PA[i]

  supports uart([UART-DTR UART-RX UART-TX]) :
    require pins:io-pin[3]
    uart([UART-DTR UART-RX UART-TX]).tx => pins[0].p
    uart([UART-DTR UART-RX UART-TX]).rx => pins[1].p
    uart([UART-DTR UART-RX UART-TX]).dtr => pins[2].p

Pins are often arbitrarily mappable, i.e. here any pin in PA[5 to 10] can support any pin of a uart interface with pins tx rx and dtr. We create a dummy bundle io-pin to support the flexibility of the mapping. Inside the supports statement for uart, we can require the three io-pin pins we need for the interface and then map them to our uart pins. The full space of possible pin assignments is captured and a valid solution will be found by the solver if any solution is possible.

pcb-module my-module :
  inst c : my-component

  supports i2c : 
    i2c.sda => c.PA[2]
    i2c.scl => c.PA[3]

Support statements can be associated with an instance's ports outside of that instance. Here we map an i2c bus to the pins of c at the module level.