logic gates and, or and xor now take an arbitrary amount of inputs.
authorFabian Stemmler <stemmler@in.tum.de>
Mon, 13 May 2019 17:18:32 +0000 (19:18 +0200)
committerFabian Stemmler <stemmler@in.tum.de>
Mon, 13 May 2019 17:18:32 +0000 (19:18 +0200)
era.mi/src/era/mi/logic/Util.java
era.mi/src/era/mi/logic/components/BasicComponent.java
era.mi/src/era/mi/logic/components/gates/AndGate.java
era.mi/src/era/mi/logic/components/gates/MultiInputGate.java [new file with mode: 0644]
era.mi/src/era/mi/logic/components/gates/OrGate.java
era.mi/src/era/mi/logic/components/gates/XorGate.java
era.mi/src/era/mi/logic/tests/ComponentTest.java
era.mi/src/era/mi/logic/tests/Connector.java
era.mi/src/era/mi/logic/timeline/Timeline.java
era.mi/src/era/mi/logic/wires/WireArray.java

index 3ca16b7..0cd4b82 100644 (file)
@@ -103,6 +103,6 @@ public final class Util
 
     interface BitOp
     {
-       Bit execute(Bit a, Bit b);
+       Bit execute(Bit a, Bit b);
     }
 }
index 930e3a5..4e56c34 100644 (file)
@@ -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;
index 5c81406..853fecc 100644 (file)
@@ -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<WireArray> getAllInputs()
-       {
-               return Collections.unmodifiableList(Arrays.asList(a, b));
-       }
-
-       @Override
-       public List<WireArray> 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 (file)
index 0000000..bfa33ed
--- /dev/null
@@ -0,0 +1,63 @@
+package era.mi.logic.components.gates;\r
+\r
+import java.util.Arrays;\r
+import java.util.Collections;\r
+import java.util.List;\r
+\r
+import era.mi.logic.Bit;\r
+import era.mi.logic.components.BasicComponent;\r
+import era.mi.logic.wires.WireArray;\r
+import era.mi.logic.wires.WireArray.WireArrayInput;\r
+\r
+public abstract class MultiInputGate extends BasicComponent\r
+{\r
+       protected WireArray[] in;\r
+       protected WireArray out;\r
+       protected WireArrayInput outI;\r
+       protected final int length;\r
+       protected Operation op;\r
+       \r
+       protected MultiInputGate(int processTime, Operation op, WireArray out, WireArray... in)\r
+       {\r
+               super(processTime);\r
+               this.op = op;\r
+               length = out.length;\r
+               this.in = in.clone();\r
+               if(in.length < 1)\r
+                       throw new IllegalArgumentException(String.format("Cannot create gate with %d wires.", in.length));\r
+               for(WireArray w : in)\r
+               {\r
+                       if(w.length != length)\r
+                               throw new IllegalArgumentException("All wires connected to the gate must be of uniform length.");\r
+                       w.addObserver(this);\r
+               }\r
+               this.out = out;\r
+               outI = out.createInput();\r
+       }\r
+\r
+\r
+       @Override\r
+       public List<WireArray> getAllInputs()\r
+       {\r
+               return Collections.unmodifiableList(Arrays.asList(in));\r
+       }\r
+\r
+       @Override\r
+       public List<WireArray> getAllOutputs()\r
+       {\r
+               return Collections.unmodifiableList(Arrays.asList(out));\r
+       }\r
+       \r
+       protected void compute()\r
+       {\r
+               Bit[] result = in[0].getValues();\r
+               for(int i = 1; i < in.length; i++)\r
+                       result = op.execute(result, in[i].getValues());\r
+               outI.feedSignals(result);\r
+       }\r
+       \r
+       protected interface Operation\r
+       {\r
+               public Bit[] execute(Bit[] a, Bit[] b);\r
+       }\r
+}\r
index 8e145d1..b538eb4 100644 (file)
@@ -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<WireArray> getAllInputs()
-       {
-               return Collections.unmodifiableList(Arrays.asList(a, b));
-       }
 
-       @Override
-       public List<WireArray> 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);
        }
 }
index b13dd2b..c20af6f 100644 (file)
@@ -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<WireArray> getAllInputs()
-       {
-               return Collections.unmodifiableList(Arrays.asList(a, b));
-       }
-
-       @Override
-       public List<WireArray> getAllOutputs()
-       {
-               return Collections.unmodifiableList(Arrays.asList(out));
-       }
 }
index c233552..4f6826b 100644 (file)
@@ -17,6 +17,7 @@ import era.mi.logic.components.TriStateBuffer;
 import era.mi.logic.components.gates.AndGate;\r
 import era.mi.logic.components.gates.NotGate;\r
 import era.mi.logic.components.gates.OrGate;\r
+import era.mi.logic.components.gates.XorGate;\r
 import era.mi.logic.wires.WireArray;\r
 import era.mi.logic.wires.WireArray.WireArrayInput;\r
 \r
@@ -29,7 +30,7 @@ class ComponentTest
                Simulation.TIMELINE.reset();\r
                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),\r
                                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);\r
-               new AndGate(1, a, b, f);\r
+               new AndGate(1, f, a, b);\r
                new NotGate(1, f, g);\r
                new Merger(h, c, g);\r
                new Mux(1, i, e, h, d);\r
@@ -177,25 +178,43 @@ class ComponentTest
     void andTest()\r
     {\r
        Simulation.TIMELINE.reset();\r
-       AndGate gate = new AndGate(1, new WireArray(4, 1), new WireArray(4, 1), new WireArray(4, 1));\r
-       gate.getA().createInput().feedSignals(Bit.ONE, Bit.ONE, Bit.ZERO, Bit.ZERO);\r
-       gate.getB().createInput().feedSignals(Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE);\r
+       WireArray a = new WireArray(4, 1), b = new WireArray(4, 3), c = new WireArray(4, 1);\r
+       new AndGate(1, c, a, b);\r
+       a.createInput().feedSignals(Bit.ONE, Bit.ONE, Bit.ZERO, Bit.ZERO);\r
+       b.createInput().feedSignals(Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE);\r
 \r
        Simulation.TIMELINE.executeAll();\r
-       assertBitArrayEquals(gate.getOut().getValues(), Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ZERO);\r
+       \r
+       assertBitArrayEquals(c.getValues(), Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ZERO);\r
     }\r
 \r
     @Test\r
     void orTest()\r
     {\r
        Simulation.TIMELINE.reset();\r
-       OrGate gate = new OrGate(1, new WireArray(4, 1), new WireArray(4, 1), new WireArray(4, 1));\r
-       gate.getA().createInput().feedSignals(Bit.ONE, Bit.ONE, Bit.ZERO, Bit.ZERO);\r
-       gate.getB().createInput().feedSignals(Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE);\r
+       WireArray a = new WireArray(4, 1), b = new WireArray(4, 3), c = new WireArray(4, 1);\r
+       new OrGate(1, c, a, b);\r
+       a.createInput().feedSignals(Bit.ONE, Bit.ONE, Bit.ZERO, Bit.ZERO);\r
+       b.createInput().feedSignals(Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE);\r
 \r
        Simulation.TIMELINE.executeAll();\r
 \r
-       assertBitArrayEquals(gate.getOut().getValues(), Bit.ONE, Bit.ONE, Bit.ZERO, Bit.ONE);\r
+       assertBitArrayEquals(c.getValues(), Bit.ONE, Bit.ONE, Bit.ZERO, Bit.ONE);\r
+    }\r
+    \r
+    @Test\r
+    void xorTest()\r
+    {\r
+       Simulation.TIMELINE.reset();\r
+       WireArray a = new WireArray(3, 1), b = new WireArray(3, 2), c = new WireArray(3, 1), d = new WireArray(3, 1);\r
+       new XorGate(1, d, a, b, c);\r
+       a.createInput().feedSignals(Bit.ZERO, Bit.ONE, Bit.ONE);\r
+       b.createInput().feedSignals(Bit.ONE, Bit.ZERO, Bit.ONE);\r
+       c.createInput().feedSignals(Bit.ONE, Bit.ZERO, Bit.ONE);\r
+\r
+       Simulation.TIMELINE.executeAll();\r
+\r
+       assertBitArrayEquals(d.getValues(), Bit.ZERO, Bit.ONE, Bit.ONE);\r
     }\r
 \r
     @Test\r
@@ -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),\r
                q = new WireArray(1, 1), nq = new WireArray(1, 1);\r
 \r
-       new OrGate(1, r, nq, t2);\r
-       new OrGate(1, s, q, t1);\r
+       new OrGate(1, t2, r, nq);\r
+       new OrGate(1, t1, s, q);\r
        new NotGate(1, t2, q);\r
        new NotGate(1, t1, nq);\r
 \r
@@ -301,7 +320,7 @@ class ComponentTest
                cI.feedSignals(Bit.Z);\r
                test.assertAfterSimulationIs(print, Bit.Z);\r
 \r
-               Connector c1 = new Connector(b, c);\r
+               new Connector(b, c);\r
                test.assertAfterSimulationIs(print, Bit.Z);\r
                System.err.println("ONE");\r
                bI.feedSignals(Bit.ONE);\r
@@ -313,7 +332,7 @@ class ComponentTest
                bI.feedSignals(Bit.Z);\r
                test.assertAfterSimulationIs(print, Bit.Z);\r
                \r
-               Connector c2 = new Connector(a, b);\r
+               new Connector(a, b);\r
                System.err.println("Z 2");\r
                aI.feedSignals(Bit.Z);\r
                test.assertAfterSimulationIs(print, Bit.Z);\r
index fe6d40d..99b0068 100644 (file)
@@ -9,16 +9,16 @@ import era.mi.logic.wires.WireArrayObserver;
 public class Connector implements WireArrayObserver\r
 {\r
        private final WireArray a;\r
-       private final WireArray b;\r
+//     private final WireArray b;\r
        private final WireArrayInput aI;\r
        private final WireArrayInput bI;\r
 \r
        public Connector(WireArray a, WireArray b)\r
        {\r
                if (a.length != b.length)\r
-                       throw new IllegalArgumentException(String.format("WireArray width does not match: %o, %o", a.length, b.length));\r
+                       throw new IllegalArgumentException(String.format("WireArray width does not match: %d, %d", a.length, b.length));\r
                this.a = a;\r
-               this.b = b;\r
+//             this.b = b;\r
                a.addObserver(this);\r
                b.addObserver(this);\r
                aI = a.createInput();\r
index 2578a9b..186e946 100644 (file)
@@ -103,4 +103,9 @@ public class Timeline
        {\r
                return "simulation time: " + currentTime + ", " + events.toString();\r
        }\r
+       \r
+       public static long toNanoseconds(long ticks)\r
+       {\r
+               return ticks; //TODO: Alter this when it has been determined how ticks should relate to real time.\r
+       }\r
 }
\ No newline at end of file
index 5e09c91..b7a83fa 100644 (file)
@@ -26,7 +26,7 @@ public class WireArray
        public WireArray(int length, int travelTime)\r
        {\r
                if (length < 1)\r
-                       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));\r
+                       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));\r
                this.length = length;\r
                this.travelTime = travelTime;\r
                initValues();\r