mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-15 07:48:29 -04:00
added bus and multiplexer
This commit is contained in:
parent
6938aaf45b
commit
f63ba56e77
23
src/main/java/de/neemann/digital/BurnException.java
Normal file
23
src/main/java/de/neemann/digital/BurnException.java
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
package de.neemann.digital;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author hneemann
|
||||||
|
*/
|
||||||
|
public class BurnException extends NodeException {
|
||||||
|
private final ObservableValue v1;
|
||||||
|
private final ObservableValue v2;
|
||||||
|
|
||||||
|
public BurnException(ObservableValue v1, ObservableValue v2) {
|
||||||
|
super("burnException");
|
||||||
|
this.v1 = v1;
|
||||||
|
this.v2 = v2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObservableValue getV1() {
|
||||||
|
return v1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObservableValue getV2() {
|
||||||
|
return v2;
|
||||||
|
}
|
||||||
|
}
|
17
src/main/java/de/neemann/digital/HighZException.java
Normal file
17
src/main/java/de/neemann/digital/HighZException.java
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
package de.neemann.digital;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author hneemann
|
||||||
|
*/
|
||||||
|
public class HighZException extends NodeException {
|
||||||
|
private final ObservableValue causedObservable;
|
||||||
|
|
||||||
|
public HighZException(ObservableValue causedObservable) {
|
||||||
|
super("readOfHighZ");
|
||||||
|
this.causedObservable = causedObservable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObservableValue getCausedObservable() {
|
||||||
|
return causedObservable;
|
||||||
|
}
|
||||||
|
}
|
@ -4,5 +4,5 @@ package de.neemann.digital;
|
|||||||
* @author hneemann
|
* @author hneemann
|
||||||
*/
|
*/
|
||||||
public interface Listener {
|
public interface Listener {
|
||||||
void needsUpdate() throws NodeException;
|
void needsUpdate();
|
||||||
}
|
}
|
||||||
|
@ -13,9 +13,9 @@ public abstract class Node implements Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void needsUpdate() throws NodeException {
|
public void needsUpdate() {
|
||||||
if (model == null)
|
if (model == null)
|
||||||
throw new NodeException("no model set");
|
throw new RuntimeException("noModelSet");
|
||||||
|
|
||||||
if (model.getVersion() != version) {
|
if (model.getVersion() != version) {
|
||||||
model.addToUpdateList(this);
|
model.addToUpdateList(this);
|
||||||
@ -25,7 +25,7 @@ public abstract class Node implements Listener {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Only read the input!
|
* Only read the input!
|
||||||
* It is not allowed to write to the outputs!!!
|
* It is not allowed to write to one of the outputs!!!
|
||||||
*
|
*
|
||||||
* @throws NodeException
|
* @throws NodeException
|
||||||
*/
|
*/
|
||||||
@ -33,10 +33,12 @@ public abstract class Node implements Listener {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Only write to the output!
|
* Only write to the output!
|
||||||
* It is not allowed to read from the inputs!!!
|
* It is not allowed to read from one of the inputs!!!
|
||||||
*
|
*
|
||||||
* @throws NodeException
|
* @throws NodeException
|
||||||
*/
|
*/
|
||||||
public abstract void writeOutputs() throws NodeException;
|
public abstract void writeOutputs() throws NodeException;
|
||||||
|
|
||||||
|
public void checkConsistence() throws NodeException {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,18 +5,20 @@ import java.util.ArrayList;
|
|||||||
/**
|
/**
|
||||||
* @author hneemann
|
* @author hneemann
|
||||||
*/
|
*/
|
||||||
public class ObservableValue {
|
public class ObservableValue extends Value {
|
||||||
|
|
||||||
private final int bits;
|
private final ArrayList<Listener> listeners;
|
||||||
private int value;
|
|
||||||
private ArrayList<Listener> listeners;
|
|
||||||
|
|
||||||
public ObservableValue(int bits) {
|
public ObservableValue(int bits) {
|
||||||
this.bits = bits;
|
this(bits, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObservableValue(int bits, boolean highZ) {
|
||||||
|
super(bits, highZ);
|
||||||
listeners = new ArrayList<>();
|
listeners = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addListener(Listener listener) throws NodeException {
|
public void addListener(Listener listener) {
|
||||||
listeners.add(listener);
|
listeners.add(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -24,29 +26,32 @@ public class ObservableValue {
|
|||||||
listeners.remove(listener);
|
listeners.remove(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void hasChanged() throws NodeException {
|
public void hasChanged() {
|
||||||
for (Listener l : listeners) {
|
for (Listener l : listeners) {
|
||||||
l.needsUpdate();
|
l.needsUpdate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setValue(int value) throws NodeException {
|
|
||||||
if (this.value != value) {
|
|
||||||
this.value = value;
|
|
||||||
hasChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getBits() {
|
public int getBits() {
|
||||||
return bits;
|
return bits;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getValueBits() {
|
public int getValue() throws NodeException {
|
||||||
return getValueBits(value);
|
if (highZ)
|
||||||
|
throw new HighZException(this);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValue(int value) {
|
||||||
|
if (this.value != value) {
|
||||||
|
this.value = value;
|
||||||
|
if (!highZ)
|
||||||
|
hasChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getValueBits() throws NodeException {
|
||||||
|
return getValueBits(getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getValueBits(int value) {
|
public int getValueBits(int value) {
|
||||||
@ -59,10 +64,28 @@ public class ObservableValue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isHighZ() {
|
||||||
|
return highZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHighZ(boolean highZ) {
|
||||||
|
if (this.highZ != highZ) {
|
||||||
|
this.highZ = highZ;
|
||||||
|
hasChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void set(int value, boolean highZ) {
|
||||||
|
setValue(value);
|
||||||
|
setHighZ(highZ);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "ObservableValue{" +
|
return "ObservableValue{" +
|
||||||
"value=" + value +
|
"value=" + (highZ ? "??" : value) +
|
||||||
", bits=" + bits +
|
", bits=" + bits +
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
|
28
src/main/java/de/neemann/digital/Value.java
Normal file
28
src/main/java/de/neemann/digital/Value.java
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
package de.neemann.digital;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author hneemann
|
||||||
|
*/
|
||||||
|
public class Value {
|
||||||
|
protected final int bits;
|
||||||
|
protected boolean highZ;
|
||||||
|
protected int value;
|
||||||
|
|
||||||
|
public Value(int bits) {
|
||||||
|
this(bits, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Value(int bits, boolean highZ) {
|
||||||
|
this.bits = bits;
|
||||||
|
this.highZ = highZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void set(int value, boolean highZ) {
|
||||||
|
this.value = value;
|
||||||
|
this.highZ = highZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void set(Value v) {
|
||||||
|
set(v.value, v.highZ);
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
package de.neemann.digital.basic;
|
package de.neemann.digital.basic;
|
||||||
|
|
||||||
|
import de.neemann.digital.NodeException;
|
||||||
import de.neemann.digital.ObservableValue;
|
import de.neemann.digital.ObservableValue;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -14,7 +15,7 @@ public class And extends Function {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected int calculate(ArrayList<ObservableValue> inputs) {
|
protected int calculate(ArrayList<ObservableValue> inputs) throws NodeException {
|
||||||
int f = -1;
|
int f = -1;
|
||||||
for (ObservableValue i : inputs) {
|
for (ObservableValue i : inputs) {
|
||||||
f &= i.getValue();
|
f &= i.getValue();
|
||||||
|
37
src/main/java/de/neemann/digital/basic/FanIn.java
Normal file
37
src/main/java/de/neemann/digital/basic/FanIn.java
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
package de.neemann.digital.basic;
|
||||||
|
|
||||||
|
import de.neemann.digital.BitsException;
|
||||||
|
import de.neemann.digital.Node;
|
||||||
|
import de.neemann.digital.NodeException;
|
||||||
|
import de.neemann.digital.ObservableValue;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author hneemann
|
||||||
|
*/
|
||||||
|
public abstract class FanIn extends Node {
|
||||||
|
protected final ArrayList<ObservableValue> inputs;
|
||||||
|
protected final ObservableValue output;
|
||||||
|
|
||||||
|
public FanIn(int bits) {
|
||||||
|
inputs = new ArrayList<>();
|
||||||
|
output = new ObservableValue(bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FanIn addInput(ObservableValue value) throws BitsException, NodeException {
|
||||||
|
output.checkBits(value);
|
||||||
|
inputs.add(value);
|
||||||
|
value.addListener(this);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeInput(ObservableValue value) {
|
||||||
|
inputs.remove(value);
|
||||||
|
value.removeListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObservableValue getOutput() {
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,5 @@
|
|||||||
package de.neemann.digital.basic;
|
package de.neemann.digital.basic;
|
||||||
|
|
||||||
import de.neemann.digital.BitsException;
|
|
||||||
import de.neemann.digital.Node;
|
|
||||||
import de.neemann.digital.NodeException;
|
import de.neemann.digital.NodeException;
|
||||||
import de.neemann.digital.ObservableValue;
|
import de.neemann.digital.ObservableValue;
|
||||||
|
|
||||||
@ -10,34 +8,14 @@ import java.util.ArrayList;
|
|||||||
/**
|
/**
|
||||||
* @author hneemann
|
* @author hneemann
|
||||||
*/
|
*/
|
||||||
public abstract class Function extends Node {
|
public abstract class Function extends FanIn {
|
||||||
|
|
||||||
private final ArrayList<ObservableValue> inputs;
|
|
||||||
private final ObservableValue output;
|
|
||||||
private int value;
|
private int value;
|
||||||
|
|
||||||
public Function(int bits) {
|
public Function(int bits) {
|
||||||
output = new ObservableValue(bits);
|
super(bits);
|
||||||
inputs = new ArrayList<>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Function addInput(ObservableValue value) throws BitsException, NodeException {
|
|
||||||
output.checkBits(value);
|
|
||||||
inputs.add(value);
|
|
||||||
value.addListener(this);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeInput(ObservableValue value) {
|
|
||||||
inputs.remove(value);
|
|
||||||
value.removeListener(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ObservableValue getOutput() {
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void readInputs() throws NodeException {
|
public void readInputs() throws NodeException {
|
||||||
value = calculate(inputs);
|
value = calculate(inputs);
|
||||||
@ -48,5 +26,5 @@ public abstract class Function extends Node {
|
|||||||
output.setValue(value);
|
output.setValue(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract int calculate(ArrayList<ObservableValue> inputs);
|
protected abstract int calculate(ArrayList<ObservableValue> inputs) throws NodeException;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package de.neemann.digital.basic;
|
package de.neemann.digital.basic;
|
||||||
|
|
||||||
|
import de.neemann.digital.NodeException;
|
||||||
import de.neemann.digital.ObservableValue;
|
import de.neemann.digital.ObservableValue;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -14,7 +15,7 @@ public class NAnd extends Function {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected int calculate(ArrayList<ObservableValue> inputs) {
|
protected int calculate(ArrayList<ObservableValue> inputs) throws NodeException {
|
||||||
int f = -1;
|
int f = -1;
|
||||||
for (ObservableValue i : inputs) {
|
for (ObservableValue i : inputs) {
|
||||||
f &= i.getValue();
|
f &= i.getValue();
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package de.neemann.digital.basic;
|
package de.neemann.digital.basic;
|
||||||
|
|
||||||
|
import de.neemann.digital.NodeException;
|
||||||
import de.neemann.digital.ObservableValue;
|
import de.neemann.digital.ObservableValue;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -13,7 +14,7 @@ public class NOr extends Function {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected int calculate(ArrayList<ObservableValue> inputs) {
|
protected int calculate(ArrayList<ObservableValue> inputs) throws NodeException {
|
||||||
int f = 0;
|
int f = 0;
|
||||||
for (ObservableValue i : inputs) {
|
for (ObservableValue i : inputs) {
|
||||||
f |= i.getValue();
|
f |= i.getValue();
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package de.neemann.digital.basic;
|
package de.neemann.digital.basic;
|
||||||
|
|
||||||
|
import de.neemann.digital.NodeException;
|
||||||
import de.neemann.digital.ObservableValue;
|
import de.neemann.digital.ObservableValue;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -14,7 +15,7 @@ public class Or extends Function {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected int calculate(ArrayList<ObservableValue> inputs) {
|
protected int calculate(ArrayList<ObservableValue> inputs) throws NodeException {
|
||||||
int f = 0;
|
int f = 0;
|
||||||
for (ObservableValue i : inputs) {
|
for (ObservableValue i : inputs) {
|
||||||
f |= i.getValue();
|
f |= i.getValue();
|
||||||
|
42
src/main/java/de/neemann/digital/wiring/Bus.java
Normal file
42
src/main/java/de/neemann/digital/wiring/Bus.java
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
package de.neemann.digital.wiring;
|
||||||
|
|
||||||
|
import de.neemann.digital.BurnException;
|
||||||
|
import de.neemann.digital.NodeException;
|
||||||
|
import de.neemann.digital.ObservableValue;
|
||||||
|
import de.neemann.digital.Value;
|
||||||
|
import de.neemann.digital.basic.FanIn;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author hneemann
|
||||||
|
*/
|
||||||
|
public class Bus extends FanIn {
|
||||||
|
|
||||||
|
private Value value;
|
||||||
|
|
||||||
|
public Bus(int bits) {
|
||||||
|
super(bits);
|
||||||
|
value = new Value(bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readInputs() throws NodeException {
|
||||||
|
ObservableValue found = null;
|
||||||
|
for (ObservableValue in : inputs) {
|
||||||
|
if (!in.isHighZ()) {
|
||||||
|
if (found != null)
|
||||||
|
throw new BurnException(in, found);
|
||||||
|
found = in;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (found == null) {
|
||||||
|
value.set(0, true);
|
||||||
|
} else {
|
||||||
|
value.set(found.getValue(), false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeOutputs() throws NodeException {
|
||||||
|
output.set(value);
|
||||||
|
}
|
||||||
|
}
|
34
src/main/java/de/neemann/digital/wiring/Multiplexer.java
Normal file
34
src/main/java/de/neemann/digital/wiring/Multiplexer.java
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
package de.neemann.digital.wiring;
|
||||||
|
|
||||||
|
import de.neemann.digital.NodeException;
|
||||||
|
import de.neemann.digital.ObservableValue;
|
||||||
|
import de.neemann.digital.basic.FanIn;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author hneemann
|
||||||
|
*/
|
||||||
|
public class Multiplexer extends FanIn {
|
||||||
|
|
||||||
|
private ObservableValue selector;
|
||||||
|
private int value;
|
||||||
|
|
||||||
|
public Multiplexer(int bits, ObservableValue selector) {
|
||||||
|
super(bits);
|
||||||
|
this.selector = selector;
|
||||||
|
selector.addListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readInputs() throws NodeException {
|
||||||
|
int n = selector.getValueBits();
|
||||||
|
if (n >= inputs.size())
|
||||||
|
throw new NodeException("multiplexerSelectsNotPresentInput");
|
||||||
|
|
||||||
|
value = inputs.get(n).getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeOutputs() throws NodeException {
|
||||||
|
output.setValue(value);
|
||||||
|
}
|
||||||
|
}
|
@ -13,8 +13,8 @@ public class FlipFlops extends TestCase {
|
|||||||
ObservableValue s = new ObservableValue(1);
|
ObservableValue s = new ObservableValue(1);
|
||||||
|
|
||||||
Model model = new Model();
|
Model model = new Model();
|
||||||
Function a1 = model.add(new NOr(1)).addInput(r);
|
FanIn a1 = model.add(new NOr(1)).addInput(r);
|
||||||
Function a2 = model.add(new NOr(1)).addInput(s);
|
FanIn a2 = model.add(new NOr(1)).addInput(s);
|
||||||
|
|
||||||
a1.addInput(a2.getOutput());
|
a1.addInput(a2.getOutput());
|
||||||
a2.addInput(a1.getOutput());
|
a2.addInput(a1.getOutput());
|
||||||
@ -39,8 +39,8 @@ public class FlipFlops extends TestCase {
|
|||||||
ObservableValue s = new ObservableValue(1);
|
ObservableValue s = new ObservableValue(1);
|
||||||
|
|
||||||
Model model = new Model();
|
Model model = new Model();
|
||||||
Function a1 = model.add(new NAnd(1)).addInput(r);
|
FanIn a1 = model.add(new NAnd(1)).addInput(r);
|
||||||
Function a2 = model.add(new NAnd(1)).addInput(s);
|
FanIn a2 = model.add(new NAnd(1)).addInput(s);
|
||||||
|
|
||||||
a1.addInput(a2.getOutput());
|
a1.addInput(a2.getOutput());
|
||||||
a2.addInput(a1.getOutput());
|
a2.addInput(a1.getOutput());
|
||||||
@ -60,22 +60,22 @@ public class FlipFlops extends TestCase {
|
|||||||
ObservableValue c = new ObservableValue(1);
|
ObservableValue c = new ObservableValue(1);
|
||||||
|
|
||||||
Model model = new Model();
|
Model model = new Model();
|
||||||
Function a1 = model.add(new And(1)).addInput(j).addInput(c);
|
FanIn a1 = model.add(new And(1)).addInput(j).addInput(c);
|
||||||
Function a2 = model.add(new And(1)).addInput(k).addInput(c);
|
FanIn a2 = model.add(new And(1)).addInput(k).addInput(c);
|
||||||
Not not = model.add(new Not(c));
|
Not not = model.add(new Not(c));
|
||||||
|
|
||||||
Function nor1 = model.add(new NOr(1)).addInput(a1.getOutput());
|
FanIn nor1 = model.add(new NOr(1)).addInput(a1.getOutput());
|
||||||
Function nor2 = model.add(new NOr(1)).addInput(a2.getOutput());
|
FanIn nor2 = model.add(new NOr(1)).addInput(a2.getOutput());
|
||||||
|
|
||||||
nor1.addInput(nor2.getOutput());
|
nor1.addInput(nor2.getOutput());
|
||||||
nor2.addInput(nor1.getOutput());
|
nor2.addInput(nor1.getOutput());
|
||||||
|
|
||||||
|
|
||||||
Function a3 = model.add(new And(1)).addInput(nor1.getOutput()).addInput(not.getOutput());
|
FanIn a3 = model.add(new And(1)).addInput(nor1.getOutput()).addInput(not.getOutput());
|
||||||
Function a4 = model.add(new And(1)).addInput(nor2.getOutput()).addInput(not.getOutput());
|
FanIn a4 = model.add(new And(1)).addInput(nor2.getOutput()).addInput(not.getOutput());
|
||||||
|
|
||||||
Function nor3 = model.add(new NOr(1)).addInput(a3.getOutput());
|
FanIn nor3 = model.add(new NOr(1)).addInput(a3.getOutput());
|
||||||
Function nor4 = model.add(new NOr(1)).addInput(a4.getOutput());
|
FanIn nor4 = model.add(new NOr(1)).addInput(a4.getOutput());
|
||||||
|
|
||||||
nor3.addInput(nor4.getOutput());
|
nor3.addInput(nor4.getOutput());
|
||||||
nor4.addInput(nor3.getOutput());
|
nor4.addInput(nor3.getOutput());
|
||||||
|
@ -39,7 +39,7 @@ public class TestExecuter {
|
|||||||
for (int i = 0; i < outputs.length; i++) {
|
for (int i = 0; i < outputs.length; i++) {
|
||||||
int should = val[i + inputs.length];
|
int should = val[i + inputs.length];
|
||||||
if (should >= 0)
|
if (should >= 0)
|
||||||
assertEquals("Value " + i, outputs[i].getValueBits(should), outputs[i].getValueBits());
|
assertEquals("output " + i, outputs[i].getValueBits(should), outputs[i].getValueBits());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,9 +16,9 @@ public class AndTest extends TestCase {
|
|||||||
|
|
||||||
|
|
||||||
Model model = new Model();
|
Model model = new Model();
|
||||||
Function and = model.add(new And(1)).addInput(a).addInput(b);
|
ObservableValue out = model.add(new And(1)).addInput(a).addInput(b).getOutput();
|
||||||
|
|
||||||
TestExecuter sc = new TestExecuter(model).setInputs(a, b).setOutputs(and.getOutput());
|
TestExecuter sc = new TestExecuter(model).setInputs(a, b).setOutputs(out);
|
||||||
sc.check(0, 0, 0);
|
sc.check(0, 0, 0);
|
||||||
sc.check(1, 0, 0);
|
sc.check(1, 0, 0);
|
||||||
sc.check(0, 1, 0);
|
sc.check(0, 1, 0);
|
||||||
|
@ -15,9 +15,9 @@ public class NAndTest extends TestCase {
|
|||||||
ObservableValue b = new ObservableValue(1);
|
ObservableValue b = new ObservableValue(1);
|
||||||
|
|
||||||
Model model = new Model();
|
Model model = new Model();
|
||||||
Function nand = model.add(new NAnd(1)).addInput(a).addInput(b);
|
ObservableValue out = model.add(new NAnd(1)).addInput(a).addInput(b).getOutput();
|
||||||
|
|
||||||
TestExecuter sc = new TestExecuter(model).setInputs(a, b).setOutputs(nand.getOutput());
|
TestExecuter sc = new TestExecuter(model).setInputs(a, b).setOutputs(out);
|
||||||
sc.check(0, 0, 1);
|
sc.check(0, 0, 1);
|
||||||
sc.check(1, 0, 1);
|
sc.check(1, 0, 1);
|
||||||
sc.check(0, 1, 1);
|
sc.check(0, 1, 1);
|
||||||
|
@ -15,9 +15,9 @@ public class NOrTest extends TestCase {
|
|||||||
ObservableValue b = new ObservableValue(1);
|
ObservableValue b = new ObservableValue(1);
|
||||||
|
|
||||||
Model model = new Model();
|
Model model = new Model();
|
||||||
Function nor = model.add(new NOr(1)).addInput(a).addInput(b);
|
ObservableValue nor = model.add(new NOr(1)).addInput(a).addInput(b).getOutput();
|
||||||
|
|
||||||
TestExecuter sc = new TestExecuter(model).setInputs(a, b).setOutputs(nor.getOutput());
|
TestExecuter sc = new TestExecuter(model).setInputs(a, b).setOutputs(nor);
|
||||||
sc.check(0, 0, 1);
|
sc.check(0, 0, 1);
|
||||||
sc.check(1, 0, 0);
|
sc.check(1, 0, 0);
|
||||||
sc.check(0, 1, 0);
|
sc.check(0, 1, 0);
|
||||||
|
@ -15,9 +15,9 @@ public class OrTest extends TestCase {
|
|||||||
ObservableValue b = new ObservableValue(1);
|
ObservableValue b = new ObservableValue(1);
|
||||||
|
|
||||||
Model model = new Model();
|
Model model = new Model();
|
||||||
Function and = model.add(new Or(1)).addInput(a).addInput(b);
|
ObservableValue and = model.add(new Or(1)).addInput(a).addInput(b).getOutput();
|
||||||
|
|
||||||
TestExecuter sc = new TestExecuter(model).setInputs(a, b).setOutputs(and.getOutput());
|
TestExecuter sc = new TestExecuter(model).setInputs(a, b).setOutputs(and);
|
||||||
sc.check(0, 0, 0);
|
sc.check(0, 0, 0);
|
||||||
sc.check(1, 0, 1);
|
sc.check(1, 0, 1);
|
||||||
sc.check(0, 1, 1);
|
sc.check(0, 1, 1);
|
||||||
|
46
src/test/java/de/neemann/digital/wiring/BusTest.java
Normal file
46
src/test/java/de/neemann/digital/wiring/BusTest.java
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
package de.neemann.digital.wiring;
|
||||||
|
|
||||||
|
import de.neemann.digital.BurnException;
|
||||||
|
import de.neemann.digital.Model;
|
||||||
|
import de.neemann.digital.ObservableValue;
|
||||||
|
import de.neemann.digital.TestExecuter;
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author hneemann
|
||||||
|
*/
|
||||||
|
public class BusTest extends TestCase {
|
||||||
|
|
||||||
|
public void testBus() throws Exception {
|
||||||
|
Model model = new Model();
|
||||||
|
ObservableValue a = new ObservableValue(1, true);
|
||||||
|
ObservableValue b = new ObservableValue(1);
|
||||||
|
ObservableValue out = model.add(new Bus(1)).addInput(a).addInput(b).getOutput();
|
||||||
|
|
||||||
|
TestExecuter te = new TestExecuter(model).setInputs(a, b).setOutputs(out);
|
||||||
|
te.check(0, 0, 0);
|
||||||
|
te.check(0, 1, 1);
|
||||||
|
a.setHighZ(false);
|
||||||
|
b.setHighZ(true);
|
||||||
|
te.check(0, 1, 0);
|
||||||
|
te.check(1, 0, 1);
|
||||||
|
a.setHighZ(false);
|
||||||
|
b.setHighZ(false);
|
||||||
|
try {
|
||||||
|
te.check(0, 0, 0);
|
||||||
|
assertTrue(false);
|
||||||
|
} catch (BurnException e) {
|
||||||
|
assertTrue(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testBusHighZ() throws Exception {
|
||||||
|
Model model = new Model();
|
||||||
|
ObservableValue a = new ObservableValue(1, true);
|
||||||
|
ObservableValue b = new ObservableValue(1, true);
|
||||||
|
ObservableValue out = model.add(new Bus(1)).addInput(a).addInput(b).getOutput();
|
||||||
|
|
||||||
|
TestExecuter te = new TestExecuter(model).setInputs(a, b).setOutputs(out);
|
||||||
|
assertTrue(out.isHighZ());
|
||||||
|
}
|
||||||
|
}
|
30
src/test/java/de/neemann/digital/wiring/MultiplexerTest.java
Normal file
30
src/test/java/de/neemann/digital/wiring/MultiplexerTest.java
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
package de.neemann.digital.wiring;
|
||||||
|
|
||||||
|
import de.neemann.digital.Model;
|
||||||
|
import de.neemann.digital.ObservableValue;
|
||||||
|
import de.neemann.digital.TestExecuter;
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author hneemann
|
||||||
|
*/
|
||||||
|
public class MultiplexerTest extends TestCase {
|
||||||
|
|
||||||
|
public void testMux() throws Exception {
|
||||||
|
Model model = new Model();
|
||||||
|
ObservableValue a = new ObservableValue(4);
|
||||||
|
ObservableValue b = new ObservableValue(4);
|
||||||
|
ObservableValue c = new ObservableValue(4);
|
||||||
|
ObservableValue d = new ObservableValue(4);
|
||||||
|
ObservableValue sel = new ObservableValue(2);
|
||||||
|
ObservableValue out = model.add(new Multiplexer(4, sel)).addInput(a).addInput(b).addInput(c).addInput(d).getOutput();
|
||||||
|
|
||||||
|
|
||||||
|
TestExecuter te = new TestExecuter(model).setInputs(a, b, c, d, sel).setOutputs(out);
|
||||||
|
te.check(3, 4, 5, 6, 0, 3);
|
||||||
|
te.check(3, 4, 5, 6, 1, 4);
|
||||||
|
te.check(3, 4, 5, 6, 2, 5);
|
||||||
|
te.check(3, 4, 5, 6, 3, 6);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user