From 2e22d5fe85038b3356ff7f2e6fa94bb8ab1c1a60 Mon Sep 17 00:00:00 2001 From: hneemann Date: Tue, 30 Jan 2024 09:36:37 +0100 Subject: [PATCH] allows recovering from oscillations --- distribution/ReleaseNotes.txt | 1 + .../java/de/neemann/digital/core/Model.java | 24 +++++++++++++++---- .../de/neemann/digital/core/element/Keys.java | 8 ++++++- .../java/de/neemann/digital/gui/Main.java | 2 ++ .../gui/components/CircuitComponent.java | 3 ++- src/main/resources/lang/lang_de.xml | 2 ++ src/main/resources/lang/lang_en.xml | 2 ++ 7 files changed, 36 insertions(+), 6 deletions(-) diff --git a/distribution/ReleaseNotes.txt b/distribution/ReleaseNotes.txt index b95fe04cf..e5818a76b 100644 --- a/distribution/ReleaseNotes.txt +++ b/distribution/ReleaseNotes.txt @@ -6,6 +6,7 @@ HEAD, planned as v0.31 - FSM editor highlights the current transition - Adds drivers with inverted output - Adds a minified circuit as a new shape for embedded circuits +- Allows recovering from oscillations. v0.30, released on 3. February 2023 - Added a search function diff --git a/src/main/java/de/neemann/digital/core/Model.java b/src/main/java/de/neemann/digital/core/Model.java index 0d25dcb85..b21a9c1a7 100644 --- a/src/main/java/de/neemann/digital/core/Model.java +++ b/src/main/java/de/neemann/digital/core/Model.java @@ -80,6 +80,7 @@ public class Model implements Iterable, SyncAccess { private AsyncSeq asyncInfos; private boolean asyncMode = false; private boolean allowGlobalValues = false; + private boolean recoverFromOscillation = false; private File rootPath; private final ArrayList observers; @@ -293,19 +294,20 @@ public class Model implements Iterable, SyncAccess { try { if (cond.doNextMicroStep()) { int counter = 0; + oscillatingNodes = null; while (cond.doNextMicroStep() && state != State.CLOSED) { if (counter++ > oscillationDetectionCounter) { if (oscillatingNodes == null) oscillatingNodes = new HashSet<>(); if (counter > oscillationDetectionCounter + COLLECTING_LOOP_COUNTER_OFFS) { - NodeException seemsToOscillate = new NodeException(Lang.get("err_seemsToOscillate")).addNodes(oscillatingNodes); - oscillatingNodes = null; - throw seemsToOscillate; + throw new NodeException(Lang.get("err_seemsToOscillate")).addNodes(oscillatingNodes); } else { oscillatingNodes.addAll(nodesToUpdateNext); } + doMicroStep(noise || recoverFromOscillation); + } else { + doMicroStep(noise); } - doMicroStep(noise); } } else { // if a calculation is initiated but there is nothing to do because there was @@ -947,6 +949,20 @@ public class Model implements Iterable, SyncAccess { return this; } + /** + * I set, the model tries to recover from oszillation by introducing noise + * to the model execution. + * Use with extreme care because is covers bugs in the simulation that lead + * to an unpredictable behaviour and makes the simulation very slow! + * + * @param recoverFromOscillation if true, the model tries to recover from an oszillation + * @return this for chained calls + */ + public Model setRecoverFromOscillation(boolean recoverFromOscillation) { + this.recoverFromOscillation = recoverFromOscillation; + return this; + } + /** * Sets async execution infos * 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 717bd4f6c..b88e7a785 100644 --- a/src/main/java/de/neemann/digital/core/element/Keys.java +++ b/src/main/java/de/neemann/digital/core/element/Keys.java @@ -566,7 +566,13 @@ public final class Keys { new Key.KeyInteger("oscillationDetectionCounter", 1000) .setComboBoxValues(1000, 5000, 10000) .setMin(1000) - .setMax(100000); + .setMax(100000).setSecondary(); + + /** + * Counter used to detect oscillations + */ + public static final Key RECOVER_FROM_OSCILLATION = + new Key<>("recoverFromOscillation", false).setSecondary(); /** * output format for numbers diff --git a/src/main/java/de/neemann/digital/gui/Main.java b/src/main/java/de/neemann/digital/gui/Main.java index 065689baa..171df8d36 100644 --- a/src/main/java/de/neemann/digital/gui/Main.java +++ b/src/main/java/de/neemann/digital/gui/Main.java @@ -1475,6 +1475,8 @@ public final class Main extends JFrame implements ClosingWindowListener.ConfirmS modelCreator = new ModelCreator(circuitComponent.getCircuit(), library); model = modelCreator.createModel(true); + model.setRecoverFromOscillation(circuitComponent.getCircuit().getAttributes().get(Keys.RECOVER_FROM_OSCILLATION)); + time = System.currentTimeMillis() - time; LOGGER.debug("model creation: " + time + " ms, " + model.getNodes().size() + " nodes"); 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 d4bcafb0e..af8d018a9 100644 --- a/src/main/java/de/neemann/digital/gui/components/CircuitComponent.java +++ b/src/main/java/de/neemann/digital/gui/components/CircuitComponent.java @@ -82,7 +82,6 @@ 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); @@ -94,6 +93,8 @@ public class CircuitComponent extends JComponent implements ChangedListener, Lib ATTR_LIST.add(Keys.BIG_ENDIAN_SETTING); ATTR_LIST.add(Keys.SKIP_HDL); ATTR_LIST.add(Keys.IS_GENERIC); + ATTR_LIST.add(Keys.OSCILLATION_DETECTION_COUNTER); + ATTR_LIST.add(Keys.RECOVER_FROM_OSCILLATION); } diff --git a/src/main/resources/lang/lang_de.xml b/src/main/resources/lang/lang_de.xml index 911f20365..5fe453990 100644 --- a/src/main/resources/lang/lang_de.xml +++ b/src/main/resources/lang/lang_de.xml @@ -1684,6 +1684,8 @@ Sind evtl. die Namen der Variablen nicht eindeutig? Oszillationserkennung Anzahl der Gatterlaufzeiten, bei der eine Oszillation erkannt wird, wenn sich die Schaltung bis dahin noch nicht stabilisiert hat. + Bei Oszillationen mit Zufallswerten weitermachen. + Wird diese Option gesetzt, wird das Verhalten der Simulation im Falle einer Oszillation unvorhersehbar und zudem extrem langsam! Telnet-Modus Wenn gesetzt, werden die Telnet Steuerkommandos ausgewertet. diff --git a/src/main/resources/lang/lang_en.xml b/src/main/resources/lang/lang_en.xml index 3d136ef8a..c595caef4 100644 --- a/src/main/resources/lang/lang_en.xml +++ b/src/main/resources/lang/lang_en.xml @@ -1667,6 +1667,8 @@ Oscillation detection Number of gate propagation times at which a oscillation is detected if the circuit has not stabilized by then. + In case of oscillations, continue with random values. + If this option is set, the behavior of the simulation becomes unpredictable and extremely slow if there is an oscillation! Telnet mode If set, the Telnet control commands are evaluated.