adds a pin control logic, see #394

This commit is contained in:
hneemann 2019-12-14 10:20:04 +01:00
parent 545e2ab57a
commit a4d65b9d02
7 changed files with 241 additions and 8 deletions

View File

@ -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);
}
}

View File

@ -143,7 +143,8 @@ public class ElementLibrary implements Iterable<ElementLibrary.ElementContainer>
.add(Keyboard.DESCRIPTION) .add(Keyboard.DESCRIPTION)
.add(Terminal.DESCRIPTION) .add(Terminal.DESCRIPTION)
.add(VGA.DESCRIPTION) .add(VGA.DESCRIPTION)
.add(MIDI.DESCRIPTION))) .add(MIDI.DESCRIPTION)
.add(PinControl.DESCRIPTION)))
.add(new LibraryNode(Lang.get("lib_wires")) .add(new LibraryNode(Lang.get("lib_wires"))
.add(Ground.DESCRIPTION) .add(Ground.DESCRIPTION)
.add(VDD.DESCRIPTION) .add(VDD.DESCRIPTION)

View File

@ -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);
}
}

View File

@ -163,6 +163,7 @@ public final class ShapeFactory {
map.put(DiodeBackward.DESCRIPTION.getName(), DiodeBackwardShape::new); map.put(DiodeBackward.DESCRIPTION.getName(), DiodeBackwardShape::new);
map.put(PullUp.DESCRIPTION.getName(), PullUpShape::new); map.put(PullUp.DESCRIPTION.getName(), PullUpShape::new);
map.put(PullDown.DESCRIPTION.getName(), PullDownShape::new); map.put(PullDown.DESCRIPTION.getName(), PullDownShape::new);
map.put(PinControl.DESCRIPTION.getName(), PinControlShape::new);
// disables string formatting for external components, see #272 // disables string formatting for external components, see #272
map.put(External.DESCRIPTION.getName(), map.put(External.DESCRIPTION.getName(),

View File

@ -338,25 +338,45 @@
<string name="elem_Driver_pin_sel">Eingang zum Steuern des Treibers. <string name="elem_Driver_pin_sel">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.</string> Ist dieser Eingang auf 1 gesetzt, wird der am Eingang anliegende Wert zum Ausgang gereicht. Ist der Eingang 0, ist der Ausgang hochohmig.</string>
<string name="elem_DriverInvSel">Treiber, invertierte Auswahl</string> <string name="elem_DriverInvSel">Treiber, invertierte Auswahl</string>
<string name="elem_DriverInvSel_tt">Ein Treiber kann dazu verwendet werden, ein Datenwort nur unter speziellen Voraussetzungen auf eine andere Leitung weiterzureichen. <string name="elem_DriverInvSel_tt">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. 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 sel Eingang auf 0 gesetzt, wird der am Eingang anliegende Wert zum Ausgang gereicht.
Ist der Eingang 1, ist der Ausgang hochohmig. Ist der Eingang 1, ist der Ausgang hochohmig.
</string> </string>
<string name="elem_DriverInvSel_pin_in">Das Eingangssignal des Treibers.</string> <string name="elem_DriverInvSel_pin_in">Das Eingangssignal des Treibers.</string>
<string name="elem_DriverInvSel_pin_sel">Eingang zum Steuern des Treibers. <string name="elem_DriverInvSel_pin_sel">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.</string> Ist dieser Eingang auf 0 gesetzt, wird der am Eingang anliegende Wert zum Ausgang gereicht. Ist der Eingang 1,
<string name="elem_DriverInvSel_pin_out">Gibt den am Eingang anliegenden Wert aus, wenn der Selection Eingang auf 0 gesetzt ist.</string> ist der Ausgang hochohmig.
</string>
<string name="elem_DriverInvSel_pin_out">Gibt den am Eingang anliegenden Wert aus, wenn der Selection Eingang auf 0
gesetzt ist.
</string>
<string name="elem_PinControl">Pinsteuerung</string>
<string name="elem_PinControl_tt">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!
</string>
<string name="elem_PinControl_pin_wr">Die auszugebenden Daten</string>
<string name="elem_PinControl_pin_oe">Aktiviert die Ausgabe</string>
<string name="elem_PinControl_pin_rd">Die zu lesenden Daten.</string>
<string name="elem_PinControl_pin_out">Der Anschluss für den eigentlichen Pin. Hier sollte nur noch ein einzelner
Eingang angeschlossen werden.
</string>
<!-- Plexers --> <!-- Plexers -->
<string name="elem_Multiplexer">Multiplexer</string> <string name="elem_Multiplexer">Multiplexer</string>
<string name="elem_Multiplexer_tt">Ein Baustein, welcher den Wert eines der Eingänge am Ausgang ausgibt. <string name="elem_Multiplexer_tt">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.</string> Über den sel-Eingang wird ausgewählt, welcher der Eingänge ausgegeben werden soll.
</string>
<string name="elem_Multiplexer_input">Der {0}. Dateneingang des Multiplexers.</string> <string name="elem_Multiplexer_input">Der {0}. Dateneingang des Multiplexers.</string>
<string name="elem_Multiplexer_output">Ausgeben wird der Wert, der am gewählten Dateneingang anliegt.</string> <string name="elem_Multiplexer_output">Ausgeben wird der Wert, der am gewählten Dateneingang anliegt.</string>
<string name="elem_Multiplexer_pin_sel">Mit dieser Leitung wird der Dateneingang ausgewählt, welcher am Ausgang ausgegeben werden soll.</string> <string name="elem_Multiplexer_pin_sel">Mit dieser Leitung wird der Dateneingang ausgewählt, welcher am Ausgang
ausgegeben werden soll.
</string>
<string name="elem_Demultiplexer">Demultiplexer</string> <string name="elem_Demultiplexer">Demultiplexer</string>
<string name="elem_Demultiplexer_tt">Ein Baustein, welcher einen Eingangswert auf verschiedene Ausgänge ausgeben kann. <string name="elem_Demultiplexer_tt">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.</string> Gibt das Eingangssignal auf einem wählbaren Ausgang aus. Die anderen Ausgänge werden auf den Vorgabewert gesetzt.</string>

View File

@ -363,11 +363,24 @@
If the sel input is 1, this output is in high z state. If the sel input is 1, this output is in high z state.
</string> </string>
<string name="elem_PinControl">Pin Control</string>
<string name="elem_PinControl_tt">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!
</string>
<string name="elem_PinControl_pin_wr">The data to be output.</string>
<string name="elem_PinControl_pin_oe">Activates the output.</string>
<string name="elem_PinControl_pin_rd">The data to be read.</string>
<string name="elem_PinControl_pin_out">The connector for the actual pin. Only a single input should be connected
here.
</string>
<!-- Plexers --> <!-- Plexers -->
<string name="elem_Multiplexer">Multiplexer</string> <string name="elem_Multiplexer">Multiplexer</string>
<string name="elem_Multiplexer_tt">A component which uses the value of the sel pin to decide which input value is set to the output.</string> <string name="elem_Multiplexer_tt">A component which uses the value of the sel pin to decide which input value is
set to the output.
</string>
<string name="elem_Multiplexer_input">The {0}. data input of the multiplexer.</string> <string name="elem_Multiplexer_input">The {0}. data input of the multiplexer.</string>
<string name="elem_Multiplexer_output">The value of the selected input.</string> <string name="elem_Multiplexer_output">The value of the selected input.</string>
<string name="elem_Multiplexer_pin_sel">This input is used to select the data input which is output.</string> <string name="elem_Multiplexer_pin_sel">This input is used to select the data input which is output.</string>

View File

@ -614,6 +614,30 @@
<elementAttributes/> <elementAttributes/>
<pos x="600" y="920"/> <pos x="600" y="920"/>
</visualElement> </visualElement>
<visualElement>
<elementName>PinControl</elementName>
<elementAttributes>
<entry>
<string>Bits</string>
<int>8</int>
</entry>
</elementAttributes>
<pos x="780" y="960"/>
</visualElement>
<visualElement>
<elementName>Tunnel</elementName>
<elementAttributes>
<entry>
<string>rotation</string>
<rotation rotation="2"/>
</entry>
<entry>
<string>NetName</string>
<string>zz</string>
</entry>
</elementAttributes>
<pos x="760" y="940"/>
</visualElement>
</visualElements> </visualElements>
<wires> <wires>
<wire> <wire>
@ -716,6 +740,10 @@
<p1 x="1080" y="900"/> <p1 x="1080" y="900"/>
<p2 x="1120" y="900"/> <p2 x="1120" y="900"/>
</wire> </wire>
<wire>
<p1 x="580" y="900"/>
<p2 x="700" y="900"/>
</wire>
<wire> <wire>
<p1 x="780" y="200"/> <p1 x="780" y="200"/>
<p2 x="800" y="200"/> <p2 x="800" y="200"/>
@ -856,6 +884,10 @@
<p1 x="580" y="980"/> <p1 x="580" y="980"/>
<p2 x="600" y="980"/> <p2 x="600" y="980"/>
</wire> </wire>
<wire>
<p1 x="700" y="980"/>
<p2 x="780" y="980"/>
</wire>
<wire> <wire>
<p1 x="280" y="980"/> <p1 x="280" y="980"/>
<p2 x="300" y="980"/> <p2 x="300" y="980"/>
@ -1060,6 +1092,14 @@
<p1 x="580" y="940"/> <p1 x="580" y="940"/>
<p2 x="600" y="940"/> <p2 x="600" y="940"/>
</wire> </wire>
<wire>
<p1 x="760" y="940"/>
<p2 x="780" y="940"/>
</wire>
<wire>
<p1 x="780" y="940"/>
<p2 x="820" y="940"/>
</wire>
<wire> <wire>
<p1 x="1080" y="620"/> <p1 x="1080" y="620"/>
<p2 x="1100" y="620"/> <p2 x="1100" y="620"/>
@ -1330,7 +1370,7 @@
</wire> </wire>
<wire> <wire>
<p1 x="580" y="860"/> <p1 x="580" y="860"/>
<p2 x="580" y="920"/> <p2 x="580" y="900"/>
</wire> </wire>
<wire> <wire>
<p1 x="580" y="360"/> <p1 x="580" y="360"/>
@ -1340,6 +1380,10 @@
<p1 x="580" y="380"/> <p1 x="580" y="380"/>
<p2 x="580" y="420"/> <p2 x="580" y="420"/>
</wire> </wire>
<wire>
<p1 x="580" y="900"/>
<p2 x="580" y="920"/>
</wire>
<wire> <wire>
<p1 x="580" y="920"/> <p1 x="580" y="920"/>
<p2 x="580" y="940"/> <p2 x="580" y="940"/>
@ -1460,6 +1504,10 @@
<p1 x="460" y="400"/> <p1 x="460" y="400"/>
<p2 x="460" y="420"/> <p2 x="460" y="420"/>
</wire> </wire>
<wire>
<p1 x="780" y="940"/>
<p2 x="780" y="960"/>
</wire>
<wire> <wire>
<p1 x="780" y="180"/> <p1 x="780" y="180"/>
<p2 x="780" y="200"/> <p2 x="780" y="200"/>
@ -1788,6 +1836,10 @@
<p1 x="500" y="760"/> <p1 x="500" y="760"/>
<p2 x="500" y="840"/> <p2 x="500" y="840"/>
</wire> </wire>
<wire>
<p1 x="820" y="940"/>
<p2 x="820" y="960"/>
</wire>
<wire> <wire>
<p1 x="440" y="560"/> <p1 x="440" y="560"/>
<p2 x="440" y="580"/> <p2 x="440" y="580"/>
@ -1888,6 +1940,10 @@
<p1 x="700" y="160"/> <p1 x="700" y="160"/>
<p2 x="700" y="460"/> <p2 x="700" y="460"/>
</wire> </wire>
<wire>
<p1 x="700" y="900"/>
<p2 x="700" y="980"/>
</wire>
<wire> <wire>
<p1 x="700" y="460"/> <p1 x="700" y="460"/>
<p2 x="700" y="540"/> <p2 x="700" y="540"/>