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