Fix memtest tests (missing parenthesis)
[gram.git] / gram / test / test_soc.py
1 # This file is Copyright (c) 2020 LambdaConcept <contact@lambdaconcept.com>
2
3 import random
4
5 from nmigen import *
6 from nmigen.asserts import Assert, Assume
7 from nmigen_soc import wishbone, memory
8 from nmigen.lib.cdc import ResetSynchronizer
9
10 from lambdasoc.periph import Peripheral
11 from lambdasoc.soc.base import SoC
12
13 from gram.common import *
14 from gram.core import gramCore
15 from gram.phy.fakephy import FakePHY, SDRAM_VERBOSE_STD, SDRAM_VERBOSE_DBG
16 from gram.modules import MT41K256M16
17 from gram.frontend.wishbone import gramWishbone
18
19 from gram.core.multiplexer import _AntiStarvation
20 from utils import *
21
22 class DDR3SoC(SoC, Elaboratable):
23 def __init__(self, *, clk_freq, dramcore_addr,
24 ddr_addr):
25 self._arbiter = wishbone.Arbiter(addr_width=30, data_width=32, granularity=8,
26 features={"cti", "bte"})
27 self._decoder = wishbone.Decoder(addr_width=30, data_width=32, granularity=8,
28 features={"cti", "bte"})
29
30 self.bus = wishbone.Interface(addr_width=30, data_width=32, granularity=32)
31 self._arbiter.add(self.bus)
32
33 tck = 2/(2*2*100e6)
34 nphases = 2
35 databits = 16
36 nranks = 1
37 addressbits = 14
38 bankbits = 3
39 cl, cwl = get_cl_cw("DDR3", tck)
40 cl_sys_latency = get_sys_latency(nphases, cl)
41 cwl_sys_latency = get_sys_latency(nphases, cwl)
42 rdcmdphase, rdphase = get_sys_phases(nphases, cl_sys_latency, cl)
43 wrcmdphase, wrphase = get_sys_phases(nphases, cwl_sys_latency, cwl)
44 physettings = PhySettings(
45 phytype="ECP5DDRPHY",
46 memtype="DDR3",
47 databits=databits,
48 dfi_databits=4*databits,
49 nranks=nranks,
50 nphases=nphases,
51 rdphase=rdphase,
52 wrphase=wrphase,
53 rdcmdphase=rdcmdphase,
54 wrcmdphase=wrcmdphase,
55 cl=cl,
56 cwl=cwl,
57 read_latency=2 + cl_sys_latency + 2 + log2_int(4//nphases) + 4,
58 write_latency=cwl_sys_latency
59 )
60
61 ddrmodule = MT41K256M16(clk_freq, "1:4")
62 self.ddrphy = FakePHY(module=ddrmodule,
63 settings=physettings,
64 verbosity=SDRAM_VERBOSE_DBG)
65
66 self.dramcore = gramCore(
67 phy=self.ddrphy,
68 geom_settings=ddrmodule.geom_settings,
69 timing_settings=ddrmodule.timing_settings,
70 clk_freq=clk_freq)
71 self._decoder.add(self.dramcore.bus, addr=dramcore_addr)
72
73 self.drambone = gramWishbone(self.dramcore)
74 self._decoder.add(self.drambone.bus, addr=ddr_addr)
75
76 self.memory_map = self._decoder.bus.memory_map
77
78 self.clk_freq = clk_freq
79
80 def elaborate(self, platform):
81 m = Module()
82
83 m.submodules.arbiter = self._arbiter
84
85 m.submodules.decoder = self._decoder
86 m.submodules.ddrphy = self.ddrphy
87 m.submodules.dramcore = self.dramcore
88 m.submodules.drambone = self.drambone
89
90 m.d.comb += [
91 self._arbiter.bus.connect(self._decoder.bus),
92 ]
93
94 return m
95
96 class SocTestCase(FHDLTestCase):
97 def init_seq(bus):
98 yield from wb_write(bus, 0x0, 0xE, 0xF) # DFII_CONTROL_ODT|DFII_CONTROL_RESET_N|DFI_CONTROL_CKE
99 yield from wb_write(bus, 0xC >> 2, 0x0, 0xF)
100 yield from wb_write(bus, 0x10 >> 2, 0x0, 0xF)
101 yield from wb_write(bus, 0x0, 0xC, 0xF)
102 yield from wb_write(bus, 0x0, 0xE, 0xF)
103
104 # MR2
105 yield from wb_write(bus, 0xC >> 2, 0x200, 0xF)
106 yield from wb_write(bus, 0x10 >> 2, 0x2, 0xF)
107 yield from wb_write(bus, 0x4 >> 2, 0xF, 0xF)
108 yield from wb_write(bus, 0x8 >> 2, 0x1, 0xF)
109
110 # MR3
111 yield from wb_write(bus, 0xC >> 2, 0x0, 0xF)
112 yield from wb_write(bus, 0x10 >> 2, 0x3, 0xF)
113 yield from wb_write(bus, 0x4 >> 2, 0xF, 0xF)
114 yield from wb_write(bus, 0x8 >> 2, 0x1, 0xF)
115
116 # MR1
117 yield from wb_write(bus, 0xC >> 2, 0x6, 0xF)
118 yield from wb_write(bus, 0x10 >> 2, 0x1, 0xF)
119 yield from wb_write(bus, 0x4 >> 2, 0xF, 0xF)
120 yield from wb_write(bus, 0x8 >> 2, 0x1, 0xF)
121
122 # MR0
123 yield from wb_write(bus, 0xC >> 2, 0x320, 0xF)
124 yield from wb_write(bus, 0x10 >> 2, 0x0, 0xF)
125 yield from wb_write(bus, 0x4 >> 2, 0xF, 0xF)
126 yield from wb_write(bus, 0x8 >> 2, 0x1, 0xF)
127 for i in range(200):
128 yield
129
130 # ZQ
131 yield from wb_write(bus, 0xC >> 2, 0x400, 0xF)
132 yield from wb_write(bus, 0x10 >> 2, 0x0, 0xF)
133 yield from wb_write(bus, 0x4 >> 2, 0x3, 0xF)
134 yield from wb_write(bus, 0x8 >> 2, 0x1, 0xF)
135 for i in range(200):
136 yield
137
138 yield from wb_write(bus, 0, 0x1, 0xF)
139 for i in range(2000):
140 yield
141
142 def test_multiple_reads(self):
143 m = Module()
144 soc = DDR3SoC(clk_freq=100e6,
145 dramcore_addr=0x00000000,
146 ddr_addr=0x10000000)
147 m.submodules += soc
148
149 def process():
150 yield from SocTestCase.init_seq(soc.bus)
151
152 yield from wb_write(soc.bus, 0x10000000 >> 2, 0xACAB2020, 0xF, 128)
153 yield
154
155 # Check for data persistence
156 for i in range(10):
157 res = yield from wb_read(soc.bus, 0x10000000 >> 2, 0xF, 128)
158 yield
159 self.assertEqual(res, 0xACAB2020)
160
161 runSimulation(m, process, "test_soc_multiple_reads.vcd")
162
163 def test_interleaved_read_write(self):
164 m = Module()
165 soc = DDR3SoC(clk_freq=100e6,
166 dramcore_addr=0x00000000,
167 ddr_addr=0x10000000)
168 m.submodules += soc
169
170 def process():
171 yield from SocTestCase.init_seq(soc.bus)
172
173 yield from wb_write(soc.bus, 0x10000000 >> 2, 0xF00DFACE, 0xF, 128)
174 yield from wb_write(soc.bus, 0x10000004 >> 2, 0x12345678, 0xF, 128)
175 yield from wb_write(soc.bus, 0x10000008 >> 2, 0x00BA0BAB, 0xF, 128)
176
177 res = yield from wb_read(soc.bus, 0x10000000 >> 2, 0xF, 128)
178 self.assertEqual(res, 0xF00DFACE)
179
180 yield from wb_write(soc.bus, 0x10000008 >> 2, 0xCAFE1000, 0xF, 128)
181
182 res = yield from wb_read(soc.bus, 0x10000004 >> 2, 0xF, 128)
183 self.assertEqual(res, 0x12345678)
184
185 res = yield from wb_read(soc.bus, 0x10000008 >> 2, 0xF, 128)
186 self.assertEqual(res, 0xCAFE1000)
187
188 runSimulation(m, process, "test_soc_interleaved_read_write.vcd")
189
190 def test_sequential_reads(self):
191 m = Module()
192 soc = DDR3SoC(clk_freq=100e6,
193 dramcore_addr=0x00000000,
194 ddr_addr=0x10000000)
195 m.submodules += soc
196
197 def process():
198 yield from SocTestCase.init_seq(soc.bus)
199
200 # Should read from same row/col/bank
201 yield from wb_read(soc.bus, 0x10000000 >> 2, 0xF, 128)
202 yield from wb_read(soc.bus, 0x10000004 >> 2, 0xF, 128)
203 yield from wb_read(soc.bus, 0x10000008 >> 2, 0xF, 128)
204 yield from wb_read(soc.bus, 0x1000000C >> 2, 0xF, 128)
205
206 # Should read from a different row
207 yield from wb_read(soc.bus, 0x10000010 >> 2, 0xF, 128)
208 yield from wb_read(soc.bus, 0x10000014 >> 2, 0xF, 128)
209 yield from wb_read(soc.bus, 0x10000018 >> 2, 0xF, 128)
210 yield from wb_read(soc.bus, 0x1000001C >> 2, 0xF, 128)
211
212 runSimulation(m, process, "test_soc_sequential_reads.vcd")
213
214 def test_random_memtest(self):
215 m = Module()
216 soc = DDR3SoC(clk_freq=100e6,
217 dramcore_addr=0x00000000,
218 ddr_addr=0x10000000)
219 m.submodules += soc
220
221 def process():
222 yield from SocTestCase.init_seq(soc.bus)
223
224 n = 100
225
226 memtest_values = []
227 for i in range(n):
228 memtest_values.append(random.randint(0, 0xFFFFFFFF))
229
230 # Write
231 for i in range(n):
232 yield from wb_write(soc.bus, (0x10000000 >> 2) + i, memtest_values[i], 0xF, 256)
233
234 # Read
235 for i in range(n):
236 self.assertEqual(memtest_values[i], (yield from wb_read(soc.bus, (0x10000000 >> 2) + i, 0xF, 256)))
237
238 runSimulation(m, process, "test_soc_random_memtest.vcd")
239
240 def test_continuous_memtest(self):
241 m = Module()
242 soc = DDR3SoC(clk_freq=100e6,
243 dramcore_addr=0x00000000,
244 ddr_addr=0x10000000)
245 m.submodules += soc
246
247 def process():
248 yield from SocTestCase.init_seq(soc.bus)
249
250 n = 100
251
252 # Write
253 for i in range(n):
254 yield from wb_write(soc.bus, (0x10000000 >> 2) + i, 0xFACE0000 | i, 0xF, 256)
255
256 # Read
257 for i in range(n):
258 self.assertEqual(0xFACE0000 | i, (yield from wb_read(soc.bus, (0x10000000 >> 2) + i, 0xF, 256)))
259
260 runSimulation(m, process, "test_soc_continuous_memtest.vcd")