diff --git a/src/main/java/de/neemann/digital/core/switching/PlainSwitch.java b/src/main/java/de/neemann/digital/core/switching/PlainSwitch.java
index 68b2279d9..81775f708 100644
--- a/src/main/java/de/neemann/digital/core/switching/PlainSwitch.java
+++ b/src/main/java/de/neemann/digital/core/switching/PlainSwitch.java
@@ -97,40 +97,48 @@ public final class PlainSwitch implements NodeInterface {
input2.addObserverToValue(this).checkBits(bits, null);
switch (unidirectional) {
case NO:
- if (input1 instanceof CommonBusValue) {
- if (input2 instanceof CommonBusValue) {
- final CommonBusValue in1 = (CommonBusValue) input1;
- final CommonBusValue in2 = (CommonBusValue) input2;
- ObservableValue constant = in1.searchConstant();
- if (constant != null)
- switchModel = new UniDirectionalSwitch(constant, output2);
- else {
- constant = in2.searchConstant();
- if (constant != null)
- switchModel = new UniDirectionalSwitch(constant, output1);
- else
- switchModel = new RealSwitch(in1, in2);
- }
- } else
- switchModel = new UniDirectionalSwitch(input1, output2);
- } else {
- if (input2 instanceof CommonBusValue) {
- switchModel = new UniDirectionalSwitch(input2, output1);
- } else {
- throw new NodeException(Lang.get("err_switchHasNoNet"), output1, output2);
- }
- }
+ switchModel = createSwitchModel(input1, input2, output1, output2, false, null);
break;
case FROM1TO2:
- switchModel = new UniDirectionalSwitch(input1, output2);
+ switchModel = new UniDirectionalSwitch(input1, output2, null);
break;
case FROM2TO1:
- switchModel = new UniDirectionalSwitch(input2, output1);
+ switchModel = new UniDirectionalSwitch(input2, output1, null);
break;
}
}
}
+ static SwitchModel createSwitchModel(
+ ObservableValue input1, ObservableValue input2,
+ ObservableValue output1, ObservableValue output2,
+ boolean isTDSwitch, String name) throws NodeException {
+
+ if (input1 instanceof CommonBusValue) {
+ if (input2 instanceof CommonBusValue) {
+ final CommonBusValue in1 = (CommonBusValue) input1;
+ final CommonBusValue in2 = (CommonBusValue) input2;
+ ObservableValue constant = in1.searchConstant();
+ if (constant != null)
+ return new UniDirectionalSwitch(constant, output2, name);
+ else {
+ constant = in2.searchConstant();
+ if (constant != null)
+ return new UniDirectionalSwitch(constant, output1, !isTDSwitch, name);
+ else
+ return new RealSwitch(in1, in2);
+ }
+ } else
+ return new UniDirectionalSwitch(input1, output2, name);
+ } else {
+ if (input2 instanceof CommonBusValue) {
+ return new UniDirectionalSwitch(input2, output1, !isTDSwitch, name);
+ } else {
+ throw new NodeException(Lang.get("err_switchHasNoNet"), output1, output2);
+ }
+ }
+ }
+
@Override
public ObservableValues getOutputs() {
return new ObservableValues(output1, output2);
@@ -215,19 +223,30 @@ public final class PlainSwitch implements NodeInterface {
private static final class UniDirectionalSwitch implements SwitchModel {
private final ObservableValue input;
private final ObservableValue output;
+ private final boolean setOpenToHighZ;
+ private final String name;
private boolean closed;
- UniDirectionalSwitch(ObservableValue input, ObservableValue output) {
+ UniDirectionalSwitch(ObservableValue input, ObservableValue output, String name) {
+ this(input, output, true, name);
+ }
+
+ UniDirectionalSwitch(ObservableValue input, ObservableValue output, boolean setOpenToHighZ, String name) {
this.input = input;
this.output = output;
+ this.setOpenToHighZ = setOpenToHighZ;
+ this.name = name;
}
@Override
public void propagate() {
if (closed) {
+ System.out.println(name + "-Closed " + output.getName());
output.set(input.getValue(), input.getHighZ());
} else {
- output.setToHighZ();
+ System.out.println(name + "-Opened " + output.getName());
+ if (setOpenToHighZ)
+ output.setToHighZ();
}
}
diff --git a/src/main/java/de/neemann/digital/core/switching/PlainSwitchDT.java b/src/main/java/de/neemann/digital/core/switching/PlainSwitchDT.java
index 4814381c2..770cf0e6e 100644
--- a/src/main/java/de/neemann/digital/core/switching/PlainSwitchDT.java
+++ b/src/main/java/de/neemann/digital/core/switching/PlainSwitchDT.java
@@ -5,38 +5,29 @@
*/
package de.neemann.digital.core.switching;
-import de.neemann.digital.core.Model;
-import de.neemann.digital.core.NodeException;
-import de.neemann.digital.core.ObservableValue;
-import de.neemann.digital.core.ObservableValues;
+import de.neemann.digital.core.*;
import de.neemann.digital.lang.Lang;
/**
* A simple double throw switch
*/
-public final class PlainSwitchDT {
- private final PlainSwitch s1;
- private final PlainSwitch s2;
+public final class PlainSwitchDT implements NodeInterface {
private final ObservableValue outputA;
private final ObservableValue outputB;
private final ObservableValue outputC;
+ private final int bits;
+ private final String name;
+ private PlainSwitch.SwitchModel s1;
+ private PlainSwitch.SwitchModel s2;
+ private boolean closed = false;
- PlainSwitchDT(int bits, int num) {
+ PlainSwitchDT(int bits, int num, String name) {
+ this.bits = bits;
+ this.name = name;
outputA = new ObservableValue("A" + num, bits).setBidirectional().setToHighZ().setDescription(Lang.get("elem_Switch_pin")).setSwitchPin(true);
outputB = new ObservableValue("B" + num, bits).setBidirectional().setToHighZ().setDescription(Lang.get("elem_Switch_pin")).setSwitchPin(true);
outputC = new ObservableValue("C" + num, bits).setBidirectional().setToHighZ().setDescription(Lang.get("elem_Switch_pin")).setSwitchPin(true);
- s1 = new PlainSwitch(outputA, outputB, false);
- s2 = new PlainSwitch(outputA, outputC, true);
- }
-
- /**
- * Adds the outputs to the given builder
- *
- * @param ov the builder to use
- */
- public void addOutputs(ObservableValues.Builder ov) {
- ov.add(outputA, outputB, outputC);
}
/**
@@ -48,8 +39,17 @@ public final class PlainSwitchDT {
* @throws NodeException NodeException
*/
public void setInputs(ObservableValue inA, ObservableValue inB, ObservableValue inC) throws NodeException {
- s1.setInputs(inA, inB);
- s2.setInputs(inA, inC);
+ if (inA != null && (inB != null || inC != null))
+ inA.addObserverToValue(this).checkBits(bits, null);
+
+ if (inA != null && inB != null) {
+ inB.addObserverToValue(this).checkBits(bits, null);
+ s1 = PlainSwitch.createSwitchModel(inA, inB, outputA, outputB, true, name+"-A-B");
+ }
+ if (inA != null && inC != null) {
+ inC.addObserverToValue(this).checkBits(bits, null);
+ s2 = PlainSwitch.createSwitchModel(inA, inC, outputA, outputC, true, name+"-A-C");
+ }
}
/**
@@ -58,8 +58,15 @@ public final class PlainSwitchDT {
* @param model the model
*/
public void init(Model model) {
- s1.init(model);
- s2.init(model);
+ if (s1 != null) {
+ s1.setModel(model);
+ s1.setClosed(closed);
+ }
+ if (s2 != null) {
+ s2.setModel(model);
+ s2.setClosed(!closed);
+ }
+ hasChanged();
}
/**
@@ -68,16 +75,29 @@ public final class PlainSwitchDT {
* @param isClosed true is A-B is closed and A-C is open
*/
public void setClosed(boolean isClosed) {
- s1.setClosed(isClosed);
- s2.setClosed(!isClosed);
+ if (this.closed != isClosed) {
+ this.closed = isClosed;
+ if (closed) {
+ if (s1 != null)
+ s1.setClosed(closed);
+ if (s2 != null)
+ s2.setClosed(!closed);
+ }
+ hasChanged();
+ }
}
- /**
- * calles is state has changed
- */
- public void hashChanged() {
- s1.hasChanged();
- s2.hasChanged();
+ @Override
+ public void hasChanged() {
+ if (s1 != null)
+ s1.propagate();
+ if (s2 != null)
+ s2.propagate();
+ }
+
+ @Override
+ public ObservableValues getOutputs() {
+ return new ObservableValues(outputA, outputB, outputC);
}
/**
diff --git a/src/main/java/de/neemann/digital/core/switching/SwitchDT.java b/src/main/java/de/neemann/digital/core/switching/SwitchDT.java
index 1e25a69f0..42ce9c2bb 100644
--- a/src/main/java/de/neemann/digital/core/switching/SwitchDT.java
+++ b/src/main/java/de/neemann/digital/core/switching/SwitchDT.java
@@ -38,7 +38,7 @@ public class SwitchDT implements Element, NodeInterface {
int poleCount = attr.get(Keys.POLES);
poles = new PlainSwitchDT[poleCount];
for (int i = 0; i < poleCount; i++)
- poles[i] = new PlainSwitchDT(bits, i + 1);
+ poles[i] = new PlainSwitchDT(bits, i + 1, attr.getCleanLabel());
}
@Override
@@ -67,7 +67,7 @@ public class SwitchDT implements Element, NodeInterface {
@Override
public void hasChanged() {
for (PlainSwitchDT p : poles)
- p.hashChanged();
+ p.hasChanged();
}
@Override
diff --git a/src/test/resources/dig/test/switch/Heintz_A_DT.dig b/src/test/resources/dig/test/switch/Heintz_A_DT.dig
index 479d3196c..6f81214d9 100644
--- a/src/test/resources/dig/test/switch/Heintz_A_DT.dig
+++ b/src/test/resources/dig/test/switch/Heintz_A_DT.dig
@@ -6,7 +6,7 @@
VDD
-
+
In
@@ -16,7 +16,7 @@
A
-
+
In
@@ -126,6 +126,14 @@
+
+
+
+
+
+
+
+
@@ -142,20 +150,12 @@
-
-
-
-
-
-
-
-
-
+
@@ -167,7 +167,7 @@
-
+
@@ -175,21 +175,13 @@
-
+
-
-
-
-
-
-
-
-
@@ -203,11 +195,7 @@
-
-
-
-
-
+
diff --git a/src/test/resources/dig/test/switch/switch_xor3.dig b/src/test/resources/dig/test/switch/switch_xor3.dig
new file mode 100644
index 000000000..8704eeff5
--- /dev/null
+++ b/src/test/resources/dig/test/switch/switch_xor3.dig
@@ -0,0 +1,158 @@
+
+
+ 1
+
+
+
+ In
+
+
+ Label
+ A
+
+
+
+
+
+ Testcase
+
+
+ Testdata
+
+ A B Y
+0 0 z
+0 1 1
+1 0 1
+1 1 z
+
+
+# transitions
+0 0 z
+0 1 1
+0 0 z
+1 0 1
+0 0 z
+1 1 z
+0 0 z
+0 1 1
+1 0 1
+0 1 1
+1 1 z
+0 1 1
+1 0 1
+1 1 z
+1 0 1
+
+
+
+
+
+
+
+ In
+
+
+ Label
+ B
+
+
+
+
+
+ VDD
+
+
+
+
+ Out
+
+
+ Label
+ Y
+
+
+
+
+
+ RelayDT
+
+
+ Label
+ R1
+
+
+
+
+
+ RelayDT
+
+
+ rotation
+
+
+
+ Label
+ R2
+
+
+
+
+
+ Ground
+
+
+
+
+ Ground
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file