{"id":20718507,"url":"https://github.com/knowm/jspice","last_synced_at":"2025-04-23T14:12:44.651Z","repository":{"id":48530922,"uuid":"85599744","full_name":"knowm/jspice","owner":"knowm","description":"JSpice is a SPICE-inspired analog circuit simulator made in Java with an emphasis on simulating memristors and analog circuits containing memristors.","archived":false,"fork":false,"pushed_at":"2021-07-21T12:14:04.000Z","size":3055,"stargazers_count":55,"open_issues_count":8,"forks_count":8,"subscribers_count":7,"default_branch":"master","last_synced_at":"2024-03-25T22:12:46.127Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/knowm.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-03-20T16:24:07.000Z","updated_at":"2024-01-22T17:58:28.000Z","dependencies_parsed_at":"2022-08-23T14:21:09.540Z","dependency_job_id":null,"html_url":"https://github.com/knowm/jspice","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/knowm%2Fjspice","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/knowm%2Fjspice/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/knowm%2Fjspice/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/knowm%2Fjspice/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/knowm","download_url":"https://codeload.github.com/knowm/jspice/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224992998,"owners_count":17403944,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-17T03:13:51.814Z","updated_at":"2024-11-17T03:13:52.697Z","avatar_url":"https://github.com/knowm.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"## Introduction\n\nJSpice is a SPICE-inspired analog circuit simulator made in Java with an emphasis on simulating memristors and analog circuits containing memristors. \n\nIn a nutshell, JSpice is very limited compared to mainstream SPICE versions and only can do the following:\n\n1. DC Operating Point Analysis\n2. DC Sweep Analysis\n3. Transient Analysis (Time response to arbitrary input waveform)\n\nJSpice was originally written at a time before any mainstream SPICE applications supported simulation of memristors, and at that point we felt it would be easier to write a custom version of SPICE in Java rather than to try to figure out how to natively integrate memristor devices into existing SPICE versions. More recently, other, more capable simulators such as Xyce, have appeared with [native support for memristors](http://knowm.org/native-memristor-device-development-in-xyce/), and we are now leveraging those tools for CMOS + memristor circuit simulations.\n\nJSpice is however still useful for rapid prototyping and serves as the simulation engine for [memristor-discovery](https://github.com/knowm/memristor-discovery). JSpice may interest you if you are interested in learning the mechanics of modified nodal analysis and your favorite programming langauge is Java. \n\n## Flow Chart of JSpice\n\nFollowing is a simplified block diagram of the main JSpice program flow. \n\n![JSpice Flow Chart ([source](http://www.ecircuitcenter.com/SpiceTopics/Overview/Overview.htm))](documentation/SPICE_flow_chart.png)  \n\n### In Words\n\n- while the simulation is not over  \n    * Formulate companion models for energy storage components, using current operating point  \n    * Newton loop :  \n        * while the convergence is not achieved  \n            - Formulate companion models for non−linear components, using current operating point  \n            - Solve for new operating point  \n        * end while   \n- end while  \n\n([source](http://dev.hypertriton.com/edacious/trunk/doc/lec.pdf))\n\nThe heart of JSpice is matrix multiplication to solve the node values.\n\n## Linear DC Operating Point Analysis\n\nThe core of any circuit simulation software is DC Operating Point Analysis. It's required for an initial solution to a Transient Analysis and also at each time step of a DC Sweep Analysis. All energy-storage components like capacitors, inductors and semiconductor charge mechanisms are ignored for this analysis. To perform a very basic DC Operating Point Analysis, the circuit Netlist needs to be loaded and parsed followed by solving linear nodal equations for voltage at each node:\n\n1. Import Netlist\n1. AC sources are zeroed out, capacitors are opened, and inductors are shorted\n1. Use Kirchhoff's current law (KCL) to determine the algebraic sum of currents at each node\n1. Using Linear Algebra, solve for the voltages at each node: G • v = i, where G is the conductance coefficients, v and i is the voltage and current at each node respectively.\n\nA computerized circuit solver like SPICE doesn't start by writing nodal equations and converting them into a matrix. An advanced technique called Modified Nodal Analysis (MNA) is used. Each device has an MNA Stamp which is directly inserted into the impedance matrix (G) and the fixed source matrix (also called the right-hand-side matrix, RHS). Each voltage node and voltage source has a row/column pair and a slot in the RHS matrix. Each device is provided with pointers to locations in the matrix that it effects. That way a device doesn't have to have knowledge of the entire circuit, just the nodes it effects.\n\nLike SPICE since version 3f5, JSpice uses MNA for Nodal Analysis, and it uses LUDecomposition to solve the systems of linear equations to determine the nodal values. For more information about MNA and MNA Stamps see the following links:\n\n1. \u003chttp://users.ecs.soton.ac.uk/mz/CctSim/contents.htm\u003e\n1. \u003chttp://www.ece.iisc.ernet.in/~dipanjan/E8_262/E8262-CAD_4+5.pdf\u003e\n1. \u003chttp://qucs.sourceforge.net/tech/technical.html\u003e\n1. \u003chttp://dev.hypertriton.com/edacious/trunk/doc/lec.pdf\u003e\n1. \u003chttp://qucs.sourceforge.net/tech/node14.html\u003e\n1. \u003chttp://users.ecs.soton.ac.uk/mz/CctSim/chap1_3.htm\u003e\n1. \u003chttp://users.ecs.soton.ac.uk/mz/CctSim/chap1_4.htm\u003e\n1. \u003chttps://www.scribd.com/document/277142543/MNA-Stamp\u003e\n\n\nThe above formulation of MNA can be applied to linear circuits only, but can extend to nonlinear. A linear circuit is an electronic circuit in which, for a sinusoidal input voltage of frequency f, any steady-state output of the circuit (the current through any component, or the voltage between any two points) is also sinusoidal with frequency f. Note that the output need not be in phase with the input.\n\nThe costs of the automatic circuit equation formulation:\n\n1. To parse the Netlist : It consists in reading and storing the Netlist. O(N).\n1. A topological analysis to build the unknowns vector: The Minimum Spanning Tree algorithm complexity is O(Nlog(N))\n1. Stamping method: Each component writes its contribution in the table equation. O(N).\n1. Matrix product: Multiplied two dense matrices costs O(N^3).\n\n### Linear DC Operating Point Analysis Examples\n\n#### I1R3 - One Current Source and Three Resistors\n\n![I1R3 Circuit Diagram](documentation/i1r3.png)  \n\n##### Code\n\nHere, the `NetlistBuilder` pattern is demonstrated.\n\n```java\npublic class DCOPI1R3 {\n\n  public static void main(String[] args) {\n\n    // run via NetlistBuilder\n    NetlistBuilder builder = new NetlistBuilder().addNetlistDCCurrent(\"a\", 1.0, \"0\", \"1\").addNetlistResistor(\"R1\", 10, \"1\", \"0\")\n        .addNetlistResistor(\"R2\", 1000, \"1\", \"2\").addNetlistResistor(\"R3\", 1000, \"2\", \"0\");\n    Netlist netlist = builder.build();\n    JSpice.simulate(netlist);\n  }\n}\n```\n\n\n##### Result\n\n```\n----nodes----\nV(1) = 9.950248756218906\nV(2) = 4.975124378109452\n----components----\nI(R1) = 0.9950248756218907\nI(R2) = 0.004975124378109454\nI(R3) = 0.004975124378109453\nI(a) = 1.0\n-------------\n```\n\n\n#### I1V1R6 -  One Current Source, One Voltage Source and Six Resistors\n\n![I1V1R6 Circuit Diagram](documentation/i1v1r6.png)  \n\n##### Code\n\nHere, the `Netlist` is created as a stand-alone class, ideal for circuit reuse.\n\n```java\npublic class DCOPI1V1R6 {\n\n  public static void main(String[] args) {\n\n    Netlist netlist = new I1V1R6();\n    JSpice.simulate(netlist);\n  }\n}\n```\n\n```java\npublic class I1V1R6 extends Netlist {\n\n  public I1V1R6() {\n\n    // build netlist, the nodes can be named anything except for ground whose node is always labeled \"0\"\n    addNetListComponent(new NetlistDCCurrent(\"a\", 0.02, \"0\", \"4\"));\n    addNetListComponent(new NetlistDCVoltage(\"x\", 10.0, \"2\", \"5\"));\n    addNetListComponent(new NetlistResistor(\"R1\", 100, \"5\", \"0\"));\n    addNetListComponent(new NetlistResistor(\"R2\", 1000, \"0\", \"3\"));\n    addNetListComponent(new NetlistResistor(\"R3\", 1000, \"2\", \"3\"));\n    addNetListComponent(new NetlistResistor(\"R4\", 100, \"1\", \"2\"));\n    addNetListComponent(new NetlistResistor(\"R5\", 1000, \"3\", \"0\"));\n    addNetListComponent(new NetlistResistor(\"R6\", 10000, \"1\", \"4\"));\n  }\n}\n```\n\n##### Result\n\n```\n----nodes----\nI(x) = 0.01250000000000003\nV(1) = 13.250000000000005\nV(2) = 11.250000000000004\nV(3) = 3.750000000000001\nV(4) = 213.25\nV(5) = 1.2500000000000029\n----components----\nI(R1) = 0.012500000000000028\nI(R2) = -0.0037500000000000007\nI(R3) = 0.007500000000000002\nI(R4) = 0.020000000000000018\nI(R5) = 0.0037500000000000007\nI(R6) = -0.02\nI(a) = 0.02\n-------------\n```\n\n## DC Sweep Analysis\n\nDC Sweep Analysis is used to calculate a circuit’s bias point over a range of values. This procedure allows you to simulate a circuit many times, sweeping the DC values within a predetermined range. You can control the source values by choosing the start and stop values and the increment for the DC range. The bias point of the circuit is calculated for each value of the sweep.   \n\nJSpice performs DC Sweep Analysis using the following process:\n\n1. The DC Operating Point is calculated using a specified start value.\n1. The value from the source is incremented and another DC Operating Point is calculated.\n1. The increment value is added again and the process continues until the stop value is reached.\n1. The result is displayed in a chart.\n\nAssumptions: Capacitors are treated as open circuits, inductors as shorts. Only DC values for voltage and current sources are used.\n\nAll energy-storage components like capacitors, inductors and semiconductor charge mechanisms are ignored for this analysis. When time-varying components are present, their long-term behavior is approximated for example, capacitors become open circuits, and inductors become short circuits.\n\n#### DC Sweep V1R4 - One Voltage Source and Four Resistors\n\n![V1R4 Circuit Diagram](documentation/v1r4.png)  \n\n##### Code\n\n```java\npublic class DCSweepV1R4 {\n\n  public static void main(String[] args) {\n\n    Netlist netlist = new V1R4();\n    netlist.setSimulationConfig(new DCSweepConfig(\"R1\", \"I(3)\", 100.0, 10000, 100));\n    JSpice.simulate(netlist);\n  }\n}\n```\n\n##### Result\n\n![V1R4 Sweep Result](documentation/DCSweepV1R4.png)  \n\n## Non-Linear DC Operating Point Analysis\n\nTo simulate real circuits containing transistors and diodes, we are interested in simulating components having arbitrary i-v relations. We use the standard Newton method, described in any numerical analysis textbook. The derivation of how the multidimensional Newton method leads to our algorithm is a bit tedious, but here is an intuitive explanation : the Newton method works by linearizing the equation around the operating point Xn, solving the linearized equation to obtain Xn+1, and iterating until convergence (being when Xn is near Xn+1; the precise definition of near involving a compromise between speed and accuracy). In circuits, we linearize the i-v characteristic around point vn : i = i(vn)+(dv/di)(v−vn). That allows us to form companion models describing the linearized component, which we can stamp. The equation is then solved for another operating point, and the cycle continues until a stable answer is found.\n\n### PN Diode Companion Model\n\n![PN Diode Companion Model ([source](http://dev.hypertriton.com/edacious/trunk/doc/lec.pdf))](documentation/PN_Diode_Model.png)  \n\n#### DCSweepV1D1 - One Voltage Source and One Diode\n\n![V1D1 Circuit Diagram](documentation/v1d1.png)  \n\n##### Code\n\n```java\npublic class DCSweepV1D1 {\n\n  public static void main(String[] args) {\n\n    Netlist netlist = new V1D1();\n    netlist.setSimulationConfig(new DCSweepConfig(\"Va\", \"I(D1)\", 0.5, .95, .005));\n    JSpice.simulate(netlist);\n  }\n}\n```\n\n##### Result\n\n![V1D1 Sweep Result](documentation/DCSweepV1D1.png)  \n\n### MOSFET NMOS Companion Model\n\n![MOSFET NMOS Companion Model ([source](http://dev.hypertriton.com/edacious/trunk/doc/lec.pdf))](documentation/NMOS_Model.png)  \n\n#### DCSweepV2NMOS1 - Two Voltage Sources and One NMOS\n\n![V2NMOS1 Circuit Diagram](documentation/v2nmos1.png)  \n\n##### Code\n\n```java\npublic class DCSweepV2NMOS1 {\n\n  public static void main(String[] args) {\n\n    // Circuit\n    Netlist netlist = new V2NMOS1();\n\n    // SweepDef\n    DCSweepConfig sweepDef1 = new DCSweepConfig(\"Vdd\", \"I(NMOS1)\", 0.0, 10.0, 0.1);\n    DCSweepConfig sweepDef2 = new DCSweepConfig(\"Vg\", \"I(NMOS1)\", 0.0, 5.0, 1.0);\n\n    // run DC sweep\n    DCSweep dcSweep = new DCSweep(netlist);\n    dcSweep.addSweepConfig(sweepDef1);\n    dcSweep.addSweepConfig(sweepDef2);\n    SimulationResult dcSweepResult = dcSweep.run(\"I(NMOS1)\");\n\n    // plot\n    SimulationPlotter.plotAll(dcSweepResult);\n\n  }\n}\n```\n\n##### Result\n\n![V2NMOS1 Sweep Result](documentation/DCSweepV2NMOS1.png)  \n\n### MOSFET PMOS Companion Model\n\n![MOSFET PMOS Companion Model ([source](http://dev.hypertriton.com/edacious/trunk/doc/lec.pdf))](documentation/PMOS_Model.png)  \n\n#### DCSweepV2PMOS1 - Two Voltage Sources and One PMOS\n\n##### Code\n\n```java\npublic class DCSweepV2PMOS1 {\n\n  public static void main(String[] args) {\n\n    // Circuit\n    Netlist netlist = new V2PMOS1();\n\n    // SweepDef\n    DCSweepConfig sweepDef1 = new DCSweepConfig(\"Vg\", \"I(PMOS1)\", -5.0, 0.0, 1.0);\n    DCSweepConfig sweepDef2 = new DCSweepConfig(\"Vdd\", \"I(PMOS1)\", -10.0, 0.0, 0.1);\n\n    // run DC sweep\n    DCSweep dcSweep = new DCSweep(netlist);\n    dcSweep.addSweepConfig(sweepDef2);\n    dcSweep.addSweepConfig(sweepDef1);\n    SimulationResult dcSweepResult = dcSweep.run(\"I(PMOS1)\");\n    System.out.println(dcSweepResult.toString());\n\n    // plot\n    SimulationPlotter.plotAll(dcSweepResult);\n  }\n}\n```\n\n##### Result\n\n![V2PMOS1 Sweep Result](documentation/DCSweepV2PMOS1.png)  \n\n\n#### CMOSInverter\n\n##### Code\n\n```java\npublic class DCSweepCMOSInverter {\n\n  public static void main(String[] args) {\n\n    Netlist netlist = new CMOSInverterCircuit();\n    netlist.setSimulationConfig(new DCSweepConfig(\"Vin\", \"V(out)\", 0, 5, .10));\n    JSpice.simulate(netlist);\n  }\n}\n```\n\n##### Result\n\n![CMOS Inverter (Vth=2.5V) Sweep Result](documentation/DCSweepCMOSInverter_Vt25.png)  \n\n![CMOS Inverter (Vth=1.5V) Sweep Result](documentation/DCSweepCMOSInverter_Vt15.png) \n\n![CMOS Inverter Transfer Curve](documentation/InverterRegions.png) \n \n\n## Transient Analysis\n\nIn Transient Analysis, also called time-domain transient analysis, JSpice computes the circuit’s response as a function of time. This analysis divides the time into segments and calculates the voltage and current levels for each given interval. Finally, the results, voltage versus time, are plotted.\n\nJSpice performs Transient Analysis using the following process:\n\nEach input cycle is divided into intervals.\nA DC Operating Point Analysis is performed for each time point in the cycle.\nThe solution for the voltage waveform at a node is determined by the value of that voltage at each time point over one complete cycle.\n\nAssumptions: DC sources have constant values; AC sources have time-dependent values. Capacitors and inductors are represented by energy storage models. Numerical integration is used to calculate the quantity of energy transfer over an interval of time.\n\nLet's see how numeric integration for a capacitor works. Knowing a function at some point in time `tn`, how could you approximate the function at a future time point `tn+1`? Here's one approach. What if you looked to the slope of the curve to tell you, at least locally, where the voltage is going? Then, simply multiply the slope by the time step `h = Δt = tn+1 - tn` and add it to the present voltage - that should get you in the neighborhood at least.\n\nThe FE formula is so intuitive, but its not the best method. Another method, the backward- Euler (BE), uses the slope at `xn+1`, rather than the one at `xn`, to predict the next voltage.\n\nOkay, we're approaching our overall goal of transforming an energy-storage component into its equivalent linear components. For example, a capacitor is transformed using a two step process:\n\nStep 1. Apply numeric integration to the current-versus-voltage relationship of a capacitor.\nStep 2. Use the result to develop a linear companion memristor well-suited for Nodal Analysis to calculate the circuit's output waveform.\n\nLong story short, given the time step size (`h`) and the voltage across the capacitor at a certain time point, the capacitor is replaced in the circuit with the following linear companion memristor consisting of a Resistor and a current source. JSpice then carries out it's nodal analysis as before.\n\n![Capacitor Model ([source](http://www.ecircuitcenter.com/SpiceTopics/Transient%20Analysis/Transient%20Analysis.htm))](documentation/Capacitor_Model.png)  \n\n### Drivers\n\nThe following time-based drivers are available: DC, Sine, Triangle, Sawtooth, Square, Pulse, Arbitrary, and Streaming Arbitrary. Most Drivers take the following arguments during creation:\n\n* Name\n* DC Offset\n* Phase\n* Amplitude\n* Frequency\n\n#### DC\n    Driver driver = new DC(\"Vdc\", 2.5);\n![DC Driver](documentation/DCDriver.png)  \n\n#### Sine\n    Driver sine = new Sine(\"Sine\", 5, Math.PI / 4, 10, 2);\n![Sine Driver](documentation/SineDriver.png)  \n\n#### Triangle\n    Driver driver = new Triangle(\"Triangle\", 5, 0.25, 10, 2);\n![Triangle Driver](documentation/TriangleDriver.png)  \n\n#### Sawtooth\n    Driver driver = new Sawtooth(\"Sawtooth\", 5, .25, 10, 2);\n![Sawtooth Driver](documentation/SawtoothDriver.png)  \n\n#### Square\n    Driver driver = new Square(\"Square\", 5, .2, 10, .5); // unit test case\n![Square Driver](documentation/SquareDriver.png)  \n\n#### Pulse\n    Driver driver = new Pulse(\"Pulse\", 5, .2, 10, .5, .10); // unit test case\n![Pulse Driver](documentation/PulseDriver.png)  \n\n#### Arbitrary\n    Driver driver = new Arbitrary(\"Arbitrary\", 0, 0, 1, 1.0, new double[] { .1, .2, .5, .6 });\n![Arbitrary Driver](documentation/ArbitraryDriver.png)  \n\n#### Arbitrary Streaming\n    Driver driver = new StreamingArbitrary(\"Arbitrary Streaming\", 0, 0, 1, 1.0, new double[] { .1, .2, .5, .6 }, new String[] { \"1\", \"0\", \"1\" });\n![Arbitrary Streaming Driver](documentation/ArbitraryStreaming.png)  \n\n\n#### CMOS Inverter with Triangle Driver\n\n![CMOS Inverter Circuit Diagram](documentation/cmos-inverter.png)  \n\n##### Code\n\n```java\npublic class TransientAnalysisCMOSInverter {\n\n  public static void main(String[] args) {\n\n    Netlist netlist = new CMOSInverterCircuit();\n    TransientConfig transientConfig = new TransientConfig(2, .05, new Triangle(\"Vin\", 2.5, 0, 2.5, 1.0));\n    netlist.setSimulationConfig(transientConfig);\n    SimulationResult simulationResult = JSpice.simulate(netlist);\n    SimulationPlotter.plot(simulationResult, \"V(in)\", \"V(out)\");\n  }\n}\n```\n\n##### Result\n\n![CMOS Inverter Transient Response](documentation/CMOSInverter.png)  \n\n\n#### RC Circuit with Square Driver\n\n![RC Circuit Diagram](documentation/rc-time-domain.png)  \n\n##### Code\n\n```java\npublic class TransientAnalysisV1R1C1 {\n\n  public static void main(String[] args) {\n\n    Netlist netlist = new V1R1C1();\n    TransientConfig transientConfig = new TransientConfig(2, .01, new Square(\"V1\", 2.5, 0, 2.5, 1.0));\n    netlist.setSimulationConfig(transientConfig);\n    SimulationResult simulationResult = JSpice.simulate(netlist);\n    SimulationPlotter.plot(simulationResult, new String[]{\"V(1)\", \"V(2)\"});\n  }\n}\n```\n\n##### Result\n\n![RC Circuit Transient Response](documentation/RC.png)  \n\n#### Half-Wave Rectifier with Sine Driver\n\n![Half-Wave Rectifier Circuit Diagram](documentation/diode-half-wave-rectifier.png)  \n\n##### Code\n\n```java\npublic class TransientAnalysisHalfWaveRectifier {\n\n  public static void main(String[] args) {\n\n    Netlist netlist = new HalfWaveRectifier();\n    TransientConfig transientConfig = new TransientConfig(.0833333333, .0002, new Sine(\"Vsrc\", 0, 0, 12, 60.0));\n    netlist.setSimulationConfig(transientConfig);\n    SimulationResult simulationResult = JSpice.simulate(netlist);\n    SimulationPlotter.plot(simulationResult, \"V(in)\", \"V(out)\");\n  }\n}\n```\n\n##### Result\n\n![Half-Wave Rectifier Circuit Transient Response](documentation/Half_Wave_Rectifier.png)  \n\n#### Pass Gate (Transmission Gate)\n\n![Pass Gate Circuit Diagram](documentation/transmission-gate.png)  \n\n##### Code\n\n```java\npublic class TransientAnalysisTransmissionGate {\n\n  public static void main(String[] args) {\n\n    Netlist netlist = new TransmissionGateCircuit();\n\n    Driver in = new Sine(\"Vin\", 0, 0, 1.0, 10.0);\n    Driver clk = new Square(\"Vclk\", 2.5, 0, 2.5, 1.0);\n    Driver clkBar = new Square(\"VclkBar\", 2.5, 0.5, 2.5, 1.0);\n\n    TransientConfig transientConfig = new TransientConfig(2, .005, in, clk, clkBar);\n    netlist.setSimulationConfig(transientConfig);\n    SimulationResult simulationResult = JSpice.simulate(netlist);\n    SimulationPlotter.plotSeparate(simulationResult, \"V(out)\", \"V(in)\", \"V(CLK)\", \"V(CLKBAR)\");\n  }\n}\n```\n\n##### Result\n\n![Pass Gate Transient Response](documentation/Trans_Pass_Gate.png)  \n\n## M-MSS Memristor Simulation\n\n### Simple Hysteresis Curves\n\n#### M-MSS Memristor Model Driven by Square Wave\n\n##### Code\n\n```java\npublic class TransientAnalysisV1MMSSMem {\n\n  public static void main(String[] args) {\n\n    Netlist netlist = new V1MMSSMem();\n    TransientConfig transientConfig = new TransientConfig(.04, .0001, new Sine(\"Vdd\", 0.0, 0, 0.5, 100.0));\n    netlist.setSimulationConfig(transientConfig);\n    SimulationResult simulationResult = JSpice.simulate(netlist);\n    SimulationPlotter.plotSeparate(simulationResult, new String[]{\"V(VDD)\", \"I(M1)\"});\n    SimulationPlotter.plotTransientInOutCurve(\"I/V Curve\", simulationResult, new String[]{\"V(VDD)\", \"I(M1)\"});\n\n  }\n}\n```\n\n##### Result\n\n![M-MSS Memristor Transient Response](documentation/Trans_MMSS.png)  \n\n\n## RS(Really Simple) Memristor Simulation\n\n### Current vs. Time\n\n#### RS Memristor Model Driven by Square Wave\n\n##### Code\n\nOption #1: `NetlistBuilder`\n\n```java\npublic class TransientAnalysisRSMem {\n\n  private final static double schottkeyAlpha = 0; // N/A\n  private final static double schottkeyBeta = 0; // N/A\n  private final static double phi = 1;\n\n  public static void main(String[] args) throws IOException, ConfigurationException {\n\n    // run via NetlistBuilder\n    NetlistBuilder builder = new NetlistBuilder().addNetlistDCVoltage(\"Vdd\", 1.0, \"VDD\", \"0\")\n        .addNetlistRSMemristor(\"M1\", schottkeyAlpha, schottkeyBeta, schottkeyAlpha, schottkeyBeta, phi, \"VDD\", \"0\")\n        .addTransientSimulationConfig(1.0E-3, 1E-5, new Sine(\"Vdd\", 0.0, 0, 1.2, 2000.0));\n    Netlist netlist = builder.build();\n    System.out.println(\"builder.getYAML() \" + builder.getYAML());\n    SimulationResult simulationResult = JSpice.simulate(netlist);\n    SimulationPlotter.plot(simulationResult, \"I(M1)\");\n  }\n}\n```\n\n##### Result\n\n![RS Memristor Transient Response](documentation/Trans_RSMem.png)\n\nBefore the simulation, a JSpice netlist, in YAML format, is printed out with `System.out.println(\"builder.getYAML() \" + builder.getYAML());`:\n\n```yaml\ncomponents:\n- type: dc_voltage\n  nodes: VDD,0\n  id: Vdd\n  voltage: 1.0\n- type: rs_mem\n  nodes: VDD,0\n  id: M1\n  schottky_forward_alpha: 0.0\n  schottky_forward_beta: 0.0\n  schottky_reverse_alpha: 0.0\n  schottky_reverse_beta: 0.0\n  phi: 1.0\nsim:\n  type: trans\n  stop_time: 0.001\n  time_step: 1.0E-5\n  drivers:\n  - type: sine\n    id: Vdd\n    dc_offset: 0.0\n    phase: 0.0\n    amplitude: 1.2\n    frequency: 2000.0\n```\n\nOption #2: run via Yml file\n\n```java\npublic class TransientAnalysisRSMem {\n\n  public static void main(String[] args) throws IOException, ConfigurationException {\n\n    SimulationResult simulationResult = JSpice.simulate(\"RSMem.yml\");\n    SimulationPlotter.plot(simulationResult, \"I(M1)\");\n  }\n}\n```\n\nOption #2: run via jar\n\n```\njava -jar jspice.jar RSMem.yml\n```\n\nIf run via the command line like this the output will be a file in the same folder as the netlist file. For this example `RSMem.yml.out`:\n\n```\nIndex   Time        I(Vdd)      V(VDD)      I(M1)       \n0   0.000010        -1.5039988203475277E-8  0.1503998802771651  1.5039988203475277E-8   \n1   0.000020        -2.984278680852828E-8   0.2984278645978257  2.984278680852828E-8    \n2   0.000030        -2.1832594377210504E-6  0.4417494632216135  2.1832594377210504E-6   \n3   0.000040        -1.3887502330681323E-5  0.5781044089220584  1.3887502330681323E-5   \n4   0.000050        -3.953072280230764E-5   0.7053423027509678  3.953072280230764E-5    \n5   0.000060        -8.134638705717506E-5   0.8214565271144263  8.134638705717506E-5    \n6   0.000070        -1.3916736454876424E-4  0.9246158913309469  1.3916736454876424E-4   \n7   0.000080        -2.1056329856917368E-4  1.0131935106024181  2.1056329856917368E-4   \n8   0.000090        -2.9129636353457367E-4  1.0857924629592235  2.9129636353457367E-4   \n9   0.000100        -3.7597536463967974E-4  1.141267819554184   3.7597536463967974E-4   \n10  0.000110        -4.5876949071941496E-4  1.1787447008744263  4.5876949071941496E-4   \n11  0.000120        -5.340592453694597E-4   1.197632074113926   5.340592453694597E-4    \n12  0.000130        -5.96941540362891E-4    1.197632074113926   5.96941540362891E-4 \n13  0.000140        -6.435530672037997E-4   1.1787447008744265  6.435530672037997E-4    \n14  0.000150        -6.712173193979965E-4   1.1412678195541843  6.712173193979965E-4    \n15  0.000160        -6.784481117009685E-4   1.0857924629592233  6.784481117009685E-4    \n16  0.000170        -6.648544422832975E-4   1.0131935106024181  6.648544422832975E-4    \n...\n94  0.000950        1.274925739669714E-4    -0.7053423027509681 -1.274925739669714E-4   \n95  0.000960        9.869419059355023E-5    -0.5781044089220596 -9.869419059355023E-5   \n96  0.000970        7.218894070585214E-5    -0.4417494632216137 -7.218894070585214E-5   \n97  0.000980        4.7345964936124135E-5   -0.2984278645978267 -4.7345964936124135E-5  \n98  0.000990        2.35071921650594E-5 -0.15039988027716694    -2.35071921650594E-5    \nEnd of JSpice Simulation\n```\n\n## SPICE Netlists\n\nJSPICE now has limited support for SPICE netlists. If you run `JSpice.simulate` and pass it a file name ending in `.cir` it will interpret it as a SPICE\nnetlist.\n\n### Caveats\n\n| Component | Notes |\n|---|---|\n| V Sine | `tdelay` and `damp factor` ignored |\n| V Pulse | `trise`, `tfall` and `tdelay` ignored |\n| .STEP | ignored |\n| .PRINT | ignored |\n| .trans | `step value` and `final time` only |\n\n### Example of running the `FF` Instruction with `.subckt` Support\n\n#### `FFXX-kTSynapse-netlist.cir`\n```\n.INCLUDE \"2-1_kTSynapse.sub\"\n\nVA A 0 DC 0 PULSE(0 .5 0 0 0 5u 10u) AC 0\nVB B 0 DC 0 PULSE(0 -.5 0 0 0 5u 10u) AC 0\n\nXX1 A B y kTSynapse2-1\n\n.model MRM5 memristor ( level=5\n+ Roff=1500 Ron=500\n+ Voff=0.27 Von=0.27\n+ Tau=0.0001 Rinit=1000 )\n\n.tran 500ns 1000us 1e-09\n\n.PRINT  tran format=raw file=AHaH2-1_pulse_test_tran.txt I(VPr1) v(Vin) v(Vmr) v(Vout) \n.END\n```\n\n#### `2-1_kTSynapse.sub`\n```\n.subckt kTSynapse2-1 A B y\nYMEMRISTOR MR1 A y MRM5\nYMEMRISTOR MR2 y B MRM5\n.ends kTSynapse2-1\n```\n\n## Run\n\n```java\nJSpice.simulate(\"FFXX-kTSynapse-netlist.cir\");\n```\n\nor\n\n```\njava -jar jspice.jar FFXX-kTSynapse-netlist.cir\n```\n\n## Continuous Integration\n\n[![Build Status](https://travis-ci.org/knowm/jspice.png?branch=master)](https://travis-ci.org/knowm/jspice.png)\n[Build History](https://travis-ci.org/knowm/jspice/builds)\n\n## Building\n\nJSpice is built with Maven, which also handles dependency management.\n\n### general\n\n    cd path/to/project\n    mvn clean package  \n    mvn javadoc:javadoc\n\n### maven-license-plugin\n\n    mvn license:check\n    mvn license:format\n    mvn license:remove\n\n### Dependency Updates\n\n    mvn versions:display-dependency-updates\n\n## TODO\n\n1. Implement for new API: initial conditions, DC Sweep orthogonal config\n1. DC Op and DC Sweep file output like for transient analysis","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fknowm%2Fjspice","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fknowm%2Fjspice","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fknowm%2Fjspice/lists"}