From a07a799d9d93669126a544b88856a05e11323b79 Mon Sep 17 00:00:00 2001 From: Fabian Stemmler Date: Mon, 13 May 2019 19:18:32 +0200 Subject: [PATCH] logic gates and, or and xor now take an arbitrary amount of inputs. --- era.mi/src/era/mi/logic/Util.java | 2 +- .../mi/logic/components/BasicComponent.java | 4 ++ .../mi/logic/components/gates/AndGate.java | 53 +--------------- .../components/gates/MultiInputGate.java | 63 +++++++++++++++++++ .../era/mi/logic/components/gates/OrGate.java | 55 ++-------------- .../mi/logic/components/gates/XorGate.java | 57 +++-------------- .../src/era/mi/logic/tests/ComponentTest.java | 45 +++++++++---- era.mi/src/era/mi/logic/tests/Connector.java | 6 +- .../src/era/mi/logic/timeline/Timeline.java | 5 ++ era.mi/src/era/mi/logic/wires/WireArray.java | 2 +- 10 files changed, 124 insertions(+), 168 deletions(-) create mode 100644 era.mi/src/era/mi/logic/components/gates/MultiInputGate.java diff --git a/era.mi/src/era/mi/logic/Util.java b/era.mi/src/era/mi/logic/Util.java index 3ca16b7a..0cd4b824 100644 --- a/era.mi/src/era/mi/logic/Util.java +++ b/era.mi/src/era/mi/logic/Util.java @@ -103,6 +103,6 @@ public final class Util interface BitOp { - Bit execute(Bit a, Bit b); + Bit execute(Bit a, Bit b); } } diff --git a/era.mi/src/era/mi/logic/components/BasicComponent.java b/era.mi/src/era/mi/logic/components/BasicComponent.java index 930e3a52..4e56c347 100644 --- a/era.mi/src/era/mi/logic/components/BasicComponent.java +++ b/era.mi/src/era/mi/logic/components/BasicComponent.java @@ -5,6 +5,10 @@ import era.mi.logic.Simulation; import era.mi.logic.wires.WireArray; import era.mi.logic.wires.WireArrayObserver; +/** + * A basic component that recomputes all outputs (with a delay), when it is updated. + * @author Fabian Stemmler + */ public abstract class BasicComponent implements WireArrayObserver, Component { private int processTime; diff --git a/era.mi/src/era/mi/logic/components/gates/AndGate.java b/era.mi/src/era/mi/logic/components/gates/AndGate.java index 5c814064..853fecc6 100644 --- a/era.mi/src/era/mi/logic/components/gates/AndGate.java +++ b/era.mi/src/era/mi/logic/components/gates/AndGate.java @@ -1,59 +1,12 @@ package era.mi.logic.components.gates; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - import era.mi.logic.Util; -import era.mi.logic.components.BasicComponent; import era.mi.logic.wires.WireArray; -import era.mi.logic.wires.WireArray.WireArrayInput; -public class AndGate extends BasicComponent +public class AndGate extends MultiInputGate { - private WireArray a, b, out; - private WireArrayInput outI; - - public AndGate(int processTime, WireArray a, WireArray b, WireArray out) - { - super(processTime); - this.a = a; - a.addObserver(this); - this.b = b; - b.addObserver(this); - this.out = out; - outI = out.createInput(); - } - - protected void compute() - { - outI.feedSignals(Util.and(a.getValues(), b.getValues())); - } - - public WireArray getA() - { - return a; - } - - public WireArray getB() - { - return b; - } - - public WireArray getOut() - { - return out; - } - - @Override - public List getAllInputs() - { - return Collections.unmodifiableList(Arrays.asList(a, b)); - } - - @Override - public List getAllOutputs() + public AndGate(int processTime, WireArray out, WireArray... in) { - return Collections.unmodifiableList(Arrays.asList(out)); + super(processTime, Util::and, out, in); } } diff --git a/era.mi/src/era/mi/logic/components/gates/MultiInputGate.java b/era.mi/src/era/mi/logic/components/gates/MultiInputGate.java new file mode 100644 index 00000000..b85939ea --- /dev/null +++ b/era.mi/src/era/mi/logic/components/gates/MultiInputGate.java @@ -0,0 +1,63 @@ +package era.mi.logic.components.gates; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import era.mi.logic.Bit; +import era.mi.logic.components.BasicComponent; +import era.mi.logic.wires.WireArray; +import era.mi.logic.wires.WireArray.WireArrayInput; + +public abstract class MultiInputGate extends BasicComponent +{ + protected WireArray[] in; + protected WireArray out; + protected WireArrayInput outI; + protected final int length; + protected Operation op; + + protected MultiInputGate(int processTime, Operation op, WireArray out, WireArray... in) + { + super(processTime); + this.op = op; + length = out.length; + this.in = in.clone(); + if(in.length < 1) + throw new IllegalArgumentException(String.format("Cannot create gate with %d wires.", in.length)); + for(WireArray w : in) + { + if(w.length != length) + throw new IllegalArgumentException("All wires connected to the gate must be of uniform length."); + w.addObserver(this); + } + this.out = out; + outI = out.createInput(); + } + + + @Override + public List getAllInputs() + { + return Collections.unmodifiableList(Arrays.asList(in)); + } + + @Override + public List getAllOutputs() + { + return Collections.unmodifiableList(Arrays.asList(out)); + } + + protected void compute() + { + Bit[] result = in[0].getValues(); + for(int i = 1; i < in.length; i++) + result = op.execute(result, in[i].getValues()); + outI.feedSignals(result); + } + + protected interface Operation + { + public Bit[] execute(Bit[] a, Bit[] b); + } +} diff --git a/era.mi/src/era/mi/logic/components/gates/OrGate.java b/era.mi/src/era/mi/logic/components/gates/OrGate.java index 8e145d15..b538eb4f 100644 --- a/era.mi/src/era/mi/logic/components/gates/OrGate.java +++ b/era.mi/src/era/mi/logic/components/gates/OrGate.java @@ -1,59 +1,12 @@ package era.mi.logic.components.gates; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - import era.mi.logic.Util; -import era.mi.logic.components.BasicComponent; import era.mi.logic.wires.WireArray; -import era.mi.logic.wires.WireArray.WireArrayInput; - -public class OrGate extends BasicComponent -{ - private WireArray a, b, out; - private WireArrayInput outI; - - public OrGate(int processTime, WireArray a, WireArray b, WireArray out) - { - super(processTime); - this.a = a; - a.addObserver(this); - this.b = b; - b.addObserver(this); - this.out = out; - this.outI = out.createInput(); - } - - protected void compute() - { - outI.feedSignals(Util.or(a.getValues(), b.getValues())); - } - - public WireArray getA() - { - return a; - } - - public WireArray getB() - { - return b; - } - - public WireArray getOut() - { - return out; - } - - @Override - public List getAllInputs() - { - return Collections.unmodifiableList(Arrays.asList(a, b)); - } - @Override - public List getAllOutputs() +public class OrGate extends MultiInputGate +{ + public OrGate(int processTime, WireArray out, WireArray... in) { - return Collections.unmodifiableList(Arrays.asList(out)); + super(processTime, Util::or, out, in); } } diff --git a/era.mi/src/era/mi/logic/components/gates/XorGate.java b/era.mi/src/era/mi/logic/components/gates/XorGate.java index b13dd2bc..c20af6f2 100644 --- a/era.mi/src/era/mi/logic/components/gates/XorGate.java +++ b/era.mi/src/era/mi/logic/components/gates/XorGate.java @@ -1,58 +1,17 @@ package era.mi.logic.components.gates; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - import era.mi.logic.Util; -import era.mi.logic.components.BasicComponent; import era.mi.logic.wires.WireArray; -import era.mi.logic.wires.WireArray.WireArrayInput; -public class XorGate extends BasicComponent -{ - private WireArray a, b, out; - private WireArrayInput outI; - - public XorGate(int processTime, WireArray a, WireArray b, WireArray out) +/** + * Outputs 1 when the number of 1 inputs is odd. + * @author Fabian Stemmler + */ +public class XorGate extends MultiInputGate +{ + public XorGate(int processTime, WireArray out, WireArray... in) { - super(processTime); - this.a = a; - a.addObserver(this); - this.b = b; - b.addObserver(this); - this.out = out; + super(processTime, Util::xor, out, in); } - protected void compute() - { - outI.feedSignals(Util.xor(a.getValues(), b.getValues())); - } - - public WireArray getA() - { - return a; - } - - public WireArray getB() - { - return b; - } - - public WireArray getOut() - { - return out; - } - - @Override - public List getAllInputs() - { - return Collections.unmodifiableList(Arrays.asList(a, b)); - } - - @Override - public List getAllOutputs() - { - return Collections.unmodifiableList(Arrays.asList(out)); - } } diff --git a/era.mi/src/era/mi/logic/tests/ComponentTest.java b/era.mi/src/era/mi/logic/tests/ComponentTest.java index 3ee55760..d48c5c63 100644 --- a/era.mi/src/era/mi/logic/tests/ComponentTest.java +++ b/era.mi/src/era/mi/logic/tests/ComponentTest.java @@ -17,6 +17,7 @@ import era.mi.logic.components.TriStateBuffer; import era.mi.logic.components.gates.AndGate; import era.mi.logic.components.gates.NotGate; import era.mi.logic.components.gates.OrGate; +import era.mi.logic.components.gates.XorGate; import era.mi.logic.wires.WireArray; import era.mi.logic.wires.WireArray.WireArrayInput; @@ -29,7 +30,7 @@ class ComponentTest Simulation.TIMELINE.reset(); WireArray a = new WireArray(1, 1), b = new WireArray(1, 1), c = new WireArray(1, 10), d = new WireArray(2, 1), e = new WireArray(1, 1), f = new WireArray(1, 1), g = new WireArray(1, 1), h = new WireArray(2, 1), i = new WireArray(2, 1), j = new WireArray(1, 1), k = new WireArray(1, 1); - new AndGate(1, a, b, f); + new AndGate(1, f, a, b); new NotGate(1, f, g); new Merger(h, c, g); new Mux(1, i, e, h, d); @@ -177,25 +178,43 @@ class ComponentTest void andTest() { Simulation.TIMELINE.reset(); - AndGate gate = new AndGate(1, new WireArray(4, 1), new WireArray(4, 1), new WireArray(4, 1)); - gate.getA().createInput().feedSignals(Bit.ONE, Bit.ONE, Bit.ZERO, Bit.ZERO); - gate.getB().createInput().feedSignals(Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE); + WireArray a = new WireArray(4, 1), b = new WireArray(4, 3), c = new WireArray(4, 1); + new AndGate(1, c, a, b); + a.createInput().feedSignals(Bit.ONE, Bit.ONE, Bit.ZERO, Bit.ZERO); + b.createInput().feedSignals(Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE); Simulation.TIMELINE.executeAll(); - assertBitArrayEquals(gate.getOut().getValues(), Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ZERO); + + assertBitArrayEquals(c.getValues(), Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ZERO); } @Test void orTest() { Simulation.TIMELINE.reset(); - OrGate gate = new OrGate(1, new WireArray(4, 1), new WireArray(4, 1), new WireArray(4, 1)); - gate.getA().createInput().feedSignals(Bit.ONE, Bit.ONE, Bit.ZERO, Bit.ZERO); - gate.getB().createInput().feedSignals(Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE); + WireArray a = new WireArray(4, 1), b = new WireArray(4, 3), c = new WireArray(4, 1); + new OrGate(1, c, a, b); + a.createInput().feedSignals(Bit.ONE, Bit.ONE, Bit.ZERO, Bit.ZERO); + b.createInput().feedSignals(Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE); Simulation.TIMELINE.executeAll(); - assertBitArrayEquals(gate.getOut().getValues(), Bit.ONE, Bit.ONE, Bit.ZERO, Bit.ONE); + assertBitArrayEquals(c.getValues(), Bit.ONE, Bit.ONE, Bit.ZERO, Bit.ONE); + } + + @Test + void xorTest() + { + Simulation.TIMELINE.reset(); + WireArray a = new WireArray(3, 1), b = new WireArray(3, 2), c = new WireArray(3, 1), d = new WireArray(3, 1); + new XorGate(1, d, a, b, c); + a.createInput().feedSignals(Bit.ZERO, Bit.ONE, Bit.ONE); + b.createInput().feedSignals(Bit.ONE, Bit.ZERO, Bit.ONE); + c.createInput().feedSignals(Bit.ONE, Bit.ZERO, Bit.ONE); + + Simulation.TIMELINE.executeAll(); + + assertBitArrayEquals(d.getValues(), Bit.ZERO, Bit.ONE, Bit.ONE); } @Test @@ -205,8 +224,8 @@ class ComponentTest WireArray r = new WireArray(1, 1), s = new WireArray(1, 1), t1 = new WireArray(1, 15), t2 = new WireArray(1, 1), q = new WireArray(1, 1), nq = new WireArray(1, 1); - new OrGate(1, r, nq, t2); - new OrGate(1, s, q, t1); + new OrGate(1, t2, r, nq); + new OrGate(1, t1, s, q); new NotGate(1, t2, q); new NotGate(1, t1, nq); @@ -301,7 +320,7 @@ class ComponentTest cI.feedSignals(Bit.Z); test.assertAfterSimulationIs(print, Bit.Z); - Connector c1 = new Connector(b, c); + new Connector(b, c); test.assertAfterSimulationIs(print, Bit.Z); System.err.println("ONE"); bI.feedSignals(Bit.ONE); @@ -313,7 +332,7 @@ class ComponentTest bI.feedSignals(Bit.Z); test.assertAfterSimulationIs(print, Bit.Z); - Connector c2 = new Connector(a, b); + new Connector(a, b); System.err.println("Z 2"); aI.feedSignals(Bit.Z); test.assertAfterSimulationIs(print, Bit.Z); diff --git a/era.mi/src/era/mi/logic/tests/Connector.java b/era.mi/src/era/mi/logic/tests/Connector.java index 7887ff25..11d74365 100644 --- a/era.mi/src/era/mi/logic/tests/Connector.java +++ b/era.mi/src/era/mi/logic/tests/Connector.java @@ -9,16 +9,16 @@ import era.mi.logic.wires.WireArrayObserver; public class Connector implements WireArrayObserver { private final WireArray a; - private final WireArray b; +// private final WireArray b; private final WireArrayInput aI; private final WireArrayInput bI; public Connector(WireArray a, WireArray b) { if (a.length != b.length) - throw new IllegalArgumentException(String.format("WireArray width does not match: %o, %o", a.length, b.length)); + throw new IllegalArgumentException(String.format("WireArray width does not match: %d, %d", a.length, b.length)); this.a = a; - this.b = b; +// this.b = b; a.addObserver(this); b.addObserver(this); aI = a.createInput(); diff --git a/era.mi/src/era/mi/logic/timeline/Timeline.java b/era.mi/src/era/mi/logic/timeline/Timeline.java index 5c88deae..20bb4009 100644 --- a/era.mi/src/era/mi/logic/timeline/Timeline.java +++ b/era.mi/src/era/mi/logic/timeline/Timeline.java @@ -103,4 +103,9 @@ public class Timeline { return "simulation time: " + currentTime + ", " + events.toString(); } + + public static long toNanoseconds(long ticks) + { + return ticks; //TODO: Alter this when it has been determined how ticks should relate to real time. + } } \ No newline at end of file diff --git a/era.mi/src/era/mi/logic/wires/WireArray.java b/era.mi/src/era/mi/logic/wires/WireArray.java index c2e974ae..153277af 100644 --- a/era.mi/src/era/mi/logic/wires/WireArray.java +++ b/era.mi/src/era/mi/logic/wires/WireArray.java @@ -26,7 +26,7 @@ public class WireArray public WireArray(int length, int travelTime) { if (length < 1) - throw new IllegalArgumentException(String.format("Tried to create an array of wires with length %o, but a length of less than 1 makes no sense.", length)); + throw new IllegalArgumentException(String.format("Tried to create an array of wires with length %d, but a length of less than 1 makes no sense.", length)); this.length = length; this.travelTime = travelTime; initValues(); -- 2.17.1