mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-16 08:25:09 -04:00
added flip flops
This commit is contained in:
parent
79bbaa238f
commit
9cb9d50f3d
@ -39,4 +39,8 @@ public abstract class Node implements Listener {
|
||||
*/
|
||||
public abstract void writeOutputs() throws NodeException;
|
||||
|
||||
public void registerNodes(Model model) {
|
||||
model.add(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -55,6 +55,14 @@ public class ObservableValue extends Value {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean getBool() {
|
||||
return getValue() != 0;
|
||||
}
|
||||
|
||||
public void setBool(boolean bool) {
|
||||
setValue(bool ? 1 : 0);
|
||||
}
|
||||
|
||||
public long getValueBits(long value) {
|
||||
return value & mask;
|
||||
}
|
||||
@ -87,11 +95,12 @@ public class ObservableValue extends Value {
|
||||
public String toString() {
|
||||
return name + "{" +
|
||||
"value=" + (highZ ? "??" : value) +
|
||||
", bits=" + bits +
|
||||
", setBits=" + bits +
|
||||
'}';
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,9 @@
|
||||
package de.neemann.digital.core.arithmetic;
|
||||
|
||||
import de.neemann.digital.core.*;
|
||||
import de.neemann.digital.core.BitsException;
|
||||
import de.neemann.digital.core.Node;
|
||||
import de.neemann.digital.core.NodeException;
|
||||
import de.neemann.digital.core.ObservableValue;
|
||||
import de.neemann.digital.core.part.AttributeKey;
|
||||
import de.neemann.digital.core.part.Part;
|
||||
import de.neemann.digital.core.part.PartAttributes;
|
||||
@ -72,8 +75,4 @@ public class Add extends Node implements Part {
|
||||
return new ObservableValue[]{sum, c_out};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerNodes(Model model) {
|
||||
model.add(this);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
package de.neemann.digital.core.arithmetic;
|
||||
|
||||
import de.neemann.digital.core.Model;
|
||||
import de.neemann.digital.core.Node;
|
||||
import de.neemann.digital.core.NodeException;
|
||||
import de.neemann.digital.core.ObservableValue;
|
||||
@ -51,8 +50,4 @@ public class Mul extends Node implements Part {
|
||||
return new ObservableValue[]{mul};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerNodes(Model model) {
|
||||
model.add(this);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
package de.neemann.digital.core.basic;
|
||||
|
||||
import de.neemann.digital.core.Model;
|
||||
import de.neemann.digital.core.Node;
|
||||
import de.neemann.digital.core.NodeException;
|
||||
import de.neemann.digital.core.ObservableValue;
|
||||
@ -42,12 +41,6 @@ public abstract class FanIn extends Node implements Part {
|
||||
return new ObservableValue[]{output};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerNodes(Model model) {
|
||||
model.add(this);
|
||||
}
|
||||
|
||||
|
||||
public static class FanInDescription extends PartTypeDescription {
|
||||
public FanInDescription(Class<?> clazz) {
|
||||
super(clazz);
|
||||
|
@ -1,6 +1,5 @@
|
||||
package de.neemann.digital.core.basic;
|
||||
|
||||
import de.neemann.digital.core.Model;
|
||||
import de.neemann.digital.core.Node;
|
||||
import de.neemann.digital.core.NodeException;
|
||||
import de.neemann.digital.core.ObservableValue;
|
||||
@ -48,8 +47,4 @@ public class Not extends Node implements Part {
|
||||
return new ObservableValue[]{output};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerNodes(Model model) {
|
||||
model.add(this);
|
||||
}
|
||||
}
|
||||
|
23
src/main/java/de/neemann/digital/core/basic/XNOr.java
Normal file
23
src/main/java/de/neemann/digital/core/basic/XNOr.java
Normal file
@ -0,0 +1,23 @@
|
||||
package de.neemann.digital.core.basic;
|
||||
|
||||
import de.neemann.digital.core.NodeException;
|
||||
import de.neemann.digital.core.part.AttributeKey;
|
||||
import de.neemann.digital.core.part.PartAttributes;
|
||||
import de.neemann.digital.core.part.PartTypeDescription;
|
||||
|
||||
/**
|
||||
* @author hneemann
|
||||
*/
|
||||
public class XNOr extends XOr {
|
||||
|
||||
public static final PartTypeDescription DESCRIPTION = new PartTypeDescription(XNOr.class, "a", "b").addAttribute(AttributeKey.Bits);
|
||||
|
||||
public XNOr(PartAttributes attributes) {
|
||||
super(attributes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readInputs() throws NodeException {
|
||||
value = ~(a.getValue() ^ b.getValue());
|
||||
}
|
||||
}
|
58
src/main/java/de/neemann/digital/core/basic/XOr.java
Normal file
58
src/main/java/de/neemann/digital/core/basic/XOr.java
Normal file
@ -0,0 +1,58 @@
|
||||
package de.neemann.digital.core.basic;
|
||||
|
||||
import de.neemann.digital.core.BitsException;
|
||||
import de.neemann.digital.core.Node;
|
||||
import de.neemann.digital.core.NodeException;
|
||||
import de.neemann.digital.core.ObservableValue;
|
||||
import de.neemann.digital.core.part.AttributeKey;
|
||||
import de.neemann.digital.core.part.Part;
|
||||
import de.neemann.digital.core.part.PartAttributes;
|
||||
import de.neemann.digital.core.part.PartTypeDescription;
|
||||
|
||||
/**
|
||||
* @author hneemann
|
||||
*/
|
||||
public class XOr extends Node implements Part {
|
||||
|
||||
public static final PartTypeDescription DESCRIPTION = new PartTypeDescription(XOr.class, "a", "b").addAttribute(AttributeKey.Bits);
|
||||
private final int bits;
|
||||
private final ObservableValue out;
|
||||
protected ObservableValue a;
|
||||
protected ObservableValue b;
|
||||
protected long value;
|
||||
|
||||
public XOr(PartAttributes attributes) {
|
||||
bits = attributes.get(AttributeKey.Bits);
|
||||
this.out = new ObservableValue("out", bits);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readInputs() throws NodeException {
|
||||
value = a.getValue() ^ b.getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeOutputs() throws NodeException {
|
||||
out.setValue(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInputs(ObservableValue... inputs) throws BitsException {
|
||||
a = inputs[0];
|
||||
a.addListener(this);
|
||||
b = inputs[1];
|
||||
b.addListener(this);
|
||||
|
||||
if (a.getBits() != bits)
|
||||
throw new BitsException("wrongBitCount", a);
|
||||
|
||||
if (b.getBits() != bits)
|
||||
throw new BitsException("wrongBitCount", b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObservableValue[] getOutputs() {
|
||||
return new ObservableValue[]{out};
|
||||
}
|
||||
|
||||
}
|
65
src/main/java/de/neemann/digital/core/flipflops/D_FF.java
Normal file
65
src/main/java/de/neemann/digital/core/flipflops/D_FF.java
Normal file
@ -0,0 +1,65 @@
|
||||
package de.neemann.digital.core.flipflops;
|
||||
|
||||
import de.neemann.digital.core.BitsException;
|
||||
import de.neemann.digital.core.Node;
|
||||
import de.neemann.digital.core.NodeException;
|
||||
import de.neemann.digital.core.ObservableValue;
|
||||
import de.neemann.digital.core.part.AttributeKey;
|
||||
import de.neemann.digital.core.part.Part;
|
||||
import de.neemann.digital.core.part.PartAttributes;
|
||||
import de.neemann.digital.core.part.PartTypeDescription;
|
||||
|
||||
/**
|
||||
* @author hneemann
|
||||
*/
|
||||
public class D_FF extends Node implements Part {
|
||||
|
||||
public static final PartTypeDescription DESCRIPTION = new PartTypeDescription(D_FF.class, "D", "C").addAttribute(AttributeKey.Bits);
|
||||
private final int bits;
|
||||
private ObservableValue dVal;
|
||||
private ObservableValue clockVal;
|
||||
private ObservableValue q;
|
||||
private ObservableValue qn;
|
||||
private boolean lastClock;
|
||||
private long value;
|
||||
|
||||
public D_FF(PartAttributes attributes) {
|
||||
bits = attributes.getBits();
|
||||
this.q = new ObservableValue("Q", bits);
|
||||
this.qn = new ObservableValue("~Q", bits);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readInputs() throws NodeException {
|
||||
boolean clock = clockVal.getBool();
|
||||
if (clock && !lastClock)
|
||||
value = dVal.getValue();
|
||||
lastClock = clock;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeOutputs() throws NodeException {
|
||||
q.setValue(value);
|
||||
qn.setValue(~value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInputs(ObservableValue... inputs) throws BitsException {
|
||||
dVal = inputs[0];
|
||||
dVal.addListener(this);
|
||||
clockVal = inputs[1];
|
||||
clockVal.addListener(this);
|
||||
|
||||
if (dVal.getBits() != bits)
|
||||
throw new BitsException("wrongBitCount", dVal);
|
||||
|
||||
if (clockVal.getBits() != 1)
|
||||
throw new BitsException("clockIsABit", clockVal);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObservableValue[] getOutputs() {
|
||||
return new ObservableValue[]{q, qn};
|
||||
}
|
||||
|
||||
}
|
74
src/main/java/de/neemann/digital/core/flipflops/JK_FF.java
Normal file
74
src/main/java/de/neemann/digital/core/flipflops/JK_FF.java
Normal file
@ -0,0 +1,74 @@
|
||||
package de.neemann.digital.core.flipflops;
|
||||
|
||||
import de.neemann.digital.core.BitsException;
|
||||
import de.neemann.digital.core.Node;
|
||||
import de.neemann.digital.core.NodeException;
|
||||
import de.neemann.digital.core.ObservableValue;
|
||||
import de.neemann.digital.core.part.Part;
|
||||
import de.neemann.digital.core.part.PartAttributes;
|
||||
import de.neemann.digital.core.part.PartTypeDescription;
|
||||
|
||||
/**
|
||||
* @author hneemann
|
||||
*/
|
||||
public class JK_FF extends Node implements Part {
|
||||
|
||||
public static final PartTypeDescription DESCRIPTION = new PartTypeDescription(JK_FF.class, "J", "C", "K");
|
||||
private ObservableValue jVal;
|
||||
private ObservableValue kVal;
|
||||
private ObservableValue clockVal;
|
||||
private ObservableValue q;
|
||||
private ObservableValue qn;
|
||||
private boolean lastClock;
|
||||
private boolean out;
|
||||
|
||||
public JK_FF(PartAttributes attributes) {
|
||||
this.q = new ObservableValue("Q", 1);
|
||||
this.qn = new ObservableValue("~Q", 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readInputs() throws NodeException {
|
||||
boolean clock = clockVal.getBool();
|
||||
if (clock && !lastClock) {
|
||||
boolean j = jVal.getBool();
|
||||
boolean k = kVal.getBool();
|
||||
|
||||
if (j && k) out = !out;
|
||||
else if (j) out = true;
|
||||
else if (k) out = false;
|
||||
}
|
||||
lastClock = clock;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeOutputs() throws NodeException {
|
||||
q.setBool(out);
|
||||
qn.setBool(!out);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInputs(ObservableValue... inputs) throws BitsException {
|
||||
jVal = inputs[0];
|
||||
jVal.addListener(this);
|
||||
clockVal = inputs[1];
|
||||
clockVal.addListener(this);
|
||||
kVal = inputs[2];
|
||||
kVal.addListener(this);
|
||||
|
||||
if (jVal.getBits() != 1)
|
||||
throw new BitsException("wrongBitCount", jVal);
|
||||
|
||||
if (kVal.getBits() != 1)
|
||||
throw new BitsException("wrongBitCount", kVal);
|
||||
|
||||
if (clockVal.getBits() != 1)
|
||||
throw new BitsException("carryIsABit", clockVal);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObservableValue[] getOutputs() {
|
||||
return new ObservableValue[]{q, qn};
|
||||
}
|
||||
|
||||
}
|
73
src/main/java/de/neemann/digital/core/flipflops/RS_FF.java
Normal file
73
src/main/java/de/neemann/digital/core/flipflops/RS_FF.java
Normal file
@ -0,0 +1,73 @@
|
||||
package de.neemann.digital.core.flipflops;
|
||||
|
||||
import de.neemann.digital.core.BitsException;
|
||||
import de.neemann.digital.core.Node;
|
||||
import de.neemann.digital.core.NodeException;
|
||||
import de.neemann.digital.core.ObservableValue;
|
||||
import de.neemann.digital.core.part.Part;
|
||||
import de.neemann.digital.core.part.PartAttributes;
|
||||
import de.neemann.digital.core.part.PartTypeDescription;
|
||||
|
||||
/**
|
||||
* @author hneemann
|
||||
*/
|
||||
public class RS_FF extends Node implements Part {
|
||||
|
||||
public static final PartTypeDescription DESCRIPTION = new PartTypeDescription(RS_FF.class, "R", "C", "S");
|
||||
private ObservableValue jVal;
|
||||
private ObservableValue kVal;
|
||||
private ObservableValue clockVal;
|
||||
private ObservableValue q;
|
||||
private ObservableValue qn;
|
||||
private boolean lastClock;
|
||||
private boolean out;
|
||||
|
||||
public RS_FF(PartAttributes attributes) {
|
||||
this.q = new ObservableValue("Q", 1);
|
||||
this.qn = new ObservableValue("~Q", 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readInputs() throws NodeException {
|
||||
boolean clock = clockVal.getBool();
|
||||
if (clock && !lastClock) {
|
||||
boolean j = jVal.getBool();
|
||||
boolean k = kVal.getBool();
|
||||
|
||||
if (j && !k) out = true;
|
||||
else if (!j && k) out = false;
|
||||
}
|
||||
lastClock = clock;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeOutputs() throws NodeException {
|
||||
q.setBool(out);
|
||||
qn.setBool(!out);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInputs(ObservableValue... inputs) throws BitsException {
|
||||
jVal = inputs[0];
|
||||
jVal.addListener(this);
|
||||
clockVal = inputs[1];
|
||||
clockVal.addListener(this);
|
||||
kVal = inputs[2];
|
||||
kVal.addListener(this);
|
||||
|
||||
if (jVal.getBits() != 1)
|
||||
throw new BitsException("wrongBitCount", jVal);
|
||||
|
||||
if (kVal.getBits() != 1)
|
||||
throw new BitsException("wrongBitCount", kVal);
|
||||
|
||||
if (clockVal.getBits() != 1)
|
||||
throw new BitsException("carryIsABit", clockVal);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObservableValue[] getOutputs() {
|
||||
return new ObservableValue[]{q, qn};
|
||||
}
|
||||
|
||||
}
|
57
src/main/java/de/neemann/digital/core/flipflops/T_FF.java
Normal file
57
src/main/java/de/neemann/digital/core/flipflops/T_FF.java
Normal file
@ -0,0 +1,57 @@
|
||||
package de.neemann.digital.core.flipflops;
|
||||
|
||||
import de.neemann.digital.core.BitsException;
|
||||
import de.neemann.digital.core.Node;
|
||||
import de.neemann.digital.core.NodeException;
|
||||
import de.neemann.digital.core.ObservableValue;
|
||||
import de.neemann.digital.core.part.Part;
|
||||
import de.neemann.digital.core.part.PartAttributes;
|
||||
import de.neemann.digital.core.part.PartTypeDescription;
|
||||
|
||||
/**
|
||||
* @author hneemann
|
||||
*/
|
||||
public class T_FF extends Node implements Part {
|
||||
|
||||
public static final PartTypeDescription DESCRIPTION = new PartTypeDescription(T_FF.class, "C");
|
||||
private ObservableValue clockVal;
|
||||
private ObservableValue q;
|
||||
private ObservableValue qn;
|
||||
private boolean lastClock;
|
||||
private boolean out;
|
||||
|
||||
public T_FF(PartAttributes attributes) {
|
||||
this.q = new ObservableValue("Q", 1);
|
||||
this.qn = new ObservableValue("~Q", 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readInputs() throws NodeException {
|
||||
boolean clock = clockVal.getBool();
|
||||
if (clock && !lastClock) {
|
||||
out = !out;
|
||||
}
|
||||
lastClock = clock;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeOutputs() throws NodeException {
|
||||
q.setBool(out);
|
||||
qn.setBool(!out);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInputs(ObservableValue... inputs) throws BitsException {
|
||||
clockVal = inputs[0];
|
||||
clockVal.addListener(this);
|
||||
|
||||
if (clockVal.getBits() != 1)
|
||||
throw new BitsException("carryIsABit", clockVal);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObservableValue[] getOutputs() {
|
||||
return new ObservableValue[]{q, qn};
|
||||
}
|
||||
|
||||
}
|
@ -55,7 +55,11 @@ public class PartAttributes {
|
||||
listeners.remove(listener);
|
||||
}
|
||||
|
||||
public PartAttributes bits(int bits) {
|
||||
public int getBits() {
|
||||
return get(AttributeKey.Bits);
|
||||
}
|
||||
|
||||
public PartAttributes setBits(int bits) {
|
||||
set(AttributeKey.Bits, bits);
|
||||
return this;
|
||||
}
|
||||
|
@ -170,10 +170,6 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave {
|
||||
setJMenuBar(bar);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
SwingUtilities.invokeLater(() -> new Main().setVisible(true));
|
||||
}
|
||||
|
||||
private static XStream getxStream() {
|
||||
XStream xStream = new XStream(new StaxDriver());
|
||||
xStream.alias("visualPart", VisualPart.class);
|
||||
@ -187,6 +183,10 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave {
|
||||
return xStream;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
SwingUtilities.invokeLater(() -> new Main().setVisible(true));
|
||||
}
|
||||
|
||||
private JFileChooser getjFileChooser() {
|
||||
JFileChooser fileChooser = new JFileChooser(filename == null ? null : filename.getParentFile());
|
||||
fileChooser.addChoosableFileFilter(new FileNameExtensionFilter("Circuit", "dig"));
|
||||
@ -195,7 +195,7 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave {
|
||||
|
||||
@Override
|
||||
public boolean isStateChanged() {
|
||||
return false;
|
||||
return circuitComponent.getCircuit().isModified();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -27,7 +27,7 @@ public class CircuitComponent extends JComponent implements Listener {
|
||||
private final PartLibrary library;
|
||||
private Circuit circuit;
|
||||
private Mouse listener;
|
||||
private AffineTransform transform = AffineTransform.getScaleInstance(1, 1);
|
||||
private AffineTransform transform = new AffineTransform();
|
||||
|
||||
public CircuitComponent(Circuit aCircuit, PartLibrary library) {
|
||||
this.circuit = aCircuit;
|
||||
@ -56,8 +56,8 @@ public class CircuitComponent extends JComponent implements Listener {
|
||||
@Override
|
||||
public void mouseWheelMoved(MouseWheelEvent e) {
|
||||
Vector pos = getPosVector(e);
|
||||
transform.translate(pos.x, pos.y);
|
||||
double f = Math.pow(0.9, e.getWheelRotation());
|
||||
transform.translate(pos.x, pos.y);
|
||||
transform.scale(f, f);
|
||||
transform.translate(-pos.x, -pos.y);
|
||||
repaint();
|
||||
@ -355,7 +355,6 @@ public class CircuitComponent extends JComponent implements Listener {
|
||||
if (vp.matches(pos)) {
|
||||
vp.clicked(CircuitComponent.this, pos);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,13 @@
|
||||
package de.neemann.digital.gui.draw.library;
|
||||
|
||||
import de.neemann.digital.core.arithmetic.Add;
|
||||
import de.neemann.digital.core.arithmetic.Mul;
|
||||
import de.neemann.digital.core.arithmetic.Sub;
|
||||
import de.neemann.digital.core.basic.*;
|
||||
import de.neemann.digital.core.flipflops.D_FF;
|
||||
import de.neemann.digital.core.flipflops.JK_FF;
|
||||
import de.neemann.digital.core.flipflops.RS_FF;
|
||||
import de.neemann.digital.core.flipflops.T_FF;
|
||||
import de.neemann.digital.core.io.In;
|
||||
import de.neemann.digital.core.io.Out;
|
||||
import de.neemann.digital.core.part.PartTypeDescription;
|
||||
@ -19,17 +26,24 @@ public class PartLibrary implements Iterable<PartLibrary.PartContainer> {
|
||||
|
||||
public PartLibrary() {
|
||||
add(And.DESCRIPTION, "Logic");
|
||||
add(Or.DESCRIPTION, "Logic");
|
||||
add(NAnd.DESCRIPTION, "Logic");
|
||||
add(Or.DESCRIPTION, "Logic");
|
||||
add(NOr.DESCRIPTION, "Logic");
|
||||
add(XOr.DESCRIPTION, "Logic");
|
||||
add(XNOr.DESCRIPTION, "Logic");
|
||||
add(Not.DESCRIPTION, "Logic");
|
||||
|
||||
add(In.DESCRIPTION, "IO");
|
||||
add(Out.DESCRIPTION, "IO");
|
||||
|
||||
// add(Add.DESCRIPTION,"Aritmetic");
|
||||
// add(Sub.DESCRIPTION,"Aritmetic");
|
||||
// add(Mul.DESCRIPTION,"Aritmetic");
|
||||
add(RS_FF.DESCRIPTION, "FlipFlops");
|
||||
add(JK_FF.DESCRIPTION, "FlipFlops");
|
||||
add(D_FF.DESCRIPTION, "FlipFlops");
|
||||
add(T_FF.DESCRIPTION, "FlipFlops");
|
||||
|
||||
add(Add.DESCRIPTION, "Aritmetic");
|
||||
add(Sub.DESCRIPTION, "Aritmetic");
|
||||
add(Mul.DESCRIPTION, "Aritmetic");
|
||||
}
|
||||
|
||||
private void add(PartTypeDescription description, String treePath) {
|
||||
|
@ -14,6 +14,7 @@ public class Circuit implements Drawable {
|
||||
private final ArrayList<VisualPart> visualParts;
|
||||
private ArrayList<Wire> wires;
|
||||
private transient boolean dotsPresent = false;
|
||||
private transient boolean modified = false;
|
||||
|
||||
public Circuit() {
|
||||
visualParts = new ArrayList<>();
|
||||
@ -35,6 +36,7 @@ public class Circuit implements Drawable {
|
||||
|
||||
public void add(VisualPart visualPart) {
|
||||
visualParts.add(visualPart);
|
||||
modified = true;
|
||||
}
|
||||
|
||||
public void add(Wire newWire) {
|
||||
@ -58,6 +60,7 @@ public class Circuit implements Drawable {
|
||||
wires = checker.check();
|
||||
|
||||
dotsPresent = false;
|
||||
modified = true;
|
||||
}
|
||||
|
||||
public ArrayList<VisualPart> getParts() {
|
||||
@ -96,6 +99,7 @@ public class Circuit implements Drawable {
|
||||
}
|
||||
}
|
||||
dotsPresent = false;
|
||||
modified = true;
|
||||
}
|
||||
|
||||
public ArrayList<Wire> getWires() {
|
||||
@ -108,4 +112,8 @@ public class Circuit implements Drawable {
|
||||
for (Wire w : wires)
|
||||
w.setValue(null);
|
||||
}
|
||||
|
||||
public boolean isModified() {
|
||||
return modified;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,9 @@
|
||||
package de.neemann.digital.gui.draw.shapes;
|
||||
|
||||
import de.neemann.digital.core.ObservableValue;
|
||||
import de.neemann.digital.core.arithmetic.Add;
|
||||
import de.neemann.digital.core.arithmetic.Mul;
|
||||
import de.neemann.digital.core.arithmetic.Sub;
|
||||
import de.neemann.digital.core.basic.*;
|
||||
import de.neemann.digital.core.io.In;
|
||||
import de.neemann.digital.core.io.Out;
|
||||
@ -26,6 +29,14 @@ public final class ShapeFactory {
|
||||
map.put(NOr.DESCRIPTION.getName(), new CreatorSimple("\u22651", NOr.DESCRIPTION, true));
|
||||
map.put(Not.DESCRIPTION.getName(), new CreatorSimple("", Not.DESCRIPTION, true));
|
||||
|
||||
map.put(XOr.DESCRIPTION.getName(), new CreatorSimple("=1", XOr.DESCRIPTION, false));
|
||||
map.put(XNOr.DESCRIPTION.getName(), new CreatorSimple("=1", XNOr.DESCRIPTION, true));
|
||||
|
||||
map.put(Add.DESCRIPTION.getName(), new CreatorSimple("+", Add.DESCRIPTION, false));
|
||||
map.put(Sub.DESCRIPTION.getName(), new CreatorSimple("-", Sub.DESCRIPTION, false));
|
||||
map.put(Mul.DESCRIPTION.getName(), new CreatorSimple("*", Mul.DESCRIPTION, false));
|
||||
|
||||
|
||||
map.put(In.DESCRIPTION.getName(), attributes -> new InputShape(attributes.get(AttributeKey.Bits), attributes.get(AttributeKey.Label)));
|
||||
map.put(Out.DESCRIPTION.getName(), attributes -> new OutputShape(attributes.get(AttributeKey.Bits), attributes.get(AttributeKey.Label)));
|
||||
}
|
||||
@ -50,12 +61,20 @@ public final class ShapeFactory {
|
||||
throw new RuntimeException("no shape for " + partName);
|
||||
else {
|
||||
PartTypeDescription pt = library.getPartType(partName);
|
||||
return new GenericShape(partName, pt.getInputNames(partAttributes), outputNames(pt, partAttributes));
|
||||
return new GenericShape(createName(partName), pt.getInputNames(partAttributes), outputNames(pt, partAttributes));
|
||||
}
|
||||
} else
|
||||
return cr.create(partAttributes);
|
||||
}
|
||||
|
||||
private String createName(String partName) {
|
||||
int p = partName.indexOf('_');
|
||||
if (p < 0)
|
||||
return partName;
|
||||
else
|
||||
return partName.substring(0, p);
|
||||
}
|
||||
|
||||
private interface Creator {
|
||||
Shape create(PartAttributes attributes);
|
||||
}
|
||||
|
@ -16,8 +16,8 @@ public class FlipFlops extends TestCase {
|
||||
ObservableValue s = new ObservableValue("s", 1);
|
||||
|
||||
Model model = new Model();
|
||||
FanIn a1 = model.add(new NOr(new PartAttributes().bits(1)));
|
||||
FanIn a2 = model.add(new NOr(new PartAttributes().bits(1)));
|
||||
FanIn a1 = model.add(new NOr(new PartAttributes().setBits(1)));
|
||||
FanIn a2 = model.add(new NOr(new PartAttributes().setBits(1)));
|
||||
|
||||
a1.setInputs(r, a2.getOutput());
|
||||
a2.setInputs(s, a1.getOutput());
|
||||
@ -42,8 +42,8 @@ public class FlipFlops extends TestCase {
|
||||
ObservableValue s = new ObservableValue("s", 1);
|
||||
|
||||
Model model = new Model();
|
||||
FanIn a1 = model.add(new NAnd(new PartAttributes().bits(1)));
|
||||
FanIn a2 = model.add(new NAnd(new PartAttributes().bits(1)));
|
||||
FanIn a1 = model.add(new NAnd(new PartAttributes().setBits(1)));
|
||||
FanIn a2 = model.add(new NAnd(new PartAttributes().setBits(1)));
|
||||
|
||||
a1.setInputs(r, a2.getOutput());
|
||||
a2.setInputs(s, a1.getOutput());
|
||||
@ -62,7 +62,7 @@ public class FlipFlops extends TestCase {
|
||||
ObservableValue k = new ObservableValue("k", 1);
|
||||
ObservableValue c = new ObservableValue("c", 1);
|
||||
|
||||
PartAttributes attr = new PartAttributes().bits(1);
|
||||
PartAttributes attr = new PartAttributes().setBits(1);
|
||||
|
||||
Model model = new Model();
|
||||
FanIn nor3 = model.add(new NOr(attr));
|
||||
|
@ -18,7 +18,7 @@ public class AddTest extends TestCase {
|
||||
|
||||
|
||||
Model model = new Model();
|
||||
Add node = new Add(new PartAttributes().bits(4));
|
||||
Add node = new Add(new PartAttributes().setBits(4));
|
||||
node.setInputs(a, b, c);
|
||||
model.add(node);
|
||||
|
||||
|
@ -16,7 +16,7 @@ public class MulTest extends TestCase {
|
||||
|
||||
|
||||
Model model = new Model();
|
||||
Mul node = model.add(new Mul(new PartAttributes().bits(4)));
|
||||
Mul node = model.add(new Mul(new PartAttributes().setBits(4)));
|
||||
node.setInputs(a, b);
|
||||
|
||||
TestExecuter sc = new TestExecuter(model).setInputs(a, b).setOutputs(node.getMul());
|
||||
|
@ -18,7 +18,7 @@ public class SubTest extends TestCase {
|
||||
|
||||
|
||||
Model model = new Model();
|
||||
Add node = new Sub(new PartAttributes().bits(4));
|
||||
Add node = new Sub(new PartAttributes().setBits(4));
|
||||
node.setInputs(a, b, c);
|
||||
model.add(node);
|
||||
|
||||
|
@ -15,9 +15,8 @@ public class AndTest extends TestCase {
|
||||
ObservableValue a = new ObservableValue("a", 1);
|
||||
ObservableValue b = new ObservableValue("b", 1);
|
||||
|
||||
|
||||
Model model = new Model();
|
||||
FanIn out = model.add(new And(new PartAttributes().bits(1)));
|
||||
FanIn out = model.add(new And(new PartAttributes().setBits(1)));
|
||||
out.setInputs(a, b);
|
||||
|
||||
TestExecuter sc = new TestExecuter(model).setInputs(a, b).setOutputs(out.getOutputs());
|
||||
|
@ -16,7 +16,7 @@ public class NAndTest extends TestCase {
|
||||
ObservableValue b = new ObservableValue("b", 1);
|
||||
|
||||
Model model = new Model();
|
||||
FanIn out = model.add(new NAnd(new PartAttributes().bits(1)));
|
||||
FanIn out = model.add(new NAnd(new PartAttributes().setBits(1)));
|
||||
out.setInputs(a, b);
|
||||
|
||||
|
||||
|
@ -16,7 +16,7 @@ public class NOrTest extends TestCase {
|
||||
ObservableValue b = new ObservableValue("b", 1);
|
||||
|
||||
Model model = new Model();
|
||||
NOr nor = model.add(new NOr(new PartAttributes().bits(1)));
|
||||
NOr nor = model.add(new NOr(new PartAttributes().setBits(1)));
|
||||
nor.setInputs(a, b);
|
||||
|
||||
TestExecuter sc = new TestExecuter(model).setInputs(a, b).setOutputs(nor.getOutputs());
|
||||
|
@ -16,7 +16,7 @@ public class OrTest extends TestCase {
|
||||
ObservableValue b = new ObservableValue("b", 1);
|
||||
|
||||
Model model = new Model();
|
||||
FanIn and = model.add(new Or(new PartAttributes().bits(1)));
|
||||
FanIn and = model.add(new Or(new PartAttributes().setBits(1)));
|
||||
and.setInputs(a, b);
|
||||
|
||||
TestExecuter sc = new TestExecuter(model).setInputs(a, b).setOutputs(and.getOutput());
|
||||
|
29
src/test/java/de/neemann/digital/core/basic/XNOrTest.java
Normal file
29
src/test/java/de/neemann/digital/core/basic/XNOrTest.java
Normal file
@ -0,0 +1,29 @@
|
||||
package de.neemann.digital.core.basic;
|
||||
|
||||
import de.neemann.digital.TestExecuter;
|
||||
import de.neemann.digital.core.Model;
|
||||
import de.neemann.digital.core.ObservableValue;
|
||||
import de.neemann.digital.core.part.PartAttributes;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* @author hneemann
|
||||
*/
|
||||
public class XNOrTest extends TestCase {
|
||||
|
||||
public void testXor() throws Exception {
|
||||
ObservableValue a = new ObservableValue("a", 1);
|
||||
ObservableValue b = new ObservableValue("b", 1);
|
||||
|
||||
|
||||
Model model = new Model();
|
||||
XNOr out = model.add(new XNOr(new PartAttributes().setBits(1)));
|
||||
out.setInputs(a, b);
|
||||
|
||||
TestExecuter sc = new TestExecuter(model).setInputs(a, b).setOutputs(out.getOutputs());
|
||||
sc.check(0, 0, 1);
|
||||
sc.check(1, 0, 0);
|
||||
sc.check(0, 1, 0);
|
||||
sc.check(1, 1, 1);
|
||||
}
|
||||
}
|
29
src/test/java/de/neemann/digital/core/basic/XOrTest.java
Normal file
29
src/test/java/de/neemann/digital/core/basic/XOrTest.java
Normal file
@ -0,0 +1,29 @@
|
||||
package de.neemann.digital.core.basic;
|
||||
|
||||
import de.neemann.digital.TestExecuter;
|
||||
import de.neemann.digital.core.Model;
|
||||
import de.neemann.digital.core.ObservableValue;
|
||||
import de.neemann.digital.core.part.PartAttributes;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* @author hneemann
|
||||
*/
|
||||
public class XOrTest extends TestCase {
|
||||
|
||||
public void testXor() throws Exception {
|
||||
ObservableValue a = new ObservableValue("a", 1);
|
||||
ObservableValue b = new ObservableValue("b", 1);
|
||||
|
||||
|
||||
Model model = new Model();
|
||||
XOr out = model.add(new XOr(new PartAttributes().setBits(1)));
|
||||
out.setInputs(a, b);
|
||||
|
||||
TestExecuter sc = new TestExecuter(model).setInputs(a, b).setOutputs(out.getOutputs());
|
||||
sc.check(0, 0, 0);
|
||||
sc.check(1, 0, 1);
|
||||
sc.check(0, 1, 1);
|
||||
sc.check(1, 1, 0);
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package de.neemann.digital.core.flipflops;
|
||||
|
||||
import de.neemann.digital.TestExecuter;
|
||||
import de.neemann.digital.core.Model;
|
||||
import de.neemann.digital.core.ObservableValue;
|
||||
import de.neemann.digital.core.part.PartAttributes;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* @author hneemann
|
||||
*/
|
||||
public class D_FFTest extends TestCase {
|
||||
public void testFlipFlop() throws Exception {
|
||||
ObservableValue d = new ObservableValue("s", 8);
|
||||
ObservableValue c = new ObservableValue("c", 1);
|
||||
|
||||
Model model = new Model();
|
||||
D_FF out = model.add(new D_FF(new PartAttributes().setBits(8)));
|
||||
out.setInputs(d, c);
|
||||
|
||||
TestExecuter sc = new TestExecuter(model).setInputs(d, c).setOutputs(out.getOutputs());
|
||||
// D C Q ~Q
|
||||
sc.check(0, 0, 0, 255);
|
||||
sc.check(1, 0, 0, 255);
|
||||
sc.check(1, 1, 1, 254);
|
||||
sc.check(1, 0, 1, 254);
|
||||
sc.check(0, 0, 1, 254);
|
||||
sc.check(7, 0, 1, 254);
|
||||
sc.check(7, 1, 7, 248);
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
package de.neemann.digital.core.flipflops;
|
||||
|
||||
import de.neemann.digital.TestExecuter;
|
||||
import de.neemann.digital.core.Model;
|
||||
import de.neemann.digital.core.ObservableValue;
|
||||
import de.neemann.digital.core.part.PartAttributes;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* @author hneemann
|
||||
*/
|
||||
public class JK_FFTest extends TestCase {
|
||||
public void testFlipFlop() throws Exception {
|
||||
ObservableValue j = new ObservableValue("j", 1);
|
||||
ObservableValue c = new ObservableValue("c", 1);
|
||||
ObservableValue k = new ObservableValue("k", 1);
|
||||
|
||||
Model model = new Model();
|
||||
JK_FF out = model.add(new JK_FF(new PartAttributes()));
|
||||
out.setInputs(j, c, k);
|
||||
|
||||
TestExecuter sc = new TestExecuter(model).setInputs(j, c, k).setOutputs(out.getOutputs());
|
||||
// J C K Q ~Q
|
||||
sc.check(0, 0, 0, 0, 1);
|
||||
sc.check(0, 0, 0, 0, 1);
|
||||
sc.check(1, 0, 0, 0, 1);
|
||||
sc.check(0, 1, 0, 0, 1);
|
||||
sc.check(1, 0, 0, 0, 1);
|
||||
sc.check(1, 1, 0, 1, 0);
|
||||
sc.check(1, 0, 1, 1, 0);
|
||||
sc.check(1, 1, 1, 0, 1);
|
||||
sc.check(1, 0, 1, 0, 1);
|
||||
sc.check(1, 1, 1, 1, 0);
|
||||
sc.check(0, 0, 1, 1, 0);
|
||||
sc.check(0, 1, 1, 0, 1);
|
||||
sc.check(0, 0, 0, 0, 1);
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
package de.neemann.digital.core.flipflops;
|
||||
|
||||
import de.neemann.digital.TestExecuter;
|
||||
import de.neemann.digital.core.Model;
|
||||
import de.neemann.digital.core.ObservableValue;
|
||||
import de.neemann.digital.core.part.PartAttributes;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* @author hneemann
|
||||
*/
|
||||
public class RS_FFTest extends TestCase {
|
||||
public void testFlipFlop() throws Exception {
|
||||
ObservableValue s = new ObservableValue("s", 1);
|
||||
ObservableValue c = new ObservableValue("c", 1);
|
||||
ObservableValue r = new ObservableValue("r", 1);
|
||||
|
||||
Model model = new Model();
|
||||
RS_FF out = model.add(new RS_FF(new PartAttributes()));
|
||||
out.setInputs(s, c, r);
|
||||
|
||||
TestExecuter sc = new TestExecuter(model).setInputs(s, c, r).setOutputs(out.getOutputs());
|
||||
// S C R Q ~Q
|
||||
sc.check(0, 0, 0, 0, 1);
|
||||
sc.check(0, 0, 0, 0, 1);
|
||||
sc.check(1, 0, 0, 0, 1);
|
||||
sc.check(0, 1, 0, 0, 1);
|
||||
sc.check(1, 0, 0, 0, 1);
|
||||
sc.check(1, 1, 0, 1, 0);
|
||||
sc.check(1, 0, 1, 1, 0);
|
||||
sc.check(1, 1, 1, 1, 0);
|
||||
sc.check(1, 0, 1, 1, 0);
|
||||
sc.check(1, 1, 1, 1, 0);
|
||||
sc.check(0, 0, 1, 1, 0);
|
||||
sc.check(0, 1, 1, 0, 1);
|
||||
sc.check(0, 0, 0, 0, 1);
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package de.neemann.digital.core.flipflops;
|
||||
|
||||
import de.neemann.digital.TestExecuter;
|
||||
import de.neemann.digital.core.Model;
|
||||
import de.neemann.digital.core.ObservableValue;
|
||||
import de.neemann.digital.core.part.PartAttributes;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* @author hneemann
|
||||
*/
|
||||
public class T_FFTest extends TestCase {
|
||||
public void testFlipFlop() throws Exception {
|
||||
ObservableValue c = new ObservableValue("c", 1);
|
||||
|
||||
Model model = new Model();
|
||||
T_FF out = model.add(new T_FF(new PartAttributes().setBits(1)));
|
||||
out.setInputs(c);
|
||||
|
||||
TestExecuter sc = new TestExecuter(model).setInputs(c).setOutputs(out.getOutputs());
|
||||
// C Q ~Q
|
||||
sc.check(0, 0, 1);
|
||||
sc.check(1, 1, 0);
|
||||
sc.check(1, 1, 0);
|
||||
sc.check(0, 1, 0);
|
||||
sc.check(0, 1, 0);
|
||||
sc.check(1, 0, 1);
|
||||
sc.check(0, 0, 1);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user