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
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
15 from soc
.fu
.ldst
.loadstore
import LoadStore1
16 from soc
.experiment
.mmu
import MMU
17 from soc
.experiment
.test
import pagetables
19 from nmigen
.compat
.sim
import run_simulation
20 from random
import random
25 """simulator process for getting memory load requests
32 while True: # wait for dc_valid
40 addr
= (yield wb
.adr
) << 3
42 print (" WB LOOKUP NO entry @ %x, returning zero" % (addr
))
47 store
= (yield wb
.dat_w
)
49 data
= mem
.get(addr
, 0)
50 # note we assume 8-bit sel, here
59 print (" DCACHE set %x mask %x data %x" % (addr
, sel
, res
))
61 data
= mem
.get(addr
, 0)
62 yield wb
.dat_r
.eq(data
)
63 print (" DCACHE get %x data %x" % (addr
, data
))
75 pspec
= TestMemPspec(ldst_ifacetype
='mmu_cache_wb',
78 #disable_cache=True, # hmmm...
84 cmpi
= ConfigMemoryPortInterface(pspec
)
85 m
.submodules
.ldst
= ldst
= cmpi
.pi
86 m
.submodules
.mmu
= mmu
= MMU()
89 l_in
, l_out
= mmu
.l_in
, mmu
.l_out
90 d_in
, d_out
= dcache
.d_in
, dcache
.d_out
91 wb_out
, wb_in
= dcache
.wb_out
, dcache
.wb_in
93 # link mmu and dcache together
94 m
.d
.comb
+= dcache
.m_in
.eq(mmu
.d_out
) # MMUToDCacheType
95 m
.d
.comb
+= mmu
.d_in
.eq(dcache
.m_out
) # DCacheToMMUType
97 # link ldst and MMU together
98 comb
+= l_in
.eq(ldst
.m_out
)
99 comb
+= ldst
.m_in
.eq(l_out
)
103 test_exceptions
= True
107 def _test_loadstore1_invalid(dut
, mem
):
108 mmu
= dut
.submodules
.mmu
109 pi
= dut
.submodules
.ldst
.pi
113 print("=== test invalid ===")
116 ld_data
, exctype
, exc
, dar_o
= yield from pi_ld(pi
, addr
, 8, msr_pr
=1)
117 print("ld_data", ld_data
, exctype
, exc
)
118 assert (exctype
== "slow")
119 invalid
= exc
.invalid
120 assert (invalid
== 1)
122 print("=== test invalid done ===")
127 def _test_loadstore1(dut
, mem
):
128 mmu
= dut
.submodules
.mmu
129 pi
= dut
.submodules
.ldst
.pi
133 yield mmu
.rin
.prtbl
.eq(0x1000000) # set process table
137 data
= 0xf553b658ba7e1f51
140 yield from pi_st(pi
, addr
, data
, 8, msr_pr
=1)
143 ld_data
, exctype
, exc
, dar_o
= yield from pi_ld(pi
, addr
, 8, msr_pr
=1)
144 assert ld_data
== 0xf553b658ba7e1f51
145 assert exctype
is None
147 ld_data
, exctype
, exc
, dar_o
= yield from pi_ld(pi
, addr
, 8, msr_pr
=1)
148 assert ld_data
== 0xf553b658ba7e1f51
149 assert exctype
is None
151 print("do_dcbz ===============")
152 yield from pi_st(pi
, addr
, data
, 8, msr_pr
=1, is_dcbz
=1)
153 print("done_dcbz ===============")
156 ld_data
, exctype
, exc
, dar_o
= yield from pi_ld(pi
, addr
, 8, msr_pr
=1)
157 print("ld_data after dcbz")
160 assert exctype
is None
163 print("=== alignment error (ld) ===")
165 ld_data
, exctype
, exc
, dar
= yield from pi_ld(pi
, addr
, 8, msr_pr
=1)
167 alignment
= exc
.alignment
168 happened
= exc
.happened
172 assert (happened
== 1)
173 assert (alignment
== 1)
175 assert (exctype
== "fast")
176 yield from wait_busy(pi
, debug
="pi_ld_E_alignment_error")
177 # wait is only needed in case of in exception here
178 print("=== alignment error test passed (ld) ===")
180 # take some cycles in between so that gtkwave separates out
187 print("=== alignment error (st) ===")
189 exctype
, exc
, dar_o
= yield from pi_st(pi
, addr
,0, 8, msr_pr
=1)
191 alignment
= exc
.alignment
192 happened
= exc
.happened
196 assert (happened
== 1)
197 assert (alignment
==1)
199 assert (exctype
== "fast")
200 #???? yield from wait_busy(pi, debug="pi_st_E_alignment_error")
201 # wait is only needed in case of in exception here
202 print("=== alignment error test passed (st) ===")
206 print("=== no alignment error (ld) ===")
208 ld_data
, exctype
, exc
, dar_o
= yield from pi_ld(pi
, addr
, 8, msr_pr
=1)
209 print("ld_data", ld_data
, exctype
, exc
)
211 alignment
= exc
.alignment
212 happened
= exc
.happened
216 assert (happened
== 0)
217 assert (alignment
== 0)
218 print("=== no alignment error done (ld) ===")
221 addrs
= [0x456920,0xa7a180,0x299420,0x1d9d60]
224 print("== RANDOM addr ==",hex(addr
))
225 ld_data
, exctype
, exc
, dar_o
= \
226 yield from pi_ld(pi
, addr
, 8, msr_pr
=1)
227 print("ld_data[RANDOM]",ld_data
,exc
,addr
)
228 assert (exctype
== None)
231 print("== RANDOM addr ==",hex(addr
))
232 exc
= yield from pi_st(pi
, addr
,0xFF*addr
, 8, msr_pr
=1)
233 assert (exctype
== None)
235 # readback written data and compare
237 print("== RANDOM addr ==",hex(addr
))
238 ld_data
, exctype
, exc
, dar_o
= \
239 yield from pi_ld(pi
, addr
, 8, msr_pr
=1)
240 print("ld_data[RANDOM_READBACK]",ld_data
,exc
,addr
)
241 assert (exctype
== None)
242 assert (ld_data
== 0xFF*addr
)
244 print("== RANDOM addr done ==")
248 def test_loadstore1():
250 m
, cmpi
= setup_mmu()
252 mem
= pagetables
.test1
258 sim
.add_sync_process(wrap(_test_loadstore1(m
, mem
)))
259 sim
.add_sync_process(wrap(wb_get(cmpi
.wb_bus(), mem
)))
260 with sim
.write_vcd('test_loadstore1.vcd'):
263 def test_loadstore1_invalid():
265 m
, cmpi
= setup_mmu()
273 sim
.add_sync_process(wrap(_test_loadstore1_invalid(m
, mem
)))
274 sim
.add_sync_process(wrap(wb_get(cmpi
.wb_bus(), mem
)))
275 with sim
.write_vcd('test_loadstore1_invalid.vcd'):
278 if __name__
== '__main__':
280 test_loadstore1_invalid()