-package era.mi.logic.tests;
-
-import static org.junit.jupiter.api.Assertions.*;
-
-import java.util.Arrays;
-import java.util.function.LongConsumer;
-
-import org.junit.jupiter.api.Test;
-
-import era.mi.logic.Bit;
-import era.mi.logic.Simulation;
-import era.mi.logic.components.Merger;
-import era.mi.logic.components.Mux;
-import era.mi.logic.components.Splitter;
-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.wires.WireArray;
-import era.mi.logic.wires.WireArray.WireArrayInput;
-
-class ComponentTest
-{
-
- @Test
- void circuitExampleTest()
- {
- 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 NotGate(1, f, g);
- new Merger(h, c, g);
- new Mux(1, i, e, h, d);
- new Splitter(i, k, j);
-
- a.createInput().feedSignals(Bit.ZERO);
- b.createInput().feedSignals(Bit.ONE);
- c.createInput().feedSignals(Bit.ZERO);
- d.createInput().feedSignals(Bit.ONE, Bit.ONE);
- e.createInput().feedSignals(Bit.ZERO);
-
- Simulation.TIMELINE.executeAll();
-
- assertEquals(Bit.ONE, j.getValue());
- assertEquals(Bit.ZERO, k.getValue());
- }
-
- @Test
- void splitterTest()
- {
- Simulation.TIMELINE.reset();
- WireArray a = new WireArray(3, 1), b = new WireArray(2, 1), c = new WireArray(3, 1), in = new WireArray(8, 1);
- in.createInput().feedSignals(Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE);
- new Splitter(in, a, b, c);
-
- Simulation.TIMELINE.executeAll();
-
- assertArrayEquals(new Bit[] { Bit.ZERO, Bit.ONE, Bit.ZERO }, a.getValues());
- assertArrayEquals(new Bit[] { Bit.ONE, Bit.ZERO }, b.getValues());
- assertArrayEquals(new Bit[] { Bit.ONE, Bit.ZERO, Bit.ONE }, c.getValues());
- }
-
- @Test
- void mergerTest()
- {
- Simulation.TIMELINE.reset();
- WireArray a = new WireArray(3, 1), b = new WireArray(2, 1), c = new WireArray(3, 1), out = new WireArray(8, 1);
- a.createInput().feedSignals(Bit.ZERO, Bit.ONE, Bit.ZERO);
- b.createInput().feedSignals(Bit.ONE, Bit.ZERO);
- c.createInput().feedSignals(Bit.ONE, Bit.ZERO, Bit.ONE);
-
- new Merger(out, a, b, c);
-
- Simulation.TIMELINE.executeAll();
-
- assertTrue(Arrays.equals(out.getValues(),
- new Bit[] { Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE }));
- }
-
- @Test
- void triStateBufferTest()
- {
- WireArray a = new WireArray(1, 1), b = new WireArray(1, 1), en = new WireArray(1, 1),
- notEn = new WireArray(1, 1);
- new NotGate(1, en, notEn);
- new TriStateBuffer(1, a, b, en);
- new TriStateBuffer(1, b, a, notEn);
-
- WireArrayInput enI = en.createInput(), aI = a.createInput(), bI = b.createInput();
- enI.feedSignals(Bit.ONE);
- aI.feedSignals(Bit.ONE);
-
- Simulation.TIMELINE.executeAll();
-
- assertEquals(Bit.ONE, b.getValue());
-
- bI.feedSignals(Bit.ZERO);
-
- Simulation.TIMELINE.executeAll();
-
- assertEquals(Bit.X, b.getValue());
- assertEquals(Bit.ONE, a.getValue());
-
- aI.clearSignals();
- enI.feedSignals(Bit.ZERO);
-
- Simulation.TIMELINE.executeAll();
-
- assertEquals(Bit.ZERO, a.getValue());
-
- }
-
- @Test
- void muxTest()
- {
- Simulation.TIMELINE.reset();
- WireArray a = new WireArray(4, 3), b = new WireArray(4, 6), c = new WireArray(4, 4),
- select = new WireArray(2, 5), out = new WireArray(4, 1);
- WireArrayInput selectIn = select.createInput();
-
- selectIn.feedSignals(Bit.ZERO, Bit.ZERO);
- a.createInput().feedSignals(Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO);
- c.createInput().feedSignals(Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE);
-
- new Mux(1, out, select, a, b, c);
- Simulation.TIMELINE.executeAll();
-
- assertArrayEquals(new Bit[] { Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO }, out.getValues());
- selectIn.feedSignals(Bit.ZERO, Bit.ONE);
- Simulation.TIMELINE.executeAll();
-
- assertArrayEquals(new Bit[] { Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE }, out.getValues());
-
- selectIn.feedSignals(Bit.ONE, Bit.ONE);
- Simulation.TIMELINE.executeAll();
-
- assertArrayEquals(new Bit[] { Bit.Z, Bit.Z, Bit.Z, Bit.Z }, out.getValues());
-
- }
-
- @Test
- 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);
-
- Simulation.TIMELINE.executeAll();
- assertArrayEquals(new Bit[] { Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ZERO }, gate.getOut().getValues());
- }
-
- @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);
-
- Simulation.TIMELINE.executeAll();
-
- assertArrayEquals(new Bit[] { Bit.ONE, Bit.ONE, Bit.ZERO, Bit.ONE }, gate.getOut().getValues());
- }
-
- @Test
- void rsLatchCircuitTest()
- {
- Simulation.TIMELINE.reset();
- 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 NotGate(1, t2, q);
- new NotGate(1, t1, nq);
-
- WireArrayInput sIn = s.createInput(), rIn = r.createInput();
-
- sIn.feedSignals(Bit.ONE);
- rIn.feedSignals(Bit.ZERO);
-
- Simulation.TIMELINE.executeAll();
-
- assertEquals(Bit.ONE, q.getValue());
- assertEquals(Bit.ZERO, nq.getValue());
-
- sIn.feedSignals(Bit.ZERO);
-
- Simulation.TIMELINE.executeAll();
- assertEquals(Bit.ONE, q.getValue());
- assertEquals(Bit.ZERO, nq.getValue());
-
- rIn.feedSignals(Bit.ONE);
-
- Simulation.TIMELINE.executeAll();
-
- assertEquals(Bit.ZERO, q.getValue());
- assertEquals(Bit.ONE, nq.getValue());
- }
-
- @Test
- void numericValueTest()
- {
- Simulation.TIMELINE.reset();
-
- WireArray a = new WireArray(4, 1);
- a.createInput().feedSignals(Bit.ONE, Bit.ONE, Bit.ONE, Bit.ONE);
-
- Simulation.TIMELINE.executeAll();
-
- assertEquals(15, a.getUnsignedValue());
- assertEquals(-1, a.getSignedValue());
- }
-
- @Test
- void multipleInputs()
- {
- Simulation.TIMELINE.reset();
- WireArray w = new WireArray(2, 1);
- WireArrayInput wI1 = w.createInput(), wI2 = w.createInput();
- wI1.feedSignals(Bit.ONE, Bit.Z);
- wI2.feedSignals(Bit.Z, Bit.X);
- Simulation.TIMELINE.executeAll();
- assertArrayEquals(new Bit[] { Bit.ONE, Bit.X }, w.getValues());
-
- wI2.feedSignals(Bit.ZERO, Bit.Z);
- Simulation.TIMELINE.executeAll();
- assertArrayEquals(new Bit[] { Bit.X, Bit.Z }, w.getValues());
-
- wI2.feedSignals(Bit.Z, Bit.Z);
- Simulation.TIMELINE.executeAll();
- assertArrayEquals(new Bit[] { Bit.ONE, Bit.Z }, w.getValues());
-
- wI2.feedSignals(Bit.ONE, Bit.Z);
- w.addObserver((i) -> fail("WireArray notified observer, although value did not change."));
- Simulation.TIMELINE.executeAll();
- assertArrayEquals(new Bit[] { Bit.ONE, Bit.Z }, w.getValues());
- }
-
- @Test
- void wireConnections()
- {
- // Nur ein Experiment, was über mehrere 'passive' Bausteine hinweg passieren würde
-
- Simulation.TIMELINE.reset();
-
- WireArray a = new WireArray(1, 2);
- WireArray b = new WireArray(1, 2);
- WireArray c = new WireArray(1, 2);
- WireArrayInput aI = a.createInput();
- WireArrayInput bI = b.createInput();
- WireArrayInput cI = c.createInput();
-
- TestBitDisplay test = new TestBitDisplay(c);
- TestBitDisplay test2 = new TestBitDisplay(a);
- LongConsumer print = time -> System.out.format("Time %2d\n a: %s\n b: %s\n c: %s\n", time, a, b, c);
-
- cI.feedSignals(Bit.ONE);
- test.assertAfterSimulationIs(print, Bit.ONE);
-
- cI.feedSignals(Bit.X);
- test.assertAfterSimulationIs(print, Bit.X);
-
- cI.feedSignals(Bit.X);
- cI.feedSignals(Bit.Z);
- test.assertAfterSimulationIs(print, Bit.Z);
-
- Connector c1 = new Connector(b, c);
- test.assertAfterSimulationIs(print, Bit.Z);
- System.err.println("ONE");
- bI.feedSignals(Bit.ONE);
- test.assertAfterSimulationIs(print, Bit.ONE);
- System.err.println("ZERO");
- bI.feedSignals(Bit.ZERO);
- test.assertAfterSimulationIs(print, Bit.ZERO);
- System.err.println("Z");
- bI.feedSignals(Bit.Z);
- test.assertAfterSimulationIs(print, Bit.Z);
-
- Connector c2 = new Connector(a, b);
- System.err.println("Z 2");
- aI.feedSignals(Bit.Z);
- test.assertAfterSimulationIs(print, Bit.Z);
- test2.assertAfterSimulationIs(Bit.Z);
- System.err.println("ONE 2");
- aI.feedSignals(Bit.ONE);
- test.assertAfterSimulationIs(print, Bit.ONE);
- test2.assertAfterSimulationIs(Bit.ONE);
- System.err.println("ZERO 2");
- aI.feedSignals(Bit.ZERO);
- test.assertAfterSimulationIs(print, Bit.ZERO);
- test2.assertAfterSimulationIs(Bit.ZERO);
- System.err.println("Z 2 II");
- aI.feedSignals(Bit.Z);
- test.assertAfterSimulationIs(print, Bit.Z);
- test2.assertAfterSimulationIs(Bit.Z);
-
- System.err.println("No Conflict yet");
- bI.feedSignals(Bit.ONE);
- test.assertAfterSimulationIs(print, Bit.ONE);
- test2.assertAfterSimulationIs(Bit.ONE);
- aI.feedSignals(Bit.ONE);
- test.assertAfterSimulationIs(print, Bit.ONE);
- test2.assertAfterSimulationIs(Bit.ONE);
- System.err.println("Conflict");
- aI.feedSignals(Bit.ZERO);
- test.assertAfterSimulationIs(print, Bit.X);
- test2.assertAfterSimulationIs(Bit.X);
- aI.feedSignals(Bit.ONE);
- test.assertAfterSimulationIs(print, Bit.ONE);
- test2.assertAfterSimulationIs(Bit.ONE);
- }
-
- private static void assertBitArrayEquals(Bit[] actual, Bit... expected)
- {
- assertArrayEquals(expected, actual);
- }
-}
+package era.mi.logic.tests;\r
+\r
+import static org.junit.jupiter.api.Assertions.*;\r
+\r
+import java.util.Arrays;\r
+import java.util.function.LongConsumer;\r
+\r
+import org.junit.jupiter.api.Test;\r
+\r
+import era.mi.logic.Bit;\r
+import era.mi.logic.Simulation;\r
+import era.mi.logic.components.Merger;\r
+import era.mi.logic.components.Mux;\r
+import era.mi.logic.components.Splitter;\r
+import era.mi.logic.components.TriStateBuffer;\r
+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.wires.WireArray;\r
+import era.mi.logic.wires.WireArray.WireArrayInput;\r
+\r
+class ComponentTest\r
+{\r
+ \r
+ @Test\r
+ void circuitExampleTest()\r
+ {\r
+ 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 NotGate(1, f, g);\r
+ new Merger(h, c, g);\r
+ new Mux(1, i, e, h, d);\r
+ new Splitter(i, k, j);\r
+ \r
+ a.createInput().feedSignals(Bit.ZERO);\r
+ b.createInput().feedSignals(Bit.ONE);\r
+ c.createInput().feedSignals(Bit.ZERO);\r
+ d.createInput().feedSignals(Bit.ONE, Bit.ONE);\r
+ e.createInput().feedSignals(Bit.ZERO);\r
+ \r
+ Simulation.TIMELINE.executeAll();\r
+ \r
+ assertEquals(Bit.ONE, j.getValue());\r
+ assertEquals(Bit.ZERO, k.getValue());\r
+ }\r
+\r
+ @Test\r
+ void splitterTest()\r
+ {\r
+ Simulation.TIMELINE.reset();\r
+ WireArray a = new WireArray(3, 1), b = new WireArray(2, 1), c = new WireArray(3, 1), in = new WireArray(8, 1);\r
+ in.createInput().feedSignals(Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE);\r
+ new Splitter(in, a, b, c);\r
+\r
+ Simulation.TIMELINE.executeAll();\r
+\r
+ assertBitArrayEquals(a.getValues(), Bit.ZERO, Bit.ONE, Bit.ZERO);\r
+ assertBitArrayEquals(b.getValues(), Bit.ONE, Bit.ZERO);\r
+ assertBitArrayEquals(c.getValues(), Bit.ONE, Bit.ZERO, Bit.ONE);\r
+ }\r
+\r
+ @Test\r
+ void mergerTest()\r
+ {\r
+ Simulation.TIMELINE.reset();\r
+ WireArray a = new WireArray(3, 1), b = new WireArray(2, 1), c = new WireArray(3, 1), out = new WireArray(8, 1);\r
+ a.createInput().feedSignals(Bit.ZERO, Bit.ONE, Bit.ZERO);\r
+ b.createInput().feedSignals(Bit.ONE, Bit.ZERO);\r
+ c.createInput().feedSignals(Bit.ONE, Bit.ZERO, Bit.ONE);\r
+\r
+ new Merger(out, a, b, c);\r
+\r
+ Simulation.TIMELINE.executeAll();\r
+\r
+ assertTrue(Arrays.equals(out.getValues(),\r
+ new Bit[] { Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE }));\r
+ }\r
+\r
+ @Test\r
+ void triStateBufferTest()\r
+ {\r
+ WireArray a = new WireArray(1, 1), b = new WireArray(1, 1), en = new WireArray(1, 1),\r
+ notEn = new WireArray(1, 1);\r
+ new NotGate(1, en, notEn);\r
+ new TriStateBuffer(1, a, b, en);\r
+ new TriStateBuffer(1, b, a, notEn);\r
+\r
+ WireArrayInput enI = en.createInput(), aI = a.createInput(), bI = b.createInput();\r
+ enI.feedSignals(Bit.ONE);\r
+ aI.feedSignals(Bit.ONE);\r
+\r
+ Simulation.TIMELINE.executeAll();\r
+\r
+ assertEquals(Bit.ONE, b.getValue());\r
+\r
+ bI.feedSignals(Bit.ZERO);\r
+\r
+ Simulation.TIMELINE.executeAll();\r
+\r
+ assertEquals(Bit.X, b.getValue());\r
+ assertEquals(Bit.ONE, a.getValue());\r
+\r
+ aI.clearSignals();\r
+ enI.feedSignals(Bit.ZERO);\r
+\r
+ Simulation.TIMELINE.executeAll();\r
+\r
+ assertEquals(Bit.ZERO, a.getValue());\r
+\r
+ }\r
+\r
+ @Test\r
+ void muxTest()\r
+ {\r
+ Simulation.TIMELINE.reset();\r
+ WireArray a = new WireArray(4, 3), b = new WireArray(4, 6), c = new WireArray(4, 4),\r
+ select = new WireArray(2, 5), out = new WireArray(4, 1);\r
+ WireArrayInput selectIn = select.createInput();\r
+\r
+ selectIn.feedSignals(Bit.ZERO, Bit.ZERO);\r
+ a.createInput().feedSignals(Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO);\r
+ c.createInput().feedSignals(Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE);\r
+\r
+ new Mux(1, out, select, a, b, c);\r
+ Simulation.TIMELINE.executeAll();\r
+\r
+ assertBitArrayEquals(out.getValues(), Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO);\r
+ selectIn.feedSignals(Bit.ZERO, Bit.ONE);\r
+ Simulation.TIMELINE.executeAll();\r
+\r
+ assertBitArrayEquals(out.getValues(), Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE);\r
+\r
+ selectIn.feedSignals(Bit.ONE, Bit.ONE);\r
+ Simulation.TIMELINE.executeAll();\r
+\r
+ assertBitArrayEquals(out.getValues(), Bit.Z, Bit.Z, Bit.Z, Bit.Z);\r
+\r
+ }\r
+\r
+ @Test\r
+ 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
+\r
+ Simulation.TIMELINE.executeAll();\r
+ assertBitArrayEquals(gate.getOut().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
+\r
+ Simulation.TIMELINE.executeAll();\r
+\r
+ assertBitArrayEquals(gate.getOut().getValues(), Bit.ONE, Bit.ONE, Bit.ZERO, Bit.ONE);\r
+ }\r
+\r
+ @Test\r
+ void rsLatchCircuitTest()\r
+ {\r
+ Simulation.TIMELINE.reset();\r
+ 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 NotGate(1, t2, q);\r
+ new NotGate(1, t1, nq);\r
+\r
+ WireArrayInput sIn = s.createInput(), rIn = r.createInput();\r
+\r
+ sIn.feedSignals(Bit.ONE);\r
+ rIn.feedSignals(Bit.ZERO);\r
+\r
+ Simulation.TIMELINE.executeAll();\r
+\r
+ assertEquals(Bit.ONE, q.getValue());\r
+ assertEquals(Bit.ZERO, nq.getValue());\r
+\r
+ sIn.feedSignals(Bit.ZERO);\r
+\r
+ Simulation.TIMELINE.executeAll();\r
+ assertEquals(Bit.ONE, q.getValue());\r
+ assertEquals(Bit.ZERO, nq.getValue());\r
+\r
+ rIn.feedSignals(Bit.ONE);\r
+\r
+ Simulation.TIMELINE.executeAll();\r
+\r
+ assertEquals(Bit.ZERO, q.getValue());\r
+ assertEquals(Bit.ONE, nq.getValue());\r
+ }\r
+\r
+ @Test\r
+ void numericValueTest()\r
+ {\r
+ Simulation.TIMELINE.reset();\r
+\r
+ WireArray a = new WireArray(4, 1);\r
+ a.createInput().feedSignals(Bit.ONE, Bit.ONE, Bit.ONE, Bit.ONE);\r
+\r
+ Simulation.TIMELINE.executeAll();\r
+\r
+ assertEquals(15, a.getUnsignedValue());\r
+ assertEquals(-1, a.getSignedValue());\r
+ }\r
+\r
+ @Test\r
+ void multipleInputs()\r
+ {\r
+ Simulation.TIMELINE.reset();\r
+ WireArray w = new WireArray(2, 1);\r
+ WireArrayInput wI1 = w.createInput(), wI2 = w.createInput();\r
+ wI1.feedSignals(Bit.ONE, Bit.Z);\r
+ wI2.feedSignals(Bit.Z, Bit.X);\r
+ Simulation.TIMELINE.executeAll();\r
+ assertBitArrayEquals(w.getValues(), Bit.ONE, Bit.X);\r
+\r
+ wI2.feedSignals(Bit.ZERO, Bit.Z);\r
+ Simulation.TIMELINE.executeAll();\r
+ assertBitArrayEquals(w.getValues(), Bit.X, Bit.Z);\r
+\r
+ wI2.feedSignals(Bit.Z, Bit.Z);\r
+ Simulation.TIMELINE.executeAll();\r
+ assertBitArrayEquals(w.getValues(), Bit.ONE, Bit.Z);\r
+\r
+ wI2.feedSignals(Bit.ONE, Bit.Z);\r
+ w.addObserver((i) -> fail("WireArray notified observer, although value did not change."));\r
+ Simulation.TIMELINE.executeAll();\r
+ assertBitArrayEquals(w.getValues(), Bit.ONE, Bit.Z);\r
+ }\r
+\r
+ @Test\r
+ void wireConnections()\r
+ {\r
+ // Nur ein Experiment, was über mehrere 'passive' Bausteine hinweg passieren würde\r
+ \r
+ Simulation.TIMELINE.reset();\r
+\r
+ WireArray a = new WireArray(1, 2);\r
+ WireArray b = new WireArray(1, 2);\r
+ WireArray c = new WireArray(1, 2);\r
+ WireArrayInput aI = a.createInput();\r
+ WireArrayInput bI = b.createInput();\r
+ WireArrayInput cI = c.createInput();\r
+\r
+ TestBitDisplay test = new TestBitDisplay(c);\r
+ TestBitDisplay test2 = new TestBitDisplay(a);\r
+ LongConsumer print = time -> System.out.format("Time %2d\n a: %s\n b: %s\n c: %s\n", time, a, b, c);\r
+\r
+ cI.feedSignals(Bit.ONE);\r
+ test.assertAfterSimulationIs(print, Bit.ONE);\r
+\r
+ cI.feedSignals(Bit.X);\r
+ test.assertAfterSimulationIs(print, Bit.X);\r
+\r
+ cI.feedSignals(Bit.X);\r
+ cI.feedSignals(Bit.Z);\r
+ test.assertAfterSimulationIs(print, Bit.Z);\r
+\r
+ Connector c1 = new Connector(b, c);\r
+ test.assertAfterSimulationIs(print, Bit.Z);\r
+ System.err.println("ONE");\r
+ bI.feedSignals(Bit.ONE);\r
+ test.assertAfterSimulationIs(print, Bit.ONE);\r
+ System.err.println("ZERO");\r
+ bI.feedSignals(Bit.ZERO);\r
+ test.assertAfterSimulationIs(print, Bit.ZERO);\r
+ System.err.println("Z");\r
+ bI.feedSignals(Bit.Z);\r
+ test.assertAfterSimulationIs(print, Bit.Z);\r
+ \r
+ Connector c2 = new Connector(a, b);\r
+ System.err.println("Z 2");\r
+ aI.feedSignals(Bit.Z);\r
+ test.assertAfterSimulationIs(print, Bit.Z);\r
+ test2.assertAfterSimulationIs(Bit.Z);\r
+ System.err.println("ONE 2");\r
+ aI.feedSignals(Bit.ONE);\r
+ test.assertAfterSimulationIs(print, Bit.ONE);\r
+ test2.assertAfterSimulationIs(Bit.ONE);\r
+ System.err.println("ZERO 2");\r
+ aI.feedSignals(Bit.ZERO);\r
+ test.assertAfterSimulationIs(print, Bit.ZERO);\r
+ test2.assertAfterSimulationIs(Bit.ZERO);\r
+ System.err.println("Z 2 II");\r
+ aI.feedSignals(Bit.Z);\r
+ test.assertAfterSimulationIs(print, Bit.Z);\r
+ test2.assertAfterSimulationIs(Bit.Z);\r
+ \r
+ System.err.println("No Conflict yet");\r
+ bI.feedSignals(Bit.ONE);\r
+ test.assertAfterSimulationIs(print, Bit.ONE);\r
+ test2.assertAfterSimulationIs(Bit.ONE);\r
+ aI.feedSignals(Bit.ONE);\r
+ test.assertAfterSimulationIs(print, Bit.ONE);\r
+ test2.assertAfterSimulationIs(Bit.ONE);\r
+ System.err.println("Conflict");\r
+ aI.feedSignals(Bit.ZERO);\r
+ test.assertAfterSimulationIs(print, Bit.X);\r
+ test2.assertAfterSimulationIs(Bit.X);\r
+ aI.feedSignals(Bit.ONE);\r
+ test.assertAfterSimulationIs(print, Bit.ONE);\r
+ test2.assertAfterSimulationIs(Bit.ONE);\r
+ }\r
+\r
+ private static void assertBitArrayEquals(Bit[] actual, Bit... expected)\r
+ {\r
+ assertArrayEquals(expected, actual);\r
+ }\r
+}\r
-package era.mi.logic.wires;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-
-import era.mi.logic.Bit;
-import era.mi.logic.Simulation;
-import era.mi.logic.Util;
-
-/**
- * Represents an array of wires that can store n bits of information.
- *
- * @author Fabian Stemmler
- *
- */
-public class WireArray
-{
- private Bit[] values;
- public final int travelTime;
- private List<WireArrayObserver> observers = new ArrayList<WireArrayObserver>();
- public final int length;
- private List<WireArrayInput> inputs = new ArrayList<WireArrayInput>();
-
- public WireArray(int length, int travelTime)
- {
- if (length < 1)
- throw new IllegalArgumentException("Tried to create an array of wires with length " + length
- + ", but a length of less than 1 makes no sense.");
- this.length = length;
- this.travelTime = travelTime;
- initValues();
- }
-
- private void initValues()
- {
- values = new Bit[length];
- for (int i = 0; i < length; i++)
- values[i] = Bit.Z;
- }
-
- private void recalculateSingleInput()
- {
- WireArrayInput input = inputs.get(0);
- if (!Arrays.equals(input.getValues(), values))
- {
- System.arraycopy(input.getValues(), 0, values, 0, length);
- notifyObservers();
- }
- }
-
- private void recalculateMultipleInputs()
- {
- Iterator<WireArrayInput> it = inputs.iterator();
- Bit[] newValues = it.next().values.clone();
-
- while (it.hasNext())
- {
- WireArrayInput input = it.next();
- Bit[] bits = input.getValues();
- for (int i = 0; i < length; i++)
- {
- if (Bit.Z.equals(bits[i]) || newValues[i].equals(bits[i]))
- continue;
- else if (Bit.Z.equals(newValues[i]))
- newValues[i] = bits[i];
- else
- newValues[i] = Bit.X;
- }
- }
-
- if (!Arrays.equals(newValues, values))
- {
- notifyObservers();
- values = newValues;
- }
- }
-
- private void recalculate()
- {
- switch (inputs.size())
- {
- case 0:
- return;
- case 1:
- recalculateSingleInput();
- break;
- default:
- recalculateMultipleInputs();
- }
- }
-
- /**
- * The WireArray is interpreted as an unsigned integer with n bits.
- *
- * @return <code>true</code> if all bits are either <code>Bit.ONE</code> or
- * <code>Bit.ZERO</code> (they do not all have to have the same value),
- * not <code>Bit.X</code> or <code>Bit.Z</code>. <code>false</code> is
- * returned otherwise.
- *
- * @author Fabian Stemmler
- */
- public boolean hasNumericValue()
- {
- for (Bit b : values)
- {
- if (b != Bit.ZERO && b != Bit.ONE)
- return false;
- }
- return true;
- }
-
- /**
- * The WireArray is interpreted as an unsigned integer with n bits.
- *
- * @return The unsigned value of the {@link WireArray}'s bits, where value 0
- * corresponds with 2^0, value 1 is 2^1 and so on.
- *
- * @author Fabian Stemmler
- */
- public long getUnsignedValue()
- {
- long val = 0;
- long mask = 1;
- for (int i = 0; i < length; i++)
- {
- switch (values[i])
- {
- default:
- case Z:
- case X:
- return 0; // TODO: Proper handling for getUnsignedValue(), if not all bits are 1 or 0;
- // Random number?
- case ONE:
- val |= mask;
- break;
- case ZERO:
- }
- mask = mask << 1;
- }
- return val;
- }
-
- /**
- * The WireArray is interpreted as a signed integer with n bits.
- *
- * @return The signed value of the {@link WireArray}'s bits, where value 0
- * corresponds with 2^0, value 1 is 2^1 and so on.
- *
- * @author Fabian Stemmler
- */
- public long getSignedValue()
- {
- long val = getUnsignedValue();
- long mask = 1 << (length - 1);
- if ((mask & val) != 0)
- {
- int shifts = 64 - length;
- return (val << shifts) >> shifts;
- }
- return val;
- }
-
- /**
- * Included for convenient use on {@link WireArray}s of length 1.
- *
- * @return The value of bit 0.
- *
- * @author Fabian Stemmler
- */
- public Bit getValue()
- {
- return getValue(0);
- }
-
- /**
- *
- * @param index Index of the requested bit.
- * @return The value of the indexed bit.
- *
- * @author Fabian Stemmler
- */
- public Bit getValue(int index)
- {
- return values[index];
- }
-
- public Bit[] getValues(int start, int end)
- {
- int length = end - start;
- Bit[] bits = new Bit[length];
- System.arraycopy(values, start, bits, 0, length);
- return bits;
- }
-
- /**
- * @return An array of length n containing the values of the n bits in the
- * {@link WireArray}. Can be safely modified.
- *
- * @author Fabian Stemmler
- */
- public Bit[] getValues()
- {
- return values.clone();
- }
-
- /**
- * Adds an {@link WireArrayObserver}, who will be notified when the value of the
- * {@link WireArray} is updated.
- *
- * @param ob The {@link WireArrayObserver} to be notified of changes.
- * @return true if the given {@link WireArrayObserver} was not already
- * registered, false otherwise
- *
- * @author Fabian Stemmler
- */
- public boolean addObserver(WireArrayObserver ob)
- {
- return observers.add(ob);
- }
-
- private void notifyObservers()
- {
- for (WireArrayObserver o : observers)
- o.update(this);
- }
-
- /**
- * Create and register a {@link WireArrayInput} object, which is tied to this
- * {@link WireArray}.
- */
- public WireArrayInput createInput()
- {
- return new WireArrayInput(this);
- }
-
- private void registerInput(WireArrayInput toRegister)
- {
- inputs.add(toRegister);
- }
-
- /**
- * A {@link WireArrayInput} feeds a constant signal into the {@link WireArray}
- * it is tied to. The combination of all inputs determines the
- * {@link WireArray}s final value. X dominates all other inputs Z does not
- * affect the final value, unless there are no other inputs than Z 0 and 1 turn
- * into X when they are mixed
- *
- * @author Fabian Stemmler
- */
- public class WireArrayInput
- {
- public final WireArray owner;
- private Bit[] values;
-
- private WireArrayInput(WireArray owner)
- {
- super();
- this.owner = owner;
- initValues();
- owner.registerInput(this);
- }
-
- private void initValues()
- {
- values = new Bit[length];
- for (int i = 0; i < length; i++)
- values[i] = Bit.Z;
- }
-
- /**
- * Sets the wires values. This takes up time, as specified by the
- * {@link WireArray}s travel time.
- *
- * @param newValues The new values the wires should take on.
- *
- * @author Fabian Stemmler
- */
- public void feedSignals(Bit... newValues)
- {
- if (newValues.length == length)
- {
- feedSignals(0, newValues);
- } else
- throw new IllegalArgumentException(
- "Attempted to input " + newValues.length + " bits instead of " + length + " bits.");
- }
-
- /**
- * Sets values of a subarray of wires. This takes up time, as specified by the
- * {@link WireArray}s travel time.
- *
- * @param newValues The new values the wires should take on.
- * @param startingBit The first index of the subarray of wires.
- *
- * @author Fabian Stemmler
- */
- public void feedSignals(int startingBit, Bit... newValues)
- {
- Simulation.TIMELINE.addEvent((e) -> setValues(startingBit, newValues), travelTime);
- }
-
- private void setValues(int startingBit, Bit... newValues)
- {
- int exclLastIndex = startingBit + newValues.length;
- if (length < exclLastIndex)
- throw new ArrayIndexOutOfBoundsException("Attempted to input bits from index " + startingBit + " to "
- + exclLastIndex + " when there are only " + length + "wires.");
- if (!Arrays.equals(values, startingBit, exclLastIndex, newValues, 0, newValues.length))
- {
- System.arraycopy(newValues, 0, values, startingBit, newValues.length);
- owner.recalculate();
- }
- }
-
- public Bit[] getValues()
- {
- return values.clone();
- }
-
- public Bit[] wireValuesExcludingMe()
- {
- Bit[] bits = Util.arrayOfZ(length);
- for (WireArrayInput wai : inputs)
- {
- if(wai == this)
- continue;
- Util.combineInto(bits, wai.getValues());
- }
- return bits;
- }
-
- public void clearSignals()
- {
- Bit[] bits = new Bit[length];
- for (int i = 0; i < length; i++)
- bits[i] = Bit.Z;
- feedSignals(bits);
- }
-
- @Override
- public String toString()
- {
- return Arrays.toString(values);
- }
- }
-
- @Override
- public String toString()
- {
- return String.format("wire 0x%08x value: %s inputs: %s", hashCode(), Arrays.toString(values), inputs);
- }
-
- public static WireArrayInput[] extractInputs(WireArray[] w)
- {
- WireArrayInput[] inputs = new WireArrayInput[w.length];
- for(int i = 0; i < w.length; i++)
- inputs[i] = w[i].createInput();
- return inputs;
- }
+package era.mi.logic.wires;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Arrays;\r
+import java.util.Iterator;\r
+import java.util.List;\r
+\r
+import era.mi.logic.Bit;\r
+import era.mi.logic.Simulation;\r
+import era.mi.logic.Util;\r
+\r
+/**\r
+ * Represents an array of wires that can store n bits of information.\r
+ * \r
+ * @author Fabian Stemmler\r
+ *\r
+ */\r
+public class WireArray\r
+{\r
+ private Bit[] values;\r
+ public final int travelTime;\r
+ private List<WireArrayObserver> observers = new ArrayList<WireArrayObserver>();\r
+ public final int length;\r
+ private List<WireArrayInput> inputs = new ArrayList<WireArrayInput>();\r
+\r
+ 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
+ this.length = length;\r
+ this.travelTime = travelTime;\r
+ initValues();\r
+ }\r
+\r
+ private void initValues()\r
+ {\r
+ values = Bit.Z.makeArray(length);\r
+ }\r
+\r
+ private void recalculateSingleInput()\r
+ {\r
+ WireArrayInput input = inputs.get(0);\r
+ if (!Arrays.equals(input.getValues(), values))\r
+ {\r
+ System.arraycopy(input.getValues(), 0, values, 0, length);\r
+ notifyObservers();\r
+ }\r
+ }\r
+\r
+ private void recalculateMultipleInputs()\r
+ {\r
+ Iterator<WireArrayInput> it = inputs.iterator();\r
+ Bit[] newValues = it.next().inputValues.clone();\r
+\r
+ while (it.hasNext())\r
+ {\r
+ WireArrayInput input = it.next();\r
+ Bit[] bits = input.getValues();\r
+ for (int i = 0; i < length; i++)\r
+ {\r
+ if (Bit.Z.equals(bits[i]) || newValues[i].equals(bits[i]))\r
+ continue;\r
+ else if (Bit.Z.equals(newValues[i]))\r
+ newValues[i] = bits[i];\r
+ else\r
+ newValues[i] = Bit.X;\r
+ }\r
+ }\r
+\r
+ if (!Arrays.equals(newValues, values))\r
+ {\r
+ notifyObservers();\r
+ values = newValues;\r
+ }\r
+ }\r
+\r
+ private void recalculate()\r
+ {\r
+ switch (inputs.size())\r
+ {\r
+ case 0:\r
+ return;\r
+ case 1:\r
+ recalculateSingleInput();\r
+ break;\r
+ default:\r
+ recalculateMultipleInputs();\r
+ }\r
+ }\r
+\r
+ /**\r
+ * The WireArray is interpreted as an unsigned integer with n bits.\r
+ * \r
+ * @return <code>true</code> if all bits are either <code>Bit.ONE</code> or\r
+ * <code>Bit.ZERO</code> (they do not all have to have the same value),\r
+ * not <code>Bit.X</code> or <code>Bit.Z</code>. <code>false</code> is\r
+ * returned otherwise.\r
+ * \r
+ * @author Fabian Stemmler\r
+ */\r
+ public boolean hasNumericValue()\r
+ {\r
+ for (Bit b : values)\r
+ {\r
+ if (b != Bit.ZERO && b != Bit.ONE)\r
+ return false;\r
+ }\r
+ return true;\r
+ }\r
+\r
+ /**\r
+ * The WireArray is interpreted as an unsigned integer with n bits.\r
+ * \r
+ * @return The unsigned value of the {@link WireArray}'s bits, where value 0\r
+ * corresponds with 2^0, value 1 is 2^1 and so on.\r
+ * \r
+ * @author Fabian Stemmler\r
+ */\r
+ public long getUnsignedValue()\r
+ {\r
+ long val = 0;\r
+ long mask = 1;\r
+ for (int i = 0; i < length; i++)\r
+ {\r
+ switch (values[i])\r
+ {\r
+ default:\r
+ case Z:\r
+ case X:\r
+ return 0; // TODO: Proper handling for getUnsignedValue(), if not all bits are 1 or 0;\r
+ // Random number?\r
+ case ONE:\r
+ val |= mask;\r
+ break;\r
+ case ZERO:\r
+ }\r
+ mask = mask << 1;\r
+ }\r
+ return val;\r
+ }\r
+\r
+ /**\r
+ * The WireArray is interpreted as a signed integer with n bits.\r
+ * \r
+ * @return The signed value of the {@link WireArray}'s bits, where value 0\r
+ * corresponds with 2^0, value 1 is 2^1 and so on.\r
+ * \r
+ * @author Fabian Stemmler\r
+ */\r
+ public long getSignedValue()\r
+ {\r
+ long val = getUnsignedValue();\r
+ long mask = 1 << (length - 1);\r
+ if ((mask & val) != 0)\r
+ {\r
+ int shifts = 64 - length;\r
+ return (val << shifts) >> shifts;\r
+ }\r
+ return val;\r
+ }\r
+\r
+ /**\r
+ * Included for convenient use on {@link WireArray}s of length 1.\r
+ * \r
+ * @return The value of bit 0.\r
+ * \r
+ * @author Fabian Stemmler\r
+ */\r
+ public Bit getValue()\r
+ {\r
+ return getValue(0);\r
+ }\r
+\r
+ /**\r
+ * \r
+ * @param index Index of the requested bit.\r
+ * @return The value of the indexed bit.\r
+ * \r
+ * @author Fabian Stemmler\r
+ */\r
+ public Bit getValue(int index)\r
+ {\r
+ return values[index];\r
+ }\r
+\r
+ public Bit[] getValues(int start, int end)\r
+ {\r
+ int length = end - start;\r
+ Bit[] bits = new Bit[length];\r
+ System.arraycopy(values, start, bits, 0, length);\r
+ return bits;\r
+ }\r
+\r
+ /**\r
+ * @return An array of length n containing the values of the n bits in the\r
+ * {@link WireArray}. Can be safely modified.\r
+ * \r
+ * @author Fabian Stemmler\r
+ */\r
+ public Bit[] getValues()\r
+ {\r
+ return values.clone();\r
+ }\r
+\r
+ /**\r
+ * Adds an {@link WireArrayObserver}, who will be notified when the value of the\r
+ * {@link WireArray} is updated.\r
+ * \r
+ * @param ob The {@link WireArrayObserver} to be notified of changes.\r
+ * @return true if the given {@link WireArrayObserver} was not already\r
+ * registered, false otherwise\r
+ * \r
+ * @author Fabian Stemmler\r
+ */\r
+ public boolean addObserver(WireArrayObserver ob)\r
+ {\r
+ return observers.add(ob);\r
+ }\r
+\r
+ private void notifyObservers()\r
+ {\r
+ for (WireArrayObserver o : observers)\r
+ o.update(this);\r
+ }\r
+\r
+ /**\r
+ * Create and register a {@link WireArrayInput} object, which is tied to this\r
+ * {@link WireArray}.\r
+ */\r
+ public WireArrayInput createInput()\r
+ {\r
+ return new WireArrayInput(this);\r
+ }\r
+\r
+ private void registerInput(WireArrayInput toRegister)\r
+ {\r
+ inputs.add(toRegister);\r
+ }\r
+\r
+ /**\r
+ * A {@link WireArrayInput} feeds a constant signal into the {@link WireArray}\r
+ * it is tied to. The combination of all inputs determines the\r
+ * {@link WireArray}s final value. X dominates all other inputs Z does not\r
+ * affect the final value, unless there are no other inputs than Z 0 and 1 turn\r
+ * into X when they are mixed\r
+ * \r
+ * @author Fabian Stemmler\r
+ */\r
+ public class WireArrayInput\r
+ {\r
+ public final WireArray owner;\r
+ private Bit[] inputValues;\r
+\r
+ private WireArrayInput(WireArray owner)\r
+ {\r
+ super();\r
+ this.owner = owner;\r
+ initValues();\r
+ owner.registerInput(this);\r
+ }\r
+\r
+ private void initValues()\r
+ {\r
+ inputValues = Bit.Z.makeArray(length);\r
+ }\r
+\r
+ /**\r
+ * Sets the wires values. This takes up time, as specified by the\r
+ * {@link WireArray}s travel time.\r
+ * \r
+ * @param newValues The new values the wires should take on.\r
+ * \r
+ * @author Fabian Stemmler\r
+ */\r
+ public void feedSignals(Bit... newValues)\r
+ {\r
+ if (newValues.length == length)\r
+ {\r
+ feedSignals(0, newValues);\r
+ } else\r
+ throw new IllegalArgumentException(String.format("Attempted to input %o bits instead of %o bits.", newValues.length, length));\r
+ }\r
+\r
+ /**\r
+ * Sets values of a subarray of wires. This takes up time, as specified by the\r
+ * {@link WireArray}s travel time.\r
+ * \r
+ * @param newValues The new values the wires should take on.\r
+ * @param startingBit The first index of the subarray of wires.\r
+ * \r
+ * @author Fabian Stemmler\r
+ */\r
+ public void feedSignals(int startingBit, Bit... newValues)\r
+ {\r
+ Simulation.TIMELINE.addEvent((e) -> setValues(startingBit, newValues), travelTime);\r
+ }\r
+\r
+ private void setValues(int startingBit, Bit... newValues)\r
+ {\r
+ int exclLastIndex = startingBit + newValues.length;\r
+ if (length < exclLastIndex)\r
+ throw new ArrayIndexOutOfBoundsException(String.format("Attempted to input bits from index %o to %o when there are only %o wires.", startingBit, exclLastIndex - 1, length));\r
+ if (!Arrays.equals(inputValues, startingBit, exclLastIndex, newValues, 0, newValues.length))\r
+ {\r
+ System.arraycopy(newValues, 0, inputValues, startingBit, newValues.length);\r
+ owner.recalculate();\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Returns a copy (safe to modify) of the values the {@link WireArrayInput} is currently feeding into the associated {@link WireArray}.\r
+ */\r
+ public Bit[] getValues()\r
+ {\r
+ return inputValues.clone();\r
+ }\r
+\r
+ /**\r
+ * {@link WireArrayInput} now feeds Z into the associated {@link WireArray}.\r
+ */\r
+ public void clearSignals()\r
+ {\r
+ feedSignals(Bit.Z.makeArray(length));\r
+ }\r
+\r
+ public Bit[] wireValuesExcludingMe() \r
+ {\r
+ Bit[] bits = Bit.Z.makeArray(length);\r
+ for (WireArrayInput wai : inputs) \r
+ {\r
+ if(wai == this)\r
+ continue;\r
+ Util.combineInto(bits, wai.getValues());\r
+ }\r
+ return bits;\r
+ }\r
+ \r
+ @Override\r
+ public String toString()\r
+ {\r
+ return Arrays.toString(inputValues);\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public String toString()\r
+ {\r
+ return String.format("wire 0x%08x value: %s inputs: %s", hashCode(), Arrays.toString(values), inputs);\r
+ }\r
+\r
+ public static WireArrayInput[] extractInputs(WireArray[] w)\r
+ {\r
+ WireArrayInput[] inputs = new WireArrayInput[w.length];\r
+ for (int i = 0; i < w.length; i++)\r
+ inputs[i] = w[i].createInput();\r
+ return inputs;\r
+ }\r
}
\ No newline at end of file