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_microwatt_mmu_bin_test5(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(0x12000) # set process table
527 yield mmu
.rin
.pid
.eq(0x1) # set PID=1
531 msr
= MSRSpec(pr
=1, dr
=1, sf
=1)
533 print("=== page-fault alignment error (ld) ===")
535 ld_data
, exctype
, exc
= yield from pi_ld(pi
, addr
, 8, msr
=msr
)
536 print("ld_data after mmu.bin test5")
543 def test_pi_ld_misalign(pi
,addr
,data_len
,msr
):
544 for i
in range(0,data_len
):
545 ld_data
, exctype
, exc
= yield from pi_ld(pi
, addr
+i
, data_len
, msr
=msr
)
548 assert exc
is None # use "is None" not "== None"
549 print("MISALIGN: test_pi_ld_misalign returned",hex(ld_data
))
551 assert exc
.alignment
== 1
554 def _test_loadstore1_misalign(dut
, mem
):
555 mmu
= dut
.submodules
.mmu
556 pi
= dut
.submodules
.ldst
.pi
557 ldst
= dut
.submodules
.ldst
# to get at DAR (NOT part of PortInterface)
560 yield mmu
.rin
.prtbl
.eq(0x12000) # set process table
561 yield mmu
.rin
.pid
.eq(0x1) # set PID=1
565 msr
= MSRSpec(pr
=0, dr
=0, sf
=1)
567 yield from test_pi_ld_misalign(pi
,0,8,msr
)
572 def _test_loadstore1(dut
, mem
):
573 mmu
= dut
.submodules
.mmu
574 pi
= dut
.submodules
.ldst
.pi
575 ldst
= dut
.submodules
.ldst
# to get at DAR (NOT part of PortInterface)
578 yield mmu
.rin
.prtbl
.eq(0x1000000) # set process table
582 data
= 0xf553b658ba7e1f51
583 msr
= MSRSpec(pr
=0, dr
=0, sf
=0)
586 yield from pi_st(pi
, addr
, data
, 8, msr
=msr
)
589 ld_data
, exctype
, exc
= yield from pi_ld(pi
, addr
, 8, msr
=msr
)
590 assert ld_data
== 0xf553b658ba7e1f51
591 assert exctype
is None
593 ld_data
, exctype
, exc
= yield from pi_ld(pi
, addr
, 8, msr
=msr
)
594 assert ld_data
== 0xf553b658ba7e1f51
595 assert exctype
is None
597 print("do_dcbz ===============")
598 yield from pi_st(pi
, addr
, data
, 8, msr
=msr
, is_dcbz
=1)
599 print("done_dcbz ===============")
602 ld_data
, exctype
, exc
= yield from pi_ld(pi
, addr
, 8, msr
=msr
)
603 print("ld_data after dcbz")
606 assert exctype
is None
609 print("=== alignment error (ld) ===")
611 ld_data
, exctype
, exc
= yield from pi_ld(pi
, addr
, 8, msr
=msr
)
613 alignment
= exc
.alignment
614 happened
= exc
.happened
615 yield # wait for dsr to update
621 assert (happened
== 1)
622 assert (alignment
== 1)
624 assert (exctype
== "fast")
625 yield from wait_busy(pi
, debug
="pi_ld_E_alignment_error")
626 # wait is only needed in case of in exception here
627 print("=== alignment error test passed (ld) ===")
629 # take some cycles in between so that gtkwave separates out
636 print("=== alignment error (st) ===")
638 exctype
, exc
= yield from pi_st(pi
, addr
,0, 8, msr
=msr
)
640 alignment
= exc
.alignment
641 happened
= exc
.happened
645 assert (happened
== 1)
646 assert (alignment
==1)
648 assert (exctype
== "fast")
649 #???? yield from wait_busy(pi, debug="pi_st_E_alignment_error")
650 # wait is only needed in case of in exception here
651 print("=== alignment error test passed (st) ===")
655 print("=== no alignment error (ld) ===")
657 ld_data
, exctype
, exc
= yield from pi_ld(pi
, addr
, 8, msr
=msr
)
658 print("ld_data", ld_data
, exctype
, exc
)
660 alignment
= exc
.alignment
661 happened
= exc
.happened
665 assert (happened
== 0)
666 assert (alignment
== 0)
667 print("=== no alignment error done (ld) ===")
670 addrs
= [0x456920,0xa7a180,0x299420,0x1d9d60]
673 print("== RANDOM addr ==",hex(addr
))
674 ld_data
, exctype
, exc
= yield from pi_ld(pi
, addr
, 8, msr
=msr
)
675 print("ld_data[RANDOM]",ld_data
,exc
,addr
)
676 assert (exctype
== None)
679 print("== RANDOM addr ==",hex(addr
))
680 exc
= yield from pi_st(pi
, addr
,0xFF*addr
, 8, msr
=msr
)
681 assert (exctype
== None)
683 # readback written data and compare
685 print("== RANDOM addr ==",hex(addr
))
686 ld_data
, exctype
, exc
= yield from pi_ld(pi
, addr
, 8, msr
=msr
)
687 print("ld_data[RANDOM_READBACK]",ld_data
,exc
,addr
)
688 assert (exctype
== None)
689 assert (ld_data
== 0xFF*addr
)
691 print("== RANDOM addr done ==")
696 def _test_loadstore1_ifetch_invalid(dut
, mem
):
697 mmu
= dut
.submodules
.mmu
698 ldst
= dut
.submodules
.ldst
700 icache
= dut
.submodules
.ldst
.icache
703 print("=== test loadstore instruction (invalid) ===")
709 # first virtual memory test
711 print ("set process table")
712 yield from debug(dut
, "set prtbl")
713 yield mmu
.rin
.prtbl
.eq(0x1000000) # set process table
716 yield from debug(dut
, "real mem instruction")
717 # set address to zero, update mem[0] to 01234
719 expected_insn
= 0x1234
720 mem
[addr
] = expected_insn
722 yield i_in
.priv_mode
.eq(1)
724 yield i_in
.nia
.eq(addr
)
725 yield i_in
.stop_mark
.eq(0)
726 yield i_m_in
.tlbld
.eq(0)
727 yield i_m_in
.tlbie
.eq(0)
728 yield i_m_in
.addr
.eq(0)
729 yield i_m_in
.pte
.eq(0)
734 # miss, stalls for a bit
736 yield i_in
.nia
.eq(addr
)
738 valid
= yield i_out
.valid
739 nia
= yield i_out
.nia
742 valid
= yield i_out
.valid
745 nia
= yield i_out
.nia
746 insn
= yield i_out
.insn
751 print ("fetched %x from addr %x" % (insn
, nia
))
752 assert insn
== expected_insn
754 print("=== test loadstore instruction (virtual) ===")
755 yield from debug(dut
, "virtual instr req")
757 # look up i-cache expecting it to fail
759 # set address to 0x10200, update mem[] to 5678
761 real_addr
= virt_addr
762 expected_insn
= 0x5678
763 mem
[real_addr
] = expected_insn
765 yield i_in
.priv_mode
.eq(1)
766 yield i_in
.virt_mode
.eq(1)
768 yield i_in
.nia
.eq(virt_addr
)
769 yield i_in
.stop_mark
.eq(0)
770 yield i_m_in
.tlbld
.eq(0)
771 yield i_m_in
.tlbie
.eq(0)
772 yield i_m_in
.addr
.eq(0)
773 yield i_m_in
.pte
.eq(0)
778 # miss, stalls for a bit
780 yield i_in
.nia
.eq(virt_addr
)
782 valid
= yield i_out
.valid
783 failed
= yield i_out
.fetch_failed
784 while not valid
and not failed
:
786 valid
= yield i_out
.valid
787 failed
= yield i_out
.fetch_failed
790 print ("failed?", "yes" if failed
else "no")
795 print("=== test invalid loadstore instruction (instruction fault) ===")
797 yield from debug(dut
, "instr fault (perm err expected)")
800 yield ldst
.priv_mode
.eq(0)
801 yield ldst
.instr_fault
.eq(1)
802 yield ldst
.maddr
.eq(virt_addr
)
803 #ld_data, exctype, exc = yield from pi_ld(pi, virt_addr, 8, msr=msr)
805 yield ldst
.instr_fault
.eq(0)
807 done
= yield (ldst
.done
)
808 exc_info
= yield from get_exception_info(pi
.exc_o
)
809 if done
or exc_info
.happened
:
812 assert exc_info
.happened
== 1 # different here as expected
814 # TODO: work out what kind of exception occurred and check it's
815 # the right one. we *expect* it to be a permissions error because
816 # the RPTE leaf node in pagetables.test2 is marked as "non-executable"
817 # but we also expect instr_fault to be set because it is an instruction
819 print (" MMU lookup exception type?")
820 for fname
in LDSTExceptionTuple
._fields
:
821 print (" fname %20s %d" % (fname
, getattr(exc_info
, fname
)))
823 # ok now printed them out and visually inspected: check them with asserts
824 assert exc_info
.instr_fault
== 1 # instruction fault (yes!)
825 assert exc_info
.perm_error
== 1 # permissions (yes!)
826 assert exc_info
.rc_error
== 0
827 assert exc_info
.alignment
== 0
828 assert exc_info
.invalid
== 0
829 assert exc_info
.segment_fault
== 0
830 assert exc_info
.rc_error
== 0
832 yield from debug(dut
, "test done")
833 yield ldst
.instr_fault
.eq(0)
841 def test_loadstore1_ifetch_unit_iface():
843 m
, cmpi
= setup_mmu()
845 mem
= pagetables
.test1
847 # set this up before passing to Simulator (which calls elaborate)
848 icache
= m
.submodules
.ldst
.icache
849 icache
.use_fetch_interface() # this is the function which converts
850 # to FetchUnitInterface. *including*
851 # rewiring the Wishbone Bus to ibus
857 sim
.add_sync_process(wrap(_test_loadstore1_ifetch_iface(m
, mem
)))
858 # add two wb_get processes onto the *same* memory dictionary.
859 # this shouuuld work.... cross-fingers...
860 sim
.add_sync_process(wrap(wb_get(cmpi
.wb_bus(), mem
)))
861 sim
.add_sync_process(wrap(wb_get(icache
.ibus
, mem
))) # ibus not bus
862 with sim
.write_vcd('test_loadstore1_ifetch_iface.vcd',
863 traces
=[m
.debug_status
]): # include extra debug
867 def test_loadstore1_ifetch():
869 m
, cmpi
= setup_mmu()
871 mem
= pagetables
.test1
877 icache
= m
.submodules
.ldst
.icache
878 sim
.add_sync_process(wrap(_test_loadstore1_ifetch(m
, mem
)))
879 # add two wb_get processes onto the *same* memory dictionary.
880 # this shouuuld work.... cross-fingers...
881 sim
.add_sync_process(wrap(wb_get(cmpi
.wb_bus(), mem
)))
882 sim
.add_sync_process(wrap(wb_get(icache
.bus
, mem
)))
883 with sim
.write_vcd('test_loadstore1_ifetch.vcd',
884 traces
=[m
.debug_status
]): # include extra debug
888 def test_loadstore1():
890 m
, cmpi
= setup_mmu()
892 mem
= pagetables
.test1
898 sim
.add_sync_process(wrap(_test_loadstore1(m
, mem
)))
899 sim
.add_sync_process(wrap(wb_get(cmpi
.wb_bus(), mem
)))
900 with sim
.write_vcd('test_loadstore1.vcd'):
904 def test_loadstore1_microwatt_mmu_bin_test2():
906 m
, cmpi
= setup_mmu()
908 mem
= pagetables
.microwatt_test2
914 sim
.add_sync_process(wrap(_test_loadstore1_microwatt_mmu_bin_test2(m
, mem
)))
915 sim
.add_sync_process(wrap(wb_get(cmpi
.wb_bus(), mem
)))
916 with sim
.write_vcd('test_microwatt_mmu_test2.vcd'):
920 def test_loadstore1_microwatt_mmu_bin_test5():
922 m
, cmpi
= setup_mmu()
924 mem
= pagetables
.microwatt_test5
930 sim
.add_sync_process(wrap(_test_loadstore1_microwatt_mmu_bin_test5(m
, mem
)))
931 sim
.add_sync_process(wrap(wb_get(cmpi
.wb_bus(), mem
)))
932 with sim
.write_vcd('test_microwatt_mmu_test5.vcd'):
936 def test_loadstore1_misalign():
938 m
, cmpi
= setup_mmu()
940 mem
= pagetables
.microwatt_test2
946 ###########1122334455667788
947 mem
[0] = 0x0102030405060708
949 sim
.add_sync_process(wrap(_test_loadstore1_misalign(m
, mem
)))
950 sim
.add_sync_process(wrap(wb_get(cmpi
.wb_bus(), mem
)))
951 with sim
.write_vcd('test_loadstore1_misalign.vcd'):
955 def test_loadstore1_invalid():
957 m
, cmpi
= setup_mmu()
965 sim
.add_sync_process(wrap(_test_loadstore1_invalid(m
, mem
)))
966 sim
.add_sync_process(wrap(wb_get(cmpi
.wb_bus(), mem
)))
967 with sim
.write_vcd('test_loadstore1_invalid.vcd'):
971 def test_loadstore1_ifetch_invalid():
972 m
, cmpi
= setup_mmu()
974 # this is a specially-arranged page table which has the permissions
975 # barred for execute on the leaf node (EAA=0x2 instead of EAA=0x3)
976 mem
= pagetables
.test2
982 icache
= m
.submodules
.ldst
.icache
983 sim
.add_sync_process(wrap(_test_loadstore1_ifetch_invalid(m
, mem
)))
984 # add two wb_get processes onto the *same* memory dictionary.
985 # this shouuuld work.... cross-fingers...
986 sim
.add_sync_process(wrap(wb_get(cmpi
.wb_bus(), mem
)))
987 sim
.add_sync_process(wrap(wb_get(icache
.bus
, mem
)))
988 with sim
.write_vcd('test_loadstore1_ifetch_invalid.vcd',
989 traces
=[m
.debug_status
]): # include extra debug
993 def test_loadstore1_ifetch_multi():
994 m
, cmpi
= setup_mmu()
997 # this is a specially-arranged page table which has the permissions
998 # barred for execute on the leaf node (EAA=0x2 instead of EAA=0x3)
999 mem
= pagetables
.test1
1001 # set this up before passing to Simulator (which calls elaborate)
1002 icache
= m
.submodules
.ldst
.icache
1003 icache
.use_fetch_interface() # this is the function which converts
1004 # to FetchUnitInterface. *including*
1005 # rewiring the Wishbone Bus to ibus
1011 sim
.add_sync_process(wrap(_test_loadstore1_ifetch_multi(m
, mem
)))
1012 # add two wb_get processes onto the *same* memory dictionary.
1013 # this shouuuld work.... cross-fingers...
1014 sim
.add_sync_process(wrap(wb_get(cmpi
.wb_bus(), mem
)))
1015 sim
.add_sync_process(wrap(wb_get(icache
.ibus
, mem
))) # ibus not bus
1016 with sim
.write_vcd('test_loadstore1_ifetch_multi.vcd',
1017 traces
=[m
.debug_status
]): # include extra debug
1020 if __name__
== '__main__':
1022 #test_loadstore1_microwatt_mmu_bin_test2()
1023 test_loadstore1_microwatt_mmu_bin_test5()
1024 #test_loadstore1_invalid()
1025 #test_loadstore1_ifetch() #FIXME
1026 #test_loadstore1_ifetch_invalid()
1027 #test_loadstore1_ifetch_unit_iface() # guess: should be working
1028 #test_loadstore1_ifetch_multi()
1029 #test_loadstore1_misalign()