mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-17 08:55:05 -04:00
both directions are working, intermix does not!
This commit is contained in:
parent
b9c5f6fd35
commit
1c7b0a0f9d
@ -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 {
|
||||
|
@ -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);
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user