diff --git a/src/main/java/de/neemann/digital/core/Model.java b/src/main/java/de/neemann/digital/core/Model.java index b93573a06..83f79dd25 100644 --- a/src/main/java/de/neemann/digital/core/Model.java +++ b/src/main/java/de/neemann/digital/core/Model.java @@ -66,6 +66,7 @@ public class Model implements Iterable, SyncAccess { private final ArrayList signals; private final ArrayList inputs; private final ArrayList outputs; + private final ArrayList testOutputs; private final ArrayList nodes; private ArrayList nodesToUpdateAct; @@ -92,6 +93,7 @@ public class Model implements Iterable, SyncAccess { this.buttonsToMap = new HashMap<>(); this.signals = new ArrayList<>(); this.outputs = new ArrayList<>(); + this.testOutputs = new ArrayList<>(); this.inputs = new ArrayList<>(); this.nodes = new ArrayList<>(); this.nodesToUpdateAct = new ArrayList<>(); @@ -586,8 +588,13 @@ public class Model implements Iterable, SyncAccess { * @param signal the signal */ public void addSignal(Signal signal) { - if (signal.isValid()) + if (signal.isValid()) { + if (signals.contains(signal)) + invalidSignal = signal; signals.add(signal); + if (signal.isTestOutput()) + testOutputs.add(signal); + } } /** @@ -623,6 +630,7 @@ public class Model implements Iterable, SyncAccess { invalidSignal = signal; signals.add(signal); outputs.add(signal); + testOutputs.add(signal); } else invalidSignal = signal; } @@ -649,6 +657,13 @@ public class Model implements Iterable, SyncAccess { return outputs; } + /** + * @return the models outputs + */ + public ArrayList getTestOutputs() { + return testOutputs; + } + /** * @return all registered signals */ diff --git a/src/main/java/de/neemann/digital/core/Signal.java b/src/main/java/de/neemann/digital/core/Signal.java index 456e43f7d..b56dc7656 100644 --- a/src/main/java/de/neemann/digital/core/Signal.java +++ b/src/main/java/de/neemann/digital/core/Signal.java @@ -16,6 +16,7 @@ public final class Signal implements Comparable { private String pinNumber; private ObservableValue bidirectionalReader; private boolean showInGraph; + private boolean testOutput; /** * Creates a new Instance @@ -60,6 +61,23 @@ public final class Signal implements Comparable { return showInGraph; } + /** + * Makes this signal to a test output signal + * + * @return this for chained calls + */ + public Signal setTestOutput() { + testOutput = true; + return this; + } + + /** + * @return true if this signal is a test output + */ + public boolean isTestOutput() { + return testOutput; + } + /** * @return the name */ diff --git a/src/main/java/de/neemann/digital/core/flipflops/FlipflopBit.java b/src/main/java/de/neemann/digital/core/flipflops/FlipflopBit.java index 43fe5bbcf..b2b81d797 100644 --- a/src/main/java/de/neemann/digital/core/flipflops/FlipflopBit.java +++ b/src/main/java/de/neemann/digital/core/flipflops/FlipflopBit.java @@ -86,7 +86,7 @@ abstract class FlipflopBit extends Node implements Element { out = v != 0; q.setBool(out); qn.setBool(!out); - })); + }).setTestOutput()); } void setOut(boolean out) { diff --git a/src/main/java/de/neemann/digital/core/flipflops/FlipflopD.java b/src/main/java/de/neemann/digital/core/flipflops/FlipflopD.java index 5dfc900ee..da4340bd5 100644 --- a/src/main/java/de/neemann/digital/core/flipflops/FlipflopD.java +++ b/src/main/java/de/neemann/digital/core/flipflops/FlipflopD.java @@ -120,7 +120,7 @@ public class FlipflopD extends Node implements Element, Countable { value = v; q.setValue(value); qn.setValue(~value); - })); + }).setTestOutput()); } /** diff --git a/src/main/java/de/neemann/digital/core/io/Probe.java b/src/main/java/de/neemann/digital/core/io/Probe.java index 9465f9682..fbcd0da9d 100644 --- a/src/main/java/de/neemann/digital/core/io/Probe.java +++ b/src/main/java/de/neemann/digital/core/io/Probe.java @@ -56,7 +56,7 @@ public class Probe implements Element { @Override public void registerNodes(Model model) { - model.addOutput(new Signal(label, value).setShowInGraph(showInGraph).setFormat(format)); + model.addSignal(new Signal(label, value).setShowInGraph(showInGraph).setFormat(format).setTestOutput()); model.registerGlobalValue(label, value); } diff --git a/src/main/java/de/neemann/digital/core/memory/Counter.java b/src/main/java/de/neemann/digital/core/memory/Counter.java index c3ef06ae4..af11f6df6 100644 --- a/src/main/java/de/neemann/digital/core/memory/Counter.java +++ b/src/main/java/de/neemann/digital/core/memory/Counter.java @@ -105,7 +105,7 @@ public class Counter extends Node implements Element, ProgramCounter { boolean o = (counter == maxValue) && enable.getBool(); out.setValue(counter); ovf.setBool(o); - })); + }).setTestOutput()); } @Override diff --git a/src/main/java/de/neemann/digital/core/memory/CounterPreset.java b/src/main/java/de/neemann/digital/core/memory/CounterPreset.java index fc307359f..8132d67f7 100644 --- a/src/main/java/de/neemann/digital/core/memory/CounterPreset.java +++ b/src/main/java/de/neemann/digital/core/memory/CounterPreset.java @@ -146,7 +146,7 @@ public class CounterPreset extends Node implements Element, ProgramCounter { boolean o = getOvfValue(counter, dir.getBool(), enable.getBool()); out.setValue(counter); ovf.setBool(o); - })); + }).setTestOutput()); } @Override diff --git a/src/main/java/de/neemann/digital/core/memory/Register.java b/src/main/java/de/neemann/digital/core/memory/Register.java index 7443031ac..4c74be678 100644 --- a/src/main/java/de/neemann/digital/core/memory/Register.java +++ b/src/main/java/de/neemann/digital/core/memory/Register.java @@ -90,7 +90,7 @@ public class Register extends Node implements Element, Countable, ProgramCounter model.addSignal(new Signal(label, q, (v, z) -> { value = v; q.setValue(value); - })); + }).setTestOutput()); } @Override diff --git a/src/main/java/de/neemann/digital/testing/TestExecutor.java b/src/main/java/de/neemann/digital/testing/TestExecutor.java index 1fa721212..3504dc810 100644 --- a/src/main/java/de/neemann/digital/testing/TestExecutor.java +++ b/src/main/java/de/neemann/digital/testing/TestExecutor.java @@ -119,7 +119,7 @@ public class TestExecutor { } } - for (Signal s : model.getOutputs()) { + for (Signal s : model.getTestOutputs()) { final int index = getIndexOf(s.getName()); if (index >= 0) { outputs.add(new TestSignal(index, s.getValue())); diff --git a/src/main/java/de/neemann/digital/testing/parser/Context.java b/src/main/java/de/neemann/digital/testing/parser/Context.java index 25e976161..dff59bad4 100644 --- a/src/main/java/de/neemann/digital/testing/parser/Context.java +++ b/src/main/java/de/neemann/digital/testing/parser/Context.java @@ -49,7 +49,7 @@ public class Context { if (model != null) { // inputs are not supported because there are cases where values // are evaluated and model inputs are not set! - for (Signal s : model.getOutputs()) + for (Signal s : model.getTestOutputs()) if (s.getName().equals(name)) return s.getValue().getValue(); } diff --git a/src/main/java/de/neemann/digital/testing/parser/Parser.java b/src/main/java/de/neemann/digital/testing/parser/Parser.java index 5515fa60c..847c4f95c 100644 --- a/src/main/java/de/neemann/digital/testing/parser/Parser.java +++ b/src/main/java/de/neemann/digital/testing/parser/Parser.java @@ -115,10 +115,15 @@ public class Parser { expect(Tokenizer.Token.IDENT); final String sName = tok.getIdent(); expect(Tokenizer.Token.EQUAL); + int sign = 1; + if (tok.peek() == Tokenizer.Token.SUB) { + tok.consume(); + sign = -1; + } expect(Tokenizer.Token.NUMBER); long n = convToLong(tok.getIdent()); expect(Tokenizer.Token.SEMICOLON); - signalInitMap.put(sName, n); + signalInitMap.put(sName, sign * n); break; case PROGRAM: tok.consume();