pcb-routing-structure

The pcb-routing-structure is a statement for defining the geometric constraints of a single-ended topology. This may include:

  1. Singled-ended transmission lines, like microstrip and striplines.
  2. Uncoupled regions for differential pair transmission lines.
  3. Fanout regions for BGAs or other dense components.

Outline

pcb-routing-structure struct-name (arg1:Type1, ...) :
  name = <String>
  description = <String>

  layer(<LayerIndex|Side>):
    trace-width = <Double>    ; mm
    clearance = <Double>      ; mm
    velocity =  <Double>      ; mm/s
    insertion-loss = <Double> ; dB/mm
    ; Option #1 - NeckDown Instance
    neck-down = <Neckdown>

    ; Option #2 - NeckDown Macro
    ;  Notice the `:` instead of `=`
    neck-down :
      trace-width = <Double>
      clearance = <Double>      ; mm
      velocity =  <Double>      ; mm/s
      insertion-loss = <Double> ; dB/mm

  layer(<LayerIndex|Side>):
    ...

The routing structure requires an expression name struct-name that uniquely identifies this statement within the current context.

The arguments list (arg1:Type1, ...) is optional and provides a means to parameterize routing structures for common statements.

The name and description properties are optional and are primarily for documentation and labeling purposes. The name property in particular is typically for UI applications. If a name property is not provided, then the expression name struct-name will be used.

The elements of the pcb-routing-structure statement are identified using a layer statement. Each of these layer statements must match with a conductor layer in the pcb-stackup defined for the current board design. Conceptually, the idea is to apply different properties depending on the layer.

The layer() statement takes an argument of either a Side like Top or Bottom, or a LayerIndex. See LayerIndex for more information.

At each layer specification, the user can list any of these properties:

  1. Required Properties:
    1. trace-width - Width in mm of the traces on this layer.
    2. velocity - Signal Propagation Velocity (also known as Group Velocity) of the signals on this layer. This is primarily used for timing constraints. This property is in units mm/s.
    3. insertion-loss - Insertion Loss per unit distance of the signals on this layer. This property is in units of dB/mm
  2. Optional Properties
    1. clearance - Minimum "Net to Net" clearance in mm of the traces on this layer. If not provided, then the default minimum clearances from the design rules will be used.
    2. neckdown - This property allows the user to specify a special set of routing properties for the neck down region. It comes in two forms:
      1. Instance Form - the user must assign a NeckDown instance.
      2. Macro Form - the user can provide, directly, statements for trace-width, clearance, etc like above.

If these properties are not explicitly provided in the routing structure, then either:

  1. The default design rules for the board will be consulted for trace-width and clearance
  2. If there are timing or loss constraints on this route, but no defined structure information for layers that have traces, then default values will be used for velocity and insertion-loss. The current default values are:
    1. velocity = 0.15e12 ; mm/s
    2. insertion-loss = 0.002 ; dB/mm

Usage

Here are a list of common examples:

Microstrip Example


val eps-r = 4.6
val vel = phase-velocity(eps-r)
val target-imped = 50.0 
val thickness = 0.035 ; mm
val height = 0.1; mm

; Compute an estimate of the trace width
;  for a 50 ohm impedance.
val w = ipc2141-microstrip-width(
  target-imped, eps-r, thickness, height 
)

public pcb-routing-structure se-50 :
  name = "50 Ohm Microstrip"

  layer(Top) :
    trace-width = w
    clearance = w * 3.0
    velocity = vel
    insertion-loss = 0.008

  layer(Bottom) :
    trace-width = w
    clearance = w * 3.0
    velocity = vel
    insertion-loss = 0.008

In this example, we construct a microstrip transmission line for the Top and Bottom layers.

Caution!

This routing structures does not provide parameters for any of the internal layers. If any of the routes that have this routing structure assigned to them transition to an internal layer, then the runtime will consult the default design rules for the trace width constraint.

Using Generator Functions

Some times, we would like to construct repeated definitions in the internal layers of a board. We can use a generator function to construct these internal layers without copy/pasting code.

; Generator for constructing a stripline at 75 ohm
;  on a target internal layer.
defn gen-internal-stripline (l:LayerIndex) :
  val w = 0.12
  inside pcb-routing-structure:
    layer(l):
      trace-width = w
      clearance = 3.0 * w
      velocity = 0.19e12 ; mm / s
      insertion-loss = 0.008 ; dB / mm


pcb-routing-structure se-75:
  name = "75 ohm Single-Ended"

  val ms-w = 0.095
  layer(Top):
    trace-width = ms-w
    clearance = 3.0 * ms-w
    velocity = 0.19e12
    insertion-loss = 0.008

  for sig-layer in [2, 5, 7] do:
    gen-internal-stripline(LayerIndex(sig-layer))

  layer(Bottom):
    trace-width = ms-w
    clearance = 3.0 * ms-w
    velocity = 0.19e12
    insertion-loss = 0.008

In this example, we use a generator function to construct the layer() statement for the internal layers. We then use a for-loop to construct that same structure multiple times.

The resulting pcb-routing-structure object has the following layer statements:

  1. layer(Top) with trace-width = 0.095
  2. layer(LayerIndex(2)) with trace-width = 0.12
  3. layer(LayerIndex(5)) with trace-width = 0.12
  4. layer(LayerIndex(7)) with trace-width = 0.12
  5. layer(Bottom) with trace-width = 0.095

Using NeckDown


; Define a single-ending routing structure for the 
;  uncoupled regions
public pcb-routing-structure se-100 ( -- clearance-mult:Double = 3.0 ) :
  name = "100 Ohm Microstrip"
  val w-100 = 0.1048
  layer(Top) :
    trace-width = w-100
    clearance = w-100 * clearance-mult
    velocity = 0.19e12
    insertion-loss = 0.008
    neckdown = NeckDown(
      clearance = 0.5 * clearance-mult * w-100
    )
  ...

; Application
structure(A => B) = se-100( clearance-mult = 2.5 )

Here the neckdown property is used to change the clearance properties of neckdown traces on the Top layer.