d2be9b7514679dde38b8cd511bdd84643faf73f4
[Mograsim.git] / era.mi / src / era / mi / logic / tests / ComponentTest.java
1 package era.mi.logic.tests;\r
2 \r
3 import static org.junit.jupiter.api.Assertions.*;\r
4 \r
5 import java.util.Arrays;\r
6 import java.util.function.LongConsumer;\r
7 \r
8 import org.junit.jupiter.api.Test;\r
9 \r
10 import era.mi.logic.Simulation;\r
11 import era.mi.logic.components.Connector;\r
12 import era.mi.logic.components.Demux;\r
13 import era.mi.logic.components.Merger;\r
14 import era.mi.logic.components.Mux;\r
15 import era.mi.logic.components.Splitter;\r
16 import era.mi.logic.components.TriStateBuffer;\r
17 import era.mi.logic.components.gates.AndGate;\r
18 import era.mi.logic.components.gates.NotGate;\r
19 import era.mi.logic.components.gates.OrGate;\r
20 import era.mi.logic.components.gates.XorGate;\r
21 import era.mi.logic.types.Bit;\r
22 import era.mi.logic.wires.Wire;\r
23 import era.mi.logic.wires.Wire.WireEnd;\r
24 \r
25 @SuppressWarnings("unused")\r
26 class ComponentTest\r
27 {\r
28 \r
29         @Test\r
30         void circuitExampleTest()\r
31         {\r
32                 Simulation.TIMELINE.reset();\r
33                 Wire a = new Wire(1, 1), b = new Wire(1, 1), c = new Wire(1, 10), d = new Wire(2, 1), e = new Wire(1, 1), f = new Wire(1, 1),\r
34                                 g = new Wire(1, 1), h = new Wire(2, 1), i = new Wire(2, 1), j = new Wire(1, 1), k = new Wire(1, 1);\r
35                 new AndGate(1, f.createEnd(), a.createReadOnlyEnd(), b.createReadOnlyEnd());\r
36                 new NotGate(1, f.createReadOnlyEnd(), g.createEnd());\r
37                 new Merger(h.createEnd(), c.createReadOnlyEnd(), g.createReadOnlyEnd());\r
38                 new Mux(1, i.createEnd(), e.createReadOnlyEnd(), h.createReadOnlyEnd(), d.createReadOnlyEnd());\r
39                 new Splitter(i.createReadOnlyEnd(), k.createEnd(), j.createEnd());\r
40 \r
41                 a.createEnd().feedSignals(Bit.ZERO);\r
42                 b.createEnd().feedSignals(Bit.ONE);\r
43                 c.createEnd().feedSignals(Bit.ZERO);\r
44                 d.createEnd().feedSignals(Bit.ONE, Bit.ONE);\r
45                 e.createEnd().feedSignals(Bit.ZERO);\r
46 \r
47                 Simulation.TIMELINE.executeAll();\r
48 \r
49                 assertEquals(Bit.ONE, j.getValue());\r
50                 assertEquals(Bit.ZERO, k.getValue());\r
51         }\r
52 \r
53         @Test\r
54         void splitterTest()\r
55         {\r
56                 Simulation.TIMELINE.reset();\r
57                 Wire a = new Wire(3, 1), b = new Wire(2, 1), c = new Wire(3, 1), in = new Wire(8, 1);\r
58                 in.createEnd().feedSignals(Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE);\r
59                 new Splitter(in.createReadOnlyEnd(), a.createEnd(), b.createEnd(), c.createEnd());\r
60 \r
61                 Simulation.TIMELINE.executeAll();\r
62 \r
63                 assertBitArrayEquals(a.getValues(), Bit.ZERO, Bit.ONE, Bit.ZERO);\r
64                 assertBitArrayEquals(b.getValues(), Bit.ONE, Bit.ZERO);\r
65                 assertBitArrayEquals(c.getValues(), Bit.ONE, Bit.ZERO, Bit.ONE);\r
66         }\r
67 \r
68         @Test\r
69         void mergerTest()\r
70         {\r
71                 Simulation.TIMELINE.reset();\r
72                 Wire a = new Wire(3, 1), b = new Wire(2, 1), c = new Wire(3, 1), out = new Wire(8, 1);\r
73                 a.createEnd().feedSignals(Bit.ZERO, Bit.ONE, Bit.ZERO);\r
74                 b.createEnd().feedSignals(Bit.ONE, Bit.ZERO);\r
75                 c.createEnd().feedSignals(Bit.ONE, Bit.ZERO, Bit.ONE);\r
76 \r
77                 new Merger(out.createEnd(), a.createReadOnlyEnd(), b.createReadOnlyEnd(), c.createReadOnlyEnd());\r
78 \r
79                 Simulation.TIMELINE.executeAll();\r
80 \r
81                 assertTrue(\r
82                                 Arrays.equals(out.getValues(), new Bit[] { Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE }));\r
83         }\r
84 \r
85         @Test\r
86         void triStateBufferTest()\r
87         {\r
88                 Wire a = new Wire(1, 1), b = new Wire(1, 1), en = new Wire(1, 1), notEn = new Wire(1, 1);\r
89                 new NotGate(1, en.createReadOnlyEnd(), notEn.createEnd());\r
90                 new TriStateBuffer(1, a.createReadOnlyEnd(), b.createEnd(), en.createReadOnlyEnd());\r
91                 new TriStateBuffer(1, b.createReadOnlyEnd(), a.createEnd(), notEn.createReadOnlyEnd());\r
92 \r
93                 WireEnd enI = en.createEnd(), aI = a.createEnd(), bI = b.createEnd();\r
94                 enI.feedSignals(Bit.ONE);\r
95                 aI.feedSignals(Bit.ONE);\r
96                 bI.feedSignals(Bit.Z);\r
97 \r
98                 Simulation.TIMELINE.executeAll();\r
99 \r
100                 assertEquals(Bit.ONE, b.getValue());\r
101 \r
102                 bI.feedSignals(Bit.ZERO);\r
103 \r
104                 Simulation.TIMELINE.executeAll();\r
105 \r
106                 assertEquals(Bit.X, b.getValue());\r
107                 assertEquals(Bit.ONE, a.getValue());\r
108 \r
109                 aI.clearSignals();\r
110                 enI.feedSignals(Bit.ZERO);\r
111 \r
112                 Simulation.TIMELINE.executeAll();\r
113 \r
114                 assertEquals(Bit.ZERO, a.getValue());\r
115 \r
116         }\r
117 \r
118         @Test\r
119         void muxTest()\r
120         {\r
121                 Simulation.TIMELINE.reset();\r
122                 Wire a = new Wire(4, 3), b = new Wire(4, 6), c = new Wire(4, 4), select = new Wire(2, 5), out = new Wire(4, 1);\r
123                 WireEnd selectIn = select.createEnd();\r
124 \r
125                 selectIn.feedSignals(Bit.ZERO, Bit.ZERO);\r
126                 a.createEnd().feedSignals(Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO);\r
127                 c.createEnd().feedSignals(Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE);\r
128 \r
129                 new Mux(1, out.createEnd(), select.createReadOnlyEnd(), a.createReadOnlyEnd(), b.createReadOnlyEnd(), c.createReadOnlyEnd());\r
130                 Simulation.TIMELINE.executeAll();\r
131 \r
132                 assertBitArrayEquals(out.getValues(), Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO);\r
133                 selectIn.feedSignals(Bit.ZERO, Bit.ONE);\r
134                 Simulation.TIMELINE.executeAll();\r
135 \r
136                 assertBitArrayEquals(out.getValues(), Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE);\r
137 \r
138                 selectIn.feedSignals(Bit.ONE, Bit.ONE);\r
139                 Simulation.TIMELINE.executeAll();\r
140 \r
141                 assertBitArrayEquals(out.getValues(), Bit.Z, Bit.Z, Bit.Z, Bit.Z);\r
142 \r
143         }\r
144 \r
145         @Test\r
146         void demuxTest()\r
147         {\r
148                 Simulation.TIMELINE.reset();\r
149                 Wire a = new Wire(4, 3), b = new Wire(4, 6), c = new Wire(4, 4), select = new Wire(2, 5), in = new Wire(4, 1);\r
150                 WireEnd selectIn = select.createEnd();\r
151 \r
152                 selectIn.feedSignals(Bit.ZERO, Bit.ZERO);\r
153                 in.createEnd().feedSignals(Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO);\r
154 \r
155                 new Demux(1, in.createReadOnlyEnd(), select.createReadOnlyEnd(), a.createEnd(), b.createEnd(), c.createEnd());\r
156                 Simulation.TIMELINE.executeAll();\r
157 \r
158                 assertBitArrayEquals(a.getValues(), Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO);\r
159                 assertBitArrayEquals(b.getValues(), Bit.U, Bit.U, Bit.U, Bit.U);\r
160                 assertBitArrayEquals(c.getValues(), Bit.U, Bit.U, Bit.U, Bit.U);\r
161                 selectIn.feedSignals(Bit.ZERO, Bit.ONE);\r
162                 Simulation.TIMELINE.executeAll();\r
163 \r
164                 assertBitArrayEquals(a.getValues(), Bit.Z, Bit.Z, Bit.Z, Bit.Z);\r
165                 assertBitArrayEquals(b.getValues(), Bit.U, Bit.U, Bit.U, Bit.U);\r
166                 assertBitArrayEquals(c.getValues(), Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO);\r
167 \r
168                 selectIn.feedSignals(Bit.ONE, Bit.ONE);\r
169                 Simulation.TIMELINE.executeAll();\r
170 \r
171                 assertBitArrayEquals(a.getValues(), Bit.Z, Bit.Z, Bit.Z, Bit.Z);\r
172                 assertBitArrayEquals(b.getValues(), Bit.U, Bit.U, Bit.U, Bit.U);\r
173                 assertBitArrayEquals(c.getValues(), Bit.Z, Bit.Z, Bit.Z, Bit.Z);\r
174 \r
175         }\r
176 \r
177         @Test\r
178         void andTest()\r
179         {\r
180                 Simulation.TIMELINE.reset();\r
181                 Wire a = new Wire(4, 1), b = new Wire(4, 3), c = new Wire(4, 1);\r
182                 new AndGate(1, c.createEnd(), a.createReadOnlyEnd(), b.createReadOnlyEnd());\r
183                 a.createEnd().feedSignals(Bit.ONE, Bit.ONE, Bit.ZERO, Bit.ZERO);\r
184                 b.createEnd().feedSignals(Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE);\r
185 \r
186                 Simulation.TIMELINE.executeAll();\r
187 \r
188                 assertBitArrayEquals(c.getValues(), Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ZERO);\r
189         }\r
190 \r
191         @Test\r
192         void orTest()\r
193         {\r
194                 Simulation.TIMELINE.reset();\r
195                 Wire a = new Wire(4, 1), b = new Wire(4, 3), c = new Wire(4, 1);\r
196                 new OrGate(1, c.createEnd(), a.createReadOnlyEnd(), b.createReadOnlyEnd());\r
197                 a.createEnd().feedSignals(Bit.ONE, Bit.ONE, Bit.ZERO, Bit.ZERO);\r
198                 b.createEnd().feedSignals(Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE);\r
199 \r
200                 Simulation.TIMELINE.executeAll();\r
201 \r
202                 assertBitArrayEquals(c.getValues(), Bit.ONE, Bit.ONE, Bit.ZERO, Bit.ONE);\r
203         }\r
204 \r
205         @Test\r
206         void xorTest()\r
207         {\r
208                 Simulation.TIMELINE.reset();\r
209                 Wire a = new Wire(3, 1), b = new Wire(3, 2), c = new Wire(3, 1), d = new Wire(3, 1);\r
210                 new XorGate(1, d.createEnd(), a.createReadOnlyEnd(), b.createReadOnlyEnd(), c.createReadOnlyEnd());\r
211                 a.createEnd().feedSignals(Bit.ZERO, Bit.ONE, Bit.ONE);\r
212                 b.createEnd().feedSignals(Bit.ONE, Bit.ZERO, Bit.ONE);\r
213                 c.createEnd().feedSignals(Bit.ONE, Bit.ZERO, Bit.ONE);\r
214 \r
215                 Simulation.TIMELINE.executeAll();\r
216 \r
217                 assertBitArrayEquals(d.getValues(), Bit.ZERO, Bit.ONE, Bit.ONE);\r
218         }\r
219 \r
220         @Test\r
221         void notTest()\r
222         {\r
223                 Simulation.TIMELINE.reset();\r
224                 Wire a = new Wire(3, 1), b = new Wire(3, 2);\r
225                 new NotGate(1, a.createReadOnlyEnd(), b.createEnd());\r
226                 a.createEnd().feedSignals(Bit.ZERO, Bit.ONE, Bit.ONE);\r
227 \r
228                 Simulation.TIMELINE.executeAll();\r
229 \r
230                 assertBitArrayEquals(b.getValues(), Bit.ONE, Bit.ZERO, Bit.ZERO);\r
231         }\r
232 \r
233         @Test\r
234         void rsLatchCircuitTest()\r
235         {\r
236                 Simulation.TIMELINE.reset();\r
237                 Wire r = new Wire(1, 1), s = new Wire(1, 1), t1 = new Wire(1, 15), t2 = new Wire(1, 1), q = new Wire(1, 1), nq = new Wire(1, 1);\r
238 \r
239                 new OrGate(1, t2.createEnd(), r.createReadOnlyEnd(), nq.createReadOnlyEnd());\r
240                 new OrGate(1, t1.createEnd(), s.createReadOnlyEnd(), q.createReadOnlyEnd());\r
241                 new NotGate(1, t2.createReadOnlyEnd(), q.createEnd());\r
242                 new NotGate(1, t1.createReadOnlyEnd(), nq.createEnd());\r
243 \r
244                 WireEnd sIn = s.createEnd(), rIn = r.createEnd();\r
245 \r
246                 sIn.feedSignals(Bit.ONE);\r
247                 rIn.feedSignals(Bit.ZERO);\r
248 \r
249                 Simulation.TIMELINE.executeAll();\r
250 \r
251                 assertEquals(Bit.ONE, q.getValue());\r
252                 assertEquals(Bit.ZERO, nq.getValue());\r
253 \r
254                 sIn.feedSignals(Bit.ZERO);\r
255 \r
256                 Simulation.TIMELINE.executeAll();\r
257                 assertEquals(Bit.ONE, q.getValue());\r
258                 assertEquals(Bit.ZERO, nq.getValue());\r
259 \r
260                 rIn.feedSignals(Bit.ONE);\r
261 \r
262                 Simulation.TIMELINE.executeAll();\r
263 \r
264                 assertEquals(Bit.ZERO, q.getValue());\r
265                 assertEquals(Bit.ONE, nq.getValue());\r
266         }\r
267 \r
268         @Test\r
269         void numericValueTest()\r
270         {\r
271                 Simulation.TIMELINE.reset();\r
272 \r
273                 Wire a = new Wire(4, 1);\r
274                 a.createEnd().feedSignals(Bit.ONE, Bit.ONE, Bit.ONE, Bit.ONE);\r
275 \r
276                 Simulation.TIMELINE.executeAll();\r
277 \r
278                 assertEquals(15, a.getUnsignedValue());\r
279                 assertEquals(-1, a.getSignedValue());\r
280         }\r
281 \r
282         @Test\r
283         void multipleInputs()\r
284         {\r
285                 Simulation.TIMELINE.reset();\r
286                 Wire w = new Wire(2, 1);\r
287                 WireEnd wI1 = w.createEnd(), wI2 = w.createEnd();\r
288                 wI1.feedSignals(Bit.ONE, Bit.Z);\r
289                 wI2.feedSignals(Bit.Z, Bit.X);\r
290                 Simulation.TIMELINE.executeAll();\r
291                 assertBitArrayEquals(w.getValues(), Bit.ONE, Bit.X);\r
292 \r
293                 wI2.feedSignals(Bit.ZERO, Bit.Z);\r
294                 Simulation.TIMELINE.executeAll();\r
295                 assertBitArrayEquals(w.getValues(), Bit.X, Bit.Z);\r
296 \r
297                 wI2.feedSignals(Bit.Z, Bit.Z);\r
298                 Simulation.TIMELINE.executeAll();\r
299                 assertBitArrayEquals(w.getValues(), Bit.ONE, Bit.Z);\r
300 \r
301                 wI2.feedSignals(Bit.ONE, Bit.Z);\r
302                 w.addObserver((i, oldValues) -> fail("WireArray notified observer, although value did not change."));\r
303                 Simulation.TIMELINE.executeAll();\r
304                 assertBitArrayEquals(w.getValues(), Bit.ONE, Bit.Z);\r
305         }\r
306 \r
307         @Test\r
308         void wireConnections()\r
309         {\r
310                 // Nur ein Experiment, was über mehrere 'passive' Bausteine hinweg passieren würde\r
311 \r
312                 Simulation.TIMELINE.reset();\r
313 \r
314                 Wire a = new Wire(1, 2);\r
315                 Wire b = new Wire(1, 2);\r
316                 Wire c = new Wire(1, 2);\r
317                 WireEnd aI = a.createEnd();\r
318                 WireEnd bI = b.createEnd();\r
319                 WireEnd cI = c.createEnd();\r
320 \r
321                 TestBitDisplay test = new TestBitDisplay(c.createReadOnlyEnd());\r
322                 TestBitDisplay test2 = new TestBitDisplay(a.createReadOnlyEnd());\r
323                 LongConsumer print = time -> System.out.format("Time %2d\n   a: %s\n   b: %s\n   c: %s\n", time, a, b, c);\r
324 \r
325                 cI.feedSignals(Bit.ONE);\r
326                 test.assertAfterSimulationIs(print, Bit.ONE);\r
327 \r
328                 cI.feedSignals(Bit.X);\r
329                 test.assertAfterSimulationIs(print, Bit.X);\r
330 \r
331                 cI.feedSignals(Bit.X);\r
332                 cI.feedSignals(Bit.Z);\r
333                 test.assertAfterSimulationIs(print, Bit.Z);\r
334 \r
335                 new Connector(b.createEnd(), c.createEnd()).connect();\r
336                 test.assertAfterSimulationIs(print, Bit.Z);\r
337                 System.err.println("ONE");\r
338                 bI.feedSignals(Bit.ONE);\r
339                 test.assertAfterSimulationIs(print, Bit.ONE);\r
340                 System.err.println("ZERO");\r
341                 bI.feedSignals(Bit.ZERO);\r
342                 test.assertAfterSimulationIs(print, Bit.ZERO);\r
343                 System.err.println("Z");\r
344                 bI.feedSignals(Bit.Z);\r
345                 test.assertAfterSimulationIs(print, Bit.Z);\r
346 \r
347                 new Connector(a.createEnd(), b.createEnd()).connect();\r
348                 System.err.println("Z 2");\r
349                 aI.feedSignals(Bit.Z);\r
350                 test.assertAfterSimulationIs(print, Bit.Z);\r
351                 test2.assertAfterSimulationIs(Bit.Z);\r
352                 System.err.println("ONE 2");\r
353                 aI.feedSignals(Bit.ONE);\r
354                 test.assertAfterSimulationIs(print, Bit.ONE);\r
355                 test2.assertAfterSimulationIs(Bit.ONE);\r
356                 System.err.println("ZERO 2");\r
357                 aI.feedSignals(Bit.ZERO);\r
358                 test.assertAfterSimulationIs(print, Bit.ZERO);\r
359                 test2.assertAfterSimulationIs(Bit.ZERO);\r
360                 System.err.println("Z 2 II");\r
361                 aI.feedSignals(Bit.Z);\r
362                 test.assertAfterSimulationIs(print, Bit.Z);\r
363                 test2.assertAfterSimulationIs(Bit.Z);\r
364 \r
365                 System.err.println("No Conflict yet");\r
366                 bI.feedSignals(Bit.ONE);\r
367                 test.assertAfterSimulationIs(print, Bit.ONE);\r
368                 test2.assertAfterSimulationIs(Bit.ONE);\r
369                 aI.feedSignals(Bit.ONE);\r
370                 test.assertAfterSimulationIs(print, Bit.ONE);\r
371                 test2.assertAfterSimulationIs(Bit.ONE);\r
372                 System.err.println("Conflict");\r
373                 aI.feedSignals(Bit.ZERO);\r
374                 test.assertAfterSimulationIs(print, Bit.X);\r
375                 test2.assertAfterSimulationIs(Bit.X);\r
376                 aI.feedSignals(Bit.ONE);\r
377                 test.assertAfterSimulationIs(print, Bit.ONE);\r
378                 test2.assertAfterSimulationIs(Bit.ONE);\r
379         }\r
380 \r
381         private static void assertBitArrayEquals(Bit[] actual, Bit... expected)\r
382         {\r
383                 assertArrayEquals(expected, actual);\r
384         }\r
385 }\r