mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-15 15:58:41 -04:00
added multiplexer and demultiplexer
This commit is contained in:
parent
7a379e7f68
commit
278fffe42e
@ -14,6 +14,7 @@ public class AttributeKey<VALUE> {
|
|||||||
public static final AttributeKey<String> InputSplit = new AttributeKey<>("Input Splitting", "");
|
public static final AttributeKey<String> InputSplit = new AttributeKey<>("Input Splitting", "");
|
||||||
public static final AttributeKey<String> OutputSplit = new AttributeKey<>("Output Splitting", "");
|
public static final AttributeKey<String> OutputSplit = new AttributeKey<>("Output Splitting", "");
|
||||||
public static final AttributeKey<Integer> Frequency = new AttributeKey<>("Frequency", 1);
|
public static final AttributeKey<Integer> Frequency = new AttributeKey<>("Frequency", 1);
|
||||||
|
public static final AttributeKey<Integer> SelectorBits = new AttributeKey<>("Selector Bits", 1);
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
private final VALUE def;
|
private final VALUE def;
|
||||||
|
@ -21,14 +21,16 @@ public interface Element {
|
|||||||
void setInputs(ObservableValue... inputs) throws NodeException;
|
void setInputs(ObservableValue... inputs) throws NodeException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When the connections between the elements are build
|
* When the connections between the elements are build all outputs a collected
|
||||||
|
* by calling this method. After the interconnection they are set to the inputs
|
||||||
|
* by calling <code>setInputs()</code>
|
||||||
*
|
*
|
||||||
* @return the list of outputs wich are set by this element
|
* @return the list of outputs wich are set by this element
|
||||||
*/
|
*/
|
||||||
ObservableValue[] getOutputs();
|
ObservableValue[] getOutputs();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The element has to connect itself to the model.
|
* The element has to register itself to the model.
|
||||||
*
|
*
|
||||||
* @param model the model to register to
|
* @param model the model to register to
|
||||||
*/
|
*/
|
||||||
@ -40,5 +42,4 @@ public interface Element {
|
|||||||
default void init() {
|
default void init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,68 @@
|
|||||||
|
package de.neemann.digital.core.wiring;
|
||||||
|
|
||||||
|
import de.neemann.digital.core.Node;
|
||||||
|
import de.neemann.digital.core.NodeException;
|
||||||
|
import de.neemann.digital.core.ObservableValue;
|
||||||
|
import de.neemann.digital.core.element.AttributeKey;
|
||||||
|
import de.neemann.digital.core.element.Element;
|
||||||
|
import de.neemann.digital.core.element.ElementAttributes;
|
||||||
|
import de.neemann.digital.core.element.ElementTypeDescription;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author hneemann
|
||||||
|
*/
|
||||||
|
public class Demultiplexer extends Node implements Element {
|
||||||
|
|
||||||
|
private final int selectorBits;
|
||||||
|
private final Integer bits;
|
||||||
|
private final long defaultValue;
|
||||||
|
private final ObservableValue[] output;
|
||||||
|
private ObservableValue selector;
|
||||||
|
private ObservableValue input;
|
||||||
|
|
||||||
|
private int oldSelectorValue;
|
||||||
|
private int selectorValue;
|
||||||
|
private long value;
|
||||||
|
|
||||||
|
public static final ElementTypeDescription DESCRIPTION = new ElementTypeDescription(Demultiplexer.class, "sel", "in")
|
||||||
|
.addAttribute(AttributeKey.Bits)
|
||||||
|
.addAttribute(AttributeKey.SelectorBits)
|
||||||
|
.addAttribute(AttributeKey.Default);
|
||||||
|
|
||||||
|
public Demultiplexer(ElementAttributes attributes) {
|
||||||
|
bits = attributes.get(AttributeKey.Bits);
|
||||||
|
this.selectorBits = attributes.get(AttributeKey.SelectorBits);
|
||||||
|
this.defaultValue = attributes.get(AttributeKey.Default);
|
||||||
|
int outputs = 1 << selectorBits;
|
||||||
|
output = new ObservableValue[outputs];
|
||||||
|
for (int i = 0; i < outputs; i++) {
|
||||||
|
output[i] = new ObservableValue("out_" + i, bits);
|
||||||
|
output[i].setValue(defaultValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ObservableValue[] getOutputs() {
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readInputs() throws NodeException {
|
||||||
|
selectorValue = (int) selector.getValue();
|
||||||
|
value = input.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeOutputs() throws NodeException {
|
||||||
|
output[oldSelectorValue].setValue(defaultValue);
|
||||||
|
output[selectorValue].setValue(value);
|
||||||
|
oldSelectorValue = selectorValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInputs(ObservableValue... inputs) throws NodeException {
|
||||||
|
selector = inputs[0].addObserver(this).checkBits(selectorBits, this);
|
||||||
|
input = inputs[1].addObserver(this).checkBits(bits, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -4,6 +4,9 @@ import de.neemann.digital.core.BitsException;
|
|||||||
import de.neemann.digital.core.NodeException;
|
import de.neemann.digital.core.NodeException;
|
||||||
import de.neemann.digital.core.ObservableValue;
|
import de.neemann.digital.core.ObservableValue;
|
||||||
import de.neemann.digital.core.basic.FanIn;
|
import de.neemann.digital.core.basic.FanIn;
|
||||||
|
import de.neemann.digital.core.element.AttributeKey;
|
||||||
|
import de.neemann.digital.core.element.ElementAttributes;
|
||||||
|
import de.neemann.digital.core.element.ElementTypeDescription;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
@ -16,17 +19,28 @@ public class Multiplexer extends FanIn {
|
|||||||
private ObservableValue selector;
|
private ObservableValue selector;
|
||||||
private long value;
|
private long value;
|
||||||
|
|
||||||
public Multiplexer(int dataBits, int selectorBits) {
|
public static final ElementTypeDescription DESCRIPTION = new ElementTypeDescription(Multiplexer.class) {
|
||||||
super(dataBits);
|
@Override
|
||||||
this.selectorBits = selectorBits;
|
public String[] getInputNames(ElementAttributes elementAttributes) {
|
||||||
|
int size = 1 << elementAttributes.get(AttributeKey.SelectorBits);
|
||||||
|
String[] names = new String[size + 1];
|
||||||
|
names[0] = "sel";
|
||||||
|
for (int i = 0; i < size; i++)
|
||||||
|
names[i + 1] = "in_" + i;
|
||||||
|
return names;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.addAttribute(AttributeKey.Bits)
|
||||||
|
.addAttribute(AttributeKey.SelectorBits);
|
||||||
|
|
||||||
|
public Multiplexer(ElementAttributes attributes) {
|
||||||
|
super(attributes.get(AttributeKey.Bits));
|
||||||
|
this.selectorBits = attributes.get(AttributeKey.SelectorBits);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void readInputs() throws NodeException {
|
public void readInputs() throws NodeException {
|
||||||
int n = (int) selector.getValue();
|
int n = (int) selector.getValue();
|
||||||
if (n >= inputs.size())
|
|
||||||
throw new NodeException("multiplexerSelectsNotPresentInput", this);
|
|
||||||
|
|
||||||
value = inputs.get(n).getValue();
|
value = inputs.get(n).getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37,11 +51,11 @@ public class Multiplexer extends FanIn {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setInputs(ObservableValue... inputs) throws NodeException {
|
public void setInputs(ObservableValue... inputs) throws NodeException {
|
||||||
selector = inputs[inputs.length - 1];
|
selector = inputs[0].addObserver(this).checkBits(selectorBits, this);
|
||||||
selector.addObserver(this);
|
ObservableValue[] in = Arrays.copyOfRange(inputs, 1, inputs.length);
|
||||||
super.setInputs(Arrays.copyOfRange(inputs, 0, inputs.length - 1));
|
super.setInputs(in);
|
||||||
|
|
||||||
if (selector.getBits() != selectorBits)
|
if (in.length != (1 << selectorBits))
|
||||||
throw new BitsException("selectorMismatch", this, selector);
|
throw new BitsException("selectorInputCountMismatch", this, selector);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -125,7 +125,7 @@ public class LibrarySelector implements ElementNotFoundNotification {
|
|||||||
importedElements.add(description.getName());
|
importedElements.add(description.getName());
|
||||||
return description;
|
return description;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
new ErrorMessage("error importing model").addCause(e).show();
|
SwingUtilities.invokeLater(new ErrorMessage("error importing model").addCause(e));
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -58,14 +58,11 @@ public class Circuit implements Drawable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public Circuit() {
|
public Circuit() {
|
||||||
visualElements = new ArrayList<>();
|
visualElements = new ArrayList<>();
|
||||||
wires = new ArrayList<>();
|
wires = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void drawTo(Graphic graphic) {
|
public void drawTo(Graphic graphic) {
|
||||||
if (!dotsPresent) {
|
if (!dotsPresent) {
|
||||||
|
@ -12,8 +12,10 @@ public class PinOrder implements ElementOrderer.OrderInterface<String> {
|
|||||||
|
|
||||||
private final ArrayList<Entry> entries;
|
private final ArrayList<Entry> entries;
|
||||||
private final ArrayList<VisualElement> elements;
|
private final ArrayList<VisualElement> elements;
|
||||||
|
private final Circuit circuit;
|
||||||
|
|
||||||
public PinOrder(Circuit circuit, String name) {
|
public PinOrder(Circuit circuit, String name) {
|
||||||
|
this.circuit = circuit;
|
||||||
this.elements = circuit.getElements();
|
this.elements = circuit.getElements();
|
||||||
entries = new ArrayList<>();
|
entries = new ArrayList<>();
|
||||||
for (int i = 0; i < elements.size(); i++)
|
for (int i = 0; i < elements.size(); i++)
|
||||||
@ -47,6 +49,7 @@ public class PinOrder implements ElementOrderer.OrderInterface<String> {
|
|||||||
entries.set(i, entries.get(j));
|
entries.set(i, entries.get(j));
|
||||||
entries.set(j, x);
|
entries.set(j, x);
|
||||||
|
|
||||||
|
circuit.modified();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Entry {
|
public static class Entry {
|
||||||
|
@ -12,9 +12,7 @@ import de.neemann.digital.core.flipflops.T_FF;
|
|||||||
import de.neemann.digital.core.io.Const;
|
import de.neemann.digital.core.io.Const;
|
||||||
import de.neemann.digital.core.io.In;
|
import de.neemann.digital.core.io.In;
|
||||||
import de.neemann.digital.core.io.Out;
|
import de.neemann.digital.core.io.Out;
|
||||||
import de.neemann.digital.core.wiring.Clock;
|
import de.neemann.digital.core.wiring.*;
|
||||||
import de.neemann.digital.core.wiring.Delay;
|
|
||||||
import de.neemann.digital.core.wiring.Splitter;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -45,6 +43,9 @@ public class ElementLibrary implements Iterable<ElementLibrary.ElementContainer>
|
|||||||
add(Out.PROBEDESCRIPTION, "IO");
|
add(Out.PROBEDESCRIPTION, "IO");
|
||||||
add(Clock.DESCRIPTION, "IO");
|
add(Clock.DESCRIPTION, "IO");
|
||||||
|
|
||||||
|
add(Multiplexer.DESCRIPTION, "Mux");
|
||||||
|
add(Demultiplexer.DESCRIPTION, "Mux");
|
||||||
|
|
||||||
add(Splitter.DESCRIPTION, "Wires");
|
add(Splitter.DESCRIPTION, "Wires");
|
||||||
add(Const.DESCRIPTION, "Wires");
|
add(Const.DESCRIPTION, "Wires");
|
||||||
|
|
||||||
|
@ -0,0 +1,55 @@
|
|||||||
|
package de.neemann.digital.gui.draw.shapes;
|
||||||
|
|
||||||
|
import de.neemann.digital.core.Observer;
|
||||||
|
import de.neemann.digital.gui.draw.elements.IOState;
|
||||||
|
import de.neemann.digital.gui.draw.elements.Pin;
|
||||||
|
import de.neemann.digital.gui.draw.elements.Pins;
|
||||||
|
import de.neemann.digital.gui.draw.graphics.Graphic;
|
||||||
|
import de.neemann.digital.gui.draw.graphics.Polygon;
|
||||||
|
import de.neemann.digital.gui.draw.graphics.Style;
|
||||||
|
import de.neemann.digital.gui.draw.graphics.Vector;
|
||||||
|
|
||||||
|
import static de.neemann.digital.gui.draw.shapes.GenericShape.SIZE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author hneemann
|
||||||
|
*/
|
||||||
|
public class DemuxerShape implements Shape {
|
||||||
|
private final int outputCount;
|
||||||
|
private Pins pins;
|
||||||
|
|
||||||
|
public DemuxerShape(int selectorBits) {
|
||||||
|
this.outputCount = 1 << selectorBits;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Pins getPins() {
|
||||||
|
if (pins == null) {
|
||||||
|
pins = new Pins();
|
||||||
|
pins.add(new Pin(new Vector(SIZE, outputCount * SIZE), "sel", Pin.Direction.input));
|
||||||
|
if (outputCount == 2) {
|
||||||
|
pins.add(new Pin(new Vector(SIZE * 2, 0 * SIZE), "out_0", Pin.Direction.output));
|
||||||
|
pins.add(new Pin(new Vector(SIZE * 2, 2 * SIZE), "out_1", Pin.Direction.output));
|
||||||
|
} else
|
||||||
|
for (int i = 0; i < outputCount; i++) {
|
||||||
|
pins.add(new Pin(new Vector(SIZE * 2, i * SIZE), "out_" + i, Pin.Direction.output));
|
||||||
|
}
|
||||||
|
pins.add(new Pin(new Vector(0, (outputCount / 2) * SIZE), "in", Pin.Direction.input));
|
||||||
|
}
|
||||||
|
return pins;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Interactor applyStateMonitor(IOState ioState, Observer guiObserver) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawTo(Graphic graphic) {
|
||||||
|
graphic.drawPolygon(new Polygon(true)
|
||||||
|
.add(2, 3)
|
||||||
|
.add(SIZE * 2 - 2, -2)
|
||||||
|
.add(SIZE * 2 - 2, outputCount * SIZE + 2)
|
||||||
|
.add(2, outputCount * SIZE - 3), Style.NORMAL);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,55 @@
|
|||||||
|
package de.neemann.digital.gui.draw.shapes;
|
||||||
|
|
||||||
|
import de.neemann.digital.core.Observer;
|
||||||
|
import de.neemann.digital.gui.draw.elements.IOState;
|
||||||
|
import de.neemann.digital.gui.draw.elements.Pin;
|
||||||
|
import de.neemann.digital.gui.draw.elements.Pins;
|
||||||
|
import de.neemann.digital.gui.draw.graphics.Graphic;
|
||||||
|
import de.neemann.digital.gui.draw.graphics.Polygon;
|
||||||
|
import de.neemann.digital.gui.draw.graphics.Style;
|
||||||
|
import de.neemann.digital.gui.draw.graphics.Vector;
|
||||||
|
|
||||||
|
import static de.neemann.digital.gui.draw.shapes.GenericShape.SIZE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author hneemann
|
||||||
|
*/
|
||||||
|
public class MuxerShape implements Shape {
|
||||||
|
private final int inputCount;
|
||||||
|
private Pins pins;
|
||||||
|
|
||||||
|
public MuxerShape(int selectorBits) {
|
||||||
|
this.inputCount = 1 << selectorBits;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Pins getPins() {
|
||||||
|
if (pins == null) {
|
||||||
|
pins = new Pins();
|
||||||
|
pins.add(new Pin(new Vector(SIZE, inputCount * SIZE), "sel", Pin.Direction.input));
|
||||||
|
if (inputCount == 2) {
|
||||||
|
pins.add(new Pin(new Vector(0, 0 * SIZE), "in_0", Pin.Direction.input));
|
||||||
|
pins.add(new Pin(new Vector(0, 2 * SIZE), "in_1", Pin.Direction.input));
|
||||||
|
} else
|
||||||
|
for (int i = 0; i < inputCount; i++) {
|
||||||
|
pins.add(new Pin(new Vector(0, i * SIZE), "in_" + i, Pin.Direction.input));
|
||||||
|
}
|
||||||
|
pins.add(new Pin(new Vector(SIZE * 2, (inputCount / 2) * SIZE), "out", Pin.Direction.output));
|
||||||
|
}
|
||||||
|
return pins;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Interactor applyStateMonitor(IOState ioState, Observer guiObserver) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawTo(Graphic graphic) {
|
||||||
|
graphic.drawPolygon(new Polygon(true)
|
||||||
|
.add(2, -2)
|
||||||
|
.add(SIZE * 2 - 2, 3)
|
||||||
|
.add(SIZE * 2 - 2, inputCount * SIZE - 3)
|
||||||
|
.add(2, inputCount * SIZE + 2), Style.NORMAL);
|
||||||
|
}
|
||||||
|
}
|
@ -11,9 +11,7 @@ import de.neemann.digital.core.element.ElementTypeDescription;
|
|||||||
import de.neemann.digital.core.io.Const;
|
import de.neemann.digital.core.io.Const;
|
||||||
import de.neemann.digital.core.io.In;
|
import de.neemann.digital.core.io.In;
|
||||||
import de.neemann.digital.core.io.Out;
|
import de.neemann.digital.core.io.Out;
|
||||||
import de.neemann.digital.core.wiring.Clock;
|
import de.neemann.digital.core.wiring.*;
|
||||||
import de.neemann.digital.core.wiring.Delay;
|
|
||||||
import de.neemann.digital.core.wiring.Splitter;
|
|
||||||
import de.neemann.digital.gui.draw.library.ElementLibrary;
|
import de.neemann.digital.gui.draw.library.ElementLibrary;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -56,6 +54,8 @@ public final class ShapeFactory {
|
|||||||
map.put(Out.LEDDESCRIPTION.getName(), attr -> new LEDShape(attr.get(AttributeKey.Label), attr.get(AttributeKey.Color)));
|
map.put(Out.LEDDESCRIPTION.getName(), attr -> new LEDShape(attr.get(AttributeKey.Label), attr.get(AttributeKey.Color)));
|
||||||
map.put(Out.PROBEDESCRIPTION.getName(), attr -> new ProbeShape(attr.get(AttributeKey.Label)));
|
map.put(Out.PROBEDESCRIPTION.getName(), attr -> new ProbeShape(attr.get(AttributeKey.Label)));
|
||||||
map.put(Clock.DESCRIPTION.getName(), attr -> new ClockShape(attr.get(AttributeKey.Label)));
|
map.put(Clock.DESCRIPTION.getName(), attr -> new ClockShape(attr.get(AttributeKey.Label)));
|
||||||
|
map.put(Multiplexer.DESCRIPTION.getName(), attr -> new MuxerShape(attr.get(AttributeKey.SelectorBits)));
|
||||||
|
map.put(Demultiplexer.DESCRIPTION.getName(), attr -> new DemuxerShape(attr.get(AttributeKey.SelectorBits)));
|
||||||
|
|
||||||
map.put(Splitter.DESCRIPTION.getName(), attr -> new SplitterShape(attr.get(AttributeKey.InputSplit), attr.get(AttributeKey.OutputSplit)));
|
map.put(Splitter.DESCRIPTION.getName(), attr -> new SplitterShape(attr.get(AttributeKey.InputSplit), attr.get(AttributeKey.OutputSplit)));
|
||||||
|
|
||||||
|
@ -0,0 +1,55 @@
|
|||||||
|
package de.neemann.digital.core.wiring;
|
||||||
|
|
||||||
|
import de.neemann.digital.TestExecuter;
|
||||||
|
import de.neemann.digital.core.Model;
|
||||||
|
import de.neemann.digital.core.ObservableValue;
|
||||||
|
import de.neemann.digital.core.element.AttributeKey;
|
||||||
|
import de.neemann.digital.core.element.ElementAttributes;
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author hneemann
|
||||||
|
*/
|
||||||
|
public class DemultiplexerTest extends TestCase {
|
||||||
|
|
||||||
|
public void testDemux() throws Exception {
|
||||||
|
Model model = new Model();
|
||||||
|
ObservableValue a = new ObservableValue("a", 4);
|
||||||
|
ObservableValue sel = new ObservableValue("sel", 2);
|
||||||
|
Demultiplexer demul = model.add(new Demultiplexer(
|
||||||
|
new ElementAttributes()
|
||||||
|
.set(AttributeKey.Bits, 4)
|
||||||
|
.set(AttributeKey.SelectorBits, 2)));
|
||||||
|
demul.setInputs(sel, a);
|
||||||
|
|
||||||
|
|
||||||
|
TestExecuter te = new TestExecuter(model).setInputs(a, sel).setOutputs(demul.getOutputs());
|
||||||
|
te.check(2, 0, 2, 0, 0, 0);
|
||||||
|
te.check(3, 0, 3, 0, 0, 0);
|
||||||
|
te.check(3, 1, 0, 3, 0, 0);
|
||||||
|
te.check(4, 2, 0, 0, 4, 0);
|
||||||
|
te.check(5, 3, 0, 0, 0, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testDemuxDefault() throws Exception {
|
||||||
|
Model model = new Model();
|
||||||
|
ObservableValue a = new ObservableValue("a", 4);
|
||||||
|
ObservableValue sel = new ObservableValue("sel", 2);
|
||||||
|
Demultiplexer demul = model.add(new Demultiplexer(
|
||||||
|
new ElementAttributes()
|
||||||
|
.set(AttributeKey.Bits, 4)
|
||||||
|
.set(AttributeKey.Default, 7)
|
||||||
|
.set(AttributeKey.SelectorBits, 2)));
|
||||||
|
demul.setInputs(sel, a);
|
||||||
|
|
||||||
|
|
||||||
|
TestExecuter te = new TestExecuter(model).setInputs(a, sel).setOutputs(demul.getOutputs());
|
||||||
|
te.check(2, 0, 2, 7, 7, 7);
|
||||||
|
te.check(3, 0, 3, 7, 7, 7);
|
||||||
|
te.check(3, 1, 7, 3, 7, 7);
|
||||||
|
te.check(4, 2, 7, 7, 4, 7);
|
||||||
|
te.check(5, 3, 7, 7, 7, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -5,6 +5,8 @@ import de.neemann.digital.core.BitsException;
|
|||||||
import de.neemann.digital.core.Model;
|
import de.neemann.digital.core.Model;
|
||||||
import de.neemann.digital.core.ObservableValue;
|
import de.neemann.digital.core.ObservableValue;
|
||||||
import de.neemann.digital.core.basic.FanIn;
|
import de.neemann.digital.core.basic.FanIn;
|
||||||
|
import de.neemann.digital.core.element.AttributeKey;
|
||||||
|
import de.neemann.digital.core.element.ElementAttributes;
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -19,8 +21,10 @@ public class MultiplexerTest extends TestCase {
|
|||||||
ObservableValue c = new ObservableValue("c", 4);
|
ObservableValue c = new ObservableValue("c", 4);
|
||||||
ObservableValue d = new ObservableValue("d", 4);
|
ObservableValue d = new ObservableValue("d", 4);
|
||||||
ObservableValue sel = new ObservableValue("sel", 2);
|
ObservableValue sel = new ObservableValue("sel", 2);
|
||||||
FanIn out = model.add(new Multiplexer(4, 2));
|
FanIn out = model.add(new Multiplexer(
|
||||||
out.setInputs(a, b, c, d, sel);
|
new ElementAttributes().set(AttributeKey.Bits, 4)
|
||||||
|
.set(AttributeKey.SelectorBits, 2)));
|
||||||
|
out.setInputs(sel, a, b, c, d);
|
||||||
|
|
||||||
|
|
||||||
TestExecuter te = new TestExecuter(model).setInputs(a, b, c, d, sel).setOutputs(out.getOutputs());
|
TestExecuter te = new TestExecuter(model).setInputs(a, b, c, d, sel).setOutputs(out.getOutputs());
|
||||||
@ -37,15 +41,33 @@ public class MultiplexerTest extends TestCase {
|
|||||||
ObservableValue c = new ObservableValue("c", 4);
|
ObservableValue c = new ObservableValue("c", 4);
|
||||||
ObservableValue d = new ObservableValue("d", 4);
|
ObservableValue d = new ObservableValue("d", 4);
|
||||||
ObservableValue sel = new ObservableValue("sel", 1);
|
ObservableValue sel = new ObservableValue("sel", 1);
|
||||||
FanIn out = new Multiplexer(4, 2);
|
FanIn out = new Multiplexer(
|
||||||
|
new ElementAttributes().set(AttributeKey.Bits, 4)
|
||||||
|
.set(AttributeKey.SelectorBits, 2));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
out.setInputs(sel, a, b, c, d);
|
out.setInputs(a, b, c, d, sel);
|
||||||
assertTrue(false);
|
assertTrue(false);
|
||||||
} catch (BitsException e) {
|
} catch (BitsException e) {
|
||||||
assertTrue(true);
|
assertTrue(true);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testMux3() throws Exception {
|
||||||
|
ObservableValue a = new ObservableValue("a", 4);
|
||||||
|
ObservableValue b = new ObservableValue("b", 4);
|
||||||
|
ObservableValue c = new ObservableValue("c", 4);
|
||||||
|
ObservableValue sel = new ObservableValue("sel", 2);
|
||||||
|
FanIn out = new Multiplexer(
|
||||||
|
new ElementAttributes().set(AttributeKey.Bits, 4)
|
||||||
|
.set(AttributeKey.SelectorBits, 2));
|
||||||
|
|
||||||
|
try {
|
||||||
|
out.setInputs(sel, a, b, c);
|
||||||
|
assertTrue(false);
|
||||||
|
} catch (BitsException e) {
|
||||||
|
assertTrue(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -63,12 +63,12 @@ public class TestNesting extends TestCase {
|
|||||||
ElementLibrary library = new ElementLibrary();
|
ElementLibrary library = new ElementLibrary();
|
||||||
LibrarySelector librarySelector = new LibrarySelector(library);
|
LibrarySelector librarySelector = new LibrarySelector(library);
|
||||||
librarySelector.setFilePath(new File(Resources.getRoot(), "dig"));
|
librarySelector.setFilePath(new File(Resources.getRoot(), "dig"));
|
||||||
ShapeFactory.getInstance().setLibrary(library);
|
ShapeFactory.getInstance().setLibrary(library); // neded to generate generic shapes
|
||||||
return TestExecuter.createFromFile(file, library);
|
return TestExecuter.createFromFile(file, library);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Nested JK-FF. One from tested model is not used!
|
* Nested JK-FF. One output from nested model is not used!
|
||||||
*
|
*
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
@ -88,11 +88,11 @@ public class TestNesting extends TestCase {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Imports the same model two times.
|
* Imports the same model two times.
|
||||||
* A simple traffic light build with two nested MS-JK flipflops.
|
* A simple traffic light build with two nested MS-JK flip flops.
|
||||||
*/
|
*/
|
||||||
public void testMultipleNesting() throws NodeException, PinException, IOException {
|
public void testMultipleNesting() throws NodeException, PinException, IOException {
|
||||||
TestExecuter te = createTestExecuterForNesting("dig/trafficLight.dig");
|
TestExecuter te = createTestExecuterForNesting("dig/trafficLight.dig");
|
||||||
te.clockUntil(1, 0, 0); // runs the sequential logic up to the given state
|
te.clockUntil(1, 0, 0); // runs the sequential logic up to the given state, its necessary because initial state is undefined
|
||||||
// C R Y G
|
// C R Y G
|
||||||
te.check(0, 1, 0, 0); // Red
|
te.check(0, 1, 0, 0); // Red
|
||||||
te.check(1, 1, 0, 0);
|
te.check(1, 1, 0, 0);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user