code-comments
[soc.git] / src / soc / experiment / test / test_loadstore1.py
1 from nmigen import (C, Module, Signal, Elaboratable, Mux, Cat, Repl, Signal)
2 from nmigen.cli import main
3 from nmigen.cli import rtlil
4 from nmutil.mask import Mask, masked
5 from nmutil.util import Display
6 from random import randint, seed
7 from nmigen.sim import Simulator, Delay, Settle
8 from nmutil.util import wrap
9
10 from soc.config.test.test_pi2ls import pi_ld, pi_st, pi_ldst, wait_busy
11 #from soc.config.test.test_pi2ls import pi_st_debug
12 from soc.config.test.test_loadstore import TestMemPspec
13 from soc.config.loadstore import ConfigMemoryPortInterface
14
15 from soc.fu.ldst.loadstore import LoadStore1
16 from soc.experiment.mmu import MMU
17 from soc.experiment.test import pagetables
18
19 from nmigen.compat.sim import run_simulation
20 from random import random
21 from openpower.test.wb_get import wb_get
22 from openpower.test import wb_get as wbget
23
24
25 def setup_mmu():
26
27 wbget.stop = False
28
29 pspec = TestMemPspec(ldst_ifacetype='mmu_cache_wb',
30 imem_ifacetype='',
31 addr_wid=48,
32 #disable_cache=True, # hmmm...
33 mask_wid=8,
34 reg_wid=64)
35
36 m = Module()
37 comb = m.d.comb
38 cmpi = ConfigMemoryPortInterface(pspec)
39 m.submodules.ldst = ldst = cmpi.pi
40 m.submodules.mmu = mmu = MMU()
41 dcache = ldst.dcache
42 icache = ldst.icache
43
44 l_in, l_out = mmu.l_in, mmu.l_out
45 d_in, d_out = dcache.d_in, dcache.d_out
46 i_in, i_out = icache.i_in, icache.i_out # FetchToICache, ICacheToDecode
47
48 # link mmu, dcache and icache together
49 m.d.comb += dcache.m_in.eq(mmu.d_out) # MMUToDCacheType
50 m.d.comb += icache.m_in.eq(mmu.i_out) # MMUToICacheType
51 m.d.comb += mmu.d_in.eq(dcache.m_out) # DCacheToMMUType
52
53 # link ldst and MMU together
54 comb += l_in.eq(ldst.m_out)
55 comb += ldst.m_in.eq(l_out)
56
57 return m, cmpi
58
59
60 test_exceptions = True
61 test_dcbz = True
62 test_random = True
63
64
65 def _test_loadstore1_invalid(dut, mem):
66 mmu = dut.submodules.mmu
67 pi = dut.submodules.ldst.pi
68 wbget.stop = False
69
70 print("=== test invalid ===")
71
72 addr = 0
73 ld_data, exctype, exc = yield from pi_ld(pi, addr, 8, msr_pr=1)
74 print("ld_data", ld_data, exctype, exc)
75 assert (exctype == "slow")
76 invalid = exc.invalid
77 assert (invalid == 1)
78
79 print("=== test invalid done ===")
80
81 wbget.stop = True
82
83
84 def _test_loadstore1(dut, mem):
85 mmu = dut.submodules.mmu
86 pi = dut.submodules.ldst.pi
87 ldst = dut.submodules.ldst # to get at DAR (NOT part of PortInterface)
88 wbget.stop = False
89
90 yield mmu.rin.prtbl.eq(0x1000000) # set process table
91 yield
92
93 addr = 0x100e0
94 data = 0xf553b658ba7e1f51
95
96 if test_dcbz:
97 yield from pi_st(pi, addr, data, 8, msr_pr=1)
98 yield
99
100 ld_data, exctype, exc = yield from pi_ld(pi, addr, 8, msr_pr=1)
101 assert ld_data == 0xf553b658ba7e1f51
102 assert exctype is None
103
104 ld_data, exctype, exc = yield from pi_ld(pi, addr, 8, msr_pr=1)
105 assert ld_data == 0xf553b658ba7e1f51
106 assert exctype is None
107
108 print("do_dcbz ===============")
109 yield from pi_st(pi, addr, data, 8, msr_pr=1, is_dcbz=1)
110 print("done_dcbz ===============")
111 yield
112
113 ld_data, exctype, exc = yield from pi_ld(pi, addr, 8, msr_pr=1)
114 print("ld_data after dcbz")
115 print(ld_data)
116 assert ld_data == 0
117 assert exctype is None
118
119 if test_exceptions:
120 print("=== alignment error (ld) ===")
121 addr = 0xFF100e0FF
122 ld_data, exctype, exc = yield from pi_ld(pi, addr, 8, msr_pr=1)
123 if exc:
124 alignment = exc.alignment
125 happened = exc.happened
126 yield # wait for dsr to update
127 dar = yield ldst.dar
128 else:
129 alignment = 0
130 happened = 0
131 dar = 0
132 assert (happened == 1)
133 assert (alignment == 1)
134 assert (dar == addr)
135 assert (exctype == "fast")
136 yield from wait_busy(pi, debug="pi_ld_E_alignment_error")
137 # wait is only needed in case of in exception here
138 print("=== alignment error test passed (ld) ===")
139
140 # take some cycles in between so that gtkwave separates out
141 # signals
142 yield
143 yield
144 yield
145 yield
146
147 print("=== alignment error (st) ===")
148 addr = 0xFF100e0FF
149 exctype, exc = yield from pi_st(pi, addr,0, 8, msr_pr=1)
150 if exc:
151 alignment = exc.alignment
152 happened = exc.happened
153 else:
154 alignment = 0
155 happened = 0
156 assert (happened == 1)
157 assert (alignment==1)
158 assert (dar==addr)
159 assert (exctype == "fast")
160 #???? yield from wait_busy(pi, debug="pi_st_E_alignment_error")
161 # wait is only needed in case of in exception here
162 print("=== alignment error test passed (st) ===")
163 yield #FIXME hangs
164
165 if True:
166 print("=== no alignment error (ld) ===")
167 addr = 0x100e0
168 ld_data, exctype, exc = yield from pi_ld(pi, addr, 8, msr_pr=1)
169 print("ld_data", ld_data, exctype, exc)
170 if exc:
171 alignment = exc.alignment
172 happened = exc.happened
173 else:
174 alignment = 0
175 happened = 0
176 assert (happened == 0)
177 assert (alignment == 0)
178 print("=== no alignment error done (ld) ===")
179
180 if test_random:
181 addrs = [0x456920,0xa7a180,0x299420,0x1d9d60]
182
183 for addr in addrs:
184 print("== RANDOM addr ==",hex(addr))
185 ld_data, exctype, exc = yield from pi_ld(pi, addr, 8, msr_pr=1)
186 print("ld_data[RANDOM]",ld_data,exc,addr)
187 assert (exctype == None)
188
189 for addr in addrs:
190 print("== RANDOM addr ==",hex(addr))
191 exc = yield from pi_st(pi, addr,0xFF*addr, 8, msr_pr=1)
192 assert (exctype == None)
193
194 # readback written data and compare
195 for addr in addrs:
196 print("== RANDOM addr ==",hex(addr))
197 ld_data, exctype, exc = yield from pi_ld(pi, addr, 8, msr_pr=1)
198 print("ld_data[RANDOM_READBACK]",ld_data,exc,addr)
199 assert (exctype == None)
200 assert (ld_data == 0xFF*addr)
201
202 print("== RANDOM addr done ==")
203
204 wbget.stop = True
205
206
207 def test_loadstore1():
208
209 m, cmpi = setup_mmu()
210
211 mem = pagetables.test1
212
213 # nmigen Simulation
214 sim = Simulator(m)
215 sim.add_clock(1e-6)
216
217 sim.add_sync_process(wrap(_test_loadstore1(m, mem)))
218 sim.add_sync_process(wrap(wb_get(cmpi.wb_bus(), mem)))
219 with sim.write_vcd('test_loadstore1.vcd'):
220 sim.run()
221
222
223 def test_loadstore1_invalid():
224
225 m, cmpi = setup_mmu()
226
227 mem = {}
228
229 # nmigen Simulation
230 sim = Simulator(m)
231 sim.add_clock(1e-6)
232
233 sim.add_sync_process(wrap(_test_loadstore1_invalid(m, mem)))
234 sim.add_sync_process(wrap(wb_get(cmpi.wb_bus(), mem)))
235 with sim.write_vcd('test_loadstore1_invalid.vcd'):
236 sim.run()
237
238
239 if __name__ == '__main__':
240 test_loadstore1()
241 test_loadstore1_invalid()