pcb-routing-structure
The pcb-routing-structure
is a statement for defining the geometric constraints of a single-ended topology. This may include:
- Singled-ended transmission lines, like microstrip and striplines.
- Uncoupled regions for differential pair transmission lines.
- Fanout regions for BGAs or other dense components.
Outline
pcb-routing-structure struct-name (arg1:Type1, ...) :
name = <String>
description = <String>
layer-constraints(<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-constraints(<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-constraints
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-constraits()
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:
- Required Properties:
trace-width
- Width in mm of the traces on this layer.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 unitsmm/s
.insertion-loss
- Insertion Loss per unit distance of the signals on this layer.- This property is in units of
dB/mm
- This property is assumed to be at the frequency of interest for this design.
- This property is in units of
- Optional Properties
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.neck-down
- This property allows the user to specify a special set of routing properties for the neckdown region. It comes in two forms:- Instance Form - the user must assign a NeckDown instance.
- 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:
- The default design rules for the board will be consulted for
trace-width
andclearance
- 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
andinsertion-loss
. The current default values are:velocity = 0.15e12 ; mm/s
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-constraints(Top) :
trace-width = w
clearance = w * 3.0
velocity = vel
insertion-loss = 0.008
layer-constraints(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 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-constraints(Top) :
trace-width = w-100
clearance = w-100 * clearance-mult
velocity = 0.19e12
insertion-loss = 0.008
neck-down = NeckDown(
clearance = 0.5 * clearance-mult * w-100
)
...
; Application
structure(A => B) = se-100( clearance-mult = 2.5 )
Here the neck-down
property is used to change the clearance properties of neckdown traces on the Top
layer.
Reusing Layer-Constraints Definitions
Sometimes, we would like to construct repeated layer-constraints
definitions
in the internal layers of a board, without resorting to copy/pasting code. We
have two methods for doing this.
Using RoutingStructureLayerConstraints
val my-layer-constraints = RoutingStructureLayerConstraints(
trace-width = 0.27
clearance = 0.37
velocity = 0.17e12
insertion-loss = 0.0087
neck-down = NeckDown(
trace-width = 0.1567
clearance = 0.17
velocity = 0.17e12
insertion-loss = 0.0087
)
)
pcb-routing-structure my-routing-structure :
name = "50 Ohm Single Ended"
layer-constraints(Top) = my-layer-constraints
layer-constraints(Bottom) = my-layer-constraints
Notice the syntax: after layer-constraints(Top)
we use an equals sign rather
than colon. This indicates the use of a pre-defined
RoutingStructureLayerConstraints
object. In place of my-layer-constraints
after the equals sign, we could alternately use a function call or any Stanza
expression that returns an object of this type.
Note that the definition of my-layer-constraints
here is pure Stanza code,
with no special macros. So when specifying neck-down we have to use the
ordinary constructor for NeckDown
(Option #1 above), not the NeckDown macro.
Using Generator Functions
We use the inside pcb-routing-structure
macro to define a generator that can
be called inside the pcb-routing-structure
definition.
; 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-constraints(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-constraints(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-constraints(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-constraints()
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:
layer-constraints(Top)
withtrace-width = 0.095
layer-constraints(LayerIndex(2))
withtrace-width = 0.12
layer-constraints(LayerIndex(5))
withtrace-width = 0.12
layer-constraints(LayerIndex(7))
withtrace-width = 0.12
layer-constraints(Bottom)
withtrace-width = 0.095