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