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(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(0x1000000) # set process table
505 data
= 0xf553b658ba7e1f51
506 msr
= MSRSpec(pr
=0, dr
=0, sf
=0)
509 yield from pi_st(pi
, addr
, data
, 8, msr
=msr
)
512 ld_data
, exctype
, exc
= yield from pi_ld(pi
, addr
, 8, msr
=msr
)
513 assert ld_data
== 0xf553b658ba7e1f51
514 assert exctype
is None
516 ld_data
, exctype
, exc
= yield from pi_ld(pi
, addr
, 8, msr
=msr
)
517 assert ld_data
== 0xf553b658ba7e1f51
518 assert exctype
is None
520 print("do_dcbz ===============")
521 yield from pi_st(pi
, addr
, data
, 8, msr
=msr
, is_dcbz
=1)
522 print("done_dcbz ===============")
525 ld_data
, exctype
, exc
= yield from pi_ld(pi
, addr
, 8, msr
=msr
)
526 print("ld_data after dcbz")
529 assert exctype
is None
532 print("=== alignment error (ld) ===")
534 ld_data
, exctype
, exc
= yield from pi_ld(pi
, addr
, 8, msr
=msr
)
536 alignment
= exc
.alignment
537 happened
= exc
.happened
538 yield # wait for dsr to update
544 assert (happened
== 1)
545 assert (alignment
== 1)
547 assert (exctype
== "fast")
548 yield from wait_busy(pi
, debug
="pi_ld_E_alignment_error")
549 # wait is only needed in case of in exception here
550 print("=== alignment error test passed (ld) ===")
552 # take some cycles in between so that gtkwave separates out
559 print("=== alignment error (st) ===")
561 exctype
, exc
= yield from pi_st(pi
, addr
,0, 8, msr
=msr
)
563 alignment
= exc
.alignment
564 happened
= exc
.happened
568 assert (happened
== 1)
569 assert (alignment
==1)
571 assert (exctype
== "fast")
572 #???? yield from wait_busy(pi, debug="pi_st_E_alignment_error")
573 # wait is only needed in case of in exception here
574 print("=== alignment error test passed (st) ===")
578 print("=== no alignment error (ld) ===")
580 ld_data
, exctype
, exc
= yield from pi_ld(pi
, addr
, 8, msr
=msr
)
581 print("ld_data", ld_data
, exctype
, exc
)
583 alignment
= exc
.alignment
584 happened
= exc
.happened
588 assert (happened
== 0)
589 assert (alignment
== 0)
590 print("=== no alignment error done (ld) ===")
593 addrs
= [0x456920,0xa7a180,0x299420,0x1d9d60]
596 print("== RANDOM addr ==",hex(addr
))
597 ld_data
, exctype
, exc
= yield from pi_ld(pi
, addr
, 8, msr
=msr
)
598 print("ld_data[RANDOM]",ld_data
,exc
,addr
)
599 assert (exctype
== None)
602 print("== RANDOM addr ==",hex(addr
))
603 exc
= yield from pi_st(pi
, addr
,0xFF*addr
, 8, msr
=msr
)
604 assert (exctype
== None)
606 # readback written data and compare
608 print("== RANDOM addr ==",hex(addr
))
609 ld_data
, exctype
, exc
= yield from pi_ld(pi
, addr
, 8, msr
=msr
)
610 print("ld_data[RANDOM_READBACK]",ld_data
,exc
,addr
)
611 assert (exctype
== None)
612 assert (ld_data
== 0xFF*addr
)
614 print("== RANDOM addr done ==")
619 def _test_loadstore1_ifetch_invalid(dut
, mem
):
620 mmu
= dut
.submodules
.mmu
621 ldst
= dut
.submodules
.ldst
623 icache
= dut
.submodules
.ldst
.icache
626 print("=== test loadstore instruction (invalid) ===")
632 # first virtual memory test
634 print ("set process table")
635 yield from debug(dut
, "set prtbl")
636 yield mmu
.rin
.prtbl
.eq(0x1000000) # set process table
639 yield from debug(dut
, "real mem instruction")
640 # set address to zero, update mem[0] to 01234
642 expected_insn
= 0x1234
643 mem
[addr
] = expected_insn
645 yield i_in
.priv_mode
.eq(1)
647 yield i_in
.nia
.eq(addr
)
648 yield i_in
.stop_mark
.eq(0)
649 yield i_m_in
.tlbld
.eq(0)
650 yield i_m_in
.tlbie
.eq(0)
651 yield i_m_in
.addr
.eq(0)
652 yield i_m_in
.pte
.eq(0)
657 # miss, stalls for a bit
659 yield i_in
.nia
.eq(addr
)
661 valid
= yield i_out
.valid
662 nia
= yield i_out
.nia
665 valid
= yield i_out
.valid
668 nia
= yield i_out
.nia
669 insn
= yield i_out
.insn
674 print ("fetched %x from addr %x" % (insn
, nia
))
675 assert insn
== expected_insn
677 print("=== test loadstore instruction (virtual) ===")
678 yield from debug(dut
, "virtual instr req")
680 # look up i-cache expecting it to fail
682 # set address to 0x10200, update mem[] to 5678
684 real_addr
= virt_addr
685 expected_insn
= 0x5678
686 mem
[real_addr
] = expected_insn
688 yield i_in
.priv_mode
.eq(1)
689 yield i_in
.virt_mode
.eq(1)
691 yield i_in
.nia
.eq(virt_addr
)
692 yield i_in
.stop_mark
.eq(0)
693 yield i_m_in
.tlbld
.eq(0)
694 yield i_m_in
.tlbie
.eq(0)
695 yield i_m_in
.addr
.eq(0)
696 yield i_m_in
.pte
.eq(0)
701 # miss, stalls for a bit
703 yield i_in
.nia
.eq(virt_addr
)
705 valid
= yield i_out
.valid
706 failed
= yield i_out
.fetch_failed
707 while not valid
and not failed
:
709 valid
= yield i_out
.valid
710 failed
= yield i_out
.fetch_failed
713 print ("failed?", "yes" if failed
else "no")
718 print("=== test invalid loadstore instruction (instruction fault) ===")
720 yield from debug(dut
, "instr fault (perm err expected)")
723 yield ldst
.priv_mode
.eq(0)
724 yield ldst
.instr_fault
.eq(1)
725 yield ldst
.maddr
.eq(virt_addr
)
726 #ld_data, exctype, exc = yield from pi_ld(pi, virt_addr, 8, msr=msr)
728 yield ldst
.instr_fault
.eq(0)
730 done
= yield (ldst
.done
)
731 exc_info
= yield from get_exception_info(pi
.exc_o
)
732 if done
or exc_info
.happened
:
735 assert exc_info
.happened
== 1 # different here as expected
737 # TODO: work out what kind of exception occurred and check it's
738 # the right one. we *expect* it to be a permissions error because
739 # the RPTE leaf node in pagetables.test2 is marked as "non-executable"
740 # but we also expect instr_fault to be set because it is an instruction
742 print (" MMU lookup exception type?")
743 for fname
in LDSTExceptionTuple
._fields
:
744 print (" fname %20s %d" % (fname
, getattr(exc_info
, fname
)))
746 # ok now printed them out and visually inspected: check them with asserts
747 assert exc_info
.instr_fault
== 1 # instruction fault (yes!)
748 assert exc_info
.perm_error
== 1 # permissions (yes!)
749 assert exc_info
.rc_error
== 0
750 assert exc_info
.alignment
== 0
751 assert exc_info
.invalid
== 0
752 assert exc_info
.segment_fault
== 0
753 assert exc_info
.rc_error
== 0
755 yield from debug(dut
, "test done")
756 yield ldst
.instr_fault
.eq(0)
764 def test_loadstore1_ifetch_unit_iface():
766 m
, cmpi
= setup_mmu()
768 mem
= pagetables
.test1
770 # set this up before passing to Simulator (which calls elaborate)
771 icache
= m
.submodules
.ldst
.icache
772 icache
.use_fetch_interface() # this is the function which converts
773 # to FetchUnitInterface. *including*
774 # rewiring the Wishbone Bus to ibus
780 sim
.add_sync_process(wrap(_test_loadstore1_ifetch_iface(m
, mem
)))
781 # add two wb_get processes onto the *same* memory dictionary.
782 # this shouuuld work.... cross-fingers...
783 sim
.add_sync_process(wrap(wb_get(cmpi
.wb_bus(), mem
)))
784 sim
.add_sync_process(wrap(wb_get(icache
.ibus
, mem
))) # ibus not bus
785 with sim
.write_vcd('test_loadstore1_ifetch_iface.vcd',
786 traces
=[m
.debug_status
]): # include extra debug
790 def test_loadstore1_ifetch():
792 m
, cmpi
= setup_mmu()
794 mem
= pagetables
.test1
800 icache
= m
.submodules
.ldst
.icache
801 sim
.add_sync_process(wrap(_test_loadstore1_ifetch(m
, mem
)))
802 # add two wb_get processes onto the *same* memory dictionary.
803 # this shouuuld work.... cross-fingers...
804 sim
.add_sync_process(wrap(wb_get(cmpi
.wb_bus(), mem
)))
805 sim
.add_sync_process(wrap(wb_get(icache
.bus
, mem
)))
806 with sim
.write_vcd('test_loadstore1_ifetch.vcd',
807 traces
=[m
.debug_status
]): # include extra debug
811 def test_loadstore1():
813 m
, cmpi
= setup_mmu()
815 mem
= pagetables
.test1
821 sim
.add_sync_process(wrap(_test_loadstore1(m
, mem
)))
822 sim
.add_sync_process(wrap(wb_get(cmpi
.wb_bus(), mem
)))
823 with sim
.write_vcd('test_loadstore1.vcd'):
827 def test_loadstore1_invalid():
829 m
, cmpi
= setup_mmu()
837 sim
.add_sync_process(wrap(_test_loadstore1_invalid(m
, mem
)))
838 sim
.add_sync_process(wrap(wb_get(cmpi
.wb_bus(), mem
)))
839 with sim
.write_vcd('test_loadstore1_invalid.vcd'):
842 def test_loadstore1_ifetch_invalid():
843 m
, cmpi
= setup_mmu()
845 # this is a specially-arranged page table which has the permissions
846 # barred for execute on the leaf node (EAA=0x2 instead of EAA=0x3)
847 mem
= pagetables
.test2
853 icache
= m
.submodules
.ldst
.icache
854 sim
.add_sync_process(wrap(_test_loadstore1_ifetch_invalid(m
, mem
)))
855 # add two wb_get processes onto the *same* memory dictionary.
856 # this shouuuld work.... cross-fingers...
857 sim
.add_sync_process(wrap(wb_get(cmpi
.wb_bus(), mem
)))
858 sim
.add_sync_process(wrap(wb_get(icache
.bus
, mem
)))
859 with sim
.write_vcd('test_loadstore1_ifetch_invalid.vcd',
860 traces
=[m
.debug_status
]): # include extra debug
863 def test_loadstore1_ifetch_multi():
864 m
, cmpi
= setup_mmu()
867 # this is a specially-arranged page table which has the permissions
868 # barred for execute on the leaf node (EAA=0x2 instead of EAA=0x3)
869 mem
= pagetables
.test1
871 # set this up before passing to Simulator (which calls elaborate)
872 icache
= m
.submodules
.ldst
.icache
873 icache
.use_fetch_interface() # this is the function which converts
874 # to FetchUnitInterface. *including*
875 # rewiring the Wishbone Bus to ibus
881 sim
.add_sync_process(wrap(_test_loadstore1_ifetch_multi(m
, mem
)))
882 # add two wb_get processes onto the *same* memory dictionary.
883 # this shouuuld work.... cross-fingers...
884 sim
.add_sync_process(wrap(wb_get(cmpi
.wb_bus(), mem
)))
885 sim
.add_sync_process(wrap(wb_get(icache
.ibus
, mem
))) # ibus not bus
886 with sim
.write_vcd('test_loadstore1_ifetch_multi.vcd',
887 traces
=[m
.debug_status
]): # include extra debug
890 if __name__
== '__main__':
892 test_loadstore1_invalid()
893 test_loadstore1_ifetch() #FIXME
894 test_loadstore1_ifetch_invalid()
895 test_loadstore1_ifetch_unit_iface() # guess: should be working
896 test_loadstore1_ifetch_multi()