should not have been duplicating wb_get function in 5 places
[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
43 l_in, l_out = mmu.l_in, mmu.l_out
44 d_in, d_out = dcache.d_in, dcache.d_out
45 wb_out, wb_in = dcache.wb_out, dcache.wb_in
46
47 # link mmu and dcache together
48 m.d.comb += dcache.m_in.eq(mmu.d_out) # MMUToDCacheType
49 m.d.comb += mmu.d_in.eq(dcache.m_out) # DCacheToMMUType
50
51 # link ldst and MMU together
52 comb += l_in.eq(ldst.m_out)
53 comb += ldst.m_in.eq(l_out)
54
55 return m, cmpi
56
57
58 test_exceptions = True
59 test_dcbz = True
60 test_random = True
61
62
63 def _test_loadstore1_invalid(dut, mem):
64 mmu = dut.submodules.mmu
65 pi = dut.submodules.ldst.pi
66 wbget.stop = False
67
68 print("=== test invalid ===")
69
70 addr = 0
71 ld_data, exctype, exc = yield from pi_ld(pi, addr, 8, msr_pr=1)
72 print("ld_data", ld_data, exctype, exc)
73 assert (exctype == "slow")
74 invalid = exc.invalid
75 assert (invalid == 1)
76
77 print("=== test invalid done ===")
78
79 wbget.stop = True
80
81
82 def _test_loadstore1(dut, mem):
83 mmu = dut.submodules.mmu
84 pi = dut.submodules.ldst.pi
85 ldst = dut.submodules.ldst # to get at DAR (NOT part of PortInterface)
86 wbget.stop = False
87
88 yield mmu.rin.prtbl.eq(0x1000000) # set process table
89 yield
90
91 addr = 0x100e0
92 data = 0xf553b658ba7e1f51
93
94 if test_dcbz:
95 yield from pi_st(pi, addr, data, 8, msr_pr=1)
96 yield
97
98 ld_data, exctype, exc = yield from pi_ld(pi, addr, 8, msr_pr=1)
99 assert ld_data == 0xf553b658ba7e1f51
100 assert exctype is None
101
102 ld_data, exctype, exc = yield from pi_ld(pi, addr, 8, msr_pr=1)
103 assert ld_data == 0xf553b658ba7e1f51
104 assert exctype is None
105
106 print("do_dcbz ===============")
107 yield from pi_st(pi, addr, data, 8, msr_pr=1, is_dcbz=1)
108 print("done_dcbz ===============")
109 yield
110
111 ld_data, exctype, exc = yield from pi_ld(pi, addr, 8, msr_pr=1)
112 print("ld_data after dcbz")
113 print(ld_data)
114 assert ld_data == 0
115 assert exctype is None
116
117 if test_exceptions:
118 print("=== alignment error (ld) ===")
119 addr = 0xFF100e0FF
120 ld_data, exctype, exc = yield from pi_ld(pi, addr, 8, msr_pr=1)
121 if exc:
122 alignment = exc.alignment
123 happened = exc.happened
124 yield # wait for dsr to update
125 dar = yield ldst.dar
126 else:
127 alignment = 0
128 happened = 0
129 dar = 0
130 assert (happened == 1)
131 assert (alignment == 1)
132 assert (dar == addr)
133 assert (exctype == "fast")
134 yield from wait_busy(pi, debug="pi_ld_E_alignment_error")
135 # wait is only needed in case of in exception here
136 print("=== alignment error test passed (ld) ===")
137
138 # take some cycles in between so that gtkwave separates out
139 # signals
140 yield
141 yield
142 yield
143 yield
144
145 print("=== alignment error (st) ===")
146 addr = 0xFF100e0FF
147 exctype, exc = yield from pi_st(pi, addr,0, 8, msr_pr=1)
148 if exc:
149 alignment = exc.alignment
150 happened = exc.happened
151 else:
152 alignment = 0
153 happened = 0
154 assert (happened == 1)
155 assert (alignment==1)
156 assert (dar==addr)
157 assert (exctype == "fast")
158 #???? yield from wait_busy(pi, debug="pi_st_E_alignment_error")
159 # wait is only needed in case of in exception here
160 print("=== alignment error test passed (st) ===")
161 yield #FIXME hangs
162
163 if True:
164 print("=== no alignment error (ld) ===")
165 addr = 0x100e0
166 ld_data, exctype, exc = yield from pi_ld(pi, addr, 8, msr_pr=1)
167 print("ld_data", ld_data, exctype, exc)
168 if exc:
169 alignment = exc.alignment
170 happened = exc.happened
171 else:
172 alignment = 0
173 happened = 0
174 assert (happened == 0)
175 assert (alignment == 0)
176 print("=== no alignment error done (ld) ===")
177
178 if test_random:
179 addrs = [0x456920,0xa7a180,0x299420,0x1d9d60]
180
181 for addr in addrs:
182 print("== RANDOM addr ==",hex(addr))
183 ld_data, exctype, exc = yield from pi_ld(pi, addr, 8, msr_pr=1)
184 print("ld_data[RANDOM]",ld_data,exc,addr)
185 assert (exctype == None)
186
187 for addr in addrs:
188 print("== RANDOM addr ==",hex(addr))
189 exc = yield from pi_st(pi, addr,0xFF*addr, 8, msr_pr=1)
190 assert (exctype == None)
191
192 # readback written data and compare
193 for addr in addrs:
194 print("== RANDOM addr ==",hex(addr))
195 ld_data, exctype, exc = yield from pi_ld(pi, addr, 8, msr_pr=1)
196 print("ld_data[RANDOM_READBACK]",ld_data,exc,addr)
197 assert (exctype == None)
198 assert (ld_data == 0xFF*addr)
199
200 print("== RANDOM addr done ==")
201
202 wbget.stop = True
203
204
205 def test_loadstore1():
206
207 m, cmpi = setup_mmu()
208
209 mem = pagetables.test1
210
211 # nmigen Simulation
212 sim = Simulator(m)
213 sim.add_clock(1e-6)
214
215 sim.add_sync_process(wrap(_test_loadstore1(m, mem)))
216 sim.add_sync_process(wrap(wb_get(cmpi.wb_bus(), mem)))
217 with sim.write_vcd('test_loadstore1.vcd'):
218 sim.run()
219
220
221 def test_loadstore1_invalid():
222
223 m, cmpi = setup_mmu()
224
225 mem = {}
226
227 # nmigen Simulation
228 sim = Simulator(m)
229 sim.add_clock(1e-6)
230
231 sim.add_sync_process(wrap(_test_loadstore1_invalid(m, mem)))
232 sim.add_sync_process(wrap(wb_get(cmpi.wb_bus(), mem)))
233 with sim.write_vcd('test_loadstore1_invalid.vcd'):
234 sim.run()
235
236
237 if __name__ == '__main__':
238 test_loadstore1()
239 test_loadstore1_invalid()