Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions lib/common/fanoutBoundaryPadding.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { expectTypesMatch } from "lib/typecheck"
import { z } from "zod"
import { distance, type Distance } from "./distance"

export interface DirectionalFanoutBoundaryPadding {
top?: Distance
right?: Distance
bottom?: Distance
left?: Distance
}

/**
* Padding between the union of the fanout source pads and the shared boundary
* where fanout traces terminate. Omitted directional values are treated as
* zero.
*/
export type FanoutBoundaryPadding = Distance | DirectionalFanoutBoundaryPadding

const nonnegativeDistance = distance.refine((value) => value >= 0, {
message: "Fanout boundary padding cannot be negative",
})

export const fanoutBoundaryPadding = z.union([
nonnegativeDistance,
z.object({
top: nonnegativeDistance.optional(),
right: nonnegativeDistance.optional(),
bottom: nonnegativeDistance.optional(),
left: nonnegativeDistance.optional(),
}),
])

expectTypesMatch<FanoutBoundaryPadding, z.input<typeof fanoutBoundaryPadding>>(
true,
)
10 changes: 10 additions & 0 deletions lib/components/autoroutingphase.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { expectTypesMatch } from "lib/typecheck"
import { z } from "zod"
import {
type FanoutBoundaryPadding,
fanoutBoundaryPadding,
} from "../common/fanoutBoundaryPadding"
import {
type NinePointAnchor,
ninePointAnchor,
Expand Down Expand Up @@ -38,6 +42,11 @@ export interface AutoroutingPhaseProps extends RoutingTolerances {
* direction unconstrained.
*/
busFanoutDirections?: Record<BusName, BusFanoutDirection>
/**
* Padding between the union of the fanout source pads and the shared
* boundary where fanout traces terminate.
*/
fanoutBoundaryPadding?: FanoutBoundaryPadding
}

const busFanoutDirection = z.union([
Expand Down Expand Up @@ -65,6 +74,7 @@ export const autoroutingPhaseProps = z
connections: z.array(z.string()).optional(),
reroute: z.boolean().optional(),
busFanoutDirections: z.record(busFanoutDirection).optional(),
fanoutBoundaryPadding: fanoutBoundaryPadding.optional(),
})
.superRefine((value, ctx) => {
if (
Expand Down
14 changes: 12 additions & 2 deletions lib/components/breakout.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { distance } from "circuit-json"
import type { Distance } from "lib/common/distance"
import { distance, type Distance } from "lib/common/distance"
import {
type FanoutBoundaryPadding,
fanoutBoundaryPadding,
} from "lib/common/fanoutBoundaryPadding"
import { expectTypesMatch } from "lib/typecheck"
import { z } from "zod"
import {
Expand All @@ -21,6 +24,12 @@ export interface BreakoutProps
paddingRight?: Distance
paddingTop?: Distance
paddingBottom?: Distance
/**
* Padding between the union of the fanout source pads and the shared
* boundary where fanout traces terminate. This is independent of the
* breakout group's layout padding.
*/
fanoutBoundaryPadding?: FanoutBoundaryPadding
}

export const breakoutProps = subcircuitGroupProps.extend({
Expand All @@ -30,6 +39,7 @@ export const breakoutProps = subcircuitGroupProps.extend({
paddingRight: distance.optional(),
paddingTop: distance.optional(),
paddingBottom: distance.optional(),
fanoutBoundaryPadding: fanoutBoundaryPadding.optional(),
})

type InferredBreakoutProps = z.input<typeof breakoutProps>
Expand Down
1 change: 1 addition & 0 deletions lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,3 +139,4 @@ export * from "./platformConfig"
export * from "./projectConfig"
export * from "./utility-types/connections-and-selectors"
export * from "./common/ninePointAnchor"
export * from "./common/fanoutBoundaryPadding"
28 changes: 28 additions & 0 deletions tests/autoroutingphase.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,34 @@ test("autorouting phase accepts per-bus fanout directions", () => {
expect(autoroutingPhaseProps.parse(raw)).toEqual(raw)
})

test("autorouting phase accepts scalar fanout boundary padding", () => {
const raw = {
autorouter: "fanout",
fanoutBoundaryPadding: "0.6mm",
} satisfies AutoroutingPhaseProps

expect(autoroutingPhaseProps.parse(raw).fanoutBoundaryPadding).toBe(0.6)
})

test("autorouting phase accepts directional fanout boundary padding", () => {
const raw = {
autorouter: "fanout",
fanoutBoundaryPadding: {
top: "0.4mm",
right: 0.8,
bottom: "1.2mm",
left: 0.5,
},
} satisfies AutoroutingPhaseProps

expect(autoroutingPhaseProps.parse(raw).fanoutBoundaryPadding).toEqual({
top: 0.4,
right: 0.8,
bottom: 1.2,
left: 0.5,
})
})
Comment on lines +45 to +71

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file now contains more than one test(...) call. The rule states that a *.test.ts file may have AT MOST one test(...). The two new tests ('autorouting phase accepts scalar fanout boundary padding' and 'autorouting phase accepts directional fanout boundary padding') should be split into separate numbered files, e.g. autoroutingphase1.test.ts, autoroutingphase2.test.ts, etc., leaving at most one test per file.

Spotted by Graphite (based on custom rule: Custom rule)

Fix in Graphite


Is this helpful? React 👍 or 👎 to let us know.


test("autorouting phase accepts a single connection", () => {
const raw: AutoroutingPhaseProps = {
phaseIndex: 2,
Expand Down
30 changes: 30 additions & 0 deletions tests/breakout.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,36 @@ test("breakout and fanout elements default to the fanout autorouter", () => {
).toBe("single_layer_fanout")
})

test("breakout accepts scalar fanout boundary padding", () => {
const raw = {
fanoutBoundaryPadding: "0.6mm",
} satisfies BreakoutProps

expect(breakoutProps.parse(raw).fanoutBoundaryPadding).toBe(0.6)
})

test("breakout accepts directional fanout boundary padding", () => {
const raw = {
fanoutBoundaryPadding: {
top: "0.4mm",
right: 0.8,
bottom: "1.2mm",
},
} satisfies BreakoutProps

expect(breakoutProps.parse(raw).fanoutBoundaryPadding).toEqual({
top: 0.4,
right: 0.8,
bottom: 1.2,
})
})

test("breakout rejects negative fanout boundary padding", () => {
expect(() =>
breakoutProps.parse({ fanoutBoundaryPadding: "-0.1mm" }),
).toThrow("Fanout boundary padding cannot be negative")
})

test("should parse breakout point props", () => {
const raw: BreakoutPointProps = {
pcbX: 5,
Expand Down
Loading