diff --git a/src/main/dig/sequential/D-TransmissionGate.dig b/src/main/dig/sequential/D-TransmissionGate.dig
index 5ca53c1fb..a1e14d66f 100644
--- a/src/main/dig/sequential/D-TransmissionGate.dig
+++ b/src/main/dig/sequential/D-TransmissionGate.dig
@@ -1,7 +1,37 @@
1
+
+
+ isDIL
+ true
+
+
+ pinCount
+ 8
+
+
+
+ Out
+
+
+ Label
+ Q
+
+
+
+
+
+ TransGate
+
+
+ rotation
+
+
+
+
+
In
@@ -9,38 +39,22 @@
Label
D
-
-
-
-
- In
-
- Label
- C
+ Default
+ 1
-
+
- Not
+ TransGate
rotation
-
-
-
- Driver
-
-
- flipSelPos
- true
-
-
-
+
Not
@@ -50,17 +64,17 @@
-
+
- Out
+ Not
- Label
- Q
+ rotation
+
-
+
Out
@@ -70,17 +84,27 @@
~Q
-
+
- DriverInvSel
+ In
+
+
+ Label
+ C
+
+
+
+
+
+ Not
rotation
-
+
Testcase
@@ -95,73 +119,107 @@ C 1 1 0
C 0 0 1
0 0 0 1
0 1 0 1
+C 1 1 0
+C 0 0 1
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/src/main/java/de/neemann/digital/core/switching/TransGate.java b/src/main/java/de/neemann/digital/core/switching/TransGate.java
new file mode 100644
index 000000000..c5e0b7e02
--- /dev/null
+++ b/src/main/java/de/neemann/digital/core/switching/TransGate.java
@@ -0,0 +1,78 @@
+package de.neemann.digital.core.switching;
+
+import de.neemann.digital.core.*;
+import de.neemann.digital.core.element.Element;
+import de.neemann.digital.core.element.ElementAttributes;
+import de.neemann.digital.core.element.ElementTypeDescription;
+import de.neemann.digital.core.element.Keys;
+import de.neemann.digital.draw.elements.PinException;
+import de.neemann.digital.lang.Lang;
+
+import static de.neemann.digital.core.element.PinInfo.input;
+
+/**
+ * Transmission Gate
+ * Created by hneemann on 17.05.17.
+ */
+public class TransGate extends Node implements Element {
+ /**
+ * The transmission gate description
+ */
+ public static final ElementTypeDescription DESCRIPTION = new ElementTypeDescription(TransGate.class, input("S"), input("~S"))
+ .addAttribute(Keys.ROTATE)
+ .addAttribute(Keys.BITS);
+
+ private final Switch aSwitch;
+ private ObservableValue s;
+ private ObservableValue ns;
+ private boolean closed;
+
+ /**
+ * Create a new instance
+ *
+ * @param attr the attributes
+ */
+ public TransGate(ElementAttributes attr) {
+ aSwitch = new Switch(attr, false, "A", "B");
+ aSwitch.getOutput1().setPinDescription(DESCRIPTION);
+ aSwitch.getOutput2().setPinDescription(DESCRIPTION);
+
+ }
+
+ @Override
+ public void setInputs(ObservableValues inputs) throws NodeException {
+ s = inputs.get(0).checkBits(1, this, 0).addObserverToValue(this);
+ ns = inputs.get(1).checkBits(1, this, 1).addObserverToValue(this);
+ aSwitch.setInputs(new ObservableValues(inputs.get(2), inputs.get(3)));
+ }
+
+ @Override
+ public ObservableValues getOutputs() throws PinException {
+ return aSwitch.getOutputs();
+ }
+
+ @Override
+ public void readInputs() throws NodeException {
+ if (s.isHighZ() || ns.isHighZ())
+ closed = false;
+ else if (s.getBool() != ns.getBool())
+ closed = s.getBool();
+ }
+
+ @Override
+ public void writeOutputs() throws NodeException {
+ aSwitch.setClosed(closed);
+ }
+
+ @Override
+ public void init(Model model) throws NodeException {
+ aSwitch.init(model);
+ model.addObserver(event -> {
+ if (event.equals(ModelEvent.STEP)) {
+ if (!s.isHighZ() && !ns.isHighZ() && (s.getBool() == ns.getBool()))
+ throw new BurnException(Lang.get("err_invalidTransmissionGateState"), new ObservableValues(s, ns));
+ }
+ });
+ }
+
+}
diff --git a/src/main/java/de/neemann/digital/draw/library/ElementLibrary.java b/src/main/java/de/neemann/digital/draw/library/ElementLibrary.java
index 626a359ca..c864bddca 100644
--- a/src/main/java/de/neemann/digital/draw/library/ElementLibrary.java
+++ b/src/main/java/de/neemann/digital/draw/library/ElementLibrary.java
@@ -94,7 +94,8 @@ public class ElementLibrary implements Iterable
.add(PullUp.DESCRIPTION)
.add(PullDown.DESCRIPTION)
.add(Driver.DESCRIPTION)
- .add(DriverInvSel.DESCRIPTION))
+ .add(DriverInvSel.DESCRIPTION)
+ .add(TransGate.DESCRIPTION))
.add(new LibraryNode(Lang.get("lib_mux"))
.add(Multiplexer.DESCRIPTION)
.add(Demultiplexer.DESCRIPTION)
diff --git a/src/main/java/de/neemann/digital/draw/shapes/ShapeFactory.java b/src/main/java/de/neemann/digital/draw/shapes/ShapeFactory.java
index 876d0fbae..4502a7c96 100644
--- a/src/main/java/de/neemann/digital/draw/shapes/ShapeFactory.java
+++ b/src/main/java/de/neemann/digital/draw/shapes/ShapeFactory.java
@@ -88,6 +88,7 @@ public final class ShapeFactory {
map.put(FGNFET.DESCRIPTION.getName(), FGFETShapeN::new);
map.put(FGPFET.DESCRIPTION.getName(), FGFETShapeP::new);
map.put(PFET.DESCRIPTION.getName(), FETShapeP::new);
+ map.put(TransGate.DESCRIPTION.getName(), TransGateShape::new);
map.put(Out.DESCRIPTION.getName(), OutputShape::new);
map.put(Out.LEDDESCRIPTION.getName(), LEDShape::new);
map.put(Button.DESCRIPTION.getName(), ButtonShape::new);
diff --git a/src/main/java/de/neemann/digital/draw/shapes/TransGateShape.java b/src/main/java/de/neemann/digital/draw/shapes/TransGateShape.java
new file mode 100644
index 000000000..71476857d
--- /dev/null
+++ b/src/main/java/de/neemann/digital/draw/shapes/TransGateShape.java
@@ -0,0 +1,74 @@
+package de.neemann.digital.draw.shapes;
+
+import de.neemann.digital.core.Observer;
+import de.neemann.digital.core.element.ElementAttributes;
+import de.neemann.digital.core.element.PinDescriptions;
+import de.neemann.digital.draw.elements.IOState;
+import de.neemann.digital.draw.elements.Pin;
+import de.neemann.digital.draw.elements.Pins;
+import de.neemann.digital.draw.graphics.Graphic;
+import de.neemann.digital.draw.graphics.Polygon;
+import de.neemann.digital.draw.graphics.Style;
+import de.neemann.digital.draw.graphics.Vector;
+
+import static de.neemann.digital.draw.shapes.GenericShape.SIZE;
+import static de.neemann.digital.draw.shapes.GenericShape.SIZE2;
+
+/**
+ * Shape of a transmission gate.
+ * Created by hneemann on 17.05.17.
+ */
+public class TransGateShape implements Shape {
+ private static final int RAD = 4;
+ private static final int P = SIZE - 5;
+ private static final Polygon TOP = new Polygon(true)
+ .add(0, 0)
+ .add(0, -SIZE)
+ .add(SIZE * 2, 0)
+ .add(SIZE * 2, -SIZE)
+ .add(0, 0);
+ private static final Polygon BOTTOM = new Polygon(true)
+ .add(0, 0)
+ .add(0, SIZE)
+ .add(SIZE * 2, 0)
+ .add(SIZE * 2, SIZE)
+ .add(0, 0);
+
+ private final PinDescriptions input;
+ private final PinDescriptions output;
+
+ /**
+ * Creates a trantmission gate
+ *
+ * @param attr the attrobutes
+ * @param input inputs
+ * @param output outputs
+ */
+ public TransGateShape(ElementAttributes attr, PinDescriptions input, PinDescriptions output) {
+ this.input = input;
+ this.output = output;
+ }
+
+ @Override
+ public Pins getPins() {
+ return new Pins()
+ .add(new Pin(new Vector(SIZE, -SIZE), input.get(0)))
+ .add(new Pin(new Vector(SIZE, SIZE), input.get(1)))
+ .add(new Pin(new Vector(0, 0), output.get(0)))
+ .add(new Pin(new Vector(SIZE * 2, 0), output.get(1)));
+ }
+
+ @Override
+ public InteractorInterface applyStateMonitor(IOState ioState, Observer guiObserver) {
+ return null;
+ }
+
+ @Override
+ public void drawTo(Graphic graphic, boolean highLight) {
+ graphic.drawPolygon(TOP, Style.NORMAL);
+ graphic.drawPolygon(BOTTOM, Style.NORMAL);
+ graphic.drawLine(new Vector(SIZE, -SIZE), new Vector(SIZE, -SIZE2), Style.NORMAL);
+ graphic.drawCircle(new Vector(SIZE - RAD, P - RAD), new Vector(SIZE + RAD, P + RAD), Style.NORMAL);
+ }
+
+}
diff --git a/src/main/resources/lang/lang_de.xml b/src/main/resources/lang/lang_de.xml
index a83cd37a9..24947fb15 100644
--- a/src/main/resources/lang/lang_de.xml
+++ b/src/main/resources/lang/lang_de.xml
@@ -423,6 +423,13 @@ Die gesammte Speichergröße beträgt damit damit dx*dy*2 Speicherworte.Der Zeilen-Zustand der LEDs einer Spalte. Jedes Bit in diesem Datenwort repräsentiert den Zustand einer Zeile der aktuellen Spalte.
Die Nummer der aktuellen Spalte, dessen Zustand gerade am anderen Eingang anliegt.
+ Transmissionsgatter
+ Ein reales Transmissionsgatter ist aus nur zwei Transistoren aufgebaut.
+ Eingang A
+ Eingang_B
+ Steuereingang
+ Steuereingang, invertiert
+
Fehler
Flipflop hat keine Bezeichnung!
Pin {0} in Element {1} ist werder Eingang noch Ausgang
@@ -515,6 +522,7 @@ Sind evtl. die Namen der Variablen nicht eindeutig?
Testsignal {0} in der Schaltung nicht gefunden!
Es sind nur {1} Bits erlaubt, es sind jedoch {0} Bits angegeben!
Es sind keine Flipflops mit mehr als einem Bit erlaubt!
+ Die Steuereingänge eines Transmission-Gates müssen invertiert beschaltet werden!
Adress-Bits
Anzahl der Adress-Bits die verwendet werden.
diff --git a/src/main/resources/lang/lang_en.xml b/src/main/resources/lang/lang_en.xml
index 678ddfd5a..11a570c94 100644
--- a/src/main/resources/lang/lang_en.xml
+++ b/src/main/resources/lang/lang_en.xml
@@ -413,6 +413,13 @@
The row state of the LEDs of a column. Each bit in this data word represents the state of a row of the current column.
The number of the current column whose state is currently visible at the other input.
+ Transmission-Gate
+ A real transmission-gate is build from only two transistors.
+ input A
+ input B
+ control input.
+ inverted control input
+
Error
D-flip-flop has no label set
Pin {0} in component {1} is not a input or output
@@ -505,6 +512,7 @@ The names of the variables may not be unique.
Test signal {0} not found in the circuit!
Only {1} bits allowed, but {0} bits found!
Flipflops with more then one bits are not allowed!
+ The two control inputs of a transmission gate must be inverted!
Address Bits
Number of address bits used.
diff --git a/src/test/resources/dig/shapes.dig b/src/test/resources/dig/shapes.dig
index be018b686..8224c0a0c 100644
--- a/src/test/resources/dig/shapes.dig
+++ b/src/test/resources/dig/shapes.dig
@@ -1,6 +1,7 @@
1
+
And
@@ -422,6 +423,11 @@
+
+ TransGate
+
+
+
\ No newline at end of file