circuit-json-to-spice 0.0.25 → 0.0.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,29 @@
1
+ import { test, expect } from "bun:test"
2
+ import { circuitJsonToSpice } from "lib/circuitJsonToSpice"
3
+ import switchCircuit from "./assets/switch.json"
4
+
5
+ test(
6
+ "Switch circuit",
7
+ async () => {
8
+ const circuitJson = switchCircuit as any
9
+
10
+ const spiceNetlist = circuitJsonToSpice(circuitJson)
11
+ const spiceString = spiceNetlist.toSpiceString()
12
+
13
+ expect(spiceString).toMatchInlineSnapshot(`
14
+ "* Circuit JSON to SPICE Netlist
15
+ .MODEL SW_SW1 SW(Ron=0.1 Roff=1e9 Vt=2.5 Vh=0.1)
16
+ .MODEL NPN NPN
17
+ RR_base N1 VP_BASE 10K
18
+ VCTRL_SW1 NCTRL_SW1 0 PULSE(0 5 0 1n 1n 0.0005 0.001)
19
+ SSW1 VP_BASE N2 NCTRL_SW1 0 SW_SW1
20
+ QQ1 VP_COLLECTOR N2 0 NPN
21
+ RR_collector N1 VP_COLLECTOR 300
22
+ Vsimulation_voltage_source_0 N1 0 DC 5
23
+ .PRINT TRAN V(VP_BASE) V(VP_COLLECTOR)
24
+ .tran 0.00005 0.004 UIC
25
+ .END"
26
+ `)
27
+ },
28
+ { timeout: 10000 },
29
+ )
@@ -68,14 +68,15 @@ const baseCircuit: AnyCircuitElement[] = [
68
68
  },
69
69
  ]
70
70
 
71
- test("voltage probe with source_port_id creates .PRINT statement", () => {
71
+ test("voltage probe with signal_input_source_port_id creates .PRINT statement", () => {
72
72
  const circuitJson: AnyCircuitElement[] = [
73
73
  ...baseCircuit,
74
74
  {
75
75
  type: "simulation_voltage_probe",
76
- source_port_id: "R1_p2",
76
+ simulation_voltage_probe_id: "probe1",
77
+ signal_input_source_port_id: "R1_p2",
77
78
  name: "VOUT",
78
- } as SimulationVoltageProbe,
79
+ },
79
80
  ]
80
81
 
81
82
  const netlist = circuitJsonToSpice(circuitJson)
@@ -86,14 +87,15 @@ test("voltage probe with source_port_id creates .PRINT statement", () => {
86
87
  expect(spiceString).toContain(`RR2 VOUT N2 1K`)
87
88
  })
88
89
 
89
- test("voltage probe with source_net_id creates .PRINT statement", () => {
90
+ test("voltage probe with signal_input_source_net_id creates .PRINT statement", () => {
90
91
  const circuitJson: AnyCircuitElement[] = [
91
92
  ...baseCircuit,
92
93
  {
93
94
  type: "simulation_voltage_probe",
94
- source_net_id: "net1",
95
+ simulation_voltage_probe_id: "probe1",
96
+ signal_input_source_net_id: "net1",
95
97
  name: "VOUT",
96
- } as SimulationVoltageProbe,
98
+ },
97
99
  ]
98
100
 
99
101
  const netlist = circuitJsonToSpice(circuitJson)
@@ -109,9 +111,10 @@ test("voltage probe without transient analysis does not create .PRINT statement"
109
111
  ...baseCircuit.filter((e) => e.type !== "simulation_experiment"),
110
112
  {
111
113
  type: "simulation_voltage_probe",
112
- source_port_id: "R1_p2",
114
+ simulation_voltage_probe_id: "probe1",
115
+ signal_input_source_port_id: "R1_p2",
113
116
  name: "VOUT",
114
- } as SimulationVoltageProbe,
117
+ },
115
118
  ]
116
119
 
117
120
  const netlist = circuitJsonToSpice(circuitJson)
@@ -138,14 +141,16 @@ test("voltage probe on ground node is ignored, but other probes are not", () =>
138
141
  },
139
142
  {
140
143
  type: "simulation_voltage_probe",
141
- source_port_id: "R2_p2",
144
+ simulation_voltage_probe_id: "probe_gnd",
145
+ signal_input_source_port_id: "R2_p2",
142
146
  name: "probe_gnd",
143
- } as SimulationVoltageProbe,
147
+ },
144
148
  {
145
149
  type: "simulation_voltage_probe",
146
- source_port_id: "R1_p2",
150
+ simulation_voltage_probe_id: "probe_vout",
151
+ signal_input_source_port_id: "R1_p2",
147
152
  name: "VOUT",
148
- } as SimulationVoltageProbe,
153
+ },
149
154
  ]
150
155
 
151
156
  const netlist = circuitJsonToSpice(circuitJson)
@@ -164,14 +169,16 @@ test("multiple voltage probes create single .PRINT statement", () => {
164
169
  ...baseCircuit,
165
170
  {
166
171
  type: "simulation_voltage_probe",
167
- source_port_id: "R1_p1",
172
+ simulation_voltage_probe_id: "probe_n1",
173
+ signal_input_source_port_id: "R1_p1",
168
174
  name: "N1",
169
- } as SimulationVoltageProbe,
175
+ },
170
176
  {
171
177
  type: "simulation_voltage_probe",
172
- source_port_id: "R1_p2",
178
+ simulation_voltage_probe_id: "probe_vout",
179
+ signal_input_source_port_id: "R1_p2",
173
180
  name: "VOUT",
174
- } as SimulationVoltageProbe,
181
+ },
175
182
  ]
176
183
 
177
184
  const netlist = circuitJsonToSpice(circuitJson)
@@ -339,19 +346,22 @@ test("probes with N-style names don't conflict with auto-generated names", () =>
339
346
  // Probes
340
347
  {
341
348
  type: "simulation_voltage_probe",
342
- source_port_id: "R1_p1",
349
+ simulation_voltage_probe_id: "probe_n1",
350
+ signal_input_source_port_id: "R1_p1",
343
351
  name: "N1",
344
- } as SimulationVoltageProbe,
352
+ },
345
353
  {
346
354
  type: "simulation_voltage_probe",
347
- source_port_id: "R2_p1",
355
+ simulation_voltage_probe_id: "probe_n2",
356
+ signal_input_source_port_id: "R2_p1",
348
357
  name: "N2",
349
- } as SimulationVoltageProbe,
358
+ },
350
359
  {
351
360
  type: "simulation_voltage_probe",
352
- source_port_id: "R4_p1",
361
+ simulation_voltage_probe_id: "probe_n4",
362
+ signal_input_source_port_id: "R4_p1",
353
363
  name: "N4",
354
- } as SimulationVoltageProbe,
364
+ },
355
365
  ]
356
366
 
357
367
  const netlist = circuitJsonToSpice(circuitJson)
@@ -373,3 +383,46 @@ test("probes with N-style names don't conflict with auto-generated names", () =>
373
383
  expect(spiceString).not.toContain("V(n3)")
374
384
  expect(spiceString).not.toContain("V(n5)")
375
385
  })
386
+
387
+ test("differential voltage probe creates .PRINT statement", () => {
388
+ const circuitJson: AnyCircuitElement[] = [
389
+ ...baseCircuit,
390
+ {
391
+ type: "simulation_voltage_probe",
392
+ simulation_voltage_probe_id: "probe_diff",
393
+ name: "VR1",
394
+ signal_input_source_port_id: "R1_p1",
395
+ reference_input_source_port_id: "R1_p2",
396
+ },
397
+ ]
398
+
399
+ const netlist = circuitJsonToSpice(circuitJson)
400
+ const spiceString = netlist.toSpiceString()
401
+
402
+ expect(spiceString).toContain("RR1 N2 N1 1K")
403
+ expect(spiceString).toContain("RR2 N1 N3 1K")
404
+ expect(spiceString).toContain(".PRINT TRAN V(N2,N1)")
405
+ })
406
+
407
+ test("differential voltage probe without a name creates .PRINT statement", () => {
408
+ const circuitJson: AnyCircuitElement[] = [
409
+ ...baseCircuit,
410
+ {
411
+ type: "simulation_voltage_probe",
412
+ simulation_voltage_probe_id: "probe_diff",
413
+ signal_input_source_port_id: "R1_p1",
414
+ reference_input_source_port_id: "R1_p2",
415
+ },
416
+ ]
417
+
418
+ const netlist = circuitJsonToSpice(circuitJson)
419
+ const spiceString = netlist.toSpiceString()
420
+
421
+ // No single-ended probe to name nodes, so nodes are auto-named.
422
+ // R1_p1 is floating -> N2
423
+ // R1_p2 is on net1 -> N1
424
+ // Probe is on R1_p1 and R1_p2, so V(N2,N1)
425
+ expect(spiceString).toContain("RR1 N2 N1 1K")
426
+ expect(spiceString).toContain("RR2 N1 N3 1K")
427
+ expect(spiceString).toContain(".PRINT TRAN V(N2,N1)")
428
+ })