mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-17 17:04:42 -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 de.neemann.digital.gui.draw.elements.PinException;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.StringTokenizer;
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -52,17 +53,35 @@ public class Splitter implements Element {
|
|||||||
public void setInputs(ObservableValue... inputs) throws NodeException {
|
public void setInputs(ObservableValue... inputs) throws NodeException {
|
||||||
this.inputs = inputs;
|
this.inputs = inputs;
|
||||||
for (int i = 0; i < inputs.length; i++) {
|
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]);
|
throw new BitsException("splitterBitsMismatch", inputs[i]);
|
||||||
inputs[i].addObserver(createObserverForInput(i));
|
registerObserversFor(inPort);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Observer createObserverForInput(int i) throws NodeException {
|
private void registerObserversFor(Port in) throws NodeException {
|
||||||
Observer observer = outPorts.getSingleTargetObserver(inPorts.getPort(i), inputs, outputs);
|
Observer observer = outPorts.getSingleTargetObserver(in, inputs, outputs);
|
||||||
if (observer == null)
|
if (observer != null) {
|
||||||
throw new NodeException("splitterMismatchError");
|
inputs[in.number].addObserver(observer);
|
||||||
return 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
|
@Override
|
||||||
@ -74,7 +93,7 @@ public class Splitter implements Element {
|
|||||||
public void registerNodes(Model model) {
|
public void registerNodes(Model model) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final class Ports {
|
public static final class Ports implements Iterable<Port> {
|
||||||
private final ArrayList<Port> ports;
|
private final ArrayList<Port> ports;
|
||||||
private int bits;
|
private int bits;
|
||||||
|
|
||||||
@ -149,6 +168,10 @@ public class Splitter implements Element {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<Port> iterator() {
|
||||||
|
return ports.iterator();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class Port {
|
private static final class Port {
|
||||||
|
@ -9,7 +9,7 @@ import junit.framework.TestCase;
|
|||||||
/**
|
/**
|
||||||
* @author hneemann
|
* @author hneemann
|
||||||
*/
|
*/
|
||||||
public class SplitterTest extends TestCase {
|
public class SplitterTest1 extends TestCase {
|
||||||
|
|
||||||
public void testBits() throws Exception {
|
public void testBits() throws Exception {
|
||||||
ObservableValue a = new ObservableValue("a", 1);
|
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