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