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..b85939e
--- /dev/null
@@ -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<WireArray> getAllInputs()
+       {
+               return Collections.unmodifiableList(Arrays.asList(in));
+       }
+
+       @Override
+       public List<WireArray> 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);
+       }
+}
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 3ee5576..d48c5c6 100644 (file)
@@ -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);
index 7887ff2..11d7436 100644 (file)
@@ -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();
index 5c88dea..20bb400 100644 (file)
@@ -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
index c2e974a..153277a 100644 (file)
@@ -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();