Organized imports
[Mograsim.git] / tests / net.mograsim.logic.model.am2900.tests / src / net / mograsim / logic / model / am2900 / am2901 / Am2901Test.java
1 package net.mograsim.logic.model.am2900.am2901;
2
3 import static net.mograsim.logic.model.am2900.am2901.TestableAm2901.Am2901_Dest.NOP;
4 import static net.mograsim.logic.model.am2900.am2901.TestableAm2901.Am2901_Dest.QREG;
5 import static net.mograsim.logic.model.am2900.am2901.TestableAm2901.Am2901_Dest.RAMF;
6 import static net.mograsim.logic.model.am2900.am2901.TestableAm2901.Am2901_Func.ADD;
7 import static net.mograsim.logic.model.am2900.am2901.TestableAm2901.Am2901_Func.AND;
8 import static net.mograsim.logic.model.am2900.am2901.TestableAm2901.Am2901_Func.EXOR;
9 import static net.mograsim.logic.model.am2900.am2901.TestableAm2901.Am2901_Func.OR;
10 import static net.mograsim.logic.model.am2900.am2901.TestableAm2901.Am2901_Func.SUBR;
11 import static net.mograsim.logic.model.am2900.am2901.TestableAm2901.Am2901_Src.AB;
12 import static net.mograsim.logic.model.am2900.am2901.TestableAm2901.Am2901_Src.DA;
13 import static net.mograsim.logic.model.am2900.am2901.TestableAm2901.Am2901_Src.DZ;
14 import static net.mograsim.logic.model.am2900.am2901.TestableAm2901.Register.Q;
15 import static net.mograsim.logic.model.am2900.am2901.TestableAm2901.Register.r0;
16 import static net.mograsim.logic.model.am2900.util.TestUtil.signed4ToSigned32;
17 import static net.mograsim.logic.model.am2900.util.TestUtil.to1bitBin;
18 import static net.mograsim.logic.model.am2900.util.TestUtil.to4bitBin;
19 import static org.junit.jupiter.api.Assertions.assertAll;
20 import static org.junit.jupiter.api.Assertions.assertEquals;
21
22 import java.awt.Point;
23 import java.util.stream.IntStream;
24 import java.util.stream.Stream;
25
26 import org.junit.jupiter.api.BeforeEach;
27 import org.junit.jupiter.api.DisplayName;
28 import org.junit.jupiter.api.MethodOrderer.OrderAnnotation;
29 import org.junit.jupiter.api.Order;
30 import org.junit.jupiter.api.Test;
31 import org.junit.jupiter.api.TestMethodOrder;
32 import org.junit.jupiter.api.extension.RegisterExtension;
33 import org.junit.jupiter.params.ParameterizedTest;
34 import org.junit.jupiter.params.provider.EnumSource;
35
36 import net.mograsim.logic.model.am2900.am2901.TestableAm2901.Register;
37 import net.mograsim.logic.model.am2900.util.DisplayStateOnFailure;
38
39 @DisplayName("Am2901 Tests")
40 @TestMethodOrder(OrderAnnotation.class)
41 public class Am2901Test
42 {
43         private TestableAm2901 am2901 = new TestableAm2901Impl();
44
45         @RegisterExtension
46         DisplayStateOnFailure failureRule = new DisplayStateOnFailure(am2901);
47
48         @BeforeEach
49         void initialize()
50         {
51                 createAndSetup();
52                 setInputsToZero();
53         }
54
55         void createAndSetup()
56         {
57                 am2901.setup();
58         }
59
60         void setRegistersToZero()
61         {
62                 setInputsToZero();
63                 for (Register r : Register.values())
64                 {
65                         setRegisterToZero(r);
66                 }
67         }
68
69         void setRegisterToZero(Register r)
70         {
71                 am2901.setD("0000");
72                 am2901.setSrc(DZ);
73                 am2901.setFunc(AND);
74                 setRegOutput(r);
75
76                 am2901.assertFullCycleSuccess();
77         }
78
79         void setRegOutput(Register r)
80         {
81                 if (r == Q)
82                 {
83                         am2901.setDest(QREG);
84                 } else
85                 {
86                         am2901.setReg_B(r.toBitString());
87                         am2901.setDest(RAMF);
88                 }
89         }
90
91         void setInputsToZero()
92         {
93                 am2901.setCarryIn("0");
94                 am2901.setQ_0("0");
95                 am2901.setQ_3("0");
96                 am2901.setRAM_0("0");
97                 am2901.setRAM_3("0");
98                 am2901.setReg_A("0000");
99                 am2901.setReg_B("0000");
100                 am2901.setD("0000");
101                 am2901.setSrc(AB);
102                 am2901.setFunc(ADD);
103                 am2901.setDest(QREG);
104 //              am2901.setNotOutEnable("0"); TODO
105                 am2901.clockOn(true);
106                 am2901.assertRunSuccess();
107         }
108
109         @ParameterizedTest(name = "{0}")
110         @Order(1)
111         @DisplayName("Direct / high level access")
112         @EnumSource(Register.class)
113         void testDirectAccess(Register r)
114         {
115                 assertEquals("UUUU", am2901.getDirectly(r));
116
117                 am2901.setDirectly(r, "1011");
118
119                 assertEquals("1011", am2901.getDirectly(r));
120         }
121
122         @ParameterizedTest(name = "{0}")
123         @Order(2)
124         @DisplayName("Setting each register to 0")
125         @EnumSource(Register.class)
126         void testSetToZero(Register r)
127         {
128                 assertEquals("UUUU", am2901.getDirectly(r));
129
130                 setRegisterToZero(r);
131
132                 assertEquals("0000", am2901.getDirectly(r));
133                 assertEquals("0000", am2901.getY());
134                 assertEquals("0", am2901.getCarryOut());
135                 assertEquals("0", am2901.getOverflow());
136                 assertEquals("0", am2901.getSign());
137                 assertEquals("1", am2901.getZero());
138         }
139
140         @Test
141         @Order(3)
142         @DisplayName("Setting all registers to 0")
143         void testSetAllToZero()
144         {
145                 setRegistersToZero();
146
147                 assertEquals("0000", am2901.getY());
148                 assertEquals("0", am2901.getCarryOut());
149                 assertEquals("0", am2901.getOverflow());
150                 assertEquals("0", am2901.getSign());
151                 assertEquals("1", am2901.getZero());
152                 assertEquals("0", am2901.getQ_0());
153                 assertEquals("0", am2901.getQ_3());
154                 assertEquals("0", am2901.getRAM_0());
155                 assertEquals("0", am2901.getRAM_3());
156
157                 assertAll("register values", Register.stream().map(r -> () ->
158                 {
159                         assertEquals("0000", am2901.getDirectly(r), r.name());
160                 }));
161         }
162
163         @Test
164         @Order(4)
165         @DisplayName("ADD operation")
166         void testADD()
167         {
168                 am2901.setSrc(DA);
169                 am2901.setFunc(ADD);
170                 am2901.setDest(NOP);
171                 am2901.setReg_A(r0.toBitString());
172
173                 assertAll(getAll4BitPairs().map(xy -> () ->
174                 {
175                         am2901.setDirectly(r0, to4bitBin(xy.x));
176                         am2901.setD(to4bitBin(xy.y));
177
178                         am2901.assertFullCycleSuccess();
179
180                         int res32Bit = xy.x + xy.y;
181                         int res4Bit = res32Bit & 0b1111;
182                         int res32Bit_sgn = signed4ToSigned32(xy.x) + signed4ToSigned32(xy.y);
183                         int res4Bit_sgn = signed4ToSigned32(res32Bit_sgn);
184
185                         assertAll("Result of " + xy.x + " + " + xy.y + " = " + res32Bit,
186                                         () -> assertEquals(to4bitBin(res32Bit), am2901.getY(), "    Y"),
187                                         () -> assertEquals(to1bitBin(res4Bit == 0), am2901.getZero(), "    F=0"),
188                                         () -> assertEquals(to1bitBin(res4Bit & 0b1000), am2901.getSign(), "    F3"),
189                                         () -> assertEquals(to1bitBin(res32Bit > 15), am2901.getCarryOut(), "    Cn+4"),
190                                         () -> assertEquals(to1bitBin(res4Bit_sgn != res32Bit_sgn), am2901.getOverflow(), "    OVR"));
191                 }));
192         }
193
194         @Test
195         @Order(4)
196         @DisplayName("AND operation")
197         void testAND()
198         {
199                 am2901.setSrc(DA);
200                 am2901.setFunc(AND);
201                 am2901.setDest(NOP);
202                 am2901.setReg_A(r0.toBitString());
203
204                 assertAll(getAll4BitPairs().map(xy -> () ->
205                 {
206                         am2901.setDirectly(r0, to4bitBin(xy.x));
207                         am2901.setD(to4bitBin(xy.y));
208
209                         am2901.assertFullCycleSuccess();
210
211                         int res32Bit = xy.x & xy.y;
212
213                         assertAll("Result of " + xy.x + " & " + xy.y + " = " + res32Bit,
214                                         () -> assertEquals(to4bitBin(res32Bit), am2901.getY(), "    Y"),
215                                         () -> assertEquals(to1bitBin(res32Bit == 0), am2901.getZero(), "    F=0"),
216                                         () -> assertEquals(to1bitBin(res32Bit & 0b1000), am2901.getSign(), "    F3")
217 //                                      () -> assertEquals(to1bitBin(res32Bit), am2901.getCarryOut(), "    Cn+4"), // TODO
218 //                                      () -> assertEquals(to1bitBin(res32Bit), am2901.getOverflow(), "    OVR") // TODO
219                         );
220                 }));
221         }
222
223         @Test
224         @Order(4)
225         @DisplayName("OR operation")
226         void testOR()
227         {
228                 am2901.setSrc(DA);
229                 am2901.setFunc(OR);
230                 am2901.setDest(NOP);
231                 am2901.setReg_A(r0.toBitString());
232
233                 assertAll(getAll4BitPairs().map(xy -> () ->
234                 {
235                         am2901.setDirectly(r0, to4bitBin(xy.x));
236                         am2901.setD(to4bitBin(xy.y));
237
238                         am2901.assertFullCycleSuccess();
239
240                         int res32Bit = xy.x | xy.y;
241
242                         assertAll("Result of " + xy.x + " | " + xy.y + " = " + res32Bit,
243                                         () -> assertEquals(to4bitBin(res32Bit), am2901.getY(), "    Y"),
244                                         () -> assertEquals(to1bitBin(res32Bit == 0), am2901.getZero(), "    F=0"),
245                                         () -> assertEquals(to1bitBin(res32Bit & 0b1000), am2901.getSign(), "    F3")
246 //                                      () -> assertEquals(to1bitBin(res32Bit != 0b1111), am2901.getCarryOut(), "    Cn+4"), // TODO
247 //                                      () -> assertEquals(to1bitBin(res32Bit != 0b1111), am2901.getOverflow(), "    OVR") // TODO
248                         );
249                 }));
250         }
251
252         @Test
253         @Order(4)
254         @DisplayName("XOR operation")
255         void testXOR()
256         {
257                 am2901.setSrc(DA);
258                 am2901.setFunc(EXOR);
259                 am2901.setDest(NOP);
260                 am2901.setReg_A(r0.toBitString());
261
262                 assertAll(getAll4BitPairs().map(xy -> () ->
263                 {
264                         am2901.setDirectly(r0, to4bitBin(xy.x));
265                         am2901.setD(to4bitBin(xy.y));
266
267                         am2901.assertFullCycleSuccess();
268
269                         int res32Bit = xy.x ^ xy.y;
270
271                         assertAll("Result of " + xy.x + " ^ " + xy.y + " = " + res32Bit,
272                                         () -> assertEquals(to4bitBin(res32Bit), am2901.getY(), "    Y"),
273                                         () -> assertEquals(to1bitBin(res32Bit == 0), am2901.getZero(), "    F=0"),
274                                         () -> assertEquals(to1bitBin(res32Bit & 0b1000), am2901.getSign(), "    F3"));
275                 }));
276         }
277
278         @Test
279         @Order(4)
280         @DisplayName("SUB operation")
281         void testSUB()
282         {
283                 am2901.setSrc(DA);
284                 am2901.setCarryIn("1");
285                 am2901.setFunc(SUBR);
286                 am2901.setDest(NOP);
287                 am2901.setReg_A(r0.toBitString());
288
289                 assertAll(getAll4BitPairs().map(xy -> () ->
290                 {
291                         am2901.setDirectly(r0, to4bitBin(xy.x));
292                         am2901.setD(to4bitBin(xy.y));
293
294                         am2901.assertFullCycleSuccess();
295
296                         int res32Bit = xy.x - xy.y;
297                         int res4Bit = res32Bit & 0b1111;
298                         int res32Bit_sgn = signed4ToSigned32(xy.x) - signed4ToSigned32(xy.y);
299                         int res4Bit_sgn = signed4ToSigned32(res32Bit_sgn);
300
301                         assertAll("Result of " + xy.x + " - " + xy.y + " = " + res32Bit,
302                                         () -> assertEquals(to4bitBin(res32Bit), am2901.getY(), "    Y"),
303                                         () -> assertEquals(to1bitBin(res4Bit == 0), am2901.getZero(), "    F=0"),
304                                         () -> assertEquals(to1bitBin(res4Bit & 0b1000), am2901.getSign(), "    F3"),
305                                         () -> assertEquals(to1bitBin(xy.x >= xy.y), am2901.getCarryOut(), "    Cn+4"),
306                                         () -> assertEquals(to1bitBin(res4Bit_sgn != res32Bit_sgn), am2901.getOverflow(), "    OVR"));
307                 }));
308         }
309
310         static Stream<Point> getAll4BitPairs()
311         {
312                 return IntStream.range(0, 16).boxed().flatMap(x -> IntStream.range(0, 16).mapToObj(y -> new Point(x, y)));
313         }
314 }