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
))
222 def _test_loadstore1_ifetch_multi(dut
, mem
):
223 mmu
= dut
.submodules
.mmu
224 ldst
= dut
.submodules
.ldst
226 icache
= dut
.submodules
.ldst
.icache
227 assert wbget
.stop
== False
229 print ("set process table")
230 yield from debug(dut
, "set prtble")
231 yield mmu
.rin
.prtbl
.eq(0x1000000) # set process table
238 # fetch instructions from multiple addresses
239 # should cope with some addresses being invalid
240 real_addrs
= [0,4,8,0,8,4,0,0,12]
241 write_mem2(mem
,0,0xF0,0xF4)
242 write_mem2(mem
,8,0xF8,0xFC)
244 yield i_in
.priv_mode
.eq(1)
245 for addr
in real_addrs
:
246 yield from debug(dut
, "real_addr "+hex(addr
))
247 insn
= yield from read_from_addr(icache
, addr
, stall
=False)
248 nia
= yield i_out
.nia
# NO, must use FetchUnitInterface
249 print ("TEST_MULTI: fetched %x from addr %x == %x" % (insn
, nia
,addr
))
250 assert insn
==0xF0+addr
252 # now with virtual memory enabled
253 yield i_in
.virt_mode
.eq(1)
255 virt_addrs
= [0x10200,0x10204,0x10208,0x10200,
256 0x102008,0x10204,0x10200,0x10200,0x10200C]
258 write_mem2(mem
,0x10200,0xF8,0xFC)
260 for addr
in virt_addrs
:
261 yield from debug(dut
, "virt_addr "+hex(addr
))
263 valid
, failed
= yield from lookup_virt(dut
,addr
)
265 print("TEST_MULTI: failed=",failed
) # this is reported wrong
266 if failed
==1: # test one first
267 yield from mmu_lookup(dut
,addr
)
268 valid
, failed
= yield from lookup_virt(dut
,addr
)
274 def _test_loadstore1_ifetch(dut
, mem
):
275 """test_loadstore1_ifetch
277 this is quite a complex multi-step test.
279 * first (just because, as a demo) read in priv mode, non-virtual.
280 just like in experiment/icache.py itself.
282 * second, using the (usual) PTE for these things (which came originally
283 from gem5-experimental experiment/radix_walk_example.txt) do a
284 virtual-memory read through the *instruction* cache.
285 this is expected to FAIL
287 * third: mess about with the MMU, setting "iside" (instruction-side),
288 requesting an MMU RADIX LOOKUP. this triggers an itlb_load
289 (instruction-cache TLB entry-insertion)
291 * fourth and finally: retry the read of the instruction through i-cache.
292 this is now expected to SUCCEED
297 mmu
= dut
.submodules
.mmu
298 ldst
= dut
.submodules
.ldst
300 icache
= dut
.submodules
.ldst
.icache
303 print("=== test loadstore instruction (real) ===")
309 # first virtual memory test
311 print ("set process table")
312 yield from debug(dut
, "set prtble")
313 yield mmu
.rin
.prtbl
.eq(0x1000000) # set process table
316 yield from debug(dut
, "real mem instruction")
317 # set address to zero, update mem[0] to 01234
319 expected_insn
= 0x1234
320 mem
[addr
] = expected_insn
322 yield i_in
.priv_mode
.eq(1)
324 yield i_in
.nia
.eq(addr
)
325 yield i_in
.stop_mark
.eq(0)
326 yield i_m_in
.tlbld
.eq(0)
327 yield i_m_in
.tlbie
.eq(0)
328 yield i_m_in
.addr
.eq(0)
329 yield i_m_in
.pte
.eq(0)
334 # miss, stalls for a bit -- this one is different here
335 ##nia, insn, valid, failed = yield from icache_read(dut,addr,0,0)
340 yield i_in
.nia
.eq(addr
)
342 valid
= yield i_out
.valid
345 valid
= yield i_out
.valid
348 nia
= yield i_out
.nia
349 insn
= yield i_out
.insn
353 print ("fetched %x from addr %x" % (insn
, nia
))
354 assert insn
== expected_insn
356 print("=== test loadstore instruction (virtual) ===")
358 # look up i-cache expecting it to fail
360 yield from debug(dut
, "virtual instr req")
361 # set address to 0x10200, update mem[] to 5678
363 real_addr
= virt_addr
364 expected_insn
= 0x5678
365 mem
[real_addr
] = expected_insn
367 yield i_in
.priv_mode
.eq(0)
368 yield i_in
.virt_mode
.eq(1)
370 yield i_in
.nia
.eq(virt_addr
)
371 yield i_in
.stop_mark
.eq(0)
372 yield i_m_in
.tlbld
.eq(0)
373 yield i_m_in
.tlbie
.eq(0)
374 yield i_m_in
.addr
.eq(0)
375 yield i_m_in
.pte
.eq(0)
380 # miss, stalls for a bit
382 yield i_in
.nia
.eq(virt_addr
)
384 valid
= yield i_out
.valid
385 failed
= yield i_out
.fetch_failed
386 while not valid
and not failed
:
388 valid
= yield i_out
.valid
389 failed
= yield i_out
.fetch_failed
392 print ("failed?", "yes" if failed
else "no")
397 print("=== test loadstore instruction (instruction fault) ===")
399 yield from debug(dut
, "instr fault")
403 yield ldst
.priv_mode
.eq(0)
404 yield ldst
.instr_fault
.eq(1)
405 yield ldst
.maddr
.eq(virt_addr
)
406 # still broken -- investigate
407 # msr = MSRSpec(pr=?, dr=?, sf=0)
408 # ld_data, exctype, exc = yield from pi_ld(pi, virt_addr, 8, msr=msr)
410 yield ldst
.instr_fault
.eq(0)
412 done
= yield (ldst
.done
)
413 exc_info
= yield from get_exception_info(pi
.exc_o
)
414 if done
or exc_info
.happened
:
417 assert exc_info
.happened
== 0 # assert just before doing the fault set zero
418 yield ldst
.instr_fault
.eq(0)
423 print("=== test loadstore instruction (try instruction again) ===")
424 yield from debug(dut
, "instr virt retry")
425 # set address to 0x10200, update mem[] to 5678
427 real_addr
= virt_addr
428 expected_insn
= 0x5678
430 yield i_in
.priv_mode
.eq(0)
431 yield i_in
.virt_mode
.eq(1)
433 yield i_in
.nia
.eq(virt_addr
)
434 yield i_in
.stop_mark
.eq(0)
435 yield i_m_in
.tlbld
.eq(0)
436 yield i_m_in
.tlbie
.eq(0)
437 yield i_m_in
.addr
.eq(0)
438 yield i_m_in
.pte
.eq(0)
443 # miss, stalls for a bit
446 yield i_in.nia.eq(virt_addr)
448 valid = yield i_out.valid
449 failed = yield i_out.fetch_failed
450 while not valid and not failed:
452 valid = yield i_out.valid
453 failed = yield i_out.fetch_failed
455 nia = yield i_out.nia
456 insn = yield i_out.insn
460 nia
, insn
, valid
, failed
= yield from icache_read(dut
,virt_addr
,0,1)
462 yield from debug(dut
, "test done")
466 print ("failed?", "yes" if failed
else "no")
469 print ("fetched %x from addr %x" % (insn
, nia
))
470 assert insn
== expected_insn
475 def _test_loadstore1_invalid(dut
, mem
):
476 mmu
= dut
.submodules
.mmu
477 pi
= dut
.submodules
.ldst
.pi
480 print("=== test invalid ===")
483 msr
= MSRSpec(pr
=1, dr
=0, sf
=0) # set problem-state
484 ld_data
, exctype
, exc
= yield from pi_ld(pi
, addr
, 8, msr
=msr
)
485 print("ld_data", ld_data
, exctype
, exc
)
486 assert (exctype
== "slow")
487 invalid
= exc
.invalid
488 assert (invalid
== 1)
490 print("=== test invalid done ===")
495 def _test_loadstore1_microwatt_mmu_bin_test2(dut
, mem
):
496 mmu
= dut
.submodules
.mmu
497 pi
= dut
.submodules
.ldst
.pi
498 ldst
= dut
.submodules
.ldst
# to get at DAR (NOT part of PortInterface)
501 yield mmu
.rin
.prtbl
.eq(0x12000) # set process table
502 yield mmu
.rin
.pid
.eq(0x1) # set PID=1
506 msr
= MSRSpec(pr
=1, dr
=1, sf
=1)
508 print("=== alignment error (ld) ===")
510 ld_data
, exctype
, exc
= yield from pi_ld(pi
, addr
, 8, msr
=msr
)
511 print("ld_data after mmu.bin test2")
513 assert ld_data
== 0x0000000badc0ffee
514 assert exctype
is None
519 def _test_loadstore1(dut
, mem
):
520 mmu
= dut
.submodules
.mmu
521 pi
= dut
.submodules
.ldst
.pi
522 ldst
= dut
.submodules
.ldst
# to get at DAR (NOT part of PortInterface)
525 yield mmu
.rin
.prtbl
.eq(0x1000000) # set process table
529 data
= 0xf553b658ba7e1f51
530 msr
= MSRSpec(pr
=0, dr
=0, sf
=0)
533 yield from pi_st(pi
, addr
, data
, 8, msr
=msr
)
536 ld_data
, exctype
, exc
= yield from pi_ld(pi
, addr
, 8, msr
=msr
)
537 assert ld_data
== 0xf553b658ba7e1f51
538 assert exctype
is None
540 ld_data
, exctype
, exc
= yield from pi_ld(pi
, addr
, 8, msr
=msr
)
541 assert ld_data
== 0xf553b658ba7e1f51
542 assert exctype
is None
544 print("do_dcbz ===============")
545 yield from pi_st(pi
, addr
, data
, 8, msr
=msr
, is_dcbz
=1)
546 print("done_dcbz ===============")
549 ld_data
, exctype
, exc
= yield from pi_ld(pi
, addr
, 8, msr
=msr
)
550 print("ld_data after dcbz")
553 assert exctype
is None
556 print("=== alignment error (ld) ===")
558 ld_data
, exctype
, exc
= yield from pi_ld(pi
, addr
, 8, msr
=msr
)
560 alignment
= exc
.alignment
561 happened
= exc
.happened
562 yield # wait for dsr to update
568 assert (happened
== 1)
569 assert (alignment
== 1)
571 assert (exctype
== "fast")
572 yield from wait_busy(pi
, debug
="pi_ld_E_alignment_error")
573 # wait is only needed in case of in exception here
574 print("=== alignment error test passed (ld) ===")
576 # take some cycles in between so that gtkwave separates out
583 print("=== alignment error (st) ===")
585 exctype
, exc
= yield from pi_st(pi
, addr
,0, 8, msr
=msr
)
587 alignment
= exc
.alignment
588 happened
= exc
.happened
592 assert (happened
== 1)
593 assert (alignment
==1)
595 assert (exctype
== "fast")
596 #???? yield from wait_busy(pi, debug="pi_st_E_alignment_error")
597 # wait is only needed in case of in exception here
598 print("=== alignment error test passed (st) ===")
602 print("=== no alignment error (ld) ===")
604 ld_data
, exctype
, exc
= yield from pi_ld(pi
, addr
, 8, msr
=msr
)
605 print("ld_data", ld_data
, exctype
, exc
)
607 alignment
= exc
.alignment
608 happened
= exc
.happened
612 assert (happened
== 0)
613 assert (alignment
== 0)
614 print("=== no alignment error done (ld) ===")
617 addrs
= [0x456920,0xa7a180,0x299420,0x1d9d60]
620 print("== RANDOM addr ==",hex(addr
))
621 ld_data
, exctype
, exc
= yield from pi_ld(pi
, addr
, 8, msr
=msr
)
622 print("ld_data[RANDOM]",ld_data
,exc
,addr
)
623 assert (exctype
== None)
626 print("== RANDOM addr ==",hex(addr
))
627 exc
= yield from pi_st(pi
, addr
,0xFF*addr
, 8, msr
=msr
)
628 assert (exctype
== None)
630 # readback written data and compare
632 print("== RANDOM addr ==",hex(addr
))
633 ld_data
, exctype
, exc
= yield from pi_ld(pi
, addr
, 8, msr
=msr
)
634 print("ld_data[RANDOM_READBACK]",ld_data
,exc
,addr
)
635 assert (exctype
== None)
636 assert (ld_data
== 0xFF*addr
)
638 print("== RANDOM addr done ==")
643 def _test_loadstore1_ifetch_invalid(dut
, mem
):
644 mmu
= dut
.submodules
.mmu
645 ldst
= dut
.submodules
.ldst
647 icache
= dut
.submodules
.ldst
.icache
650 print("=== test loadstore instruction (invalid) ===")
656 # first virtual memory test
658 print ("set process table")
659 yield from debug(dut
, "set prtbl")
660 yield mmu
.rin
.prtbl
.eq(0x1000000) # set process table
663 yield from debug(dut
, "real mem instruction")
664 # set address to zero, update mem[0] to 01234
666 expected_insn
= 0x1234
667 mem
[addr
] = expected_insn
669 yield i_in
.priv_mode
.eq(1)
671 yield i_in
.nia
.eq(addr
)
672 yield i_in
.stop_mark
.eq(0)
673 yield i_m_in
.tlbld
.eq(0)
674 yield i_m_in
.tlbie
.eq(0)
675 yield i_m_in
.addr
.eq(0)
676 yield i_m_in
.pte
.eq(0)
681 # miss, stalls for a bit
683 yield i_in
.nia
.eq(addr
)
685 valid
= yield i_out
.valid
686 nia
= yield i_out
.nia
689 valid
= yield i_out
.valid
692 nia
= yield i_out
.nia
693 insn
= yield i_out
.insn
698 print ("fetched %x from addr %x" % (insn
, nia
))
699 assert insn
== expected_insn
701 print("=== test loadstore instruction (virtual) ===")
702 yield from debug(dut
, "virtual instr req")
704 # look up i-cache expecting it to fail
706 # set address to 0x10200, update mem[] to 5678
708 real_addr
= virt_addr
709 expected_insn
= 0x5678
710 mem
[real_addr
] = expected_insn
712 yield i_in
.priv_mode
.eq(1)
713 yield i_in
.virt_mode
.eq(1)
715 yield i_in
.nia
.eq(virt_addr
)
716 yield i_in
.stop_mark
.eq(0)
717 yield i_m_in
.tlbld
.eq(0)
718 yield i_m_in
.tlbie
.eq(0)
719 yield i_m_in
.addr
.eq(0)
720 yield i_m_in
.pte
.eq(0)
725 # miss, stalls for a bit
727 yield i_in
.nia
.eq(virt_addr
)
729 valid
= yield i_out
.valid
730 failed
= yield i_out
.fetch_failed
731 while not valid
and not failed
:
733 valid
= yield i_out
.valid
734 failed
= yield i_out
.fetch_failed
737 print ("failed?", "yes" if failed
else "no")
742 print("=== test invalid loadstore instruction (instruction fault) ===")
744 yield from debug(dut
, "instr fault (perm err expected)")
747 yield ldst
.priv_mode
.eq(0)
748 yield ldst
.instr_fault
.eq(1)
749 yield ldst
.maddr
.eq(virt_addr
)
750 #ld_data, exctype, exc = yield from pi_ld(pi, virt_addr, 8, msr=msr)
752 yield ldst
.instr_fault
.eq(0)
754 done
= yield (ldst
.done
)
755 exc_info
= yield from get_exception_info(pi
.exc_o
)
756 if done
or exc_info
.happened
:
759 assert exc_info
.happened
== 1 # different here as expected
761 # TODO: work out what kind of exception occurred and check it's
762 # the right one. we *expect* it to be a permissions error because
763 # the RPTE leaf node in pagetables.test2 is marked as "non-executable"
764 # but we also expect instr_fault to be set because it is an instruction
766 print (" MMU lookup exception type?")
767 for fname
in LDSTExceptionTuple
._fields
:
768 print (" fname %20s %d" % (fname
, getattr(exc_info
, fname
)))
770 # ok now printed them out and visually inspected: check them with asserts
771 assert exc_info
.instr_fault
== 1 # instruction fault (yes!)
772 assert exc_info
.perm_error
== 1 # permissions (yes!)
773 assert exc_info
.rc_error
== 0
774 assert exc_info
.alignment
== 0
775 assert exc_info
.invalid
== 0
776 assert exc_info
.segment_fault
== 0
777 assert exc_info
.rc_error
== 0
779 yield from debug(dut
, "test done")
780 yield ldst
.instr_fault
.eq(0)
788 def test_loadstore1_ifetch_unit_iface():
790 m
, cmpi
= setup_mmu()
792 mem
= pagetables
.test1
794 # set this up before passing to Simulator (which calls elaborate)
795 icache
= m
.submodules
.ldst
.icache
796 icache
.use_fetch_interface() # this is the function which converts
797 # to FetchUnitInterface. *including*
798 # rewiring the Wishbone Bus to ibus
804 sim
.add_sync_process(wrap(_test_loadstore1_ifetch_iface(m
, mem
)))
805 # add two wb_get processes onto the *same* memory dictionary.
806 # this shouuuld work.... cross-fingers...
807 sim
.add_sync_process(wrap(wb_get(cmpi
.wb_bus(), mem
)))
808 sim
.add_sync_process(wrap(wb_get(icache
.ibus
, mem
))) # ibus not bus
809 with sim
.write_vcd('test_loadstore1_ifetch_iface.vcd',
810 traces
=[m
.debug_status
]): # include extra debug
814 def test_loadstore1_ifetch():
816 m
, cmpi
= setup_mmu()
818 mem
= pagetables
.test1
824 icache
= m
.submodules
.ldst
.icache
825 sim
.add_sync_process(wrap(_test_loadstore1_ifetch(m
, mem
)))
826 # add two wb_get processes onto the *same* memory dictionary.
827 # this shouuuld work.... cross-fingers...
828 sim
.add_sync_process(wrap(wb_get(cmpi
.wb_bus(), mem
)))
829 sim
.add_sync_process(wrap(wb_get(icache
.bus
, mem
)))
830 with sim
.write_vcd('test_loadstore1_ifetch.vcd',
831 traces
=[m
.debug_status
]): # include extra debug
835 def test_loadstore1():
837 m
, cmpi
= setup_mmu()
839 mem
= pagetables
.test1
845 sim
.add_sync_process(wrap(_test_loadstore1(m
, mem
)))
846 sim
.add_sync_process(wrap(wb_get(cmpi
.wb_bus(), mem
)))
847 with sim
.write_vcd('test_loadstore1.vcd'):
851 def test_loadstore1_microwatt_mmu_bin_test2():
853 m
, cmpi
= setup_mmu()
855 mem
= pagetables
.microwatt_test2
861 sim
.add_sync_process(wrap(_test_loadstore1_microwatt_mmu_bin_test2(m
, mem
)))
862 sim
.add_sync_process(wrap(wb_get(cmpi
.wb_bus(), mem
)))
863 with sim
.write_vcd('test_loadstore1.vcd'):
867 def test_loadstore1_invalid():
869 m
, cmpi
= setup_mmu()
877 sim
.add_sync_process(wrap(_test_loadstore1_invalid(m
, mem
)))
878 sim
.add_sync_process(wrap(wb_get(cmpi
.wb_bus(), mem
)))
879 with sim
.write_vcd('test_loadstore1_invalid.vcd'):
882 def test_loadstore1_ifetch_invalid():
883 m
, cmpi
= setup_mmu()
885 # this is a specially-arranged page table which has the permissions
886 # barred for execute on the leaf node (EAA=0x2 instead of EAA=0x3)
887 mem
= pagetables
.test2
893 icache
= m
.submodules
.ldst
.icache
894 sim
.add_sync_process(wrap(_test_loadstore1_ifetch_invalid(m
, mem
)))
895 # add two wb_get processes onto the *same* memory dictionary.
896 # this shouuuld work.... cross-fingers...
897 sim
.add_sync_process(wrap(wb_get(cmpi
.wb_bus(), mem
)))
898 sim
.add_sync_process(wrap(wb_get(icache
.bus
, mem
)))
899 with sim
.write_vcd('test_loadstore1_ifetch_invalid.vcd',
900 traces
=[m
.debug_status
]): # include extra debug
903 def test_loadstore1_ifetch_multi():
904 m
, cmpi
= setup_mmu()
907 # this is a specially-arranged page table which has the permissions
908 # barred for execute on the leaf node (EAA=0x2 instead of EAA=0x3)
909 mem
= pagetables
.test1
911 # set this up before passing to Simulator (which calls elaborate)
912 icache
= m
.submodules
.ldst
.icache
913 icache
.use_fetch_interface() # this is the function which converts
914 # to FetchUnitInterface. *including*
915 # rewiring the Wishbone Bus to ibus
921 sim
.add_sync_process(wrap(_test_loadstore1_ifetch_multi(m
, mem
)))
922 # add two wb_get processes onto the *same* memory dictionary.
923 # this shouuuld work.... cross-fingers...
924 sim
.add_sync_process(wrap(wb_get(cmpi
.wb_bus(), mem
)))
925 sim
.add_sync_process(wrap(wb_get(icache
.ibus
, mem
))) # ibus not bus
926 with sim
.write_vcd('test_loadstore1_ifetch_multi.vcd',
927 traces
=[m
.debug_status
]): # include extra debug
930 if __name__
== '__main__':
932 test_loadstore1_microwatt_mmu_bin_test2()
933 #test_loadstore1_invalid()
934 #test_loadstore1_ifetch() #FIXME
935 #test_loadstore1_ifetch_invalid()
936 #test_loadstore1_ifetch_unit_iface() # guess: should be working
937 #test_loadstore1_ifetch_multi()