{
  "openapi": "3.1.1",
  "info": {
    "title": "Ohmforge Logic Simulator (VCD) API",
    "version": "1.0.0",
    "summary": "Gate-level netlist + stimuli → event-driven waveforms, timing diagram, VCD and truth table.",
    "description": "Every endpoint performs the same calculation as the human page and returns inputs, result, units, assumptions, sources, warnings and computedAt. MCP endpoint: /mcp."
  },
  "servers": [
    {
      "url": "https://ohmforgelogicsimulator.usefulweb.app"
    }
  ],
  "paths": {
    "/api/v1/calculate": {
      "post": {
        "operationId": "calculate",
        "summary": "Gate-level netlist + stimuli → event-driven waveforms, timing diagram, VCD and truth table.",
        "description": "Simulate a digital circuit written as a small text netlist: gates, tri-state buffers, multiplexers, latches, D/JK/T flip-flops, counters and shift registers with propagation delays and four-valued logic (0, 1, x, z). You get a timing diagram, a timing table, a VCD file for GTKWave or PulseView, setup/hold violations and, for combinational circuits, the truth table.\n\nMethodology:\n- Event-driven simulation on integer time units: a time-ordered event queue applies driver changes, resolves each net from all its drivers (z yields, equal values agree, a conflict gives x) and re-evaluates only the elements that read a changed net. Zero-delay feedback is iterated as delta cycles (max 1000 per time step).\n- Gates follow the four-valued tables of IEEE 1364: a 0 on an AND input forces 0, a 1 on an OR input forces 1, otherwise x/z inputs give x. Tri-state buffers drive z when disabled and x when the enable is unknown.\n- Delays are inertial, as for Verilog gate primitives: a pulse shorter than the gate delay is swallowed. rise= and fall= set separate delays for transitions to 1 and to 0.\n- Flip-flops act on the 0→1 clock edge (edge=neg for 1→0); an edge through x makes the output x unless it would not change. Asynchronous RST/SET are active high. Power-up state is x unless init= is given. setup= and hold= mark a data change too close to the edge as a violation and drive x; real metastability (random resolution after a delay) is not modelled.\n- The Verilog subset is translated to the same elements: assign expressions become gates (the #delay on the gate that drives the target), always blocks with nonblocking assignments become D flip-flops whose D input is a multiplexer tree built from the if/else branches; an \"if (rst)\" branch with constant assignments becomes an asynchronous reset or set. Vectors, parameters, initial blocks and hierarchy are rejected with the line number.\n- Truth tables (combinational circuits with up to 6 inputs) simulate every input combination until the circuit settles. The VCD export follows IEEE 1364-2005 clause 18 (header, $var wire per net and per bus, $dumpvars at #0) without a $date line, so identical input gives an identical file.\n\nLogic-level simulation with fixed integer delays: no analogue behaviour, no fan-out or load-dependent delays, no real metastability. Use it to understand timing and to check logic, not to sign off a hardware design.",
        "tags": [
          "apps"
        ],
        "x-mcp-tool": "ohmforge_logic_simulator",
        "x-owner-app": "ohmforge",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OhmforgeLogicSimulatorInput"
              },
              "examples": {
                "example1": {
                  "summary": "Half adder with gate delays (XOR glitch window)",
                  "value": {
                    "netlist": "name Half adder\ninput A B\noutput S C\nxor U1 S A B delay=2\nand U2 C A B delay=1\ncount A B period=10"
                  }
                },
                "example2": {
                  "summary": "4-bit ripple counter: transient wrong counts",
                  "value": {
                    "netlist": "name 4-bit ripple counter\ntimescale 1ns\nclock CLK period=10\nconst ONE 1\ninput RST\nstim RST 0:1 3:0\ntff F0 Q0 ONE CLK RST=RST delay=2\ntff F1 Q1 ONE Q0 RST=RST edge=neg delay=2\ntff F2 Q2 ONE Q1 RST=RST edge=neg delay=2\ntff F3 Q3 ONE Q2 RST=RST edge=neg delay=2\nbus Q Q3 Q2 Q1 Q0\nduration 170"
                  }
                },
                "example3": {
                  "summary": "Synchronous counter, shift register and a setup violation",
                  "value": {
                    "netlist": "name Synchronous counter, shift register and a setup violation\nclock CLK period=20\ninput RST EN D\nstim RST 0:1 15:0\nstim EN 0:1 90:0 130:1\nstim D 0:0 25:1 69:0 105:1\ncounter C1 Q=q CLK=CLK RST=RST EN=EN width=3 CO=carry delay=1\nshiftreg S1 Q=s D=D CLK=CLK RST=RST width=4 delay=1\ndff FF1 Q=dq D=D CLK=CLK RST=RST setup=3 delay=1\nduration 200"
                  }
                },
                "example4": {
                  "summary": "Tri-state bus contention resolves to x",
                  "value": {
                    "netlist": "name Shared bus with tri-state drivers\ninput A B SELA SELB\nstim A 0:1 40:0\nstim B 0:0 20:1\nstim SELA 0:1 30:0\nstim SELB 0:0 30:1 50:1\nstim SELA 50:1\nbufif1 T1 BUS A SELA delay=1\nbufif1 T2 BUS B SELB delay=1\nduration 70"
                  }
                },
                "example5": {
                  "summary": "2-bit counter written in the Verilog subset",
                  "value": {
                    "netlist": "// 2-bit counter with enable, asynchronous reset and a decoded output\nmodule cnt2(input clk, input rst, input en, output reg q0, output reg q1, output two);\n  wire carry;\n  assign carry = q0 & en;\n  assign #1 two = q1 & ~q0;\n  always @(posedge clk or posedge rst)\n    if (rst) begin\n      q0 <= 0;\n      q1 <= 0;\n    end else begin\n      if (en) q0 <= ~q0;\n      q1 <= q1 ^ carry;\n    end\nendmodule",
                    "stimuli": "clock clk period=10\nstim rst 0:1 3:0\nstim en 0:1 50:0 70:1\nduration 100"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OhmforgeLogicSimulatorResult"
                }
              }
            }
          },
          "400": {
            "description": "Malformed JSON body.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Invalid input (see errors[]).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (see Retry-After).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tool": {
      "get": {
        "operationId": "getToolDefinition",
        "summary": "Inputs, output schema and examples for this tool",
        "responses": {
          "200": {
            "description": "Tool definition.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Problem": {
        "type": "object",
        "description": "RFC 9457 problem details. 422 responses include per-field `errors`.",
        "required": [
          "type",
          "title",
          "status",
          "detail"
        ],
        "properties": {
          "type": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "integer"
          },
          "detail": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "field",
                "message"
              ],
              "properties": {
                "field": {
                  "type": "string"
                },
                "message": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "OhmforgeLogicSimulatorInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "netlist": {
            "title": "Netlist",
            "description": "Native format or a structural Verilog subset (one module of single-bit nets: input/output/wire/reg, gate primitives, assign with & | ^ ~ ?: and #delay, always @(posedge clk [or posedge rst]) with <= and if/else; stimuli then go into the extra lines). Native format, one statement per line. Elements: TYPE NAME then nets (output first) or PIN=net, plus delay=N (or rise=/fall=), e.g. \"and U1 Y A B delay=2\", \"dff F1 Q=q D=d CLK=clk RST=r setup=3\". Types: and or nand nor xor xnor not buf bufif1 bufif0 notif1 notif0 mux2 mux4 dlatch srlatch dff jkff tff counter shiftreg. Sources: input, clock NET period=10 duty=0.5, stim NET 0:0 10:1, count A B period=10, const NET 1. Also output, bus, timescale, duration, name. # starts a comment.",
            "type": "string",
            "maxLength": 200000,
            "default": "name Half adder\ninput A B\noutput S C\nxor U1 S A B delay=2\nand U2 C A B delay=1\ncount A B period=10"
          },
          "stimuli": {
            "title": "Extra stimulus lines (optional)",
            "description": "Appended to the netlist, e.g. \"stim A 0:0 15:1 30:x\". Handy for trying other inputs on the same circuit.",
            "type": "string",
            "maxLength": 50000,
            "default": ""
          },
          "duration": {
            "title": "Duration (time units, 0 = from the netlist)",
            "description": "Integer time units of the timescale. 0 uses the netlist's duration line, the end of a count pattern, or 1.25 × the last stimulus.",
            "type": "integer",
            "minimum": 0,
            "maximum": 10000000,
            "default": 0
          },
          "signals": {
            "title": "Signals to show (optional)",
            "description": "Comma-separated net or bus names for the diagram and table; empty shows all. The VCD always contains every net.",
            "type": "string",
            "maxLength": 2000,
            "default": ""
          }
        },
        "required": []
      },
      "OhmforgeLogicSimulatorResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "schemaVersion",
          "tool",
          "computedAt",
          "inputs",
          "summary",
          "result",
          "units",
          "assumptions",
          "sources",
          "warnings",
          "presentation",
          "links"
        ],
        "properties": {
          "schemaVersion": {
            "type": "string",
            "const": "1.0"
          },
          "tool": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "id",
              "name",
              "version"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "version": {
                "type": "string"
              }
            }
          },
          "computedAt": {
            "type": "string",
            "format": "date-time"
          },
          "inputs": {
            "type": "object",
            "description": "Normalised inputs actually used, including applied defaults."
          },
          "summary": {
            "type": "string"
          },
          "result": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "name",
              "timescale",
              "duration",
              "events",
              "signals",
              "buses",
              "violations",
              "warnings",
              "truthTable",
              "vcd"
            ],
            "properties": {
              "name": {
                "type": "string"
              },
              "timescale": {
                "type": "string"
              },
              "duration": {
                "type": "integer"
              },
              "events": {
                "type": "integer"
              },
              "signals": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "name",
                    "changes"
                  ],
                  "properties": {
                    "name": {
                      "type": "string"
                    },
                    "changes": {
                      "type": "array",
                      "description": "[time, value] pairs; value is 0, 1, x or z (bus lanes: decimal or bit string).",
                      "items": {
                        "type": "array",
                        "items": {
                          "type": [
                            "integer",
                            "string"
                          ]
                        }
                      }
                    },
                    "kind": {
                      "type": "string"
                    }
                  }
                }
              },
              "buses": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "name",
                    "bits"
                  ],
                  "properties": {
                    "name": {
                      "type": "string"
                    },
                    "bits": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                }
              },
              "violations": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "t",
                    "element",
                    "kind",
                    "text"
                  ],
                  "properties": {
                    "t": {
                      "type": "integer"
                    },
                    "element": {
                      "type": "string"
                    },
                    "kind": {
                      "type": "string"
                    },
                    "text": {
                      "type": "string"
                    }
                  }
                }
              },
              "warnings": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "truthTable": {
                "type": [
                  "object",
                  "null"
                ],
                "additionalProperties": false,
                "properties": {
                  "inputs": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "outputs": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "rows": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "additionalProperties": false,
                      "properties": {
                        "index": {
                          "type": "integer"
                        },
                        "inputs": {
                          "type": "string"
                        },
                        "outputs": {
                          "type": "string"
                        }
                      }
                    }
                  },
                  "settle": {
                    "type": "array",
                    "items": {
                      "type": "integer"
                    }
                  }
                }
              },
              "vcd": {
                "type": "string",
                "description": "IEEE 1364 four-state value change dump."
              }
            }
          },
          "units": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "assumptions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "title"
              ],
              "properties": {
                "title": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "publisher": {
                  "type": "string"
                },
                "retrievedAt": {
                  "type": "string"
                },
                "note": {
                  "type": "string"
                }
              }
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "presentation": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Display blocks used by the human page (same data)."
          },
          "links": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "human",
              "api",
              "openapi",
              "methodology"
            ],
            "properties": {
              "human": {
                "type": "string",
                "format": "uri"
              },
              "api": {
                "type": "string",
                "format": "uri"
              },
              "openapi": {
                "type": "string",
                "format": "uri"
              },
              "methodology": {
                "type": "string",
                "format": "uri"
              }
            }
          }
        }
      }
    }
  }
}