diff --git a/src/main/java/de/neemann/digital/core/io/PinControl.java b/src/main/java/de/neemann/digital/core/io/PinControl.java new file mode 100644 index 000000000..be9b3f3de --- /dev/null +++ b/src/main/java/de/neemann/digital/core/io/PinControl.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2019 Helmut Neemann. + * Use of this source code is governed by the GPL v3 license + * that can be found in the LICENSE file. + */ +package de.neemann.digital.core.io; + +import de.neemann.digital.core.Node; +import de.neemann.digital.core.NodeException; +import de.neemann.digital.core.ObservableValue; +import de.neemann.digital.core.ObservableValues; +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 static de.neemann.digital.core.element.PinInfo.input; + +/** + * The pin control logic + */ +public class PinControl extends Node implements Element { + + /** + * The description of the pin control logic + */ + public static final ElementTypeDescription DESCRIPTION = new ElementTypeDescription(PinControl.class, input("wr"), input("oe")) + .addAttribute(Keys.ROTATE) + .addAttribute(Keys.BITS); + + private final int bits; + private final ObservableValue rdValue; + private final ObservableValue outWriteValue; + private ObservableValue wrValue; + private ObservableValue oeValue; + private ObservableValue outReadValue; + private long wr; + private boolean oe; + private long outRead; + + /** + * Creates a new instance + * + * @param attr the elements attributes + */ + public PinControl(ElementAttributes attr) { + bits = attr.getBits(); + rdValue = new ObservableValue("rd", bits).setPinDescription(DESCRIPTION); + outWriteValue = new ObservableValue("out", bits).setPinDescription(DESCRIPTION).setBidirectional(); + } + + @Override + public void setInputs(ObservableValues inputs) throws NodeException { + wrValue = inputs.get(0).addObserverToValue(this).checkBits(bits, this); + oeValue = inputs.get(1).addObserverToValue(this).checkBits(1, this); + outReadValue = inputs.get(2).addObserverToValue(this).checkBits(bits, this); + } + + @Override + public void readInputs() throws NodeException { + wr = wrValue.getValue(); + oe = oeValue.getBool(); + outRead = outReadValue.getValue(); + } + + @Override + public void writeOutputs() throws NodeException { + if (oe) { + outWriteValue.setValue(wr); + rdValue.setValue(wr); + } else { + outWriteValue.setToHighZ(); + rdValue.setValue(outRead); + } + } + + + @Override + public ObservableValues getOutputs() { + return new ObservableValues(rdValue, outWriteValue); + } +} 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 f981e04be..c29c20e47 100644 --- a/src/main/java/de/neemann/digital/draw/library/ElementLibrary.java +++ b/src/main/java/de/neemann/digital/draw/library/ElementLibrary.java @@ -143,7 +143,8 @@ public class ElementLibrary implements Iterable .add(Keyboard.DESCRIPTION) .add(Terminal.DESCRIPTION) .add(VGA.DESCRIPTION) - .add(MIDI.DESCRIPTION))) + .add(MIDI.DESCRIPTION) + .add(PinControl.DESCRIPTION))) .add(new LibraryNode(Lang.get("lib_wires")) .add(Ground.DESCRIPTION) .add(VDD.DESCRIPTION) diff --git a/src/main/java/de/neemann/digital/draw/shapes/PinControlShape.java b/src/main/java/de/neemann/digital/draw/shapes/PinControlShape.java new file mode 100644 index 000000000..4b8bb9649 --- /dev/null +++ b/src/main/java/de/neemann/digital/draw/shapes/PinControlShape.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2019 Helmut Neemann. + * Use of this source code is governed by the GPL v3 license + * that can be found in the LICENSE file. + */ +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.Style; +import de.neemann.digital.draw.graphics.Vector; + +import static de.neemann.digital.draw.shapes.GenericShape.SIZE; + +/** + * The shape for the pin control logic + */ +public class PinControlShape implements Shape { + private final PinDescriptions in; + private final PinDescriptions out; + + /** + * Creates a new instance + * + * @param attr the elements attributes + * @param in the inputs + * @param out the outputs + */ + public PinControlShape(ElementAttributes attr, PinDescriptions in, PinDescriptions out) { + this.in = in; + this.out = out; + } + + @Override + public Pins getPins() { + return new Pins() + .add(new Pin(new Vector(0, -SIZE), in.get(0))) + .add(new Pin(new Vector(0, 0), out.get(0))) + .add(new Pin(new Vector(0, +SIZE), in.get(1))) + .add(new Pin(new Vector(SIZE * 2, 0), out.get(1))); + } + + @Override + public InteractorInterface applyStateMonitor(IOState ioState, Observer guiObserver) { + return null; + } + + @Override + public void drawTo(Graphic graphic, Style highLight) { + graphic.drawLine(new Vector(0, -SIZE), new Vector(SIZE, 0), Style.NORMAL); + graphic.drawLine(new Vector(0, 0), new Vector(SIZE, 0), Style.NORMAL); + graphic.drawLine(new Vector(0, SIZE), new Vector(SIZE, 0), Style.NORMAL); + graphic.drawLine(new Vector(SIZE, 0), new Vector(SIZE * 2, 0), Style.NORMAL); + } +} 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 6081000f8..5baafa7d8 100644 --- a/src/main/java/de/neemann/digital/draw/shapes/ShapeFactory.java +++ b/src/main/java/de/neemann/digital/draw/shapes/ShapeFactory.java @@ -163,6 +163,7 @@ public final class ShapeFactory { map.put(DiodeBackward.DESCRIPTION.getName(), DiodeBackwardShape::new); map.put(PullUp.DESCRIPTION.getName(), PullUpShape::new); map.put(PullDown.DESCRIPTION.getName(), PullDownShape::new); + map.put(PinControl.DESCRIPTION.getName(), PinControlShape::new); // disables string formatting for external components, see #272 map.put(External.DESCRIPTION.getName(), diff --git a/src/main/resources/lang/lang_de.xml b/src/main/resources/lang/lang_de.xml index 2a60b4b96..76112b696 100644 --- a/src/main/resources/lang/lang_de.xml +++ b/src/main/resources/lang/lang_de.xml @@ -338,25 +338,45 @@ Eingang zum Steuern des Treibers. Ist dieser Eingang auf 1 gesetzt, wird der am Eingang anliegende Wert zum Ausgang gereicht. Ist der Eingang 0, ist der Ausgang hochohmig. Treiber, invertierte Auswahl - Ein Treiber kann dazu verwendet werden, ein Datenwort nur unter speziellen Voraussetzungen auf eine andere Leitung weiterzureichen. + Ein Treiber kann dazu verwendet werden, ein Datenwort nur unter speziellen + Voraussetzungen auf eine andere Leitung weiterzureichen. Gesteuert wird der Treiber durch den sel Eingang. Ist der sel Eingang auf 0 gesetzt, wird der am Eingang anliegende Wert zum Ausgang gereicht. Ist der Eingang 1, ist der Ausgang hochohmig. Das Eingangssignal des Treibers. Eingang zum Steuern des Treibers. - Ist dieser Eingang auf 0 gesetzt, wird der am Eingang anliegende Wert zum Ausgang gereicht. Ist der Eingang 1, ist der Ausgang hochohmig. - Gibt den am Eingang anliegenden Wert aus, wenn der Selection Eingang auf 0 gesetzt ist. + Ist dieser Eingang auf 0 gesetzt, wird der am Eingang anliegende Wert zum Ausgang gereicht. Ist der Eingang 1, + ist der Ausgang hochohmig. + + Gibt den am Eingang anliegenden Wert aus, wenn der Selection Eingang auf 0 + gesetzt ist. + + Pinsteuerung + Steuerlogik für einen bidirektionalen Pin. + Nur im Rahmen der VHDL- oder Verilog-Generierung erforderlich! + Diese Komponente ist notwendig, um einen bidirektionalen HDL-Port zu erstellen! + Wenn Sie keinen bidirektionalen IO-Port auf einem FPGA verwenden wollen, verwenden Sie diese Komponente nicht! + + Die auszugebenden Daten + Aktiviert die Ausgabe + Die zu lesenden Daten. + Der Anschluss für den eigentlichen Pin. Hier sollte nur noch ein einzelner + Eingang angeschlossen werden. + Multiplexer Ein Baustein, welcher den Wert eines der Eingänge am Ausgang ausgibt. - Über den sel-Eingang wird ausgewählt, welcher der Eingänge ausgegeben werden soll. + Über den sel-Eingang wird ausgewählt, welcher der Eingänge ausgegeben werden soll. + Der {0}. Dateneingang des Multiplexers. Ausgeben wird der Wert, der am gewählten Dateneingang anliegt. - Mit dieser Leitung wird der Dateneingang ausgewählt, welcher am Ausgang ausgegeben werden soll. + Mit dieser Leitung wird der Dateneingang ausgewählt, welcher am Ausgang + ausgegeben werden soll. + Demultiplexer Ein Baustein, welcher einen Eingangswert auf verschiedene Ausgänge ausgeben kann. Gibt das Eingangssignal auf einem wählbaren Ausgang aus. Die anderen Ausgänge werden auf den Vorgabewert gesetzt. diff --git a/src/main/resources/lang/lang_en.xml b/src/main/resources/lang/lang_en.xml index 9084ba4f8..cac2712ec 100644 --- a/src/main/resources/lang/lang_en.xml +++ b/src/main/resources/lang/lang_en.xml @@ -363,11 +363,24 @@ If the sel input is 1, this output is in high z state. + Pin Control + Control logic for a bi-directional pin. Only needed in the context of VHDL or + Verilog generation! This component is necessary to create a bi-directional HDL port! If you don't want + to use a di-directional IO-port on an FPGA, don't use this component! + + The data to be output. + Activates the output. + The data to be read. + The connector for the actual pin. Only a single input should be connected + here. + Multiplexer - A component which uses the value of the sel pin to decide which input value is set to the output. + A component which uses the value of the sel pin to decide which input value is + set to the output. + The {0}. data input of the multiplexer. The value of the selected input. This input is used to select the data input which is output. diff --git a/src/test/resources/dig/backtrack/AllComponents.dig b/src/test/resources/dig/backtrack/AllComponents.dig index 3c5cbab72..d9fab394c 100644 --- a/src/test/resources/dig/backtrack/AllComponents.dig +++ b/src/test/resources/dig/backtrack/AllComponents.dig @@ -614,6 +614,30 @@ + + PinControl + + + Bits + 8 + + + + + + Tunnel + + + rotation + + + + NetName + zz + + + + @@ -716,6 +740,10 @@ + + + + @@ -856,6 +884,10 @@ + + + + @@ -1060,6 +1092,14 @@ + + + + + + + + @@ -1330,7 +1370,7 @@ - + @@ -1340,6 +1380,10 @@ + + + + @@ -1460,6 +1504,10 @@ + + + + @@ -1788,6 +1836,10 @@ + + + + @@ -1888,6 +1940,10 @@ + + + +