both directions are working, intermix does not!

This commit is contained in:
hneemann 2016-03-20 18:29:30 +01:00
parent b9c5f6fd35
commit 1c7b0a0f9d
3 changed files with 118 additions and 9 deletions

View File

@ -8,6 +8,7 @@ import de.neemann.digital.core.element.ElementTypeDescription;
import de.neemann.digital.gui.draw.elements.PinException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.StringTokenizer;
/**
@ -52,17 +53,35 @@ public class Splitter implements Element {
public void setInputs(ObservableValue... inputs) throws NodeException {
this.inputs = inputs;
for (int i = 0; i < inputs.length; i++) {
if (inPorts.getPort(i).getBits() != inputs[i].getBits())
Port inPort = inPorts.getPort(i);
if (inPort.getBits() != inputs[i].getBits())
throw new BitsException("splitterBitsMismatch", inputs[i]);
inputs[i].addObserver(createObserverForInput(i));
registerObserversFor(inPort);
}
}
private Observer createObserverForInput(int i) throws NodeException {
Observer observer = outPorts.getSingleTargetObserver(inPorts.getPort(i), inputs, outputs);
if (observer == null)
throw new NodeException("splitterMismatchError");
return observer;
private void registerObserversFor(Port in) throws NodeException {
Observer observer = outPorts.getSingleTargetObserver(in, inputs, outputs);
if (observer != null) {
inputs[in.number].addObserver(observer);
return;
}
for (Port out : outPorts) {
if (out.getPos() >= in.getPos() &&
out.getPos() + out.getBits() <= in.getPos() + in.getBits()) {
final int bitPos = out.getPos() - in.getPos();
final ObservableValue inValue = inputs[in.number];
final ObservableValue outValue = outputs[out.number];
inValue.addObserver(new Observer() {
@Override
public void hasChanged() {
outValue.setValue(inValue.getValue() >> bitPos);
}
});
}
}
}
@Override
@ -74,7 +93,7 @@ public class Splitter implements Element {
public void registerNodes(Model model) {
}
public static final class Ports {
public static final class Ports implements Iterable<Port> {
private final ArrayList<Port> ports;
private int bits;
@ -149,6 +168,10 @@ public class Splitter implements Element {
return null;
}
@Override
public Iterator<Port> iterator() {
return ports.iterator();
}
}
private static final class Port {

View File

@ -9,7 +9,7 @@ import junit.framework.TestCase;
/**
* @author hneemann
*/
public class SplitterTest extends TestCase {
public class SplitterTest1 extends TestCase {
public void testBits() throws Exception {
ObservableValue a = new ObservableValue("a", 1);

View File

@ -0,0 +1,86 @@
package de.neemann.digital.core.wiring;
import de.neemann.digital.TestExecuter;
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 SplitterTest2 extends TestCase {
public void testBits() throws Exception {
ObservableValue a = new ObservableValue("a", 4);
Splitter splitter = new Splitter(new ElementAttributes()
.set(AttributeKey.InputSplit, "4")
.set(AttributeKey.OutputSplit, "1,1,1,1"));
splitter.setInputs(a);
ObservableValue[] outputs = splitter.getOutputs();
assertEquals(4, outputs.length);
TestExecuter sc = new TestExecuter().setInputs(a).setOutputsOf(splitter);
sc.check(0, 0, 0, 0, 0);
sc.check(1, 1, 0, 0, 0);
sc.check(2, 0, 1, 0, 0);
sc.check(4, 0, 0, 1, 0);
sc.check(8, 0, 0, 0, 1);
sc.check(15, 1, 1, 1, 1);
}
public void testMoreBits() throws Exception {
ObservableValue a = new ObservableValue("a", 16);
Splitter splitter = new Splitter(new ElementAttributes()
.set(AttributeKey.InputSplit, "16")
.set(AttributeKey.OutputSplit, "4,4,4,4"));
splitter.setInputs(a);
ObservableValue[] outputs = splitter.getOutputs();
assertEquals(4, outputs.length);
TestExecuter sc = new TestExecuter().setInputs(a).setOutputsOf(splitter);
sc.check(0x0000, 0x0, 0x0, 0x0, 0x0);
sc.check(0x1000, 0x0, 0x0, 0x0, 0x1);
sc.check(0x0100, 0x0, 0x0, 0x1, 0x0);
sc.check(0x0010, 0x0, 0x1, 0x0, 0x0);
sc.check(0x0001, 0x1, 0x0, 0x0, 0x0);
sc.check(0xa000, 0x0, 0x0, 0x0, 0xa);
sc.check(0x0b00, 0x0, 0x0, 0xb, 0x0);
sc.check(0x00c0, 0x0, 0xc, 0x0, 0x0);
sc.check(0x000d, 0xd, 0x0, 0x0, 0x0);
}
public void testMix() throws Exception {
ObservableValue a = new ObservableValue("a", 8);
ObservableValue b = new ObservableValue("b", 8);
Splitter splitter = new Splitter(new ElementAttributes()
.set(AttributeKey.InputSplit, "8,8")
.set(AttributeKey.OutputSplit, "4,4,4,4"));
splitter.setInputs(a, b);
ObservableValue[] outputs = splitter.getOutputs();
assertEquals(4, outputs.length);
TestExecuter sc = new TestExecuter().setInputs(a, b).setOutputsOf(splitter);
sc.check(0x00, 0x00, 0x0, 0x0, 0x0, 0x0);
sc.check(0x10, 0x00, 0x0, 0x1, 0x0, 0x0);
sc.check(0x01, 0x00, 0x1, 0x0, 0x0, 0x0);
sc.check(0x00, 0x10, 0x0, 0x0, 0x0, 0x1);
sc.check(0x00, 0x01, 0x0, 0x0, 0x1, 0x0);
sc.check(0xf0, 0x00, 0x0, 0xf, 0x0, 0x0);
sc.check(0x0f, 0x00, 0xf, 0x0, 0x0, 0x0);
sc.check(0x00, 0xf0, 0x0, 0x0, 0x0, 0xf);
sc.check(0x00, 0x0f, 0x0, 0x0, 0xf, 0x0);
sc.check(0xff, 0xff, 0xf, 0xf, 0xf, 0xf);
}
}