Skip to content
Closed
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
23 changes: 10 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -232,10 +232,11 @@ export interface AmmeterProps<
```ts
export interface AnalogSimulationProps {
name?: string;
simulationType?: "spice_transient_analysis";
simulationType?: "spice_dc_operating_point" | "spice_transient_analysis";
duration?: number | string;
startTime?: number | string;
timePerStep?: number | string;
timeout?: number | string;
spiceEngine?: AutocompleteString<"spicey" | "ngspice">;
spiceOptions?: SpiceOptions;
graphIndependentAxes?: boolean;
Expand Down Expand Up @@ -448,6 +449,12 @@ export interface ChipPropsSU<
*/
noConnect?: readonly PinLabel[] | PinLabel[];
connections?: Connections<PinLabel>;
/**
* Treat this chip as the intentional boundary of an analog simulation.
* Defaults to false, allowing an accidentally missing SPICE model to be
* reported instead of silently omitting the chip.
*/
simulationBoundary?: boolean;
spiceModel?: SpiceModelElement;
}
```
Expand Down Expand Up @@ -718,11 +725,7 @@ export type FabricationNoteRectProps = z.input<typeof fabricationNoteRectProps>;
export interface FabricationNoteTextProps extends PcbLayoutProps {
text: string;
anchorAlignment?:
| "center"
| "top_left"
| "top_right"
| "bottom_left"
| "bottom_right";
"center" | "top_left" | "top_right" | "bottom_left" | "bottom_right";
font?: "tscircuit2024";
fontSize?: string | number;
color?: string;
Expand Down Expand Up @@ -1288,11 +1291,7 @@ export interface PcbNoteRectProps extends Omit<PcbLayoutProps, "pcbRotation"> {
export interface PcbNoteTextProps extends PcbLayoutProps {
text: string;
anchorAlignment?:
| "center"
| "top_left"
| "top_right"
| "bottom_left"
| "bottom_right";
"center" | "top_left" | "top_right" | "bottom_left" | "bottom_right";
font?: "tscircuit2024";
fontSize?: string | number;
color?: string;
Expand Down Expand Up @@ -2126,7 +2125,6 @@ export interface PlatformConfig {
```

[Source](https://github.com/tscircuit/props/blob/main/lib/platformConfig.ts)

<!-- PLATFORM_CONFIG_END -->

<!-- PROJECT_CONFIG_START -->
Expand All @@ -2150,5 +2148,4 @@ export interface ProjectConfig extends Pick<
```

[Source](https://github.com/tscircuit/props/blob/main/lib/projectConfig.ts)

<!-- PROJECT_CONFIG_END -->
8 changes: 6 additions & 2 deletions generated/COMPONENT_TYPES.md
Original file line number Diff line number Diff line change
Expand Up @@ -902,10 +902,11 @@ export const ammeterProps = commonComponentProps.extend({
```typescript
export interface AnalogSimulationProps {
name?: string
simulationType?: "spice_transient_analysis"
simulationType?: "spice_dc_operating_point" | "spice_transient_analysis"
duration?: number | string
startTime?: number | string
timePerStep?: number | string
timeout?: number | string
spiceEngine?: AutocompleteString<"spicey" | "ngspice">
spiceOptions?: SpiceOptions
graphIndependentAxes?: boolean
Expand All @@ -919,11 +920,12 @@ export interface SpiceOptions {
export const analogSimulationProps = z.object({
name: z.string().optional(),
simulationType: z
.literal("spice_transient_analysis")
.enum(["spice_dc_operating_point", "spice_transient_analysis"])
.default("spice_transient_analysis"),
duration: ms.optional(),
startTime: ms.optional(),
timePerStep: ms.optional(),
timeout: ms.optional(),
spiceEngine: spiceEngine.optional(),
spiceOptions: spiceOptions.optional(),
graphIndependentAxes: z.boolean().optional(),
Expand Down Expand Up @@ -1193,6 +1195,7 @@ export interface ChipPropsSU<
externallyConnectedPins?: string[][]
noConnect?: readonly PinLabel[] | PinLabel[]
connections?: Connections<PinLabel>
simulationBoundary?: boolean
spiceModel?: SpiceModelElement
}
/**
Expand Down Expand Up @@ -1235,6 +1238,7 @@ export const chipProps = commonComponentProps.extend({
noSchematicRepresentation: z.boolean().optional(),
noConnect: noConnectProp.optional(),
connections: connectionsProp.optional(),
simulationBoundary: z.boolean().default(false),
spiceModel: spicemodelElement.optional(),
})
```
Expand Down
19 changes: 17 additions & 2 deletions generated/PROPS_OVERVIEW.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,11 @@ export interface AmmeterProps<PinLabel extends string = string>

export interface AnalogSimulationProps {
name?: string
simulationType?: "spice_transient_analysis"
simulationType?: "spice_dc_operating_point" | "spice_transient_analysis"
duration?: number | string
startTime?: number | string
timePerStep?: number | string
timeout?: number | string
spiceEngine?: AutocompleteString<"spicey" | "ngspice">
spiceOptions?: SpiceOptions
graphIndependentAxes?: boolean
Expand Down Expand Up @@ -448,6 +449,12 @@ export interface ChipPropsSU<
*/
noConnect?: readonly PinLabel[] | PinLabel[]
connections?: Connections<PinLabel>
/**
* Treat this chip as the intentional boundary of an analog simulation.
* Defaults to false, allowing an accidentally missing SPICE model to be
* reported instead of silently omitting the chip.
*/
simulationBoundary?: boolean
spiceModel?: SpiceModelElement
}

Expand Down Expand Up @@ -2123,7 +2130,15 @@ export interface SolderJumperProps extends JumperProps {


export interface SpiceEngine {
simulate: (spiceString: string) => Promise<SpiceEngineSimulationResult>
simulate: (
spiceString: string,
options?: SpiceEngineSimulationOptions,
) => Promise<SpiceEngineSimulationResult>
}


export interface SpiceEngineSimulationOptions {
timeoutMs?: number
}


Expand Down
6 changes: 4 additions & 2 deletions lib/components/analogsimulation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ import { z } from "zod"

export interface AnalogSimulationProps {
name?: string
simulationType?: "spice_transient_analysis"
simulationType?: "spice_dc_operating_point" | "spice_transient_analysis"
duration?: number | string
startTime?: number | string
timePerStep?: number | string
timeout?: number | string
spiceEngine?: AutocompleteString<"spicey" | "ngspice">
spiceOptions?: SpiceOptions
graphIndependentAxes?: boolean
Expand All @@ -35,11 +36,12 @@ const spiceOptions = z.object({
export const analogSimulationProps = z.object({
name: z.string().optional(),
simulationType: z
.literal("spice_transient_analysis")
.enum(["spice_dc_operating_point", "spice_transient_analysis"])
.default("spice_transient_analysis"),
duration: ms.optional(),
startTime: ms.optional(),
timePerStep: ms.optional(),
timeout: ms.optional(),
spiceEngine: spiceEngine.optional(),
spiceOptions: spiceOptions.optional(),
graphIndependentAxes: z.boolean().optional(),
Expand Down
7 changes: 7 additions & 0 deletions lib/components/chip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,12 @@ export interface ChipPropsSU<
*/
noConnect?: readonly PinLabel[] | PinLabel[]
connections?: Connections<PinLabel>
/**
* Treat this chip as the intentional boundary of an analog simulation.
* Defaults to false, allowing an accidentally missing SPICE model to be
* reported instead of silently omitting the chip.
*/
simulationBoundary?: boolean
spiceModel?: SpiceModelElement
}

Expand Down Expand Up @@ -172,6 +178,7 @@ export const chipProps = commonComponentProps.extend({
noSchematicRepresentation: z.boolean().optional(),
noConnect: noConnectProp.optional(),
connections: connectionsProp.optional(),
simulationBoundary: z.boolean().default(false),
spiceModel: spicemodelElement.optional(),
})

Expand Down
9 changes: 8 additions & 1 deletion lib/platformConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,15 @@ export interface SpiceEngineSimulationResult {
simulationResultCircuitJson: CircuitJson
}

export interface SpiceEngineSimulationOptions {
timeoutMs?: number
}

export interface SpiceEngine {
simulate: (spiceString: string) => Promise<SpiceEngineSimulationResult>
simulate: (
spiceString: string,
options?: SpiceEngineSimulationOptions,
) => Promise<SpiceEngineSimulationResult>
}

export type SimpleRouteJson = any
Expand Down
14 changes: 14 additions & 0 deletions tests/analogsimulation.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,20 @@ test("analog simulation accepts time parameters", () => {
expect(parsed.timePerStep).toBe(0.001)
})

test("analog simulation accepts DC operating-point analysis and timeout", () => {
const raw: AnalogSimulationProps = {
name: "bias",
simulationType: "spice_dc_operating_point",
timeout: "2s",
}

expectTypeOf(raw).toMatchTypeOf<z.input<typeof analogSimulationProps>>()

const parsed = analogSimulationProps.parse(raw)
expect(parsed.simulationType).toBe("spice_dc_operating_point")
expect(parsed.timeout).toBe(2000)
})

test("analog simulation accepts spice engine selection", () => {
const raw: AnalogSimulationProps = {
spiceEngine: "spicey",
Expand Down
10 changes: 10 additions & 0 deletions tests/spicemodel.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,16 @@ test("chip spiceModel accepts a spicemodel element", () => {
expect(chipProps.parse(raw).spiceModel).toBe(raw.spiceModel)
})

test("chip accepts an explicit analog simulation boundary", () => {
const raw: ChipProps = {
name: "U1",
simulationBoundary: true,
}

expect(chipProps.parse(raw).simulationBoundary).toBe(true)
expect(chipProps.parse({ name: "U2" }).simulationBoundary).toBe(false)
})

test("chip spiceModel rejects plain model objects", () => {
expect(() => {
chipProps.parse({
Expand Down
Loading