added a switch and a LUT example using four switches.

This commit is contained in:
hneemann 2016-11-12 16:21:16 +01:00
parent 0a53360c7e
commit ee1e61374e
11 changed files with 531 additions and 5 deletions

View File

@ -0,0 +1,278 @@
<?xml version="1.0" encoding="utf-8"?>
<circuit>
<version>1</version>
<visualElements>
<visualElement>
<elementName>Multiplexer</elementName>
<elementAttributes>
<entry>
<string>Selector Bits</string>
<int>2</int>
</entry>
<entry>
<string>flipSelPos</string>
<boolean>true</boolean>
</entry>
</elementAttributes>
<pos x="140" y="60"/>
</visualElement>
<visualElement>
<elementName>Splitter</elementName>
<elementAttributes>
<entry>
<string>rotation</string>
<rotation rotation="3"/>
</entry>
<entry>
<string>Input Splitting</string>
<string>1,1</string>
</entry>
<entry>
<string>Output Splitting</string>
<string>2</string>
</entry>
</elementAttributes>
<pos x="160" y="-40"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>A</string>
</entry>
</elementAttributes>
<pos x="-80" y="-100"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>B</string>
</entry>
</elementAttributes>
<pos x="-80" y="-60"/>
</visualElement>
<visualElement>
<elementName>Ground</elementName>
<elementAttributes/>
<pos x="100" y="200"/>
</visualElement>
<visualElement>
<elementName>Switch</elementName>
<elementAttributes>
<entry>
<string>Closed</string>
<boolean>true</boolean>
</entry>
<entry>
<string>rotation</string>
<rotation rotation="1"/>
</entry>
<entry>
<string>Label</string>
<string>S_3</string>
</entry>
</elementAttributes>
<pos x="100" y="180"/>
</visualElement>
<visualElement>
<elementName>Ground</elementName>
<elementAttributes/>
<pos x="40" y="200"/>
</visualElement>
<visualElement>
<elementName>Switch</elementName>
<elementAttributes>
<entry>
<string>rotation</string>
<rotation rotation="1"/>
</entry>
<entry>
<string>Label</string>
<string>S_2</string>
</entry>
</elementAttributes>
<pos x="40" y="180"/>
</visualElement>
<visualElement>
<elementName>Ground</elementName>
<elementAttributes/>
<pos x="-20" y="200"/>
</visualElement>
<visualElement>
<elementName>Switch</elementName>
<elementAttributes>
<entry>
<string>rotation</string>
<rotation rotation="1"/>
</entry>
<entry>
<string>Label</string>
<string>S_1</string>
</entry>
</elementAttributes>
<pos x="-20" y="180"/>
</visualElement>
<visualElement>
<elementName>Ground</elementName>
<elementAttributes/>
<pos x="-80" y="200"/>
</visualElement>
<visualElement>
<elementName>Switch</elementName>
<elementAttributes>
<entry>
<string>Closed</string>
<boolean>true</boolean>
</entry>
<entry>
<string>rotation</string>
<rotation rotation="1"/>
</entry>
<entry>
<string>Label</string>
<string>S_0</string>
</entry>
</elementAttributes>
<pos x="-80" y="180"/>
</visualElement>
<visualElement>
<elementName>PullUp</elementName>
<elementAttributes/>
<pos x="-80" y="40"/>
</visualElement>
<visualElement>
<elementName>PullUp</elementName>
<elementAttributes/>
<pos x="-20" y="40"/>
</visualElement>
<visualElement>
<elementName>PullUp</elementName>
<elementAttributes/>
<pos x="40" y="40"/>
</visualElement>
<visualElement>
<elementName>PullUp</elementName>
<elementAttributes/>
<pos x="100" y="40"/>
</visualElement>
<visualElement>
<elementName>Out</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>Y</string>
</entry>
</elementAttributes>
<pos x="220" y="100"/>
</visualElement>
<visualElement>
<elementName>Testcase</elementName>
<elementAttributes>
<entry>
<string>Testdata</string>
<testData>
<dataString>A B Y
0 0 0
0 1 1
1 0 1
1 1 0</dataString>
</testData>
</entry>
</elementAttributes>
<pos x="240" y="-120"/>
</visualElement>
</visualElements>
<wires>
<wire>
<p1 x="-20" y="80"/>
<p2 x="140" y="80"/>
</wire>
<wire>
<p1 x="-80" y="-100"/>
<p2 x="160" y="-100"/>
</wire>
<wire>
<p1 x="40" y="100"/>
<p2 x="140" y="100"/>
</wire>
<wire>
<p1 x="180" y="100"/>
<p2 x="220" y="100"/>
</wire>
<wire>
<p1 x="100" y="120"/>
<p2 x="140" y="120"/>
</wire>
<wire>
<p1 x="-80" y="-60"/>
<p2 x="140" y="-60"/>
</wire>
<wire>
<p1 x="-80" y="60"/>
<p2 x="140" y="60"/>
</wire>
<wire>
<p1 x="160" y="-100"/>
<p2 x="160" y="-40"/>
</wire>
<wire>
<p1 x="160" y="-20"/>
<p2 x="160" y="60"/>
</wire>
<wire>
<p1 x="-20" y="180"/>
<p2 x="-20" y="200"/>
</wire>
<wire>
<p1 x="-20" y="40"/>
<p2 x="-20" y="80"/>
</wire>
<wire>
<p1 x="-20" y="80"/>
<p2 x="-20" y="140"/>
</wire>
<wire>
<p1 x="100" y="180"/>
<p2 x="100" y="200"/>
</wire>
<wire>
<p1 x="100" y="40"/>
<p2 x="100" y="120"/>
</wire>
<wire>
<p1 x="100" y="120"/>
<p2 x="100" y="140"/>
</wire>
<wire>
<p1 x="40" y="180"/>
<p2 x="40" y="200"/>
</wire>
<wire>
<p1 x="40" y="40"/>
<p2 x="40" y="100"/>
</wire>
<wire>
<p1 x="40" y="100"/>
<p2 x="40" y="140"/>
</wire>
<wire>
<p1 x="140" y="-60"/>
<p2 x="140" y="-40"/>
</wire>
<wire>
<p1 x="-80" y="180"/>
<p2 x="-80" y="200"/>
</wire>
<wire>
<p1 x="-80" y="40"/>
<p2 x="-80" y="60"/>
</wire>
<wire>
<p1 x="-80" y="60"/>
<p2 x="-80" y="140"/>
</wire>
</wires>
</circuit>

View File

@ -97,11 +97,17 @@ public final class Keys {
= new Key.KeyBits("Addr Bits");
/**
* signed flag for comparator element
* indicates a diode as blown fuse or as programmed
*/
public static final Key<Boolean> BLOWN
= new Key<>("Blown", false);
/**
* indicates a switch as closed or not
*/
public static final Key<Boolean> CLOSED
= new Key<>("Closed", false);
/**
* signed flag for comparator element
*/

View File

@ -0,0 +1,80 @@
package de.neemann.digital.core.wiring;
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 static de.neemann.digital.core.element.PinInfo.input;
/**
* A simple switch
*/
public class Switch implements Element, Observer {
/**
* The diodes description
*/
public static final ElementTypeDescription DESCRIPTION = new ElementTypeDescription(Switch.class, input("in"))
.addAttribute(Keys.ROTATE)
.addAttribute(Keys.LABEL)
.addAttribute(Keys.CLOSED);
private final ObservableValue output;
private boolean closed;
private ObservableValue input;
/**
* Creates a new instance
*
* @param attr the elements attributes
*/
public Switch(ElementAttributes attr) {
output = new ObservableValue("out", 1, true);
closed = attr.get(Keys.CLOSED);
if (!closed)
output.set(1, true);
}
@Override
public void setInputs(ObservableValues inputs) throws NodeException {
input = inputs.get(0).addObserverToValue(this).checkBits(1, null);
}
@Override
public ObservableValues getOutputs() {
return output.asList();
}
@Override
public void registerNodes(Model model) {
// its just a wire and has no delay, so it is'nt a node
}
@Override
public void hasChanged() {
if (closed) {
output.set(input.getValue(), input.isHighZ());
} else {
output.set(0, true);
}
}
@Override
public void init(Model model) throws NodeException {
hasChanged();
}
/**
* Sets the closed state of the switch
*
* @param closed true if closed
*/
public void setClosed(boolean closed) {
if (this.closed != closed) {
this.closed = closed;
hasChanged();
}
}
}

View File

@ -72,9 +72,10 @@ public class ElementLibrary implements Iterable<ElementLibrary.ElementContainer>
add(Ground.DESCRIPTION, menu);
add(VDD.DESCRIPTION, menu);
add(Splitter.DESCRIPTION, menu);
add(Tunnel.DESCRIPTION, menu);
add(Switch.DESCRIPTION, menu);
add(Clock.DESCRIPTION, menu);
add(Delay.DESCRIPTION, menu);
add(Tunnel.DESCRIPTION, menu);
add(Driver.DESCRIPTION, menu);
add(DriverInvSel.DESCRIPTION, menu);
add(Reset.DESCRIPTION, menu);

View File

@ -78,6 +78,7 @@ public final class ShapeFactory {
map.put(Const.DESCRIPTION.getName(), ConstShape::new);
map.put(Ground.DESCRIPTION.getName(), GroundShape::new);
map.put(VDD.DESCRIPTION.getName(), VDDShape::new);
map.put(Switch.DESCRIPTION.getName(), SwitchShape::new);
map.put(Out.DESCRIPTION.getName(), OutputShape::new);
map.put(Out.LEDDESCRIPTION.getName(), LEDShape::new);
map.put(Button.DESCRIPTION.getName(), ButtonShape::new);

View File

@ -0,0 +1,83 @@
package de.neemann.digital.draw.shapes;
import de.neemann.digital.core.Observer;
import de.neemann.digital.core.element.Element;
import de.neemann.digital.core.element.ElementAttributes;
import de.neemann.digital.core.element.Keys;
import de.neemann.digital.core.element.PinDescriptions;
import de.neemann.digital.core.wiring.Switch;
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.*;
import de.neemann.digital.draw.graphics.Polygon;
import de.neemann.digital.gui.components.CircuitComponent;
import de.neemann.digital.gui.sync.Sync;
import java.awt.*;
import static de.neemann.digital.draw.shapes.GenericShape.SIZE;
import static de.neemann.digital.draw.shapes.GenericShape.SIZE2;
/**
* The diodes shape
*/
public class SwitchShape implements Shape {
private final PinDescriptions inputs;
private final PinDescriptions outputs;
private final String label;
private boolean closed;
/**
* Creates a new instance
*
* @param attributes the attributes
* @param inputs the inputs
* @param outputs the outputs
*/
public SwitchShape(ElementAttributes attributes, PinDescriptions inputs, PinDescriptions outputs) {
this.inputs = inputs;
this.outputs = outputs;
closed = attributes.get(Keys.CLOSED);
label = attributes.getCleanLabel();
}
@Override
public Pins getPins() {
return new Pins()
.add(new Pin(new Vector(0, 0), inputs.get(0)))
.add(new Pin(new Vector(SIZE * 2, 0), outputs.get(0)));
}
@Override
public InteractorInterface applyStateMonitor(IOState ioState, Observer guiObserver) {
return new Interactor() {
@Override
public boolean clicked(CircuitComponent cc, Point pos, IOState ioState, Element element, Sync modelSync) {
closed = !closed;
if (ioState != null) {
modelSync.access(() -> ((Switch) element).setClosed(closed));
}
return true;
}
};
}
@Override
public void drawTo(Graphic graphic, boolean highLight) {
int yOffs = 0;
if (closed) {
graphic.drawLine(new Vector(0, 0), new Vector(SIZE * 2, 0), Style.NORMAL);
} else {
yOffs = SIZE2 / 2;
graphic.drawLine(new Vector(0, 0), new Vector(SIZE * 2 - 4, -yOffs * 2), Style.NORMAL);
}
graphic.drawLine(new Vector(SIZE, -yOffs), new Vector(SIZE, -yOffs - SIZE), Style.THIN);
graphic.drawLine(new Vector(SIZE2, -yOffs - SIZE), new Vector(SIZE + SIZE2, -yOffs - SIZE), Style.THIN);
if (label != null && label.length() > 0)
graphic.drawText(new Vector(SIZE, 4), new Vector(SIZE * 2, 4), label, Orientation.CENTERTOP, Style.SHAPE_PIN);
}
}

View File

@ -50,6 +50,10 @@ Es kann dann ein Programm bis zum nächsten BRK-Befehl ausgeführt werden.</stri
<string name="elem_Ground_tt">Eine Messeverbindung. Gibt immer Null aus.</string>
<string name="elem_VDD">Betriebsspannung</string>
<string name="elem_VDD_tt">Anschluss zur Betriebsspannung. Gibt immer Eins aus.</string>
<string name="elem_Tunnel">Tunnel</string>
<string name="elem_Tunnel_tt">Verbindet Elemente, ohne eine Leitung zu ziehen. Alle Tunnelelemente, welche den selben Netznamen tragen, sind miteinander verbunden. Der Tunnel ist immer lokal, es können keine Verbindungen über Schaltungsgrenzen hinaus erzeugt werden.</string>
<string name="elem_Switch">Schalter</string>
<string name="elem_Switch_tt">Einfacher unidirektionaler Schalter.</string>
<string name="elem_Counter">Zähler</string>
<string name="elem_D_FF">D_FF</string>
<string name="elem_Data">Messwertgraph</string>
@ -124,7 +128,7 @@ in der Stabilisierungsphase befindet. Hat sich die Schaltung stabilisiert wird d
<string name="elem_Seven-Seg-Hex_tt">Siebensegmentanzeige mit einem 4 Bit hexadezimalen Eingang.</string>
<string name="elem_Seven-Seg_tt">Siebensegmentanzeige bei der jedes Segment über einen eigenen Eingang gesteuert werden kann.</string>
<string name="elem_Splitter">Splitter</string>
<string name="elem_Splitter_tt">Führt mehrere Leitungen zu einer gemeinsamen Leitung zusammen, bzw. splittet diese wieder auf.</string>
<string name="elem_Splitter_tt">Führt mehrere Leitungen zu einem gemeinsamen Bus zusammen, bzw. splittet diesen wieder auf.</string>
<string name="elem_Sub">Subtrahierer</string>
<string name="elem_T_FF">T_FF</string>
<string name="elem_Terminal">Terminal</string>
@ -260,6 +264,8 @@ Zur Analyse können Sie die Schaltung im Gatterschrittmodus ausführen.</string>
<string name="key_SelectorBits">Anzahl der Auswahlbits</string>
<string name="key_SelectorBits_tt">Anzahl der Bits, die in der Auswahlleitung vorhanden sind.</string>
<string name="key_Signed">Vorzeichen</string>
<string name="key_Closed">Geschlossen</string>
<string name="key_Closed_tt">Gibt an, ob der Schalter bei Modelstart offen oder geschlossen ist.</string>
<string name="key_Value">Wert</string>
<string name="key_Width">Breite</string>
<string name="key_Width_tt">Breite des Symbols wenn diese Schaltung in eine andere eingefügt wird.</string>

View File

@ -50,6 +50,10 @@ Then you can execute the circuit to the next BRK instruction.</string>
<string name="elem_Ground_tt">A connection to ground. Output is always zero.</string>
<string name="elem_VDD">Supply voltage</string>
<string name="elem_VDD_tt">A connection to the supply voltage. Output is always one.</string>
<string name="elem_Tunnel">Tunnel</string>
<string name="elem_Tunnel_tt">Connects parts without a wire. All tunnel elements, which have the same net name, are connected together. Works only local, so it is not possible to connect different circuits.</string>
<string name="elem_Switch">Switch</string>
<string name="elem_Switch_tt">Simple unidirectional switch.</string>
<string name="elem_Counter">Counter</string>
<string name="elem_D_FF">D_FF</string>
<string name="elem_Data">Data graph</string>
@ -255,6 +259,8 @@ To analyse you can run the circuit in single gate step mode.</string>
<string name="key_SelectorBits">Number of Selector Bits</string>
<string name="key_SelectorBits_tt">Number of bits used for the selector input.</string>
<string name="key_Signed">Signed</string>
<string name="key_Closed">Closed</string>
<string name="key_Closed_tt">Sets the initial state of the switch.</string>
<string name="key_Value">Value</string>
<string name="key_Width">Width</string>
<string name="key_Width_tt">With of symbol if this circuit is used as an component in an other circuit.</string>

View File

@ -0,0 +1,50 @@
package de.neemann.digital.core.wiring;
import de.neemann.digital.core.NodeException;
import de.neemann.digital.core.ObservableValue;
import de.neemann.digital.core.element.ElementAttributes;
import de.neemann.digital.core.element.Keys;
import junit.framework.TestCase;
/**
* Created by hneemann on 12.11.16.
*/
public class SwitchTest extends TestCase {
public void testSwitchOn() throws NodeException {
ObservableValue in = new ObservableValue("a", 1);
Switch aSwitch = new Switch(new ElementAttributes().set(Keys.CLOSED, true));
aSwitch.setInputs(in.asList());
ObservableValue out = aSwitch.getOutputs().get(0);
in.set(1,false);
assertEquals(1, out.getValue());
assertFalse(out.isHighZ());
in.set(0,false);
assertEquals(0, out.getValue());
assertFalse(out.isHighZ());
in.set(0,true);
assertTrue(out.isHighZ());
}
public void testSwitchOff() throws NodeException {
ObservableValue in = new ObservableValue("a", 1);
Switch aSwitch = new Switch(new ElementAttributes().set(Keys.CLOSED, false));
aSwitch.setInputs(in.asList());
ObservableValue out = aSwitch.getOutputs().get(0);
in.set(1,false);
assertTrue(out.isHighZ());
in.set(0,false);
assertTrue(out.isHighZ());
in.set(0,true);
assertTrue(out.isHighZ());
}
}

View File

@ -27,8 +27,8 @@ public class TestExamples extends TestCase {
*/
public void testDistExamples() throws Exception {
File examples = new File(Resources.getRoot().getParentFile().getParentFile(), "/main/dig");
assertEquals(86, new FileScanner(this::check).scan(examples));
assertEquals(15,testCasesInFiles);
assertEquals(87, new FileScanner(this::check).scan(examples));
assertEquals(16,testCasesInFiles);
}
/**

View File

@ -372,6 +372,21 @@
<elementAttributes/>
<pos x="640" y="740"/>
</visualElement>
<visualElement>
<elementName>Ground</elementName>
<elementAttributes/>
<pos x="600" y="460"/>
</visualElement>
<visualElement>
<elementName>VDD</elementName>
<elementAttributes/>
<pos x="660" y="460"/>
</visualElement>
<visualElement>
<elementName>Switch</elementName>
<elementAttributes/>
<pos x="720" y="460"/>
</visualElement>
</visualElements>
<wires/>
</circuit>