1 """MMU PortInterface Test
3 quite basic, goes directly to the MMU to assert signals (does not
7 from nmigen
import (C
, Module
, Signal
, Elaboratable
, Mux
, Cat
, Repl
, Signal
)
8 from nmigen
.cli
import main
9 from nmigen
.cli
import rtlil
10 from nmutil
.mask
import Mask
, masked
11 from nmutil
.util
import Display
14 from nmigen
.back
.pysim
import Simulator
, Delay
, Settle
16 from nmigen
.sim
.cxxsim
import Simulator
, Delay
, Settle
17 from nmutil
.util
import wrap
19 from soc
.config
.test
.test_pi2ls
import pi_ld
, pi_st
, pi_ldst
20 from soc
.config
.test
.test_loadstore
import TestMemPspec
21 from soc
.config
.loadstore
import ConfigMemoryPortInterface
23 from soc
.fu
.ldst
.loadstore
import LoadStore1
24 from soc
.experiment
.mmu
import MMU
26 from nmigen
.compat
.sim
import run_simulation
31 def b(x
): # byte-reverse function
32 return int.from_bytes(x
.to_bytes(8, byteorder
='little'),
33 byteorder
='big', signed
=False)
36 """simulator process for getting memory load requests
42 while True: # wait for dc_valid
50 addr
= (yield wb
.adr
) << 3
52 print (" WB LOOKUP NO entry @ %x, returning zero" % (addr
))
57 store
= (yield wb
.dat_w
)
59 data
= mem
.get(addr
, 0)
60 # note we assume 8-bit sel, here
69 print (" DCACHE set %x mask %x data %x" % (addr
, sel
, res
))
71 data
= mem
.get(addr
, 0)
72 yield wb
.dat_r
.eq(data
)
73 print (" DCACHE get %x data %x" % (addr
, data
))
81 def mmu_lookup(dut
, addr
):
82 mmu
= dut
.submodules
.mmu
85 print("pi_ld", hex(addr
))
86 data
= yield from pi_ld(dut
.submodules
.ldst
.pi
, addr
, 4, msr_pr
=1)
87 print("pi_ld done, data", hex(data
))
89 # original test code kept for reference
90 while not stop: # wait for dc_valid / err
91 print("waiting for mmu")
92 l_done = yield (mmu.l_out.done)
93 l_err = yield (mmu.l_out.err)
94 l_badtree = yield (mmu.l_out.badtree)
95 l_permerr = yield (mmu.l_out.perm_error)
96 l_rc_err = yield (mmu.l_out.rc_error)
97 l_segerr = yield (mmu.l_out.segerr)
98 l_invalid = yield (mmu.l_out.invalid)
99 if (l_done or l_err or l_badtree or
100 l_permerr or l_rc_err or l_segerr or l_invalid):
104 phys_addr
= yield mmu
.d_out
.addr
105 pte
= yield mmu
.d_out
.pte
106 l_done
= yield (mmu
.l_out
.done
)
107 l_err
= yield (mmu
.l_out
.err
)
108 l_badtree
= yield (mmu
.l_out
.badtree
)
109 print ("translated done %d err %d badtree %d addr %x pte %x" % \
110 (l_done
, l_err
, l_badtree
, phys_addr
, pte
))
112 yield mmu
.l_in
.valid
.eq(0)
118 mmu
= dut
.submodules
.mmu
120 yield mmu
.rin
.prtbl
.eq(0x1000000) # set process table
123 # expecting this data to return
124 # 0x1000: 0xdeadbeef01234567,
125 # 0x1008: 0xfeedf00ff001a5a5
130 # TODO mmu_lookup using port interface
132 data
= yield from mmu_lookup(dut
, addr
)
133 assert data
== 0x1234567
135 data
= yield from mmu_lookup(dut
, addr
+8)
136 assert data
== 0xf001a5a5
137 #assert phys_addr == addr # happens to be the same (for this example)
139 data
= yield from mmu_lookup(dut
, addr
+4)
140 assert data
== 0xdeadbeef
142 data
= yield from mmu_lookup(dut
, addr
+8)
143 assert data
== 0xf001a5a5
145 yield from pi_st(dut
.submodules
.ldst
.pi
, addr
+4, 0x10015a5a, 4, msr_pr
=1)
147 data
= yield from mmu_lookup(dut
, addr
+4)
148 assert data
== 0x10015a5a
157 pspec
= TestMemPspec(ldst_ifacetype
='mmu_cache_wb',
160 #disable_cache=True, # hmmm...
166 cmpi
= ConfigMemoryPortInterface(pspec
)
167 m
.submodules
.ldst
= ldst
= cmpi
.pi
168 m
.submodules
.mmu
= mmu
= MMU()
171 l_in
, l_out
= mmu
.l_in
, mmu
.l_out
172 d_in
, d_out
= dcache
.d_in
, dcache
.d_out
173 wb_out
, wb_in
= dcache
.wb_out
, dcache
.wb_in
175 # link mmu and dcache together
176 m
.d
.comb
+= dcache
.m_in
.eq(mmu
.d_out
) # MMUToDCacheType
177 m
.d
.comb
+= mmu
.d_in
.eq(dcache
.m_out
) # DCacheToMMUType
179 # link ldst and MMU together
180 comb
+= l_in
.eq(ldst
.m_out
)
181 comb
+= ldst
.m_in
.eq(l_out
)
188 m
, cmpi
= setup_mmu()
190 # virtual "memory" to use for this test
192 mem
= {0x10000: # PARTITION_TABLE_2
193 # PATB_GR=1 PRTB=0x1000 PRTS=0xb
194 b(0x800000000100000b),
196 0x30000: # RADIX_ROOT_PTE
197 # V = 1 L = 0 NLB = 0x400 NLS = 9
198 b(0x8000000000040009),
200 0x40000: # RADIX_SECOND_LEVEL
201 # V = 1 L = 1 SW = 0 RPN = 0
202 # R = 1 C = 1 ATT = 0 EAA 0x7
203 b(0xc000000000000183),
205 0x1000000: # PROCESS_TABLE_3
206 # RTS1 = 0x2 RPDB = 0x300 RTS2 = 0x5 RPDS = 13
207 b(0x40000000000300ad),
210 0x1000: 0xdeadbeef01234567,
211 0x1008: 0xfeedf00ff001a5a5
219 sim
.add_sync_process(wrap(ldst_sim(m
)))
220 sim
.add_sync_process(wrap(wb_get(cmpi
.wb_bus(), mem
)))
221 with sim
.write_vcd('test_ldst_pi.vcd'):
224 def ldst_sim_misalign(dut
):
225 mmu
= dut
.submodules
.mmu
229 yield mmu
.rin
.prtbl
.eq(0x1000000) # set process table
232 data
= yield from pi_ld(dut
.submodules
.ldst
.pi
, 0x1007, 8, msr_pr
=1)
233 print ("misalign ld data", hex(data
))
239 def test_misalign_mmu():
241 m
, cmpi
= setup_mmu()
243 # virtual "memory" to use for this test
245 mem
= {0x10000: # PARTITION_TABLE_2
246 # PATB_GR=1 PRTB=0x1000 PRTS=0xb
247 b(0x800000000100000b),
249 0x30000: # RADIX_ROOT_PTE
250 # V = 1 L = 0 NLB = 0x400 NLS = 9
251 b(0x8000000000040009),
253 0x40000: # RADIX_SECOND_LEVEL
254 # V = 1 L = 1 SW = 0 RPN = 0
255 # R = 1 C = 1 ATT = 0 EAA 0x7
256 b(0xc000000000000183),
258 0x1000000: # PROCESS_TABLE_3
259 # RTS1 = 0x2 RPDB = 0x300 RTS2 = 0x5 RPDS = 13
260 b(0x40000000000300ad),
263 0x1000: 0xdeadbeef01234567,
264 0x1008: 0xfeedf00ff001a5a5
272 sim
.add_sync_process(wrap(ldst_sim_misalign(m
)))
273 sim
.add_sync_process(wrap(wb_get(cmpi
.wb_bus(), mem
)))
274 with sim
.write_vcd('test_ldst_pi_misalign.vcd'):
278 if __name__
== '__main__':