1 from nmigen
import (C
, Module
, Signal
, Elaboratable
, Mux
, Cat
, Repl
, Signal
,
3 from nmigen
.cli
import main
4 from nmigen
.cli
import rtlil
5 from nmutil
.mask
import Mask
, masked
6 from nmutil
.util
import Display
7 from random
import randint
, seed
8 from nmigen
.sim
import Simulator
, Delay
, Settle
9 from nmutil
.util
import wrap
11 from soc
.config
.test
.test_pi2ls
import (pi_ld
, pi_st
, pi_ldst
, wait_busy
,
13 #from soc.config.test.test_pi2ls import pi_st_debug
14 from soc
.config
.test
.test_loadstore
import TestMemPspec
15 from soc
.config
.loadstore
import ConfigMemoryPortInterface
17 from soc
.fu
.ldst
.loadstore
import LoadStore1
18 from soc
.experiment
.mmu
import MMU
19 from soc
.experiment
.test
import pagetables
21 from nmigen
.compat
.sim
import run_simulation
22 from random
import random
23 from openpower
.test
.wb_get
import wb_get
24 from openpower
.test
import wb_get
as wbget
25 from openpower
.exceptions
import LDSTExceptionTuple
27 from soc
.config
.test
.test_fetch
import read_from_addr
28 from openpower
.decoder
.power_enums
import MSRSpec
35 pspec
= TestMemPspec(ldst_ifacetype
='mmu_cache_wb',
38 #disable_cache=True, # hmmm...
44 cmpi
= ConfigMemoryPortInterface(pspec
)
45 m
.submodules
.ldst
= ldst
= cmpi
.pi
46 m
.submodules
.mmu
= mmu
= MMU()
50 l_in
, l_out
= mmu
.l_in
, mmu
.l_out
51 d_in
, d_out
= dcache
.d_in
, dcache
.d_out
52 i_in
, i_out
= icache
.i_in
, icache
.i_out
# FetchToICache, ICacheToDecode
54 # link mmu, dcache and icache together
55 m
.d
.comb
+= dcache
.m_in
.eq(mmu
.d_out
) # MMUToDCacheType
56 m
.d
.comb
+= icache
.m_in
.eq(mmu
.i_out
) # MMUToICacheType
57 m
.d
.comb
+= mmu
.d_in
.eq(dcache
.m_out
) # DCacheToMMUType
59 # link ldst and MMU together
60 comb
+= l_in
.eq(ldst
.m_out
)
61 comb
+= ldst
.m_in
.eq(l_out
)
63 # add a debug status Signal: use "msg.str = "blah"
64 # then toggle with yield msg.eq(0); yield msg.eq(1)
65 debug_status
= Signal(8, decoder
=lambda _
: debug_status
.str)
66 m
.debug_status
= debug_status
72 def icache_read(dut
,addr
,priv
,virt
):
74 icache
= dut
.submodules
.ldst
.icache
78 yield i_in
.priv_mode
.eq(priv
)
79 yield i_in
.virt_mode
.eq(virt
)
81 yield i_in
.nia
.eq(addr
)
82 yield i_in
.stop_mark
.eq(0)
85 yield i_in
.nia
.eq(addr
)
87 valid
= yield i_out
.valid
88 failed
= yield i_out
.fetch_failed
89 while not valid
and not failed
:
91 valid
= yield i_out
.valid
92 failed
= yield i_out
.fetch_failed
96 insn
= yield i_out
.insn
100 return nia
, insn
, valid
, failed
103 test_exceptions
= True
109 print ("set debug message", msg
)
110 dut
.debug_status
.str = msg
# set the message
111 yield dut
.debug_status
.eq(0) # trigger an update
112 yield dut
.debug_status
.eq(1)
115 def _test_loadstore1_ifetch_iface(dut
, mem
):
116 """test_loadstore1_ifetch_iface
118 read in priv mode, non-virtual. tests the FetchUnitInterface
122 mmu
= dut
.submodules
.mmu
123 ldst
= dut
.submodules
.ldst
125 icache
= dut
.submodules
.ldst
.icache
128 print("=== test loadstore instruction (real) ===")
134 yield from debug(dut
, "real mem instruction")
135 # set address to 0x8, update mem[0x8] to 01234 | 0x5678<<32
136 # (have to do 64-bit writes into the dictionary-memory-emulated-thing)
139 expected_insn2
= 0x5678
140 expected_insn
= 0x1234
141 mem
[addr
] = expected_insn | expected_insn2
<<32
143 yield i_in
.priv_mode
.eq(1)
144 insn
= yield from read_from_addr(icache
, addr
, stall
=False)
146 nia
= yield i_out
.nia
# NO, must use FetchUnitInterface
147 print ("fetched %x from addr %x" % (insn
, nia
))
148 assert insn
== expected_insn
150 print("=== test loadstore instruction (2nd, real) ===")
151 yield from debug(dut
, "real mem 2nd (addr 0xc)")
153 insn2
= yield from read_from_addr(icache
, addr2
, stall
=False)
155 nia
= yield i_out
.nia
# NO, must use FetchUnitInterface
156 print ("fetched %x from addr2 %x" % (insn2
, nia
))
157 assert insn2
== expected_insn2
159 print("=== test loadstore instruction (done) ===")
161 yield from debug(dut
, "test done")
165 print ("fetched %x from addr %x" % (insn
, nia
))
166 assert insn
== expected_insn
171 def write_mem2(mem
, addr
, i1
, i2
):
172 mem
[addr
] = i1 | i2
<<32
175 #TODO: use fetch interface here
176 def lookup_virt(dut
,addr
):
177 icache
= dut
.submodules
.ldst
.icache
180 yield i_in
.priv_mode
.eq(0)
181 yield i_in
.virt_mode
.eq(1)
183 yield i_in
.stop_mark
.eq(0)
185 yield icache
.a_i_valid
.eq(1)
186 yield icache
.a_pc_i
.eq(addr
)
188 valid
= yield i_out
.valid
189 failed
= yield i_out
.fetch_failed
190 while not valid
and not failed
:
192 valid
= yield i_out
.valid
193 failed
= yield i_out
.fetch_failed
194 yield icache
.a_i_valid
.eq(0)
199 def mmu_lookup(dut
,addr
):
200 ldst
= dut
.submodules
.ldst
202 yield from debug(dut
, "instr fault "+hex(addr
))
203 yield ldst
.priv_mode
.eq(0)
204 yield ldst
.instr_fault
.eq(1)
205 yield ldst
.maddr
.eq(addr
)
207 yield ldst
.instr_fault
.eq(0)
209 done
= yield (ldst
.done
)
210 exc_info
= yield from get_exception_info(pi
.exc_o
)
211 if done
or exc_info
.happened
:
215 assert exc_info
.happened
== 0 # assert just before doing the fault set zero
216 yield ldst
.instr_fault
.eq(0)
217 yield from debug(dut
, "instr fault done "+hex(addr
))
223 def _test_loadstore1_ifetch_multi(dut
, mem
):
224 mmu
= dut
.submodules
.mmu
225 ldst
= dut
.submodules
.ldst
227 icache
= dut
.submodules
.ldst
.icache
228 assert wbget
.stop
== False
230 print ("set process table")
231 yield from debug(dut
, "set prtble")
232 yield mmu
.rin
.prtbl
.eq(0x1000000) # set process table
239 # fetch instructions from multiple addresses
240 # should cope with some addresses being invalid
241 real_addrs
= [0,4,8,0,8,4,0,0,12]
242 write_mem2(mem
,0,0xF0,0xF4)
243 write_mem2(mem
,8,0xF8,0xFC)
245 yield i_in
.priv_mode
.eq(1)
246 for addr
in real_addrs
:
247 yield from debug(dut
, "real_addr "+hex(addr
))
248 insn
= yield from read_from_addr(icache
, addr
, stall
=False)
249 nia
= yield i_out
.nia
# NO, must use FetchUnitInterface
250 print ("TEST_MULTI: fetched %x from addr %x == %x" % (insn
, nia
,addr
))
251 assert insn
==0xF0+addr
253 # now with virtual memory enabled
254 yield i_in
.virt_mode
.eq(1)
256 virt_addrs
= [0x10200,0x10204,0x10208,0x10200,
257 0x102008,0x10204,0x10200,0x10200,0x10200C]
259 write_mem2(mem
,0x10200,0xF8,0xFC)
261 for addr
in virt_addrs
:
262 yield from debug(dut
, "virt_addr "+hex(addr
))
264 valid
, failed
= yield from lookup_virt(dut
,addr
)
266 print("TEST_MULTI: failed=",failed
) # this is reported wrong
267 if failed
==1: # test one first
268 yield from mmu_lookup(dut
,addr
)
269 valid
, failed
= yield from lookup_virt(dut
,addr
)
275 def _test_loadstore1_ifetch(dut
, mem
):
276 """test_loadstore1_ifetch
278 this is quite a complex multi-step test.
280 * first (just because, as a demo) read in priv mode, non-virtual.
281 just like in experiment/icache.py itself.
283 * second, using the (usual) PTE for these things (which came originally
284 from gem5-experimental experiment/radix_walk_example.txt) do a
285 virtual-memory read through the *instruction* cache.
286 this is expected to FAIL
288 * third: mess about with the MMU, setting "iside" (instruction-side),
289 requesting an MMU RADIX LOOKUP. this triggers an itlb_load
290 (instruction-cache TLB entry-insertion)
292 * fourth and finally: retry the read of the instruction through i-cache.
293 this is now expected to SUCCEED
298 mmu
= dut
.submodules
.mmu
299 ldst
= dut
.submodules
.ldst
301 icache
= dut
.submodules
.ldst
.icache
304 print("=== test loadstore instruction (real) ===")
310 # first virtual memory test
312 print ("set process table")
313 yield from debug(dut
, "set prtble")
314 yield mmu
.rin
.prtbl
.eq(0x1000000) # set process table
317 yield from debug(dut
, "real mem instruction")
318 # set address to zero, update mem[0] to 01234
320 expected_insn
= 0x1234
321 mem
[addr
] = expected_insn
323 yield i_in
.priv_mode
.eq(1)
325 yield i_in
.nia
.eq(addr
)
326 yield i_in
.stop_mark
.eq(0)
327 yield i_m_in
.tlbld
.eq(0)
328 yield i_m_in
.tlbie
.eq(0)
329 yield i_m_in
.addr
.eq(0)
330 yield i_m_in
.pte
.eq(0)
335 # miss, stalls for a bit -- this one is different here
336 ##nia, insn, valid, failed = yield from icache_read(dut,addr,0,0)
341 yield i_in
.nia
.eq(addr
)
343 valid
= yield i_out
.valid
346 valid
= yield i_out
.valid
349 nia
= yield i_out
.nia
350 insn
= yield i_out
.insn
354 print ("fetched %x from addr %x" % (insn
, nia
))
355 assert insn
== expected_insn
357 print("=== test loadstore instruction (virtual) ===")
359 # look up i-cache expecting it to fail
361 yield from debug(dut
, "virtual instr req")
362 # set address to 0x10200, update mem[] to 5678
364 real_addr
= virt_addr
365 expected_insn
= 0x5678
366 mem
[real_addr
] = expected_insn
368 yield i_in
.priv_mode
.eq(0)
369 yield i_in
.virt_mode
.eq(1)
371 yield i_in
.nia
.eq(virt_addr
)
372 yield i_in
.stop_mark
.eq(0)
373 yield i_m_in
.tlbld
.eq(0)
374 yield i_m_in
.tlbie
.eq(0)
375 yield i_m_in
.addr
.eq(0)
376 yield i_m_in
.pte
.eq(0)
381 # miss, stalls for a bit
383 yield i_in
.nia
.eq(virt_addr
)
385 valid
= yield i_out
.valid
386 failed
= yield i_out
.fetch_failed
387 while not valid
and not failed
:
389 valid
= yield i_out
.valid
390 failed
= yield i_out
.fetch_failed
393 print ("failed?", "yes" if failed
else "no")
398 print("=== test loadstore instruction (instruction fault) ===")
400 yield from debug(dut
, "instr fault")
404 yield ldst
.priv_mode
.eq(0)
405 yield ldst
.instr_fault
.eq(1)
406 yield ldst
.maddr
.eq(virt_addr
)
407 # still broken -- investigate
408 # msr = MSRSpec(pr=?, dr=?, sf=0)
409 # ld_data, exctype, exc = yield from pi_ld(pi, virt_addr, 8, msr=msr)
411 yield ldst
.instr_fault
.eq(0)
413 done
= yield (ldst
.done
)
414 exc_info
= yield from get_exception_info(pi
.exc_o
)
415 if done
or exc_info
.happened
:
418 assert exc_info
.happened
== 0 # assert just before doing the fault set zero
419 yield ldst
.instr_fault
.eq(0)
424 print("=== test loadstore instruction (try instruction again) ===")
425 yield from debug(dut
, "instr virt retry")
426 # set address to 0x10200, update mem[] to 5678
428 real_addr
= virt_addr
429 expected_insn
= 0x5678
431 yield i_in
.priv_mode
.eq(0)
432 yield i_in
.virt_mode
.eq(1)
434 yield i_in
.nia
.eq(virt_addr
)
435 yield i_in
.stop_mark
.eq(0)
436 yield i_m_in
.tlbld
.eq(0)
437 yield i_m_in
.tlbie
.eq(0)
438 yield i_m_in
.addr
.eq(0)
439 yield i_m_in
.pte
.eq(0)
444 # miss, stalls for a bit
447 yield i_in.nia.eq(virt_addr)
449 valid = yield i_out.valid
450 failed = yield i_out.fetch_failed
451 while not valid and not failed:
453 valid = yield i_out.valid
454 failed = yield i_out.fetch_failed
456 nia = yield i_out.nia
457 insn = yield i_out.insn
461 nia
, insn
, valid
, failed
= yield from icache_read(dut
,virt_addr
,0,1)
463 yield from debug(dut
, "test done")
467 print ("failed?", "yes" if failed
else "no")
470 print ("fetched %x from addr %x" % (insn
, nia
))
471 assert insn
== expected_insn
476 def _test_loadstore1_invalid(dut
, mem
):
477 mmu
= dut
.submodules
.mmu
478 pi
= dut
.submodules
.ldst
.pi
481 print("=== test invalid ===")
484 msr
= MSRSpec(pr
=1, dr
=0, sf
=0) # set problem-state
485 ld_data
, exctype
, exc
= yield from pi_ld(pi
, addr
, 8, msr
=msr
)
486 print("ld_data", ld_data
, exctype
, exc
)
487 assert (exctype
== "slow")
488 invalid
= exc
.invalid
489 assert (invalid
== 1)
491 print("=== test invalid done ===")
496 def _test_loadstore1_microwatt_mmu_bin_test2(dut
, mem
):
497 mmu
= dut
.submodules
.mmu
498 pi
= dut
.submodules
.ldst
.pi
499 ldst
= dut
.submodules
.ldst
# to get at DAR (NOT part of PortInterface)
502 yield mmu
.rin
.prtbl
.eq(0x12000) # set process table
503 yield mmu
.rin
.pid
.eq(0x1) # set PID=1
507 msr
= MSRSpec(pr
=1, dr
=1, sf
=1)
509 print("=== alignment error (ld) ===")
511 ld_data
, exctype
, exc
= yield from pi_ld(pi
, addr
, 8, msr
=msr
)
512 print("ld_data after mmu.bin test2")
514 assert ld_data
== 0x0000000badc0ffee
515 assert exctype
is None
520 def _test_loadstore1(dut
, mem
):
521 mmu
= dut
.submodules
.mmu
522 pi
= dut
.submodules
.ldst
.pi
523 ldst
= dut
.submodules
.ldst
# to get at DAR (NOT part of PortInterface)
526 yield mmu
.rin
.prtbl
.eq(0x1000000) # set process table
530 data
= 0xf553b658ba7e1f51
531 msr
= MSRSpec(pr
=0, dr
=0, sf
=0)
534 yield from pi_st(pi
, addr
, data
, 8, msr
=msr
)
537 ld_data
, exctype
, exc
= yield from pi_ld(pi
, addr
, 8, msr
=msr
)
538 assert ld_data
== 0xf553b658ba7e1f51
539 assert exctype
is None
541 ld_data
, exctype
, exc
= yield from pi_ld(pi
, addr
, 8, msr
=msr
)
542 assert ld_data
== 0xf553b658ba7e1f51
543 assert exctype
is None
545 print("do_dcbz ===============")
546 yield from pi_st(pi
, addr
, data
, 8, msr
=msr
, is_dcbz
=1)
547 print("done_dcbz ===============")
550 ld_data
, exctype
, exc
= yield from pi_ld(pi
, addr
, 8, msr
=msr
)
551 print("ld_data after dcbz")
554 assert exctype
is None
557 print("=== alignment error (ld) ===")
559 ld_data
, exctype
, exc
= yield from pi_ld(pi
, addr
, 8, msr
=msr
)
561 alignment
= exc
.alignment
562 happened
= exc
.happened
563 yield # wait for dsr to update
569 assert (happened
== 1)
570 assert (alignment
== 1)
572 assert (exctype
== "fast")
573 yield from wait_busy(pi
, debug
="pi_ld_E_alignment_error")
574 # wait is only needed in case of in exception here
575 print("=== alignment error test passed (ld) ===")
577 # take some cycles in between so that gtkwave separates out
584 print("=== alignment error (st) ===")
586 exctype
, exc
= yield from pi_st(pi
, addr
,0, 8, msr
=msr
)
588 alignment
= exc
.alignment
589 happened
= exc
.happened
593 assert (happened
== 1)
594 assert (alignment
==1)
596 assert (exctype
== "fast")
597 #???? yield from wait_busy(pi, debug="pi_st_E_alignment_error")
598 # wait is only needed in case of in exception here
599 print("=== alignment error test passed (st) ===")
603 print("=== no alignment error (ld) ===")
605 ld_data
, exctype
, exc
= yield from pi_ld(pi
, addr
, 8, msr
=msr
)
606 print("ld_data", ld_data
, exctype
, exc
)
608 alignment
= exc
.alignment
609 happened
= exc
.happened
613 assert (happened
== 0)
614 assert (alignment
== 0)
615 print("=== no alignment error done (ld) ===")
618 addrs
= [0x456920,0xa7a180,0x299420,0x1d9d60]
621 print("== RANDOM addr ==",hex(addr
))
622 ld_data
, exctype
, exc
= yield from pi_ld(pi
, addr
, 8, msr
=msr
)
623 print("ld_data[RANDOM]",ld_data
,exc
,addr
)
624 assert (exctype
== None)
627 print("== RANDOM addr ==",hex(addr
))
628 exc
= yield from pi_st(pi
, addr
,0xFF*addr
, 8, msr
=msr
)
629 assert (exctype
== None)
631 # readback written data and compare
633 print("== RANDOM addr ==",hex(addr
))
634 ld_data
, exctype
, exc
= yield from pi_ld(pi
, addr
, 8, msr
=msr
)
635 print("ld_data[RANDOM_READBACK]",ld_data
,exc
,addr
)
636 assert (exctype
== None)
637 assert (ld_data
== 0xFF*addr
)
639 print("== RANDOM addr done ==")
644 def _test_loadstore1_ifetch_invalid(dut
, mem
):
645 mmu
= dut
.submodules
.mmu
646 ldst
= dut
.submodules
.ldst
648 icache
= dut
.submodules
.ldst
.icache
651 print("=== test loadstore instruction (invalid) ===")
657 # first virtual memory test
659 print ("set process table")
660 yield from debug(dut
, "set prtbl")
661 yield mmu
.rin
.prtbl
.eq(0x1000000) # set process table
664 yield from debug(dut
, "real mem instruction")
665 # set address to zero, update mem[0] to 01234
667 expected_insn
= 0x1234
668 mem
[addr
] = expected_insn
670 yield i_in
.priv_mode
.eq(1)
672 yield i_in
.nia
.eq(addr
)
673 yield i_in
.stop_mark
.eq(0)
674 yield i_m_in
.tlbld
.eq(0)
675 yield i_m_in
.tlbie
.eq(0)
676 yield i_m_in
.addr
.eq(0)
677 yield i_m_in
.pte
.eq(0)
682 # miss, stalls for a bit
684 yield i_in
.nia
.eq(addr
)
686 valid
= yield i_out
.valid
687 nia
= yield i_out
.nia
690 valid
= yield i_out
.valid
693 nia
= yield i_out
.nia
694 insn
= yield i_out
.insn
699 print ("fetched %x from addr %x" % (insn
, nia
))
700 assert insn
== expected_insn
702 print("=== test loadstore instruction (virtual) ===")
703 yield from debug(dut
, "virtual instr req")
705 # look up i-cache expecting it to fail
707 # set address to 0x10200, update mem[] to 5678
709 real_addr
= virt_addr
710 expected_insn
= 0x5678
711 mem
[real_addr
] = expected_insn
713 yield i_in
.priv_mode
.eq(1)
714 yield i_in
.virt_mode
.eq(1)
716 yield i_in
.nia
.eq(virt_addr
)
717 yield i_in
.stop_mark
.eq(0)
718 yield i_m_in
.tlbld
.eq(0)
719 yield i_m_in
.tlbie
.eq(0)
720 yield i_m_in
.addr
.eq(0)
721 yield i_m_in
.pte
.eq(0)
726 # miss, stalls for a bit
728 yield i_in
.nia
.eq(virt_addr
)
730 valid
= yield i_out
.valid
731 failed
= yield i_out
.fetch_failed
732 while not valid
and not failed
:
734 valid
= yield i_out
.valid
735 failed
= yield i_out
.fetch_failed
738 print ("failed?", "yes" if failed
else "no")
743 print("=== test invalid loadstore instruction (instruction fault) ===")
745 yield from debug(dut
, "instr fault (perm err expected)")
748 yield ldst
.priv_mode
.eq(0)
749 yield ldst
.instr_fault
.eq(1)
750 yield ldst
.maddr
.eq(virt_addr
)
751 #ld_data, exctype, exc = yield from pi_ld(pi, virt_addr, 8, msr=msr)
753 yield ldst
.instr_fault
.eq(0)
755 done
= yield (ldst
.done
)
756 exc_info
= yield from get_exception_info(pi
.exc_o
)
757 if done
or exc_info
.happened
:
760 assert exc_info
.happened
== 1 # different here as expected
762 # TODO: work out what kind of exception occurred and check it's
763 # the right one. we *expect* it to be a permissions error because
764 # the RPTE leaf node in pagetables.test2 is marked as "non-executable"
765 # but we also expect instr_fault to be set because it is an instruction
767 print (" MMU lookup exception type?")
768 for fname
in LDSTExceptionTuple
._fields
:
769 print (" fname %20s %d" % (fname
, getattr(exc_info
, fname
)))
771 # ok now printed them out and visually inspected: check them with asserts
772 assert exc_info
.instr_fault
== 1 # instruction fault (yes!)
773 assert exc_info
.perm_error
== 1 # permissions (yes!)
774 assert exc_info
.rc_error
== 0
775 assert exc_info
.alignment
== 0
776 assert exc_info
.invalid
== 0
777 assert exc_info
.segment_fault
== 0
778 assert exc_info
.rc_error
== 0
780 yield from debug(dut
, "test done")
781 yield ldst
.instr_fault
.eq(0)
789 def test_loadstore1_ifetch_unit_iface():
791 m
, cmpi
= setup_mmu()
793 mem
= pagetables
.test1
795 # set this up before passing to Simulator (which calls elaborate)
796 icache
= m
.submodules
.ldst
.icache
797 icache
.use_fetch_interface() # this is the function which converts
798 # to FetchUnitInterface. *including*
799 # rewiring the Wishbone Bus to ibus
805 sim
.add_sync_process(wrap(_test_loadstore1_ifetch_iface(m
, mem
)))
806 # add two wb_get processes onto the *same* memory dictionary.
807 # this shouuuld work.... cross-fingers...
808 sim
.add_sync_process(wrap(wb_get(cmpi
.wb_bus(), mem
)))
809 sim
.add_sync_process(wrap(wb_get(icache
.ibus
, mem
))) # ibus not bus
810 with sim
.write_vcd('test_loadstore1_ifetch_iface.vcd',
811 traces
=[m
.debug_status
]): # include extra debug
815 def test_loadstore1_ifetch():
817 m
, cmpi
= setup_mmu()
819 mem
= pagetables
.test1
825 icache
= m
.submodules
.ldst
.icache
826 sim
.add_sync_process(wrap(_test_loadstore1_ifetch(m
, mem
)))
827 # add two wb_get processes onto the *same* memory dictionary.
828 # this shouuuld work.... cross-fingers...
829 sim
.add_sync_process(wrap(wb_get(cmpi
.wb_bus(), mem
)))
830 sim
.add_sync_process(wrap(wb_get(icache
.bus
, mem
)))
831 with sim
.write_vcd('test_loadstore1_ifetch.vcd',
832 traces
=[m
.debug_status
]): # include extra debug
836 def test_loadstore1():
838 m
, cmpi
= setup_mmu()
840 mem
= pagetables
.test1
846 sim
.add_sync_process(wrap(_test_loadstore1(m
, mem
)))
847 sim
.add_sync_process(wrap(wb_get(cmpi
.wb_bus(), mem
)))
848 with sim
.write_vcd('test_loadstore1.vcd'):
852 def test_loadstore1_microwatt_mmu_bin_test2():
854 m
, cmpi
= setup_mmu()
856 mem
= pagetables
.microwatt_test2
862 sim
.add_sync_process(wrap(_test_loadstore1_microwatt_mmu_bin_test2(m
, mem
)))
863 sim
.add_sync_process(wrap(wb_get(cmpi
.wb_bus(), mem
)))
864 with sim
.write_vcd('test_loadstore1.vcd'):
868 def test_loadstore1_invalid():
870 m
, cmpi
= setup_mmu()
878 sim
.add_sync_process(wrap(_test_loadstore1_invalid(m
, mem
)))
879 sim
.add_sync_process(wrap(wb_get(cmpi
.wb_bus(), mem
)))
880 with sim
.write_vcd('test_loadstore1_invalid.vcd'):
884 def test_loadstore1_ifetch_invalid():
885 m
, cmpi
= setup_mmu()
887 # this is a specially-arranged page table which has the permissions
888 # barred for execute on the leaf node (EAA=0x2 instead of EAA=0x3)
889 mem
= pagetables
.test2
895 icache
= m
.submodules
.ldst
.icache
896 sim
.add_sync_process(wrap(_test_loadstore1_ifetch_invalid(m
, mem
)))
897 # add two wb_get processes onto the *same* memory dictionary.
898 # this shouuuld work.... cross-fingers...
899 sim
.add_sync_process(wrap(wb_get(cmpi
.wb_bus(), mem
)))
900 sim
.add_sync_process(wrap(wb_get(icache
.bus
, mem
)))
901 with sim
.write_vcd('test_loadstore1_ifetch_invalid.vcd',
902 traces
=[m
.debug_status
]): # include extra debug
906 def test_loadstore1_ifetch_multi():
907 m
, cmpi
= setup_mmu()
910 # this is a specially-arranged page table which has the permissions
911 # barred for execute on the leaf node (EAA=0x2 instead of EAA=0x3)
912 mem
= pagetables
.test1
914 # set this up before passing to Simulator (which calls elaborate)
915 icache
= m
.submodules
.ldst
.icache
916 icache
.use_fetch_interface() # this is the function which converts
917 # to FetchUnitInterface. *including*
918 # rewiring the Wishbone Bus to ibus
924 sim
.add_sync_process(wrap(_test_loadstore1_ifetch_multi(m
, mem
)))
925 # add two wb_get processes onto the *same* memory dictionary.
926 # this shouuuld work.... cross-fingers...
927 sim
.add_sync_process(wrap(wb_get(cmpi
.wb_bus(), mem
)))
928 sim
.add_sync_process(wrap(wb_get(icache
.ibus
, mem
))) # ibus not bus
929 with sim
.write_vcd('test_loadstore1_ifetch_multi.vcd',
930 traces
=[m
.debug_status
]): # include extra debug
933 if __name__
== '__main__':
935 test_loadstore1_microwatt_mmu_bin_test2()
936 #test_loadstore1_invalid()
937 #test_loadstore1_ifetch() #FIXME
938 #test_loadstore1_ifetch_invalid()
939 #test_loadstore1_ifetch_unit_iface() # guess: should be working
940 #test_loadstore1_ifetch_multi()