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