From 2758ecb94a746f3567c607ae5096a2f580d3ccd6 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 7 Dec 2025 10:31:19 +0200 Subject: [PATCH] feat: Use proper MOSFET model for SPICE conversion --- lib/circuitJsonToSpice.ts | 33 +++++++++++-------------- tests/examples/boost-converter.test.tsx | 4 +-- tests/examples/buck-converter.test.tsx | 4 +-- 3 files changed, 19 insertions(+), 22 deletions(-) diff --git a/lib/circuitJsonToSpice.ts b/lib/circuitJsonToSpice.ts index 0ca6bef..0f4b42c 100644 --- a/lib/circuitJsonToSpice.ts +++ b/lib/circuitJsonToSpice.ts @@ -6,6 +6,7 @@ import { VoltageSourceCommand } from "./spice-commands/VoltageSourceCommand" import { BJTCommand } from "./spice-commands/BJTCommand" import { DiodeCommand } from "./spice-commands/DiodeCommand" import { InductorCommand } from "./spice-commands/InductorCommand" +import { MOSFETCommand } from "./spice-commands/MOSFETCommand" import { VoltageControlledSwitchCommand } from "./spice-commands/VoltageControlledSwitchCommand" import type { AnyCircuitElement, @@ -361,33 +362,29 @@ export function circuitJsonToSpice( const sourceNode = nodeMap.get(sourcePort?.source_port_id ?? "") || "0" - const channel_type = component.channel_type + // For 3-pin MOSFETs, substrate is typically connected to source + const substrateNode = sourceNode - let positiveControl = gateNode - let negativeControl = sourceNode - if (channel_type === "p") { - positiveControl = sourceNode - negativeControl = gateNode - } + const channel_type = (component as any).channel_type ?? "n" + const mosfet_mode = (component as any).mosfet_mode ?? "enhancement" + + const modelType = `${channel_type.toUpperCase()}MOS` + const modelName = `${modelType}_${mosfet_mode.toUpperCase()}` - const modelName = "ENH_SW" if (!netlist.models.has(modelName)) { - netlist.models.set( - modelName, - `.MODEL ${modelName} SW(Ron=0.1 Roff=1e9 Vt=2.5 Vh=0.1)`, - ) + netlist.models.set(modelName, `.MODEL ${modelName} ${modelType}`) } - const switchCmd = new VoltageControlledSwitchCommand({ + const mosfetCmd = new MOSFETCommand({ name: component.name, - positiveNode: drainNode, - negativeNode: sourceNode, - positiveControl, - negativeControl, + drain: drainNode, + gate: gateNode, + source: sourceNode, + substrate: substrateNode, model: modelName, }) - spiceComponent = new SpiceComponent(component.name, switchCmd, [ + spiceComponent = new SpiceComponent(component.name, mosfetCmd, [ drainNode, gateNode, sourceNode, diff --git a/tests/examples/boost-converter.test.tsx b/tests/examples/boost-converter.test.tsx index f4c2259..93d79f1 100644 --- a/tests/examples/boost-converter.test.tsx +++ b/tests/examples/boost-converter.test.tsx @@ -17,12 +17,12 @@ test( expect(spiceString).toMatchInlineSnapshot(` "* Circuit JSON to SPICE Netlist .MODEL D D - .MODEL ENH_SW SW(Ron=0.1 Roff=1e9 Vt=2.5 Vh=0.1) + .MODEL NMOS_ENHANCEMENT NMOS LL1 N1 N2 1 DD1 N2 N3 D CC1 N3 0 10U RR1 N3 0 1K - SM1 N2 0 N4 0 ENH_SW + MM1 N2 N4 0 0 NMOS_ENHANCEMENT Vsimulation_voltage_source_0 N1 0 DC 5 Vsimulation_voltage_source_1 N4 0 PULSE(0 10 0 1n 1n 0.00068 0.001) .END" diff --git a/tests/examples/buck-converter.test.tsx b/tests/examples/buck-converter.test.tsx index 65154e8..59cfc74 100644 --- a/tests/examples/buck-converter.test.tsx +++ b/tests/examples/buck-converter.test.tsx @@ -12,9 +12,9 @@ test( expect(spiceString).toMatchInlineSnapshot(` "* Circuit JSON to SPICE Netlist - .MODEL ENH_SW SW(Ron=0.1 Roff=1e9 Vt=2.5 Vh=0.1) + .MODEL PMOS_ENHANCEMENT PMOS .MODEL D D - SM1 N2 VP_IN VP_IN N1 ENH_SW + MM1 N2 N1 VP_IN VP_IN PMOS_ENHANCEMENT DD1 0 N2 D LL1 N2 VP_OUT 10 CC1 VP_OUT 0 10U