## Simulation

In this context, simulation means circuit simulation using a lumped element model of the circuit generated from the abstract model. More practically, simulation means SPICE simulation.

There are two levels of the implementation:

- low level, which requires more knowledge on SPICE syntax, plus requires the drawing to be decorated with SPICE-specific symbols
- high level, which is further away from the SPICE syntax and is designed to operate on drawings without having to add extra SPICE or simulation specific symbols (sources, probes, commands, etc.)

The high level simulation is recommended if:

- you are new to circuit simulation
- sheets drawn for a production workflow (e.g. PCB workflow) should be simulated without having to add SPICE decoration and without having to copy out the relevant part
- can run ngspice from sch-rnd so you do not need to use shell or to write scripts for quick iterations; results are displayed within sch-rnd (when used from GUI)
- works with both GUI (dialog boxes) and CLI (actions)

The low level simulation is recommended if:

- you already have a lot of experience with spice and the SPICE syntax
- you want maximum flexibility on the SPICE side (arbitrary commands)
- you do not mind making your drawing simulation-specific
- sch-rnd does not run the simulator, merely exports the netlist; you will need to run the simulator using the netlist (from a shell, maybe using scripts, or a Makefile)

The easiest way to learn both the low and the high level simulation is the tutorial

### High level simulation

The high level sim differs a lot from the classic "drawn for spice" schematics model. It really models how circuits are tested in real life:

- the drawing is for the real board, typically done for the PCB workflow
- multiple different "simulation setups" can be defined
- a setup includes test bench configuration, which describes which parts of the circuit should be included in the simulation, so you do not need to simulate the whole circuit and you do not need to copy out the relevant part into a separate sheet for simulation
- a setup includes instructions for modifications for the test: adding sources or resistors (e.g. load) or capacitors or inductances; removing parts; disconnecting pins; changing attributes (e.g. value of components);
- a setup includes output configuration that contains commands for SPICE to run different analyses and also contains instructions to sch-rnd on how to present the output of those runs.

All this remembered in sim setup config so you don't need to modify your production board for sim testing.

The configuration stored for high level simulation has the following logical structure:

- simulation setup #1
- test bench configuration; this allows running the simulation on parts of the drawing instead of the whole drawing
- 0 or more text-specified modifications that are performed before the netlist export:
  - add components (e.g. sources, load resistors/capacitors/inductors)
    - device type
    - device parameters (e.g. dc, ac, time-dependent-function components for sources, resistance/capacitance/inductance for discretes)
  - remove components
  - break existing connections
  - change component attributes
  - change global states (e.g. temperature)
- 0 or more output configurations
  - analysis type
  - presentation
    - type (e.g. plot)
    - list or properties to present
- simulation setup #2
  - (same fields as above)
- simulation setup #3
  - (same fields as above)
- ...

On the bottom of the dialog there are buttons for:

- selecting the simulation view to use, which also specifies the simulator to use (only sim_ngspice is available at the moment); this information is not part of the configuration saved
- activating the simulation; this means switching to a sheet of the project the simulation is for, switching to the view selected for the simulation, enabling the test bench configured and triggering a compilation to get it all displayed. CLI alternative: SimActivate() action.
- running the simulation; this activates the simulation, compiles immediately, executes the simulator in the background and presents the results in the 3rd tab. CLI alternative: SimRun() action.

The GUI variant with the run button is designed to be suitable for quick turnaround circuit tuning: single-click button that can re-generate all the plots in-place in the non-modal simulation setup dialog; this means you can keep the window open, make changes to your production circuit and run the simulation instantly to see the result.

#### Properties, addressing

In the list of properties for presentation and in the positive and negative connection of an add modification, node addresses are used. A node address is either the name of an abstract network or a pair of abstract component and port name, e.g. CN2-4 means "port 4 of component CN2".

Note: port name means the name the port is listed by in the abstract model, which is typically the original terminal name, and not the "pin number", or the calculated display/name attribute. For example using a polarized symbol, e.g. a diode it is typically A and C (not 1 and 2); or using a transistor symbol, the port names are B, E, C (and not 1, 2 and 3). Tip: switch to the raw view to reveal the original port names or use the abstract model dialog to find them.

#### config subtree in project.lht

All high level simulation config data is stored in the plugins/sim/setups subtree on the project role (in project.lht). In theory the config system allows storing the setups subtree in any config source; in practice the GUI depends on it is stored in the project file. An advanced user may choose to store sim setup config elsewhere and do the configuration manually, not using the simulation setup dialog.

The setups subtree structure documented in the appendix.

#### Actions: high level sim automation

It is possible to run the high level simulation without GUI, using actions. The system works the same, using the same simulation setups, running the simulator in the background, but instead of presenting the results on the screen, saving them in self-contained files. The user then should run 3rd party scripts and software to parse this file and present the results.

Action SimActivate(setup_name, view_name) performs the same as the 'activate' button on the GUI: it sets up the configuration and view to match the named simulation setup. Setup_name is the name of one of the sim setups from the plugins/sim/setups config subtree and view_name is the name of a view that has a sim_* plugin in it, e.g. sim_ngpsice. View_name is used to select the simulation backend (simulation software).

Action SimRun(setup_name, view_name, [output_filename]) performs the same as the 'run' button on the GUI, saving the output in a contained plain text file. Output is saved in sim.txt if no file name is specified in the 3rd argument.

#### Old sheet files, missing views

As of sch-rnd 1.0.2, the default config contains a view called sim_ngspice which is set up as a target for the high level sim to work with ngspice-30 or newer. Sheets and project created before 1.0.2 will typically lack this view. Adding the view is trivial either in the view GUI and in the project file. The most important aspects is to include target_sim_ngspice at the end of the engine list ad include std_forge before that.

As of 1.0.2, the ordered engine list for the sim_ngspice view is:

1. std_forge
2. std_cschem
3. std_devmap
4. target_sim_ngspice

Std_forge is used to operate the test benching mechanism and target_sim_ngspice is the engine that generates the spice export and runs ngspice in the background. The other engines are just standard functionality the user would generally expect to work (std_cschem for things like the connect attribute, std_devmap for the devmap and portmap mechanisms).

### Low level (raw) simulation

The low level, raw, simulation mechanism is used to enable an sch-rnd project to export to circuit simulation, e.g. spice. The high level simulation is built on top of the low level.

The low level simulation consists of:

- a set of conventional attributes and mechanisms built on top of them
- a set of the target_spice plugin which tunes the compilation so that the abstract model is usable for spice netlist export
- a view, normally called spice_raw, which uses target_spice as the target engine

The normal workflow is:

- set the view to spice_raw
- fill in all relevant attributes in symbols
- add extra symbols (e.g. voltage sources)
- compile and export using the spice export format
- maybe edit the exported file (e.g. gnucap requires that because of incompatibility)
- run a spice simulator on the exported file

The extra symbols drawn for spice simulation may interfere with other workflows, e.g. if the same project is used as a source for a PCB workflow. There are multiple mechanisms to deal with this:

- the classic approach: draw spice-related extras on separate sheet and do not include that sheet in workflows different than spice
- use test benching or project stances in general to omit them
- the PCB workflow will automatically omit any component from the export that does not have a footprint attribute

### Test benching

The test bench mechanism is responsible for selecting parts of the circuit for simulation. Test benching operates on project level. It is implemented using the test_bench project stance and forge-if/test_bench attribute in symbols and wirenets to conditionally omit objects that are not part of the currently selected test bench.

#### Test benching using the GUI

On the user interface, defining named test benches are done using the File menu, project submenu, project stances submenu; in the project stances dialog select the test_bench stance and click Edit... then enter a new test bench name; it is created and saved in the project config immediately.

Grouping object into test benches can be done on the GUI by selecting the given objects, then Select menu, Change selected objects submenu, Testbench affiliation submenu. This opens the test bench quick edit dialog which presents a matrix of checkboxes for all selected symbols vs. all project stances available at the time of opening the window. Ticking a checkbox means the given object is part of the given test bench.

After filling in the matrix for a few symbols, changing the test bench stance in the project stances dialog will expose the mechanism:

- if the test_bench stance is set to a named test bench, any symbol that has test bench affiliation but does not include the currently set test bench becomes omitted, which is indicated using a red cross; this is the case when a partial circuit is to be simulated; by default symbols not affiliated with any test benches are present included in all test benches
- if the test_bench stance is empty, the whole circuit is simulated

#### Test benching in the config

The project stance test_bench is part of the config tree: /stances/test_bench is a string containing the name of the currently activated test bench; /stances/test_bench_values is an array of all known test bench names. These shall be set on the project role (so they are part of the project file). The GUI expects and edits them on the project role.

Symbol test bench affiliation is controlled by the symbol attribute forge-if/test_bench. It could be an arbitrary forge script, but the GUI expects a script in the following structure:

    (stance.test_bench != "") && (stance.test_bench != "foo") && (stance.test_bench != "bar")
    scalar,omit
    sub,^.*$,yes,omit

For the GUI to understand, the expression in the first line must:

- start with (stance.test_bench != "")
- must list 1 or more && (stance.test_bench != "name") sections with different test bench names