2a96b3d872b423fbebf3f23f68e366f7d87d14a2
[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 gram.test.utils import *
21
22 class DDR3SoC(SoC, Elaboratable):
23 def __init__(self, *, clk_freq, dramcore_addr,
24 ddr_addr):
25 self._decoder = wishbone.Decoder(addr_width=30, data_width=32, granularity=8,
26 features={"cti", "bte"})
27
28 self.bus = wishbone.Interface(addr_width=30, data_width=32, granularity=8)
29
30 tck = 2/(2*2*100e6)
31 nphases = 2
32 databits = 16
33 nranks = 1
34 addressbits = 14
35 bankbits = 3
36 cl, cwl = get_cl_cw("DDR3", tck)
37 cl_sys_latency = get_sys_latency(nphases, cl)
38 cwl_sys_latency = get_sys_latency(nphases, cwl)
39 rdcmdphase, rdphase = get_sys_phases(nphases, cl_sys_latency, cl)
40 wrcmdphase, wrphase = get_sys_phases(nphases, cwl_sys_latency, cwl)
41 physettings = PhySettings(
42 phytype="ECP5DDRPHY",
43 memtype="DDR3",
44 databits=databits,
45 dfi_databits=4*databits,
46 nranks=nranks,
47 nphases=nphases,
48 rdphase=rdphase,
49 wrphase=wrphase,
50 rdcmdphase=rdcmdphase,
51 wrcmdphase=wrcmdphase,
52 cl=cl,
53 cwl=cwl,
54 read_latency=2 + cl_sys_latency + 2 + log2_int(4//nphases) + 4,
55 write_latency=cwl_sys_latency
56 )
57
58 ddrmodule = MT41K256M16(clk_freq, "1:2")
59 self.ddrphy = FakePHY(module=ddrmodule,
60 settings=physettings,
61 verbosity=SDRAM_VERBOSE_DBG)
62
63 self.dramcore = gramCore(
64 phy=self.ddrphy,
65 geom_settings=ddrmodule.geom_settings,
66 timing_settings=ddrmodule.timing_settings,
67 clk_freq=clk_freq)
68 self._decoder.add(self.dramcore.bus, addr=dramcore_addr)
69
70 self.drambone = gramWishbone(self.dramcore)
71 self._decoder.add(self.drambone.bus, addr=ddr_addr)
72
73 self.memory_map = self._decoder.bus.memory_map
74
75 self.clk_freq = clk_freq
76
77 def elaborate(self, platform):
78 m = Module()
79
80 m.submodules.decoder = self._decoder
81 m.submodules.ddrphy = self.ddrphy
82 m.submodules.dramcore = self.dramcore
83 m.submodules.drambone = self.drambone
84
85 m.d.comb += [
86 self.bus.connect(self._decoder.bus),
87 ]
88
89 return m
90
91 class SocTestCase(FHDLTestCase):
92 def init_seq(bus):
93 yield from wb_write(bus, 0x0, 0xE, 0xF) # DFII_CONTROL_ODT|DFII_CONTROL_RESET_N|DFI_CONTROL_CKE
94 yield from wb_write(bus, 0xC >> 2, 0x0, 0xF)
95 yield from wb_write(bus, 0x10 >> 2, 0x0, 0xF)
96 yield from wb_write(bus, 0x0, 0xC, 0xF)
97 yield from wb_write(bus, 0x0, 0xE, 0xF)
98
99 # MR2
100 yield from wb_write(bus, 0xC >> 2, 0x200, 0xF)
101 yield from wb_write(bus, 0x10 >> 2, 0x2, 0xF)
102 yield from wb_write(bus, 0x4 >> 2, 0xF, 0xF)
103 yield from wb_write(bus, 0x8 >> 2, 0x1, 0xF)
104
105 # MR3
106 yield from wb_write(bus, 0xC >> 2, 0x0, 0xF)
107 yield from wb_write(bus, 0x10 >> 2, 0x3, 0xF)
108 yield from wb_write(bus, 0x4 >> 2, 0xF, 0xF)
109 yield from wb_write(bus, 0x8 >> 2, 0x1, 0xF)
110
111 # MR1
112 yield from wb_write(bus, 0xC >> 2, 0x6, 0xF)
113 yield from wb_write(bus, 0x10 >> 2, 0x1, 0xF)
114 yield from wb_write(bus, 0x4 >> 2, 0xF, 0xF)
115 yield from wb_write(bus, 0x8 >> 2, 0x1, 0xF)
116
117 # MR0
118 yield from wb_write(bus, 0xC >> 2, 0x320, 0xF)
119 yield from wb_write(bus, 0x10 >> 2, 0x0, 0xF)
120 yield from wb_write(bus, 0x4 >> 2, 0xF, 0xF)
121 yield from wb_write(bus, 0x8 >> 2, 0x1, 0xF)
122 for i in range(200):
123 yield
124
125 # ZQ
126 yield from wb_write(bus, 0xC >> 2, 0x400, 0xF)
127 yield from wb_write(bus, 0x10 >> 2, 0x0, 0xF)
128 yield from wb_write(bus, 0x4 >> 2, 0x3, 0xF)
129 yield from wb_write(bus, 0x8 >> 2, 0x1, 0xF)
130 for i in range(200):
131 yield
132
133 yield from wb_write(bus, 0, 0x1, 0xF)
134 for i in range(2000):
135 yield
136
137 def test_multiple_reads(self):
138 soc = DDR3SoC(clk_freq=100e6,
139 dramcore_addr=0x00000000,
140 ddr_addr=0x10000000)
141
142 def process():
143 yield from SocTestCase.init_seq(soc.bus)
144
145 yield from wb_write(soc.bus, 0x10000000 >> 2, 0xACAB2020, 0xF, 128)
146 yield
147
148 # Check for data persistence
149 for i in range(10):
150 res = yield from wb_read(soc.bus, 0x10000000 >> 2, 0xF, 128)
151 yield
152 self.assertEqual(res, 0xACAB2020)
153
154 runSimulation(soc, process, "test_soc_multiple_reads.vcd")
155
156 def test_interleaved_read_write(self):
157 soc = DDR3SoC(clk_freq=100e6,
158 dramcore_addr=0x00000000,
159 ddr_addr=0x10000000)
160
161 def process():
162 yield from SocTestCase.init_seq(soc.bus)
163
164 yield from wb_write(soc.bus, 0x10000000 >> 2, 0xF00DFACE, 0xF, 128)
165 yield from wb_write(soc.bus, 0x10000004 >> 2, 0x12345678, 0xF, 128)
166 yield from wb_write(soc.bus, 0x10000008 >> 2, 0x00BA0BAB, 0xF, 128)
167
168 res = yield from wb_read(soc.bus, 0x10000000 >> 2, 0xF, 128)
169 self.assertEqual(res, 0xF00DFACE)
170
171 yield from wb_write(soc.bus, 0x10000008 >> 2, 0xCAFE1000, 0xF, 128)
172
173 res = yield from wb_read(soc.bus, 0x10000004 >> 2, 0xF, 128)
174 self.assertEqual(res, 0x12345678)
175
176 res = yield from wb_read(soc.bus, 0x10000008 >> 2, 0xF, 128)
177 self.assertEqual(res, 0xCAFE1000)
178
179 runSimulation(soc, process, "test_soc_interleaved_read_write.vcd")
180
181 def test_random_memtest(self):
182 soc = DDR3SoC(clk_freq=100e6,
183 dramcore_addr=0x00000000,
184 ddr_addr=0x10000000)
185
186 def process():
187 yield from SocTestCase.init_seq(soc.bus)
188
189 n = 64
190
191 memtest_values = []
192 for i in range(n):
193 memtest_values.append(random.randint(0, 0xFFFFFFFF))
194
195 # Write
196 for i in range(n):
197 yield from wb_write(soc.bus, (0x10000000 >> 2) + i, memtest_values[i], 0xF, 256)
198
199 # Read
200 for i in range(n):
201 self.assertEqual(memtest_values[i], (yield from wb_read(soc.bus, (0x10000000 >> 2) + i, 0xF, 256)))
202
203 runSimulation(soc, process, "test_soc_random_memtest.vcd")
204
205 def test_continuous_memtest(self):
206 soc = DDR3SoC(clk_freq=100e6,
207 dramcore_addr=0x00000000,
208 ddr_addr=0x10000000)
209
210 def process():
211 yield from SocTestCase.init_seq(soc.bus)
212
213 n = 128
214
215 # Write
216 for i in range(n):
217 yield from wb_write(soc.bus, (0x10000000 >> 2) + i, 0xFACE0000 | i, 0xF, 256)
218
219 # Read
220 for i in range(n):
221 self.assertEqual(0xFACE0000 | i, (yield from wb_read(soc.bus, (0x10000000 >> 2) + i, 0xF, 256)))
222
223 runSimulation(soc, process, "test_soc_continuous_memtest.vcd")