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
, exc
= yield from pi_ld(pi
, addr
, 8, msr_pr
=1)
117 print("ld_data",ld_data
,exc
)
119 invalid
= yield pi
.exc_o
.invalid
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
, exc
= yield from pi_ld(pi
, addr
, 8, msr_pr
=1)
144 assert ld_data
== 0xf553b658ba7e1f51
146 ld_data
, exc
= yield from pi_ld(pi
, addr
, 8, msr_pr
=1)
147 assert ld_data
== 0xf553b658ba7e1f51
150 print("do_dcbz ===============")
151 yield from pi_st(pi
, addr
, data
, 8, msr_pr
=1, is_dcbz
=1)
152 print("done_dcbz ===============")
155 ld_data
, exc
= yield from pi_ld(pi
, addr
, 8, msr_pr
=1)
156 print("ld_data after dcbz")
162 print("=== alignment error (ld) ===")
164 ld_data
, exc
= yield from pi_ld(pi
, addr
, 8, msr_pr
=1)
165 alignment
= yield pi
.exc_o
.alignment
166 happened
= yield pi
.exc_o
.happened
172 yield from wait_busy(pi
, debug
="pi_ld_E_alignment_error")
173 # wait is only needed in case of in exception here
174 print("=== alignment error test passed (ld) ===")
178 print("=== alignment error (st) ===")
180 exc = yield from pi_st(pi, addr,0, 8, msr_pr=1)
181 alignment = yield pi.exc_o.alignment
182 happened = yield pi.exc_o.happened
188 #???? yield from wait_busy(pi, debug="pi_st_E_alignment_error")
189 # wait is only needed in case of in exception here
190 print("=== alignment error test passed (st) ===")
191 #yield # IMPORTANT: wait one clock cycle after failed st
194 print("=== no error ===")
196 ld_data
, exc
= yield from pi_ld(pi
, addr
, 8, msr_pr
=1)
197 print("ld_data",ld_data
,exc
)
198 print("=== no error done ===")
201 addrs
= [0x456920,0xa7a180,0x299420,0x1d9d60]
205 print("== RANDOM addr ==",hex(addr
))
206 ld_data
, exc
= yield from pi_ld(pi
, addr
, 8, msr_pr
=1)
207 print("ld_data[RANDOM]",ld_data
,exc
,addr
)
208 #if exc=="wait_ldok_infinite_loop": # break cond for debugging
209 # print("wait_ldok_infinite_loop:break",count)
216 print("== RANDOM addr ==",hex(addr
))
217 exc
= yield from pi_st(pi
, addr
,0xFF*addr
, 8, msr_pr
=1)
218 #print("ld_data[RANDOM]",ld_data,exc,addr)
220 yield #FIXME: takes one more cycle to complete
223 # readback written data and compare
225 print("== RANDOM addr ==",hex(addr
))
226 ld_data
, exc
= yield from pi_ld(pi
, addr
, 8, msr_pr
=1)
227 print("ld_data[RANDOM_READBACK]",ld_data
,exc
,addr
)
228 #if exc=="wait_ldok_infinite_loop": # break cond for debugging
229 # print("wait_ldok_infinite_loop:break",count)
232 assert(ld_data
== 0xFF*addr
)
235 print("== RANDOM addr done ==")
239 def test_loadstore1():
241 m
, cmpi
= setup_mmu()
243 mem
= pagetables
.test1
249 sim
.add_sync_process(wrap(_test_loadstore1(m
, mem
)))
250 sim
.add_sync_process(wrap(wb_get(cmpi
.wb_bus(), mem
)))
251 with sim
.write_vcd('test_loadstore1.vcd'):
254 def test_loadstore1_invalid():
256 m
, cmpi
= setup_mmu()
264 sim
.add_sync_process(wrap(_test_loadstore1_invalid(m
, mem
)))
265 sim
.add_sync_process(wrap(wb_get(cmpi
.wb_bus(), mem
)))
266 with sim
.write_vcd('test_loadstore1_invalid.vcd'):
269 if __name__
== '__main__':
271 test_loadstore1_invalid()