Skip to content

Commit 5ee889d

Browse files
authored
Add component pin listing (#12)
* Refine component pin formatting * chore: format imports
1 parent 9334aea commit 5ee889d

File tree

4 files changed

+97
-9
lines changed

4 files changed

+97
-9
lines changed

lib/convertCircuitJsonToReadableNetlist.ts

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1+
import { su } from "@tscircuit/soup-util"
12
import type {
2-
CircuitJson,
33
AnyCircuitElement,
4+
CircuitJson,
45
SourceNet,
56
SourcePort,
67
} from "circuit-json"
7-
import { su } from "@tscircuit/soup-util"
88
import { getFullConnectivityMapFromCircuitJson } from "circuit-json-to-connectivity-map"
99
import { generateNetName } from "./generateNetName"
1010
import { getReadableNameForPin } from "./getReadableNameForPin"
@@ -120,5 +120,63 @@ export const convertCircuitJsonToReadableNetlist = (
120120
}
121121
}
122122

123+
// build map of port ids to the nets they connect to
124+
const portIdToNetNames: Record<string, string[]> = {}
125+
for (const [netId, connectedIds] of Object.entries(netMap)) {
126+
const portIds = connectedIds.filter((id) => id.startsWith("source_port"))
127+
if (portIds.length === 0) continue
128+
const net = source_nets.find((n) => connectedIds.includes(n.source_net_id))
129+
let netName = net?.name
130+
if (!netName) {
131+
netName = generateNetName({ circuitJson, connectedIds })
132+
}
133+
for (const portId of portIds) {
134+
if (!portIdToNetNames[portId]) portIdToNetNames[portId] = []
135+
portIdToNetNames[portId].push(netName)
136+
}
137+
}
138+
139+
if (source_components.length > 0) {
140+
netlist.push("")
141+
netlist.push("COMPONENT_PINS:")
142+
for (const component of source_components) {
143+
const cadComponent = su(circuitJson).cad_component.getWhere({
144+
source_component_id: component.source_component_id,
145+
})
146+
const footprint = cadComponent?.footprinter_string
147+
let header = component.name
148+
if (component.ftype === "simple_resistor") {
149+
header = `${component.name} (${component.display_resistance} ${footprint})`
150+
} else if (component.ftype === "simple_capacitor") {
151+
header = `${component.name} (${component.display_capacitance} ${footprint})`
152+
} else if (component.manufacturer_part_number) {
153+
header = `${component.name} (${component.manufacturer_part_number})`
154+
}
155+
netlist.push(header)
156+
const ports = source_ports
157+
.filter((p) => p.source_component_id === component.source_component_id)
158+
.sort((a, b) => (a.pin_number ?? 0) - (b.pin_number ?? 0))
159+
for (const port of ports) {
160+
const mainPin =
161+
port.pin_number !== undefined ? `pin${port.pin_number}` : port.name
162+
const aliases: string[] = []
163+
if (port.name && port.name !== mainPin) aliases.push(port.name)
164+
for (const hint of port.port_hints ?? []) {
165+
if (hint === String(port.pin_number)) continue
166+
if (hint !== mainPin && hint !== port.name) aliases.push(hint)
167+
}
168+
const aliasPart =
169+
aliases.length > 0
170+
? `(${Array.from(new Set(aliases)).join(", ")})`
171+
: ""
172+
const nets = portIdToNetNames[port.source_port_id] ?? []
173+
const netsPart =
174+
nets.length > 0 ? `NETS(${nets.join(", ")})` : "NOT_CONNECTED"
175+
netlist.push(`- ${mainPin}${aliasPart}: ${netsPart}`)
176+
}
177+
netlist.push("")
178+
}
179+
}
180+
123181
return netlist.join("\n")
124182
}

lib/getReadableNameForPin.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1+
import { su } from "@tscircuit/soup-util"
12
import type {
2-
CircuitJson,
33
AnyCircuitElement,
4+
CircuitJson,
45
SourceNet,
56
SourcePort,
67
} from "circuit-json"
7-
import { su } from "@tscircuit/soup-util"
88
import { scorePhrase } from "./scorePhrase"
99

1010
export const getReadableNameForPin = ({

tests/test1-basic-circuit.test.tsx

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import { renderCircuit } from "tests/fixtures/render-circuit"
1+
import { expect, it } from "bun:test"
22
import { convertCircuitJsonToReadableNetlist } from "lib/convertCircuitJsonToReadableNetlist"
3-
import { it, expect } from "bun:test"
3+
import { renderCircuit } from "tests/fixtures/render-circuit"
44

55
declare module "bun:test" {
66
interface Matchers<T = unknown> {
@@ -34,6 +34,16 @@ it("test1 should render a basic circuit", () => {
3434
NET: C1_pos
3535
- R1 pin1
3636
- C1 pin1 (+)
37+
38+
39+
COMPONENT_PINS:
40+
R1 (1kΩ 0402)
41+
- pin1(anode, pos, left): NETS(C1_pos)
42+
- pin2(cathode, neg, right): NOT_CONNECTED
43+
44+
C1 (1nF 0402)
45+
- pin1(anode, pos, left): NETS(C1_pos)
46+
- pin2(cathode, neg, right): NOT_CONNECTED
3747
"
3848
`)
3949
})

tests/test2-chip.test.tsx

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import { renderCircuit } from "tests/fixtures/render-circuit"
1+
import { expect, it } from "bun:test"
22
import { convertCircuitJsonToReadableNetlist } from "lib/convertCircuitJsonToReadableNetlist"
3-
import { it, expect } from "bun:test"
3+
import { renderCircuit } from "tests/fixtures/render-circuit"
44

55
declare module "bun:test" {
66
interface Matchers<T = unknown> {
@@ -64,6 +64,26 @@ NET: U1_SDA
6464
6565
EMPTY NET PINS:
6666
- U1 GPIO3
67-
- U1 VDD"
67+
- U1 VDD
68+
69+
COMPONENT_PINS:
70+
U1 (ATMEGA328P)
71+
- pin1(GND): NETS(GND)
72+
- pin2(AGND): NETS(GND)
73+
- pin3(GPIO1, SCL): NETS(GND)
74+
- pin4(GPIO2, SDA): NETS(U1_SDA)
75+
- pin5(GPIO3): NETS(GPIO4)
76+
- pin6(GPIO4, UART_TX): NOT_CONNECTED
77+
- pin7(GPIO5, UART_RX): NOT_CONNECTED
78+
- pin8(VDD): NETS(V5)
79+
80+
R1 (1kΩ 0402)
81+
- pin1(anode, pos, left): NETS(C1_pos)
82+
- pin2(cathode, neg, right): NETS(U1_SDA)
83+
84+
C1 (1nF 0402)
85+
- pin1(anode, pos, left): NETS(C1_pos)
86+
- pin2(cathode, neg, right): NOT_CONNECTED
87+
"
6888
`)
6989
})

0 commit comments

Comments
 (0)