diff --git a/src/main/java/de/neemann/digital/core/Model.java b/src/main/java/de/neemann/digital/core/Model.java index c9f648731..3ca4bd4ae 100644 --- a/src/main/java/de/neemann/digital/core/Model.java +++ b/src/main/java/de/neemann/digital/core/Model.java @@ -52,9 +52,9 @@ public class Model implements Iterable, SyncAccess { /** * Maximal number of calculation loops before oscillating behaviour is detected */ - private static final int MAX_LOOP_COUNTER = 1000; - private static final int COLLECTING_LOOP_COUNTER = MAX_LOOP_COUNTER + 100; + private static final int COLLECTING_LOOP_COUNTER_OFFS = 100; private ArrayList brVal; + private int oscillationDetectionCounter = 1000; private enum State {BUILDING, INITIALIZING, RUNNING, CLOSED} @@ -104,6 +104,17 @@ public class Model implements Iterable, SyncAccess { this.observers = new ArrayList<>(); } + /** + * Sets the number of gate delays at which an oscillation is detected. + * + * @param oscillationDetectionCounter number of steps + * @return this for chained calls + */ + public Model setOscillationDetectionCounter(int oscillationDetectionCounter) { + this.oscillationDetectionCounter = oscillationDetectionCounter; + return this; + } + /** * Sets this model to async mode. * Async mode means that the circuit is not able to reach a stable state once the reset gates are released. @@ -283,10 +294,10 @@ public class Model implements Iterable, SyncAccess { if (cond.doNextMicroStep()) { int counter = 0; while (cond.doNextMicroStep() && state != State.CLOSED) { - if (counter++ > MAX_LOOP_COUNTER) { + if (counter++ > oscillationDetectionCounter) { if (oscillatingNodes == null) oscillatingNodes = new HashSet<>(); - if (counter > COLLECTING_LOOP_COUNTER) { + if (counter > oscillationDetectionCounter + COLLECTING_LOOP_COUNTER_OFFS) { NodeException seemsToOscillate = new NodeException(Lang.get("err_seemsToOscillate")).addNodes(oscillatingNodes); oscillatingNodes = null; throw seemsToOscillate; diff --git a/src/main/java/de/neemann/digital/core/element/Keys.java b/src/main/java/de/neemann/digital/core/element/Keys.java index afcfa3676..b47d666a2 100644 --- a/src/main/java/de/neemann/digital/core/element/Keys.java +++ b/src/main/java/de/neemann/digital/core/element/Keys.java @@ -530,6 +530,15 @@ public final class Keys { public static final Key SETTINGS_SHOW_TUNNEL_RENAME_DIALOG = new Key<>("tunnelRenameDialog", true).setSecondary(); + /** + * Counter used to detect oscillations + */ + public static final Key OSCILLATION_DETECTION_COUNTER = + new Key.KeyInteger("oscillationDetectionCounter", 1000) + .setComboBoxValues(1000, 5000, 10000) + .setMin(1000) + .setMax(100000); + /** * output format for numbers */ diff --git a/src/main/java/de/neemann/digital/draw/model/ModelCreator.java b/src/main/java/de/neemann/digital/draw/model/ModelCreator.java index a0eef7eeb..d6d9e74f1 100644 --- a/src/main/java/de/neemann/digital/draw/model/ModelCreator.java +++ b/src/main/java/de/neemann/digital/draw/model/ModelCreator.java @@ -291,7 +291,8 @@ public class ModelCreator implements Iterable { public Model createModel(boolean attachWires) throws PinException, NodeException { Model m = new Model() .setRootPath(circuit.getOrigin()) - .setAllowGlobalValues(attachWires); + .setAllowGlobalValues(attachWires) + .setOscillationDetectionCounter(circuit.getAttributes().get(Keys.OSCILLATION_DETECTION_COUNTER)); for (Net n : netList) n.interconnect(m, attachWires); diff --git a/src/main/java/de/neemann/digital/gui/components/CircuitComponent.java b/src/main/java/de/neemann/digital/gui/components/CircuitComponent.java index 294db28cb..476928dc8 100644 --- a/src/main/java/de/neemann/digital/gui/components/CircuitComponent.java +++ b/src/main/java/de/neemann/digital/gui/components/CircuitComponent.java @@ -77,6 +77,7 @@ public class CircuitComponent extends JComponent implements ChangedListener, Lib ATTR_LIST.add(Keys.PINCOUNT); ATTR_LIST.add(Keys.BACKGROUND_COLOR); ATTR_LIST.add(Keys.DESCRIPTION); + ATTR_LIST.add(Keys.OSCILLATION_DETECTION_COUNTER); ATTR_LIST.add(Keys.LOCKED_MODE); ATTR_LIST.add(Keys.ROMMANAGER); ATTR_LIST.add(Keys.SHOW_DATA_TABLE); diff --git a/src/main/resources/lang/lang_de.xml b/src/main/resources/lang/lang_de.xml index 39ad387a3..33d7ab807 100644 --- a/src/main/resources/lang/lang_de.xml +++ b/src/main/resources/lang/lang_de.xml @@ -1681,6 +1681,10 @@ Sind evtl. die Namen der Variablen nicht eindeutig? Nachleuchten Gibt die Dauer des Nachleuchtens an. Je größer der Wert, je länger die Nachleuchtdauer. + Oszillationserkennung + Anzahl der Gatterlaufzeiten, bei der eine Oszillation erkannt + wird, wenn sich die Schaltung bis dahin noch nicht stabilisiert hat. + Telnet-Modus Wenn gesetzt, werden die Telnet Steuerkommandos ausgewertet. Zusätzlich werden vom Server die Kommandos SGA und ECHO gesendet. diff --git a/src/main/resources/lang/lang_en.xml b/src/main/resources/lang/lang_en.xml index 2453a1aaf..8a9429b82 100644 --- a/src/main/resources/lang/lang_en.xml +++ b/src/main/resources/lang/lang_en.xml @@ -1664,6 +1664,10 @@ Persistence Of Vision Specifies the duration of the afterglow. The larger the value, the longer the afterglow duration. + Oscillation detection + Number of gate propagation times at which a oscillation is + detected if the circuit has not stabilized by then. + Telnet mode If set, the Telnet control commands are evaluated. In addition, the server sends the SGA and ECHO commands. If this option is disabled,