Rename VCD file output
[gram.git] / gram / test / test_soc.py
1 # This file is Copyright (c) 2020 LambdaConcept <contact@lambdaconcept.com>
2
3 from nmigen import *
4 from nmigen.asserts import Assert, Assume
5 from nmigen_soc import wishbone, memory
6 from nmigen.lib.cdc import ResetSynchronizer
7
8 from lambdasoc.periph import Peripheral
9 from lambdasoc.soc.base import SoC
10
11 from gram.common import *
12 from gram.core import gramCore
13 from gram.phy.fakephy import FakePHY, SDRAM_VERBOSE_STD, SDRAM_VERBOSE_DBG
14 from gram.modules import MT41K256M16
15 from gram.frontend.wishbone import gramWishbone
16
17 from gram.core.multiplexer import _AntiStarvation
18 from utils import *
19
20 class DDR3SoC(SoC, Elaboratable):
21 def __init__(self, *, clk_freq, dramcore_addr,
22 ddr_addr):
23 self._arbiter = wishbone.Arbiter(addr_width=30, data_width=32, granularity=8,
24 features={"cti", "bte"})
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=32)
29 self._arbiter.add(self.bus)
30
31 tck = 2/(2*2*100e6)
32 nphases = 2
33 databits = 16
34 nranks = 1
35 addressbits = 14
36 bankbits = 3
37 cl, cwl = get_cl_cw("DDR3", tck)
38 cl_sys_latency = get_sys_latency(nphases, cl)
39 cwl_sys_latency = get_sys_latency(nphases, cwl)
40 rdcmdphase, rdphase = get_sys_phases(nphases, cl_sys_latency, cl)
41 wrcmdphase, wrphase = get_sys_phases(nphases, cwl_sys_latency, cwl)
42 physettings = PhySettings(
43 phytype="ECP5DDRPHY",
44 memtype="DDR3",
45 databits=databits,
46 dfi_databits=4*databits,
47 nranks=nranks,
48 nphases=nphases,
49 rdphase=rdphase,
50 wrphase=wrphase,
51 rdcmdphase=rdcmdphase,
52 wrcmdphase=wrcmdphase,
53 cl=cl,
54 cwl=cwl,
55 read_latency=2 + cl_sys_latency + 2 + log2_int(4//nphases) + 4,
56 write_latency=cwl_sys_latency
57 )
58
59 ddrmodule = MT41K256M16(clk_freq, "1:4")
60 self.ddrphy = FakePHY(module=ddrmodule,
61 settings=physettings,
62 verbosity=SDRAM_VERBOSE_DBG)
63
64 self.dramcore = gramCore(
65 phy=self.ddrphy,
66 geom_settings=ddrmodule.geom_settings,
67 timing_settings=ddrmodule.timing_settings,
68 clk_freq=clk_freq)
69 self._decoder.add(self.dramcore.bus, addr=dramcore_addr)
70
71 self.drambone = gramWishbone(self.dramcore)
72 self._decoder.add(self.drambone.bus, addr=ddr_addr)
73
74 self.memory_map = self._decoder.bus.memory_map
75
76 self.clk_freq = clk_freq
77
78 def elaborate(self, platform):
79 m = Module()
80
81 m.submodules.arbiter = self._arbiter
82
83 m.submodules.decoder = self._decoder
84 m.submodules.ddrphy = self.ddrphy
85 m.submodules.dramcore = self.dramcore
86 m.submodules.drambone = self.drambone
87
88 m.d.comb += [
89 self._arbiter.bus.connect(self._decoder.bus),
90 ]
91
92 return m
93
94 class SocTestCase(FHDLTestCase):
95 def init_seq(bus):
96 yield from wb_write(bus, 0x0, 0xE, 0xF) # DFII_CONTROL_ODT|DFII_CONTROL_RESET_N|DFI_CONTROL_CKE
97 yield from wb_write(bus, 0xC >> 2, 0x0, 0xF)
98 yield from wb_write(bus, 0x10 >> 2, 0x0, 0xF)
99 yield from wb_write(bus, 0x0, 0xC, 0xF)
100 yield from wb_write(bus, 0x0, 0xE, 0xF)
101
102 # MR2
103 yield from wb_write(bus, 0xC >> 2, 0x200, 0xF)
104 yield from wb_write(bus, 0x10 >> 2, 0x2, 0xF)
105 yield from wb_write(bus, 0x4 >> 2, 0xF, 0xF)
106 yield from wb_write(bus, 0x8 >> 2, 0x1, 0xF)
107
108 # MR3
109 yield from wb_write(bus, 0xC >> 2, 0x0, 0xF)
110 yield from wb_write(bus, 0x10 >> 2, 0x3, 0xF)
111 yield from wb_write(bus, 0x4 >> 2, 0xF, 0xF)
112 yield from wb_write(bus, 0x8 >> 2, 0x1, 0xF)
113
114 # MR1
115 yield from wb_write(bus, 0xC >> 2, 0x6, 0xF)
116 yield from wb_write(bus, 0x10 >> 2, 0x1, 0xF)
117 yield from wb_write(bus, 0x4 >> 2, 0xF, 0xF)
118 yield from wb_write(bus, 0x8 >> 2, 0x1, 0xF)
119
120 # MR0
121 yield from wb_write(bus, 0xC >> 2, 0x320, 0xF)
122 yield from wb_write(bus, 0x10 >> 2, 0x0, 0xF)
123 yield from wb_write(bus, 0x4 >> 2, 0xF, 0xF)
124 yield from wb_write(bus, 0x8 >> 2, 0x1, 0xF)
125 for i in range(200):
126 yield
127
128 # ZQ
129 yield from wb_write(bus, 0xC >> 2, 0x400, 0xF)
130 yield from wb_write(bus, 0x10 >> 2, 0x0, 0xF)
131 yield from wb_write(bus, 0x4 >> 2, 0x3, 0xF)
132 yield from wb_write(bus, 0x8 >> 2, 0x1, 0xF)
133 for i in range(200):
134 yield
135
136 yield from wb_write(bus, 0, 0x1, 0xF)
137 for i in range(2000):
138 yield
139
140 def test_multiple_reads(self):
141 m = Module()
142 soc = DDR3SoC(clk_freq=100e6,
143 dramcore_addr=0x00000000,
144 ddr_addr=0x10000000)
145 m.submodules += soc
146
147 def process():
148 yield from SocTestCase.init_seq(soc.bus)
149
150 yield from wb_write(soc.bus, 0x10000000 >> 2, 0xACAB2020, 0xF, 128)
151 yield
152
153 # Check for data persistence
154 for i in range(10):
155 res = yield from wb_read(soc.bus, 0x10000000 >> 2, 0xF, 128)
156 yield
157 self.assertEqual(res, 0xACAB2020)
158
159 runSimulation(m, process, "test_soc_multiple_reads.vcd")
160
161 def test_interleaved_read_write(self):
162 m = Module()
163 soc = DDR3SoC(clk_freq=100e6,
164 dramcore_addr=0x00000000,
165 ddr_addr=0x10000000)
166 m.submodules += soc
167
168 def process():
169 yield from SocTestCase.init_seq(soc.bus)
170
171 yield from wb_write(soc.bus, 0x10000000 >> 2, 0xF00DFACE, 0xF, 128)
172 yield from wb_write(soc.bus, 0x10000004 >> 2, 0x12345678, 0xF, 128)
173
174 res = yield from wb_read(soc.bus, 0x10000000 >> 2, 0xF, 128)
175 self.assertEqual(res, 0xF00DFACE)
176
177 res = yield from wb_read(soc.bus, 0x10000004 >> 2, 0xF, 128)
178 self.assertEqual(res, 0x12345678)
179
180 runSimulation(m, process, "test_soc_interleaved_read_write.vcd")