Mention contrib/test_failfast in test README
[gram.git] / gram / test / test_soc.py
index e4b1c6e8b40790b860536971f84643da96793426..fae835cf5ebfedbf4ac54dff15c41fb28fe9809f 100644 (file)
@@ -1,5 +1,7 @@
 # This file is Copyright (c) 2020 LambdaConcept <contact@lambdaconcept.com>
 
+import random
+
 from nmigen import *
 from nmigen.asserts import Assert, Assume
 from nmigen_soc import wishbone, memory
@@ -20,13 +22,10 @@ from utils import *
 class DDR3SoC(SoC, Elaboratable):
     def __init__(self, *, clk_freq, dramcore_addr,
                  ddr_addr):
-        self._arbiter = wishbone.Arbiter(addr_width=30, data_width=32, granularity=8,
-                                         features={"cti", "bte"})
         self._decoder = wishbone.Decoder(addr_width=30, data_width=32, granularity=8,
                                          features={"cti", "bte"})
 
         self.bus = wishbone.Interface(addr_width=30, data_width=32, granularity=32)
-        self._arbiter.add(self.bus)
 
         tck = 2/(2*2*100e6)
         nphases = 2
@@ -56,7 +55,7 @@ class DDR3SoC(SoC, Elaboratable):
             write_latency=cwl_sys_latency
         )
 
-        ddrmodule = MT41K256M16(clk_freq, "1:4")
+        ddrmodule = MT41K256M16(clk_freq, "1:2")
         self.ddrphy = FakePHY(module=ddrmodule,
             settings=physettings,
             verbosity=SDRAM_VERBOSE_DBG)
@@ -78,75 +77,70 @@ class DDR3SoC(SoC, Elaboratable):
     def elaborate(self, platform):
         m = Module()
 
-        m.submodules.arbiter = self._arbiter
-
         m.submodules.decoder = self._decoder
         m.submodules.ddrphy = self.ddrphy
         m.submodules.dramcore = self.dramcore
         m.submodules.drambone = self.drambone
 
         m.d.comb += [
-            self._arbiter.bus.connect(self._decoder.bus),
+            self.bus.connect(self._decoder.bus),
         ]
 
         return m
 
 class SocTestCase(FHDLTestCase):
-    def test_soc(self):
-        m = Module()
+    def init_seq(bus):
+        yield from wb_write(bus, 0x0, 0xE, 0xF) # DFII_CONTROL_ODT|DFII_CONTROL_RESET_N|DFI_CONTROL_CKE
+        yield from wb_write(bus, 0xC >> 2, 0x0, 0xF)
+        yield from wb_write(bus, 0x10 >> 2, 0x0, 0xF)
+        yield from wb_write(bus, 0x0, 0xC, 0xF)
+        yield from wb_write(bus, 0x0, 0xE, 0xF)
+
+        # MR2
+        yield from wb_write(bus, 0xC >> 2, 0x200, 0xF)
+        yield from wb_write(bus, 0x10 >> 2, 0x2, 0xF)
+        yield from wb_write(bus, 0x4 >> 2, 0xF, 0xF)
+        yield from wb_write(bus, 0x8 >> 2, 0x1, 0xF)
+
+        # MR3
+        yield from wb_write(bus, 0xC >> 2, 0x0, 0xF)
+        yield from wb_write(bus, 0x10 >> 2, 0x3, 0xF)
+        yield from wb_write(bus, 0x4 >> 2, 0xF, 0xF)
+        yield from wb_write(bus, 0x8 >> 2, 0x1, 0xF)
+
+        # MR1
+        yield from wb_write(bus, 0xC >> 2, 0x6, 0xF)
+        yield from wb_write(bus, 0x10 >> 2, 0x1, 0xF)
+        yield from wb_write(bus, 0x4 >> 2, 0xF, 0xF)
+        yield from wb_write(bus, 0x8 >> 2, 0x1, 0xF)
+
+        # MR0
+        yield from wb_write(bus, 0xC >> 2, 0x320, 0xF)
+        yield from wb_write(bus, 0x10 >> 2, 0x0, 0xF)
+        yield from wb_write(bus, 0x4 >> 2, 0xF, 0xF)
+        yield from wb_write(bus, 0x8 >> 2, 0x1, 0xF)
+        for i in range(200):
+            yield
+
+        # ZQ
+        yield from wb_write(bus, 0xC >> 2, 0x400, 0xF)
+        yield from wb_write(bus, 0x10 >> 2, 0x0, 0xF)
+        yield from wb_write(bus, 0x4 >> 2, 0x3, 0xF)
+        yield from wb_write(bus, 0x8 >> 2, 0x1, 0xF)
+        for i in range(200):
+            yield
+
+        yield from wb_write(bus, 0, 0x1, 0xF)
+        for i in range(2000):
+            yield
+
+    def test_multiple_reads(self):
         soc = DDR3SoC(clk_freq=100e6,
             dramcore_addr=0x00000000,
             ddr_addr=0x10000000)
-        m.submodules += soc
 
         def process():
-            yield from wb_write(soc.bus, 0x0, 0xE, 0xF) # DFII_CONTROL_ODT|DFII_CONTROL_RESET_N|DFI_CONTROL_CKE
-            yield from wb_write(soc.bus, 0xC >> 2, 0x0, 0xF)
-            yield from wb_write(soc.bus, 0x10 >> 2, 0x0, 0xF)
-            yield from wb_write(soc.bus, 0x0, 0xC, 0xF)
-
-            yield from wb_write(soc.bus, 0x0, 0xE, 0xF)
-
-            # MR2
-            yield from wb_write(soc.bus, 0xC >> 2, 0x200, 0xF)
-            yield from wb_write(soc.bus, 0x10 >> 2, 0x2, 0xF)
-            yield from wb_write(soc.bus, 0x4 >> 2, 0xF, 0xF)
-            yield from wb_write(soc.bus, 0x8 >> 2, 0x1, 0xF)
-
-            # MR3
-            yield from wb_write(soc.bus, 0xC >> 2, 0x0, 0xF)
-            yield from wb_write(soc.bus, 0x10 >> 2, 0x3, 0xF)
-            yield from wb_write(soc.bus, 0x4 >> 2, 0xF, 0xF)
-            yield from wb_write(soc.bus, 0x8 >> 2, 0x1, 0xF)
-
-            # MR1
-            yield from wb_write(soc.bus, 0xC >> 2, 0x6, 0xF)
-            yield from wb_write(soc.bus, 0x10 >> 2, 0x1, 0xF)
-            yield from wb_write(soc.bus, 0x4 >> 2, 0xF, 0xF)
-            yield from wb_write(soc.bus, 0x8 >> 2, 0x1, 0xF)
-
-            # MR0
-            yield from wb_write(soc.bus, 0xC >> 2, 0x320, 0xF)
-            yield from wb_write(soc.bus, 0x10 >> 2, 0x0, 0xF)
-            yield from wb_write(soc.bus, 0x4 >> 2, 0xF, 0xF)
-            yield from wb_write(soc.bus, 0x8 >> 2, 0x1, 0xF)
-
-            for i in range(200):
-                yield
-
-            # ZQ
-            yield from wb_write(soc.bus, 0xC >> 2, 0x400, 0xF)
-            yield from wb_write(soc.bus, 0x10 >> 2, 0x0, 0xF)
-            yield from wb_write(soc.bus, 0x4 >> 2, 0x3, 0xF)
-            yield from wb_write(soc.bus, 0x8 >> 2, 0x1, 0xF)
-
-            for i in range(200):
-                yield
-
-            yield from wb_write(soc.bus, 0, 0x1, 0xF)
-
-            for i in range(2000):
-                yield
+            yield from SocTestCase.init_seq(soc.bus)
 
             yield from wb_write(soc.bus, 0x10000000 >> 2, 0xACAB2020, 0xF, 128)
             yield
@@ -154,7 +148,76 @@ class SocTestCase(FHDLTestCase):
             # Check for data persistence
             for i in range(10):
                 res = yield from wb_read(soc.bus, 0x10000000 >> 2, 0xF, 128)
+                yield
                 self.assertEqual(res, 0xACAB2020)
-            
 
-        runSimulation(m, process, "test_soc.vcd")
+        runSimulation(soc, process, "test_soc_multiple_reads.vcd")
+
+    def test_interleaved_read_write(self):
+        soc = DDR3SoC(clk_freq=100e6,
+            dramcore_addr=0x00000000,
+            ddr_addr=0x10000000)
+
+        def process():
+            yield from SocTestCase.init_seq(soc.bus)
+
+            yield from wb_write(soc.bus, 0x10000000 >> 2, 0xF00DFACE, 0xF, 128)
+            yield from wb_write(soc.bus, 0x10000004 >> 2, 0x12345678, 0xF, 128)
+            yield from wb_write(soc.bus, 0x10000008 >> 2, 0x00BA0BAB, 0xF, 128)
+
+            res = yield from wb_read(soc.bus, 0x10000000 >> 2, 0xF, 128)
+            self.assertEqual(res, 0xF00DFACE)
+
+            yield from wb_write(soc.bus, 0x10000008 >> 2, 0xCAFE1000, 0xF, 128)
+
+            res = yield from wb_read(soc.bus, 0x10000004 >> 2, 0xF, 128)
+            self.assertEqual(res, 0x12345678)
+
+            res = yield from wb_read(soc.bus, 0x10000008 >> 2, 0xF, 128)
+            self.assertEqual(res, 0xCAFE1000)
+
+        runSimulation(soc, process, "test_soc_interleaved_read_write.vcd")
+
+    def test_random_memtest(self):
+        soc = DDR3SoC(clk_freq=100e6,
+            dramcore_addr=0x00000000,
+            ddr_addr=0x10000000)
+
+        def process():
+            yield from SocTestCase.init_seq(soc.bus)
+
+            n = 64
+
+            memtest_values = []
+            for i in range(n):
+                memtest_values.append(random.randint(0, 0xFFFFFFFF))
+
+            # Write
+            for i in range(n):
+                yield from wb_write(soc.bus, (0x10000000 >> 2) + i, memtest_values[i], 0xF, 256)
+
+            # Read
+            for i in range(n):
+                self.assertEqual(memtest_values[i], (yield from wb_read(soc.bus, (0x10000000 >> 2) + i, 0xF, 256)))
+
+        runSimulation(soc, process, "test_soc_random_memtest.vcd")
+
+    def test_continuous_memtest(self):
+        soc = DDR3SoC(clk_freq=100e6,
+            dramcore_addr=0x00000000,
+            ddr_addr=0x10000000)
+
+        def process():
+            yield from SocTestCase.init_seq(soc.bus)
+
+            n = 128
+
+            # Write
+            for i in range(n):
+                yield from wb_write(soc.bus, (0x10000000 >> 2) + i, 0xFACE0000 | i, 0xF, 256)
+
+            # Read
+            for i in range(n):
+                self.assertEqual(0xFACE0000 | i, (yield from wb_read(soc.bus, (0x10000000 >> 2) + i, 0xF, 256)))
+
+        runSimulation(soc, process, "test_soc_continuous_memtest.vcd")