package net.mograsim.logic.ui.am2900;\r
\r
+import static net.mograsim.logic.ui.am2900.TestUtil.*;\r
import static net.mograsim.logic.ui.am2900.TestableAm2901.Am2901_Dest.*;\r
import static net.mograsim.logic.ui.am2900.TestableAm2901.Am2901_Func.*;\r
import static net.mograsim.logic.ui.am2900.TestableAm2901.Am2901_Src.*;\r
-import static org.junit.jupiter.api.Assertions.assertEquals;\r
+import static net.mograsim.logic.ui.am2900.TestableAm2901.Register.*;\r
+import static org.junit.jupiter.api.Assertions.*;\r
+\r
+import java.awt.Point;\r
+import java.util.stream.IntStream;\r
+import java.util.stream.Stream;\r
\r
import org.junit.jupiter.api.BeforeEach;\r
+import org.junit.jupiter.api.Order;\r
+import org.junit.jupiter.api.MethodOrderer.OrderAnnotation;\r
import org.junit.jupiter.api.Test;\r
+import org.junit.jupiter.api.TestMethodOrder;\r
+import org.junit.jupiter.params.ParameterizedTest;\r
+import org.junit.jupiter.params.provider.ArgumentsSource;\r
+import net.mograsim.logic.ui.am2900.TestableAm2901.Register;\r
\r
-import net.mograsim.logic.ui.am2900.TestableAm2901.Result;\r
-\r
+@TestMethodOrder(OrderAnnotation.class)\r
public class Am2901Test\r
{\r
private TestableAm2901 am2901;\r
void initialize()\r
{\r
createAndSetup();\r
- setRegistersToZero();\r
- }\r
-\r
- @Test\r
- void testInit()\r
- {\r
- assertEquals("0", am2901.getCarryOut());\r
- assertEquals("0", am2901.getOverflow());\r
- assertEquals("0", am2901.getSign());\r
- assertEquals("1", am2901.getZero());\r
- assertEquals("0000", am2901.getY());\r
- assertEquals("0", am2901.getQ_0());\r
- assertEquals("0", am2901.getQ_3());\r
- assertEquals("0", am2901.getRAM_0());\r
- assertEquals("0", am2901.getRAM_3());\r
+ setInputsToZero();\r
}\r
\r
void createAndSetup()\r
void setRegistersToZero()\r
{\r
setInputsToZero();\r
- for (Regsiter r : Regsiter.values())\r
+ for (Register r : Register.values())\r
{\r
setRegisterToZero(r);\r
}\r
}\r
\r
- void setRegisterToZero(Regsiter r)\r
+ void setRegisterToZero(Register r)\r
{\r
System.out.println("Setting reg " + r + " to zero");\r
+\r
am2901.setD("0000");\r
am2901.setSrc(DZ);\r
am2901.setFunc(AND);\r
- if (r == Regsiter.Q)\r
+ setRegOutput(r);\r
+\r
+ am2901.assertFullCycleSuccess();\r
+ }\r
+\r
+ void setRegOutput(Register r)\r
+ {\r
+ if (r == Q)\r
{\r
am2901.setDest(QREG);\r
} else\r
am2901.setReg_B(r.toBitString());\r
am2901.setDest(RAMF);\r
}\r
- assertRunSuccess();\r
- am2901.toogleClock();\r
- assertRunSuccess();\r
- am2901.toogleClock();\r
- assertRunSuccess();\r
}\r
\r
void setInputsToZero()\r
am2901.setFunc(ADD);\r
am2901.setDest(QREG);\r
// am2901.setNotOutEnable("0"); TODO\r
- assertRunSuccess();\r
+ am2901.clockOn(true);\r
+ am2901.assertRunSuccess();\r
}\r
\r
- void assertRunSuccess()\r
+ @Order(1)\r
+ @ParameterizedTest\r
+ @ArgumentsSource(TestableAm2901.RegisterProvider.class)\r
+ void testDirectAccess(Register r)\r
{\r
- assertEquals(Result.SUCCESS, am2901.run());\r
+ assertEquals("UUUU", am2901.getDirectly(r));\r
+\r
+ am2901.setDirectly(r, "1011");\r
+\r
+ assertEquals("1011", am2901.getDirectly(r));\r
}\r
\r
- public enum Regsiter\r
+ @Order(2)\r
+ @ParameterizedTest\r
+ @ArgumentsSource(TestableAm2901.RegisterProvider.class)\r
+ void testSetToZero(Register r)\r
{\r
- r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, rA, rB, rC, rD, rE, rF, Q;\r
+ assertEquals("UUUU", am2901.getDirectly(r));\r
+\r
+ setRegisterToZero(r);\r
\r
- public String toBitString()\r
+ assertEquals("0000", am2901.getDirectly(r));\r
+ assertEquals("0000", am2901.getY());\r
+ assertEquals("0", am2901.getCarryOut());\r
+ assertEquals("0", am2901.getOverflow());\r
+ assertEquals("0", am2901.getSign());\r
+ assertEquals("1", am2901.getZero());\r
+ }\r
+\r
+ @Order(3)\r
+ @Test\r
+ void testSetAllToZero()\r
+ {\r
+ setRegistersToZero();\r
+\r
+ assertEquals("0000", am2901.getY());\r
+ assertEquals("0", am2901.getCarryOut());\r
+ assertEquals("0", am2901.getOverflow());\r
+ assertEquals("0", am2901.getSign());\r
+ assertEquals("1", am2901.getZero());\r
+ assertEquals("0", am2901.getQ_0());\r
+ assertEquals("0", am2901.getQ_3());\r
+ assertEquals("0", am2901.getRAM_0());\r
+ assertEquals("0", am2901.getRAM_3());\r
+\r
+ assertAll("register values", Register.stream().map(r -> () ->\r
{\r
- if (this.ordinal() > 0xF)\r
- throw new UnsupportedOperationException();\r
- return TestUtil.to4bitBin(this.ordinal());\r
- }\r
+ assertEquals("0000", am2901.getDirectly(r), r.name());\r
+ }));\r
+ }\r
+\r
+ @Order(4)\r
+ @Test\r
+ void testADD()\r
+ {\r
+ am2901.setSrc(DA);\r
+ am2901.setFunc(ADD);\r
+ am2901.setDest(NOP);\r
+ am2901.setReg_A(r0.toBitString());\r
+\r
+ assertAll(getAll4BitPairs().map(xy -> () ->\r
+ {\r
+ am2901.setDirectly(r0, to4bitBin(xy.x));\r
+ am2901.setD(to4bitBin(xy.y));\r
+\r
+ am2901.assertFullCycleSuccess();\r
+\r
+ int res32Bit = xy.x + xy.y;\r
+ int res4Bit = res32Bit & 0b1111;\r
+ int res32Bit_sgn = signed4ToSigned32(xy.x) + signed4ToSigned32(xy.y);\r
+ int res4Bit_sgn = signed4ToSigned32(res32Bit_sgn);\r
+\r
+ String desc = xy.x + " + " + xy.y + " = " + res4Bit + ": ";\r
+\r
+ assertEquals(to4bitBin(res4Bit & 0b1111), am2901.getY(), desc + "Y");\r
+ assertEquals(to1bitBin(res4Bit == 0), am2901.getZero(), desc + "F=0");\r
+ assertEquals(to1bitBin(res4Bit & 0b1000), am2901.getSign(), desc + "F3");\r
+ assertEquals(to1bitBin(res32Bit & 0b1_0000), am2901.getCarryOut(), desc + "Cn+4");\r
+ assertEquals(to1bitBin(res4Bit_sgn != res32Bit_sgn), am2901.getOverflow(), desc + "OVR");\r
+ }));\r
+ }\r
+\r
+ @Order(4)\r
+ @Test\r
+ void testAND()\r
+ {\r
+ am2901.setSrc(DA);\r
+ am2901.setFunc(AND);\r
+ am2901.setDest(NOP);\r
+ am2901.setReg_A(r0.toBitString());\r
+\r
+ assertAll(getAll4BitPairs().map(xy -> () ->\r
+ {\r
+ am2901.setDirectly(r0, to4bitBin(xy.x));\r
+ am2901.setD(to4bitBin(xy.y));\r
+\r
+ am2901.assertFullCycleSuccess();\r
+\r
+ int res32Bit = xy.x & xy.y;\r
+\r
+ String desc = xy.x + " & " + xy.y + " = " + res32Bit + ": ";\r
+\r
+ assertEquals(to4bitBin(res32Bit), am2901.getY(), desc + "Y");\r
+ assertEquals(to1bitBin(res32Bit == 0), am2901.getZero(), desc + "F=0");\r
+ assertEquals(to1bitBin(res32Bit & 0b1000), am2901.getSign(), desc + "F3");\r
+// assertEquals(to1bitBin(res32Bit), am2901.getCarryOut(), desc + "Cn+4"); // TODO\r
+// assertEquals(to1bitBin(res32Bit), am2901.getOverflow(), desc + "OVR"); // TODO\r
+ }));\r
+ }\r
+\r
+ @Order(4)\r
+ @Test\r
+ void testOR()\r
+ {\r
+ am2901.setSrc(DA);\r
+ am2901.setFunc(OR);\r
+ am2901.setDest(NOP);\r
+ am2901.setReg_A(r0.toBitString());\r
+\r
+ assertAll(getAll4BitPairs().map(xy -> () ->\r
+ {\r
+ am2901.setDirectly(r0, to4bitBin(xy.x));\r
+ am2901.setD(to4bitBin(xy.y));\r
+\r
+ am2901.assertFullCycleSuccess();\r
+\r
+ int res32Bit = xy.x | xy.y;\r
+\r
+ String desc = xy.x + " | " + xy.y + " = " + res32Bit + ": ";\r
+\r
+ assertEquals(to4bitBin(res32Bit), am2901.getY(), desc + "Y");\r
+ assertEquals(to1bitBin(res32Bit == 0), am2901.getZero(), desc + "F=0");\r
+ assertEquals(to1bitBin(res32Bit & 0b1000), am2901.getSign(), desc + "F3");\r
+// assertEquals(to1bitBin(res32Bit != 0b1111), am2901.getCarryOut(), desc + "Cn+4"); // TODO\r
+// assertEquals(to1bitBin(res32Bit != 0b1111), am2901.getOverflow(), desc + "OVR"); // TODO\r
+ }));\r
+ }\r
+\r
+ @Order(4)\r
+ @Test\r
+ void testXOR()\r
+ {\r
+ am2901.setSrc(DA);\r
+ am2901.setFunc(EXOR);\r
+ am2901.setDest(NOP);\r
+ am2901.setReg_A(r0.toBitString());\r
+\r
+ assertAll(getAll4BitPairs().map(xy -> () ->\r
+ {\r
+ am2901.setDirectly(r0, to4bitBin(xy.x));\r
+ am2901.setD(to4bitBin(xy.y));\r
+\r
+ am2901.assertFullCycleSuccess();\r
+\r
+ int res32Bit = xy.x ^ xy.y;\r
+\r
+ String desc = xy.x + " ^ " + xy.y + " = " + res32Bit + ": ";\r
+\r
+ assertEquals(to4bitBin(res32Bit), am2901.getY(), desc + "Y");\r
+ assertEquals(to1bitBin(res32Bit == 0), am2901.getZero(), desc + "F=0");\r
+ assertEquals(to1bitBin(res32Bit & 0b1000), am2901.getSign(), desc + "F3");\r
+// assertEquals(to1bitBin(res32Bit != 0b1111), am2901.getCarryOut(), desc + "Cn+4"); // TODO\r
+// assertEquals(to1bitBin(res32Bit != 0b1111), am2901.getOverflow(), desc + "OVR"); // TODO\r
+ }));\r
+ }\r
+\r
+ @Order(4)\r
+ @Test\r
+ void testSUB()\r
+ {\r
+ am2901.setSrc(DA);\r
+ am2901.setCarryIn("1");\r
+ am2901.setFunc(SUBR);\r
+ am2901.setDest(NOP);\r
+ am2901.setReg_A(r0.toBitString());\r
+\r
+ assertAll(getAll4BitPairs().map(xy -> () ->\r
+ {\r
+ am2901.setDirectly(r0, to4bitBin(xy.x));\r
+ am2901.setD(to4bitBin(xy.y));\r
+\r
+ am2901.assertFullCycleSuccess();\r
+\r
+ int res32Bit = xy.x - xy.y;\r
+ int res4Bit = res32Bit & 0b1111;\r
+ int res32Bit_sgn = signed4ToSigned32(xy.x) - signed4ToSigned32(xy.y);\r
+ int res4Bit_sgn = signed4ToSigned32(res32Bit_sgn);\r
+\r
+ String desc = xy.x + " - " + xy.y + " = " + res4Bit + ": ";\r
+\r
+ assertEquals(to4bitBin(res4Bit & 0b1111), am2901.getY(), desc + "Y");\r
+ assertEquals(to1bitBin(res4Bit == 0), am2901.getZero(), desc + "F=0");\r
+ assertEquals(to1bitBin(res4Bit & 0b1000), am2901.getSign(), desc + "F3");\r
+ assertEquals(to1bitBin(xy.x >= xy.y), am2901.getCarryOut(), desc + "Cn+4");\r
+ assertEquals(to1bitBin(res4Bit_sgn != res32Bit_sgn), am2901.getOverflow(), desc + "OVR");\r
+ }));\r
+ }\r
+\r
+ static Stream<Point> getAll4BitPairs()\r
+ {\r
+ return IntStream.range(0, 16).boxed().flatMap(x -> IntStream.range(0, 16).mapToObj(y -> new Point(x, y)));\r
}\r
}\r
--- /dev/null
+package net.mograsim.logic.ui.am2900;
+
+import net.mograsim.logic.ui.SimpleLogicUIStandalone;
+import net.mograsim.logic.ui.model.ViewModelModifiable;
+import net.mograsim.logic.ui.model.components.GUIAndGate;
+import net.mograsim.logic.ui.model.components.GUIBitDisplay;
+import net.mograsim.logic.ui.model.components.GUIManualSwitch;
+import net.mograsim.logic.ui.model.components.GUINotGate;
+import net.mograsim.logic.ui.model.components.SimpleRectangularSubmodelComponent;
+import net.mograsim.logic.ui.model.components.TextComponent;
+import net.mograsim.logic.ui.model.components.mi.nandbased.GUIdff;
+import net.mograsim.logic.ui.model.components.mi.nandbased.am2901.GUIAm2901;
+import net.mograsim.logic.ui.model.wires.ConnectionPoint;
+import net.mograsim.logic.ui.model.wires.WireCrossPoint;
+import net.mograsim.logic.ui.util.ModellingTool;
+
+public class Am2901Testbench
+{
+ public static void main(String[] args)
+ {
+ SimpleLogicUIStandalone.executeVisualisation(Am2901Testbench::createTestbench);
+ }
+
+ public static void createTestbench(ViewModelModifiable model)
+ {
+ SimpleRectangularSubmodelComponent comp = new GUIAm2901(model);
+ ModellingTool tool = ModellingTool.createFor(model);
+
+ comp.moveTo(240, 0);
+
+ GUIManualSwitch enable = new GUIManualSwitch(model);
+ WireCrossPoint wcp0 = new WireCrossPoint(model, 1);
+ GUINotGate not1 = new GUINotGate(model, 1);
+ GUINotGate not2 = new GUINotGate(model, 1);
+ GUINotGate not3 = new GUINotGate(model, 1);
+ GUIAndGate and = new GUIAndGate(model, 1);
+ tool.connect(wcp0, enable, "");
+ tool.connect(wcp0, and, "A");
+ tool.connect(wcp0, not1, "A");
+ tool.connect(not1, not2, "Y", "A");
+ tool.connect(not2, not3, "Y", "A");
+ tool.connect(not3, and, "Y", "B");
+ enable.moveTo(20, -32.5);
+ wcp0.moveTo(35, -26);
+ not1.moveTo(50, -20);
+ not2.moveTo(80, -20);
+ not3.moveTo(110, -20);
+ and.moveTo(135, -30);
+ ConnectionPoint last = and.getPin("Y");
+
+ for (int i = 0; i < comp.getInputPinNames().size(); i++)
+ {
+ double x = 55 + 70 * (i % 2);
+ double y = 10 * i;
+
+ WireCrossPoint wcp = new WireCrossPoint(model, 1);
+ GUIdff d_ff = new GUIdff(model);
+ GUIManualSwitch sw = new GUIManualSwitch(model);
+
+ tool.connect(last, wcp);
+ tool.connect(wcp, d_ff, "C");
+ tool.connect(sw, d_ff, "", "D");
+ tool.connect(d_ff, comp, "Q", comp.getInputPinNames().get(i));
+ last = wcp.getPin();
+
+ TextComponent label = new TextComponent(model, comp.getInputPinNames().get(i));
+
+ sw.moveTo(x, y + 7.5);
+ wcp.moveTo(160, y);
+ d_ff.moveTo(170, y);
+ label.moveTo(x - 25, y + 15);
+ }
+
+ for (int i = 0; i < comp.getOutputPinNames().size(); i++)
+ {
+ double x = 300 + 75 * (i % 2);
+ double y = 10 * i - 2.5;
+ GUIBitDisplay bd = new GUIBitDisplay(model);
+ bd.moveTo(x, y);
+ tool.connect(bd.getInputPin(), comp, comp.getOutputPinNames().get(i));
+
+ TextComponent label = new TextComponent(model, comp.getOutputPinNames().get(i));
+ label.moveTo(x + 50, y + 8);
+ }
+ }
+}
\ No newline at end of file