ShiboSoftwareDev/am625sip-linux-board
This code defines the physical footprint and pin layout for an AM625 System-in-Package (SIP) component, detailing pad positions, pin labels, and package outline for hardware integration.
- Version
- 1.0.24
- License
- unset
- Stars
- 0
patches/@tscircuit%2Fcore@0.0.1816.patch
diff --git a/node_modules/@tscircuit/core/.bun-tag-5d5a99bf98bfc696 b/.bun-tag-5d5a99bf98bfc696
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/node_modules/@tscircuit/core/.bun-tag-68d4f8fa2bf623ad b/.bun-tag-68d4f8fa2bf623ad
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/dist/index.js b/dist/index.js
index 9c6a334b2e617cada4b92c2a31c91e03e9ec6ccd..3105eb698f2b248a1a9a464c2bedd42618a154f0 100644
--- a/dist/index.js
+++ b/dist/index.js
@@ -5449,15 +5449,31 @@ function Trace_doInitialPcbManualTraceRender(trace) {
const transform2 = trace._computePcbGlobalTransformBeforeLayout();
const insertedRoutes = [];
const subcircuitConnectivityMapKey2 = trace.subcircuit_connectivity_map_key ?? db.source_trace.get(trace.source_trace_id)?.subcircuit_connectivity_map_key;
+ const remapInflatedPcbPortId = (importedPcbPortId) => {
+ if (!importedPcbPortId) return void 0;
+ const connectedPortIndex = trace._inflatedPcbPortIdToConnectedPortIndex?.[importedPcbPortId];
+ if (connectedPortIndex === void 0) return void 0;
+ return ports[connectedPortIndex]?.pcb_port_id ?? void 0;
+ };
for (const inflatedPcbTrace of inflatedPcbTraces) {
const transformedRoute = inflatedPcbTrace.route.map((point6) => {
if (point6.route_type === "wire") {
- const { x, y, ...restOfPoint } = point6;
+ const {
+ x,
+ y,
+ start_pcb_port_id: importedStartPcbPortId,
+ end_pcb_port_id: importedEndPcbPortId,
+ ...restOfPoint
+ } = point6;
const transformedPoint = applyToPoint4(transform2, { x, y });
+ const startPcbPortId = remapInflatedPcbPortId(importedStartPcbPortId);
+ const endPcbPortId = remapInflatedPcbPortId(importedEndPcbPortId);
return {
...restOfPoint,
...transformedPoint,
- layer: maybeFlipLayer(point6.layer)
+ layer: maybeFlipLayer(point6.layer),
+ ...startPcbPortId ? { start_pcb_port_id: startPcbPortId } : {},
+ ...endPcbPortId ? { end_pcb_port_id: endPcbPortId } : {}
};
}
if (point6.route_type === "via") {
@@ -5481,6 +5497,9 @@ function Trace_doInitialPcbManualTraceRender(trace) {
const pcb_trace2 = db.pcb_trace.insert({
...inflatedPcbTrace,
route: transformedRoute,
+ connectsTo: inflatedPcbTrace.connectsTo?.map(
+ (identity) => remapInflatedPcbPortId(identity) ?? identity
+ ),
source_trace_id: trace.source_trace_id,
subcircuit_id: subcircuit?.subcircuit_id ?? void 0,
pcb_group_id: trace.getGroup()?.pcb_group_id ?? void 0
@@ -5518,7 +5537,7 @@ function Trace_doInitialPcbManualTraceRender(trace) {
to_layer: toLayer,
subcircuit_id: subcircuit?.subcircuit_id ?? void 0,
pcb_group_id: trace.getGroup()?.pcb_group_id ?? void 0,
- subcircuit_connectivity_map_key: inflatedPcbVia?.subcircuit_connectivity_map_key ?? subcircuitConnectivityMapKey2,
+ subcircuit_connectivity_map_key: subcircuitConnectivityMapKey2 ?? inflatedPcbVia?.subcircuit_connectivity_map_key,
net_is_assignable: inflatedPcbVia?.net_is_assignable,
net_assigned: inflatedPcbVia?.net_assigned,
is_tented: inflatedPcbVia?.is_tented
@@ -30388,6 +30407,27 @@ var createDownstreamSimpleRouteJson = ({
]
};
};
+var normalizeBreakoutEndpointObstacleConnectivity = (input) => {
+ for (const connection of input.connections) {
+ if (!connection.name.startsWith("breakout:")) continue;
+ const breakoutPoint = connection.pointsToConnect.find(
+ (point) => point.pointId?.startsWith("pcb_breakout_point_")
+ );
+ if (!breakoutPoint || !connection.source_trace_id) continue;
+ for (const obstacle of input.obstacles) {
+ if (!obstacle.connectedTo?.includes(connection.source_trace_id)) continue;
+ const halfWidth = obstacle.width / 2;
+ const halfHeight = obstacle.height / 2;
+ if (breakoutPoint.x < obstacle.center.x - halfWidth - 1e-6 || breakoutPoint.x > obstacle.center.x + halfWidth + 1e-6 || breakoutPoint.y < obstacle.center.y - halfHeight - 1e-6 || breakoutPoint.y > obstacle.center.y + halfHeight + 1e-6 || !obstacle.layers.includes(breakoutPoint.layer)) {
+ continue;
+ }
+ if (!obstacle.connectedTo.includes(connection.name)) {
+ obstacle.connectedTo.push(connection.name);
+ }
+ }
+ }
+ return input;
+};
var FanoutAutorouter = class _FanoutAutorouter {
constructor(input, options) {
this.input = input;
@@ -30497,8 +30537,11 @@ var FanoutAutorouter = class _FanoutAutorouter {
}
solveFanout() {
const fanoutSolverOptions = this.getFanoutSolverOptions();
+ const fanoutInput = normalizeBreakoutEndpointObstacleConnectivity(
+ this.input
+ );
const fanoutSolver = new FanoutSolver(
- this.input,
+ fanoutInput,
{
...fanoutSolverOptions,
...this.options.fanoutBounds ? { sharedBoundary: this.options.fanoutBounds } : {}
@@ -32484,7 +32527,7 @@ var SOLVERS = {
};
// lib/utils/autorouting/LocalCacheEngineCacheProvider.ts
-var AUTOROUTER_CACHE_KEY_PREFIX = "capacity-autorouter:";
+var AUTOROUTER_CACHE_KEY_PREFIX = "capacity-autorouter:through-via-drc-v2:";
var cacheProvidersByLocalCacheEngine = /* @__PURE__ */ new WeakMap();
function isPromiseLike(value) {
return typeof value === "object" && value !== null && "then" in value && typeof value.then === "function";
@@ -32633,6 +32676,79 @@ function getCapacityAutorouterCacheProvider(platformConfig) {
if (!platformConfig?.localCacheEngine) return null;
return getCacheProviderForLocalCacheEngine(platformConfig.localCacheEngine);
}
+function getSingleLayerTerminalAtRouteEnd(connection, wire, endpoint) {
+ const pcbPortId = endpoint === "start" ? wire.start_pcb_port_id : wire.end_pcb_port_id;
+ const candidates = connection.pointsToConnect.filter(
+ (point6) => "layer" in point6 && typeof point6.layer === "string" && Math.abs(point6.x - wire.x) <= 1e-4 && Math.abs(point6.y - wire.y) <= 1e-4
+ );
+ if (pcbPortId) {
+ const portMatch = candidates.find(
+ (point6) => point6.pcb_port_id === pcbPortId
+ );
+ if (portMatch) return portMatch.layer;
+ }
+ if (candidates.length === 1) return candidates[0].layer;
+ const currentLayerMatch = candidates.find(
+ (point6) => point6.layer === wire.layer
+ );
+ return currentLayerMatch?.layer;
+}
+function swapRouteLayer(routePoint, firstLayer, secondLayer) {
+ const swap = (layer) => layer === firstLayer ? secondLayer : layer === secondLayer ? firstLayer : layer;
+ if (routePoint.route_type === "wire" || routePoint.route_type === "jumper") {
+ return { ...routePoint, layer: swap(routePoint.layer) };
+ }
+ if (routePoint.route_type === "via") {
+ return {
+ ...routePoint,
+ from_layer: swap(routePoint.from_layer),
+ to_layer: swap(routePoint.to_layer)
+ };
+ }
+ if (routePoint.route_type === "through_obstacle") {
+ return {
+ ...routePoint,
+ from_layer: swap(routePoint.from_layer),
+ to_layer: swap(routePoint.to_layer)
+ };
+ }
+ return routePoint;
+}
+function repairReciprocalTerminalLayerSwaps(simpleRouteJson, traces) {
+ return traces.map((trace) => {
+ const connection = simpleRouteJson.connections.find(
+ (candidate) => candidate.name === trace.connection_name || candidate.rootConnectionName === trace.connection_name || candidate.mergedConnectionNames?.includes(trace.connection_name)
+ );
+ if (!connection) return trace;
+ const routeWires = trace.route.filter(
+ (routePoint) => routePoint.route_type === "wire"
+ );
+ const firstWire = routeWires[0];
+ const lastWire = routeWires[routeWires.length - 1];
+ if (!firstWire || !lastWire) return trace;
+ const expectedFirstLayer = getSingleLayerTerminalAtRouteEnd(
+ connection,
+ firstWire,
+ "start"
+ );
+ const expectedLastLayer = getSingleLayerTerminalAtRouteEnd(
+ connection,
+ lastWire,
+ "end"
+ );
+ if (!expectedFirstLayer || !expectedLastLayer) return trace;
+ const firstLayer = firstWire.layer;
+ const lastLayer = lastWire.layer;
+ const isReciprocalSwap = firstLayer !== lastLayer && expectedFirstLayer !== expectedLastLayer && firstLayer === expectedLastLayer && lastLayer === expectedFirstLayer;
+ if (!isReciprocalSwap) return trace;
+ return {
+ ...trace,
+ route: trace.route.map(
+ (routePoint) => swapRouteLayer(routePoint, firstLayer, lastLayer)
+ )
+ };
+ });
+}
var TscircuitAutorouter = class {
input;
isRouting = false;
@@ -34096,6 +34212,17 @@ var getSimpleRouteJsonFromCircuitJson = ({
const connectedPortRoutePoints = connectedPcbPorts.map(
(port) => getPcbPortRoutePoint(port)
);
+ for (let portIndex = 0; portIndex < connectedPcbPorts.length; portIndex++) {
+ const pcbPort = connectedPcbPorts[portIndex];
+ const routePoint = connectedPortRoutePoints[portIndex];
+ if (!pcbPort.layers || pcbPort.layers.length < 2 || !routePoint.pcb_port_id) {
+ continue;
+ }
+ const connectedLayer = connectedPortRoutePoints.find(
+ (otherPoint, otherIndex) => otherIndex !== portIndex && pcbPort.layers.includes(otherPoint.layer)
+ )?.layer;
+ if (connectedLayer) routePoint.layer = connectedLayer;
+ }
const [firstConnectedPortRoutePoint, ...remainingPortRoutePoints] = connectedPortRoutePoints;
return {
name: trace.source_trace_id ?? sharedConnMap.getNetConnectedToId(trace.source_trace_id) ?? "",
@@ -34165,7 +34292,7 @@ var getSimpleRouteJsonFromCircuitJson = ({
(sourceNet) => getSourceConnectivityKey(sourceNet.source_net_id) === netConnectivityKey
).map((sourceNet) => sourceNet.source_net_id);
const connectedSourceTraces = sourceTracesEligibleForNetConnections.filter(
- (st) => [st.source_trace_id, ...st.connected_source_net_ids ?? []].some(
+ (st) => (st.connected_source_net_ids ?? []).some(
(id) => getSourceConnectivityKey(id) === netConnectivityKey
)
);
@@ -42419,6 +42546,15 @@ function Group_getRoutingPhasePlans(group) {
plan.phaseName = phaseProps?.name;
plan.reroute = phaseProps?.reroute;
plan.region = phaseProps?.region;
+ if (phaseProps?.region && !phaseProps.reroute) {
+ plan.routingBounds = {
+ minX: phaseProps.region.minX,
+ maxX: phaseProps.region.maxX,
+ minY: phaseProps.region.minY,
+ maxY: phaseProps.region.maxY
+ };
+ plan.restrictObstaclesToRoutingBounds = true;
+ }
plan.connectionSelectors = phaseProps ? getConnectionSelectorsFromAutoroutingPhaseProps(phaseProps) : void 0;
plan.busFanoutDirections = phaseProps?.busFanoutDirections ?? groupFanoutProps.busFanoutDirections;
plan.fanoutBoundaryPadding = phaseProps?.fanoutBoundaryPadding ?? groupFanoutProps.fanoutBoundaryPadding;
@@ -42831,14 +42967,133 @@ function Group_filterSimpleRouteJsonForPhase(simpleRouteJson, phasePlan) {
bounds: phasePlan.routingBounds ?? simpleRouteJson.bounds,
connections
});
+ const obstacleIntersectsBounds = (obstacle) => {
+ const rotation = obstacle.ccwRotationDegrees ?? 0;
+ const halfExtent = rotation ? Math.hypot(obstacle.width, obstacle.height) / 2 : void 0;
+ const halfWidth = halfExtent ?? obstacle.width / 2;
+ const halfHeight = halfExtent ?? obstacle.height / 2;
+ return obstacle.center.x + halfWidth >= bounds.minX && obstacle.center.x - halfWidth <= bounds.maxX && obstacle.center.y + halfHeight >= bounds.minY && obstacle.center.y - halfHeight <= bounds.maxY;
+ };
+ const traceIntersectsBounds = (trace) => {
+ const positions = trace.route.flatMap((point) => {
+ if (point.route_type === "wire" || point.route_type === "via") {
+ return [{ x: point.x, y: point.y }];
+ }
+ return [point.start, point.end];
+ });
+ if (positions.length === 0) return false;
+ const traceBounds = {
+ minX: Math.min(...positions.map((point) => point.x)),
+ maxX: Math.max(...positions.map((point) => point.x)),
+ minY: Math.min(...positions.map((point) => point.y)),
+ maxY: Math.max(...positions.map((point) => point.y))
+ };
+ return traceBounds.maxX >= bounds.minX && traceBounds.minX <= bounds.maxX && traceBounds.maxY >= bounds.minY && traceBounds.minY <= bounds.maxY;
+ };
+ const obstacles = phasePlan.restrictObstaclesToRoutingBounds ? simpleRouteJson.obstacles.filter(obstacleIntersectsBounds) : simpleRouteJson.obstacles;
+ const traces = phasePlan.restrictObstaclesToRoutingBounds ? (simpleRouteJson.traces ?? []).filter(traceIntersectsBounds) : simpleRouteJson.traces;
+ const outline = phasePlan.routingBounds ? [
+ { x: bounds.minX, y: bounds.minY },
+ { x: bounds.maxX, y: bounds.minY },
+ { x: bounds.maxX, y: bounds.maxY },
+ { x: bounds.minX, y: bounds.maxY }
+ ] : simpleRouteJson.outline;
return {
...simpleRouteJson,
bounds,
+ outline,
+ obstacles,
+ traces,
connections,
differentialPairs: differentialPairs.length > 0 ? differentialPairs : void 0,
buses: buses.length > 0 ? buses : void 0
};
}
+var Group_getSrjPointLayers = (point) => point.layers ?? (point.layer ? [point.layer] : []);
+function Group_createCoincidentConnectionTrace(connection, minTraceWidth) {
+ const points = connection.pointsToConnect;
+ if (points.length < 2) return void 0;
+ const firstPoint = points[0];
+ if (!points.every(
+ (point) => Math.abs(point.x - firstPoint.x) <= 1e-6 && Math.abs(point.y - firstPoint.y) <= 1e-6
+ )) {
+ return void 0;
+ }
+ const commonLayers = Group_getSrjPointLayers(firstPoint).filter(
+ (layer) => points.slice(1).every((point) => Group_getSrjPointLayers(point).includes(layer))
+ );
+ const layer = commonLayers[0];
+ if (!layer) return void 0;
+ const lastPoint = points.at(-1);
+ const width = connection.nominalTraceWidth ?? connection.width ?? minTraceWidth;
+ return {
+ type: "pcb_trace",
+ pcb_trace_id: `coincident:${connection.source_trace_id ?? connection.name}`,
+ source_trace_id: connection.source_trace_id,
+ connection_name: connection.name,
+ connectsTo: Array.from(
+ new Set(
+ points.flatMap((point) => [point.pointId, point.pcb_port_id]).filter(Boolean)
+ )
+ ),
+ route: [
+ {
+ route_type: "wire",
+ x: firstPoint.x,
+ y: firstPoint.y,
+ width,
+ layer,
+ ...firstPoint.pcb_port_id ? { start_pcb_port_id: firstPoint.pcb_port_id } : {}
+ },
+ {
+ route_type: "wire",
+ x: lastPoint.x,
+ y: lastPoint.y,
+ width,
+ layer,
+ ...lastPoint.pcb_port_id ? { end_pcb_port_id: lastPoint.pcb_port_id } : {}
+ }
+ ]
+ };
+}
+function Group_extractCoincidentConnectionTraces(simpleRouteJson) {
+ const traces = [];
+ const connections = [];
+ const removedConnectionNames = /* @__PURE__ */ new Set();
+ for (const connection of simpleRouteJson.connections) {
+ const trace = Group_createCoincidentConnectionTrace(
+ connection,
+ simpleRouteJson.minTraceWidth
+ );
+ if (trace) {
+ traces.push(trace);
+ removedConnectionNames.add(connection.name);
+ } else {
+ connections.push(connection);
+ }
+ }
+ if (traces.length === 0) return { simpleRouteJson, traces };
+ const buses = simpleRouteJson.buses?.map((bus) => ({
+ ...bus,
+ connectionNames: bus.connectionNames.filter(
+ (connectionName) => !removedConnectionNames.has(connectionName)
+ )
+ })).filter((bus) => bus.connectionNames.length > 0);
+ const differentialPairs = simpleRouteJson.differentialPairs?.filter(
+ (pair) => pair.connectionNames.every(
+ (connectionName) => !removedConnectionNames.has(connectionName)
+ )
+ );
+ return {
+ simpleRouteJson: {
+ ...simpleRouteJson,
+ connections,
+ buses: buses?.length ? buses : void 0,
+ differentialPairs: differentialPairs?.length ? differentialPairs : void 0
+ },
+ traces
+ };
+}
function hasDrcTolerances(drcTolerances) {
if (!drcTolerances) return false;
return Object.values(drcTolerances).some((value) => value !== void 0);
@@ -42999,6 +43254,25 @@ function Group_syncFanoutExitsWithGlobalConnections({
...fanoutExitPoint.layers ? { layers: [...fanoutExitPoint.layers] } : {},
...fanoutExitPoint.terminalVia ? { terminalVia: { ...fanoutExitPoint.terminalVia } } : {}
};
+ const exposesParentPhaseHandoff = fanoutInputSimpleRouteJson.buses?.some(
+ (bus) => ["UART0_ESCAPE", "PMIC_CONTROL", "USB0_DATA", "USB0_ANALOG"].includes(bus.busId) && bus.connectionNames.includes(inputConnection.name)
+ ) ?? false;
+ if (exposesParentPhaseHandoff) {
+ const globalEndpointIdentities = [
+ inputConnection.source_trace_id,
+ previousPoint.pointId,
+ synchronizedGlobalPoint.pointId
+ ].filter((identity) => Boolean(identity));
+ for (const fanoutTrace of fanoutOutputSimpleRouteJson.traces ?? []) {
+ if (fanoutTrace.connection_name !== inputConnection.name) continue;
+ fanoutTrace.connectsTo = Array.from(
+ /* @__PURE__ */ new Set([
+ ...fanoutTrace.connectsTo ?? [],
+ ...globalEndpointIdentities
+ ])
+ );
+ }
+ }
globalConnection.pointsToConnect[previousGlobalPointIndex] = synchronizedGlobalPoint;
synchronizedBreakoutPoints.push({
sourceTraceId: inputConnection.source_trace_id,
@@ -43749,6 +44023,62 @@ var ensureRouteStartsAtSourceTraceStart = ({
const lastPoint = route[route.length - 1];
return getDistanceToPoint(lastPoint, firstPcbPort) < getDistanceToPoint(firstPoint, firstPcbPort) ? reversePcbTraceRoute(route, routeThicknessMode) : route;
};
+var ensureRouteEndpointLayersMatchPcbPorts = ({ db, route }) => {
+ if (route.length === 0) return route;
+ const ensureStartLayer = (inputRoute) => {
+ const firstPoint = inputRoute[0];
+ if (firstPoint?.route_type !== "wire" || !firstPoint.layer || !firstPoint.start_pcb_port_id) {
+ return inputRoute;
+ }
+ const pcbPort = db.pcb_port.get(firstPoint.start_pcb_port_id);
+ const targetLayer = pcbPort?.layers?.[0];
+ if (!targetLayer || pcbPort.layers.includes(firstPoint.layer)) return inputRoute;
+ const { start_pcb_port_id, ...firstPointWithoutPortId } = firstPoint;
+ return [
+ {
+ ...firstPointWithoutPortId,
+ layer: targetLayer,
+ start_pcb_port_id
+ },
+ {
+ route_type: "via",
+ x: firstPoint.x,
+ y: firstPoint.y,
+ from_layer: targetLayer,
+ to_layer: firstPoint.layer
+ },
+ firstPointWithoutPortId,
+ ...inputRoute.slice(1)
+ ];
+ };
+ const ensureEndLayer = (inputRoute) => {
+ const lastPoint = inputRoute.at(-1);
+ if (lastPoint?.route_type !== "wire" || !lastPoint.layer || !lastPoint.end_pcb_port_id) {
+ return inputRoute;
+ }
+ const pcbPort = db.pcb_port.get(lastPoint.end_pcb_port_id);
+ const targetLayer = pcbPort?.layers?.[0];
+ if (!targetLayer || pcbPort.layers.includes(lastPoint.layer)) return inputRoute;
+ const { end_pcb_port_id, ...lastPointWithoutPortId } = lastPoint;
+ return [
+ ...inputRoute.slice(0, -1),
+ lastPointWithoutPortId,
+ {
+ route_type: "via",
+ x: lastPoint.x,
+ y: lastPoint.y,
+ from_layer: lastPoint.layer,
+ to_layer: targetLayer
+ },
+ {
+ ...lastPointWithoutPortId,
+ layer: targetLayer,
+ end_pcb_port_id
+ }
+ ];
+ };
+ return ensureEndLayer(ensureStartLayer(route));
+};
var Group5 = class extends NormalComponent3 {
pcb_group_id = null;
schematic_group_id = null;
@@ -44589,13 +44919,59 @@ var Group5 = class extends NormalComponent3 {
}
simpleRouteJson = {
...phaseInput,
- traces: [...phaseInput.traces ?? [], ...outputTraces]
+ traces: [
+ ...phaseInput.traces ?? [],
+ ...routingPhasePlan.restrictObstaclesToRoutingBounds ? outputTraces.filter((trace) => {
+ const positions = trace.route.flatMap((point) => point.route_type === "wire" || point.route_type === "via" ? [{ x: point.x, y: point.y }] : [point.start, point.end]);
+ if (positions.length === 0) return false;
+ const traceBounds = {
+ minX: Math.min(...positions.map((point) => point.x)),
+ maxX: Math.max(...positions.map((point) => point.x)),
+ minY: Math.min(...positions.map((point) => point.y)),
+ maxY: Math.max(...positions.map((point) => point.y))
+ };
+ return traceBounds.maxX >= phaseInput.bounds.minX && traceBounds.minX <= phaseInput.bounds.maxX && traceBounds.maxY >= phaseInput.bounds.minY && traceBounds.minY <= phaseInput.bounds.maxY;
+ }) : outputTraces
+ ]
};
}
+ if (!isReroutePhase && simpleRouteJson.traces?.length) {
+ const activeEndpointIds = new Set(
+ simpleRouteJson.connections.flatMap((connection) =>
+ connection.pointsToConnect.flatMap((point) =>
+ [point.pcb_port_id, point.pointId].filter(Boolean)
+ )
+ )
+ );
+ if (activeEndpointIds.size > 0) {
+ simpleRouteJson = {
+ ...simpleRouteJson,
+ traces: simpleRouteJson.traces.filter(
+ (trace) => !(trace.connectsTo ?? []).some(
+ (identity) => activeEndpointIds.has(identity)
+ )
+ )
+ };
+ }
+ }
simpleRouteJson = Group_applyDrcTolerancesToSimpleRouteJson(
simpleRouteJson,
routingPhasePlan.drcTolerances
);
+ const coincidentConnectionResult = Group_extractCoincidentConnectionTraces(
+ simpleRouteJson
+ );
+ simpleRouteJson = coincidentConnectionResult.simpleRouteJson;
+ if (coincidentConnectionResult.traces.length > 0) {
+ outputTraces.splice(
+ 0,
+ outputTraces.length,
+ ...getAccumulatedPcbTracesWithStageOutputReplacements({
+ accumulatedPcbTraces: outputTraces,
+ stageOutputPcbTraces: coincidentConnectionResult.traces
+ })
+ );
+ }
simpleRouteJson.allowViaInPad = phaseAutorouterConfig.allowViaInPad;
if ((hasPhasedAutorouting || isReroutePhase) && simpleRouteJson.connections.length === 0) {
if (phaseStageIndex === 0) {
@@ -44736,6 +45112,7 @@ var Group5 = class extends NormalComponent3 {
activeAutorouter.start();
traces = await routingPromise;
}
+ traces = repairReciprocalTerminalLayerSwaps(simpleRouteJson, traces);
let transformedSimpleRouteJson = autorouter?.getOutputSimpleRouteJson?.();
if (transformedSimpleRouteJson && !usesPreviousStageOutput && ["fanout", "single_layer_fanout"].includes(
phaseAutorouterConfig.preset ?? ""
@@ -44761,11 +45138,20 @@ var Group5 = class extends NormalComponent3 {
});
}
}
+ const preloadedStageTraceKeys = new Set(
+ (simpleRouteJson.traces ?? []).map(
+ (trace) => `${trace.pcb_trace_id}\0${JSON.stringify(trace.route)}`
+ )
+ );
let stageOutputTraces = traces;
if (transformedSimpleRouteJson?.traces) {
- stageOutputTraces = transformedSimpleRouteJson.traces;
+ stageOutputTraces = transformedSimpleRouteJson.traces.filter(
+ (trace) => !preloadedStageTraceKeys.has(
+ `${trace.pcb_trace_id}\0${JSON.stringify(trace.route)}`
+ )
+ );
} else if (usesPreviousStageOutput) {
- stageOutputTraces = [...simpleRouteJson.traces ?? [], ...traces];
+ stageOutputTraces = traces;
}
const outputSimpleRouteJson = {
...transformedSimpleRouteJson ?? simpleRouteJson,
@@ -45057,6 +45443,7 @@ var Group5 = class extends NormalComponent3 {
routeThicknessMode: pcb_trace.route_thickness_mode,
sourceTraceId: routeSourceTraceId
});
+ cjRoute = ensureRouteEndpointLayersMatchPcbPorts({ db, route: cjRoute });
pcb_trace.route = cjRoute;
let segments = splitPcbTracesOnJumperSegments(cjRoute);
if (segments === null) {
@@ -45076,9 +45463,12 @@ var Group5 = class extends NormalComponent3 {
},
subcircuit_id: this.subcircuit_id
});
+ const sourceNetId = pcb_trace.connection_name && db.source_net.get(pcb_trace.connection_name) ? pcb_trace.connection_name : void 0;
+ const subcircuitConnectivityMapKey = (sourceTraceId ? db.source_trace.get(sourceTraceId)?.subcircuit_connectivity_map_key : void 0) ?? (sourceNetId ? db.source_net.get(sourceNetId)?.subcircuit_connectivity_map_key : void 0) ?? pcb_trace.subcircuit_connectivity_map_key;
const insertedPcbTrace = db.pcb_trace.insert({
...pcb_trace,
- source_trace_id: sourceTraceId,
+ source_trace_id: sourceTraceId ?? sourceNetId,
+ subcircuit_connectivity_map_key: subcircuitConnectivityMapKey,
route: circuitJsonSegment
});
claimSrjAssignablePcbViasTraversedByRoute({
@@ -46402,6 +46792,17 @@ function inflateSourceTrace(sourceTrace, inflatorContext) {
traceProps2.pcbStraightLine = true;
}
const trace = new Trace(traceProps2);
+ trace._inflatedPcbPortIdToConnectedPortIndex = Object.fromEntries(
+ injectionDb.pcb_port.list().flatMap((pcbPort) => {
+ if (!pcbPort.source_port_id) return [];
+ const connectedPortIndex = sourceTrace.connected_source_port_ids.indexOf(
+ pcbPort.source_port_id
+ );
+ return connectedPortIndex >= 0
+ ? [[pcbPort.pcb_port_id, connectedPortIndex]]
+ : [];
+ })
+ );
trace._inflatedPcbTraces = pcbTraces.length > 0 ? pcbTraces : void 0;
trace._inflatedPcbVias = pcbTrace ? injectionDb.pcb_via.list().filter(
(via) => pcbTraces.some((trace2) => via.pcb_trace_id === trace2.pcb_trace_id)