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_classic
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
)
547 assert exc
is None # use "is None" not "== None"
548 print("MISALIGN: test_pi_ld_misalign returned",hex(ld_data
))
551 def test_pi_st_ld_misalign(pi
, addr
, data_len
, msr
):
552 data
= 0x0102030405060708
553 for i
in range(0, data_len
):
554 exctype
, exc
= yield from pi_st(pi
, addr
+i
, data
, data_len
, msr
=msr
)
556 assert exc
is None # use "is None" not "== None"
557 ld_data
, exctype
, exc
= yield from pi_ld(pi
, addr
+i
, data_len
, msr
=msr
)
559 assert exc
is None # use "is None" not "== None"
560 print("MISALIGN: test_pi_ld_misalign returned",hex(ld_data
))
561 assert ld_data
== data
564 def _test_loadstore1_misalign(dut
, mem
):
565 mmu
= dut
.submodules
.mmu
566 pi
= dut
.submodules
.ldst
.pi
567 ldst
= dut
.submodules
.ldst
# to get at DAR (NOT part of PortInterface)
570 yield mmu
.rin
.prtbl
.eq(0x12000) # set process table
571 yield mmu
.rin
.pid
.eq(0x1) # set PID=1
575 msr
= MSRSpec(pr
=0, dr
=0, sf
=1)
577 yield from test_pi_ld_misalign(pi
,0,8,msr
)
579 yield from test_pi_st_ld_misalign(pi
,0,8,msr
)
584 def _test_loadstore1(dut
, mem
):
585 mmu
= dut
.submodules
.mmu
586 pi
= dut
.submodules
.ldst
.pi
587 ldst
= dut
.submodules
.ldst
# to get at DAR (NOT part of PortInterface)
590 yield mmu
.rin
.prtbl
.eq(0x1000000) # set process table
594 data
= 0xf553b658ba7e1f51
595 msr
= MSRSpec(pr
=0, dr
=0, sf
=0)
598 yield from pi_st(pi
, addr
, data
, 8, msr
=msr
)
601 ld_data
, exctype
, exc
= yield from pi_ld(pi
, addr
, 8, msr
=msr
)
602 assert ld_data
== 0xf553b658ba7e1f51
603 assert exctype
is None
605 ld_data
, exctype
, exc
= yield from pi_ld(pi
, addr
, 8, msr
=msr
)
606 assert ld_data
== 0xf553b658ba7e1f51
607 assert exctype
is None
609 print("do_dcbz ===============")
610 yield from pi_st(pi
, addr
, data
, 8, msr
=msr
, is_dcbz
=1)
611 print("done_dcbz ===============")
614 ld_data
, exctype
, exc
= yield from pi_ld(pi
, addr
, 8, msr
=msr
)
615 print("ld_data after dcbz")
618 assert exctype
is None
621 print("=== alignment error (ld) ===")
623 ld_data
, exctype
, exc
= yield from pi_ld(pi
, addr
, 8, msr
=msr
)
625 alignment
= exc
.alignment
626 happened
= exc
.happened
627 yield # wait for dsr to update
633 assert (happened
== 1)
634 assert (alignment
== 1)
636 assert (exctype
== "fast")
637 yield from wait_busy(pi
, debug
="pi_ld_E_alignment_error")
638 # wait is only needed in case of in exception here
639 print("=== alignment error test passed (ld) ===")
641 # take some cycles in between so that gtkwave separates out
648 print("=== alignment error (st) ===")
650 exctype
, exc
= yield from pi_st(pi
, addr
,0, 8, msr
=msr
)
652 alignment
= exc
.alignment
653 happened
= exc
.happened
657 assert (happened
== 1)
658 assert (alignment
==1)
660 assert (exctype
== "fast")
661 #???? yield from wait_busy(pi, debug="pi_st_E_alignment_error")
662 # wait is only needed in case of in exception here
663 print("=== alignment error test passed (st) ===")
667 print("=== no alignment error (ld) ===")
669 ld_data
, exctype
, exc
= yield from pi_ld(pi
, addr
, 8, msr
=msr
)
670 print("ld_data", ld_data
, exctype
, exc
)
672 alignment
= exc
.alignment
673 happened
= exc
.happened
677 assert (happened
== 0)
678 assert (alignment
== 0)
679 print("=== no alignment error done (ld) ===")
682 addrs
= [0x456920,0xa7a180,0x299420,0x1d9d60]
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]",ld_data
,exc
,addr
)
688 assert (exctype
== None)
691 print("== RANDOM addr ==",hex(addr
))
692 exc
= yield from pi_st(pi
, addr
,0xFF*addr
, 8, msr
=msr
)
693 assert (exctype
== None)
695 # readback written data and compare
697 print("== RANDOM addr ==",hex(addr
))
698 ld_data
, exctype
, exc
= yield from pi_ld(pi
, addr
, 8, msr
=msr
)
699 print("ld_data[RANDOM_READBACK]",ld_data
,exc
,addr
)
700 assert (exctype
== None)
701 assert (ld_data
== 0xFF*addr
)
703 print("== RANDOM addr done ==")
708 def _test_loadstore1_ifetch_invalid(dut
, mem
):
709 mmu
= dut
.submodules
.mmu
710 ldst
= dut
.submodules
.ldst
712 icache
= dut
.submodules
.ldst
.icache
715 print("=== test loadstore instruction (invalid) ===")
721 # first virtual memory test
723 print ("set process table")
724 yield from debug(dut
, "set prtbl")
725 yield mmu
.rin
.prtbl
.eq(0x1000000) # set process table
728 yield from debug(dut
, "real mem instruction")
729 # set address to zero, update mem[0] to 01234
731 expected_insn
= 0x1234
732 mem
[addr
] = expected_insn
734 yield i_in
.priv_mode
.eq(1)
736 yield i_in
.nia
.eq(addr
)
737 yield i_in
.stop_mark
.eq(0)
738 yield i_m_in
.tlbld
.eq(0)
739 yield i_m_in
.tlbie
.eq(0)
740 yield i_m_in
.addr
.eq(0)
741 yield i_m_in
.pte
.eq(0)
746 # miss, stalls for a bit
748 yield i_in
.nia
.eq(addr
)
750 valid
= yield i_out
.valid
751 nia
= yield i_out
.nia
754 valid
= yield i_out
.valid
757 nia
= yield i_out
.nia
758 insn
= yield i_out
.insn
763 print ("fetched %x from addr %x" % (insn
, nia
))
764 assert insn
== expected_insn
766 print("=== test loadstore instruction (virtual) ===")
767 yield from debug(dut
, "virtual instr req")
769 # look up i-cache expecting it to fail
771 # set address to 0x10200, update mem[] to 5678
773 real_addr
= virt_addr
774 expected_insn
= 0x5678
775 mem
[real_addr
] = expected_insn
777 yield i_in
.priv_mode
.eq(1)
778 yield i_in
.virt_mode
.eq(1)
780 yield i_in
.nia
.eq(virt_addr
)
781 yield i_in
.stop_mark
.eq(0)
782 yield i_m_in
.tlbld
.eq(0)
783 yield i_m_in
.tlbie
.eq(0)
784 yield i_m_in
.addr
.eq(0)
785 yield i_m_in
.pte
.eq(0)
790 # miss, stalls for a bit
792 yield i_in
.nia
.eq(virt_addr
)
794 valid
= yield i_out
.valid
795 failed
= yield i_out
.fetch_failed
796 while not valid
and not failed
:
798 valid
= yield i_out
.valid
799 failed
= yield i_out
.fetch_failed
802 print ("failed?", "yes" if failed
else "no")
807 print("=== test invalid loadstore instruction (instruction fault) ===")
809 yield from debug(dut
, "instr fault (perm err expected)")
812 yield ldst
.priv_mode
.eq(0)
813 yield ldst
.instr_fault
.eq(1)
814 yield ldst
.maddr
.eq(virt_addr
)
815 #ld_data, exctype, exc = yield from pi_ld(pi, virt_addr, 8, msr=msr)
817 yield ldst
.instr_fault
.eq(0)
819 done
= yield (ldst
.done
)
820 exc_info
= yield from get_exception_info(pi
.exc_o
)
821 if done
or exc_info
.happened
:
824 assert exc_info
.happened
== 1 # different here as expected
826 # TODO: work out what kind of exception occurred and check it's
827 # the right one. we *expect* it to be a permissions error because
828 # the RPTE leaf node in pagetables.test2 is marked as "non-executable"
829 # but we also expect instr_fault to be set because it is an instruction
831 print (" MMU lookup exception type?")
832 for fname
in LDSTExceptionTuple
._fields
:
833 print (" fname %20s %d" % (fname
, getattr(exc_info
, fname
)))
835 # ok now printed them out and visually inspected: check them with asserts
836 assert exc_info
.instr_fault
== 1 # instruction fault (yes!)
837 assert exc_info
.perm_error
== 1 # permissions (yes!)
838 assert exc_info
.rc_error
== 0
839 assert exc_info
.alignment
== 0
840 assert exc_info
.invalid
== 0
841 assert exc_info
.segment_fault
== 0
842 assert exc_info
.rc_error
== 0
844 yield from debug(dut
, "test done")
845 yield ldst
.instr_fault
.eq(0)
853 def test_loadstore1_ifetch_unit_iface():
855 m
, cmpi
= setup_mmu()
857 mem
= pagetables
.test1
859 # set this up before passing to Simulator (which calls elaborate)
860 icache
= m
.submodules
.ldst
.icache
861 icache
.use_fetch_interface() # this is the function which converts
862 # to FetchUnitInterface. *including*
863 # rewiring the Wishbone Bus to ibus
869 sim
.add_sync_process(wrap(_test_loadstore1_ifetch_iface(m
, mem
)))
870 # add two wb_get_classic processes onto the *same* memory dictionary.
871 # this shouuuld work.... cross-fingers...
872 sim
.add_sync_process(wrap(wb_get_classic(cmpi
.wb_bus(), mem
)))
873 sim
.add_sync_process(wrap(wb_get_classic(icache
.ibus
, mem
))) # ibus not bus
874 with sim
.write_vcd('test_loadstore1_ifetch_iface.vcd',
875 traces
=[m
.debug_status
]): # include extra debug
879 def test_loadstore1_ifetch():
881 m
, cmpi
= setup_mmu()
883 mem
= pagetables
.test1
889 icache
= m
.submodules
.ldst
.icache
890 sim
.add_sync_process(wrap(_test_loadstore1_ifetch(m
, mem
)))
891 # add two wb_get_classic processes onto the *same* memory dictionary.
892 # this shouuuld work.... cross-fingers...
893 sim
.add_sync_process(wrap(wb_get_classic(cmpi
.wb_bus(), mem
)))
894 sim
.add_sync_process(wrap(wb_get_classic(icache
.bus
, mem
)))
895 with sim
.write_vcd('test_loadstore1_ifetch.vcd',
896 traces
=[m
.debug_status
]): # include extra debug
900 def test_loadstore1():
902 m
, cmpi
= setup_mmu()
904 mem
= pagetables
.test1
910 sim
.add_sync_process(wrap(_test_loadstore1(m
, mem
)))
911 sim
.add_sync_process(wrap(wb_get_classic(cmpi
.wb_bus(), mem
)))
912 with sim
.write_vcd('test_loadstore1.vcd'):
916 def test_loadstore1_microwatt_mmu_bin_test2():
918 m
, cmpi
= setup_mmu()
920 mem
= pagetables
.microwatt_test2
926 sim
.add_sync_process(wrap(_test_loadstore1_microwatt_mmu_bin_test2(m
, mem
)))
927 sim
.add_sync_process(wrap(wb_get_classic(cmpi
.wb_bus(), mem
)))
928 with sim
.write_vcd('test_microwatt_mmu_test2.vcd'):
932 def test_loadstore1_microwatt_mmu_bin_test5():
934 m
, cmpi
= setup_mmu()
936 mem
= pagetables
.microwatt_test5
942 sim
.add_sync_process(wrap(_test_loadstore1_microwatt_mmu_bin_test5(m
, mem
)))
943 sim
.add_sync_process(wrap(wb_get_classic(cmpi
.wb_bus(), mem
)))
944 with sim
.write_vcd('test_microwatt_mmu_test5.vcd'):
948 def test_loadstore1_misalign():
950 m
, cmpi
= setup_mmu()
952 mem
= pagetables
.microwatt_test2
958 ###########1122334455667788
959 mem
[0] = 0x0102030405060708
960 mem
[8] = 0xffffffffffffffff
962 sim
.add_sync_process(wrap(_test_loadstore1_misalign(m
, mem
)))
963 sim
.add_sync_process(wrap(wb_get_classic(cmpi
.wb_bus(), mem
)))
964 with sim
.write_vcd('test_loadstore1_misalign.vcd'):
969 def test_loadstore1_invalid():
971 m
, cmpi
= setup_mmu()
979 sim
.add_sync_process(wrap(_test_loadstore1_invalid(m
, mem
)))
980 sim
.add_sync_process(wrap(wb_get_classic(cmpi
.wb_bus(), mem
)))
981 with sim
.write_vcd('test_loadstore1_invalid.vcd'):
985 def test_loadstore1_ifetch_invalid():
986 m
, cmpi
= setup_mmu()
988 # this is a specially-arranged page table which has the permissions
989 # barred for execute on the leaf node (EAA=0x2 instead of EAA=0x3)
990 mem
= pagetables
.test2
996 icache
= m
.submodules
.ldst
.icache
997 sim
.add_sync_process(wrap(_test_loadstore1_ifetch_invalid(m
, mem
)))
998 # add two wb_get_classic processes onto the *same* memory dictionary.
999 # this shouuuld work.... cross-fingers...
1000 sim
.add_sync_process(wrap(wb_get_classic(cmpi
.wb_bus(), mem
)))
1001 sim
.add_sync_process(wrap(wb_get_classic(icache
.bus
, mem
)))
1002 with sim
.write_vcd('test_loadstore1_ifetch_invalid.vcd',
1003 traces
=[m
.debug_status
]): # include extra debug
1007 def test_loadstore1_ifetch_multi():
1008 m
, cmpi
= setup_mmu()
1011 # this is a specially-arranged page table which has the permissions
1012 # barred for execute on the leaf node (EAA=0x2 instead of EAA=0x3)
1013 mem
= pagetables
.test1
1015 # set this up before passing to Simulator (which calls elaborate)
1016 icache
= m
.submodules
.ldst
.icache
1017 icache
.use_fetch_interface() # this is the function which converts
1018 # to FetchUnitInterface. *including*
1019 # rewiring the Wishbone Bus to ibus
1025 sim
.add_sync_process(wrap(_test_loadstore1_ifetch_multi(m
, mem
)))
1026 # add two wb_get_classic processes onto the *same* memory dictionary.
1027 # this shouuuld work.... cross-fingers...
1028 sim
.add_sync_process(wrap(wb_get_classic(cmpi
.wb_bus(), mem
)))
1029 sim
.add_sync_process(wrap(wb_get_classic(icache
.ibus
, mem
))) # ibus not bus
1030 with sim
.write_vcd('test_loadstore1_ifetch_multi.vcd',
1031 traces
=[m
.debug_status
]): # include extra debug
1034 if __name__
== '__main__':
1036 #test_loadstore1_microwatt_mmu_bin_test2()
1037 #test_loadstore1_microwatt_mmu_bin_test5()
1038 #test_loadstore1_invalid()
1039 #test_loadstore1_ifetch() #FIXME
1040 #test_loadstore1_ifetch_invalid()
1041 #test_loadstore1_ifetch_unit_iface() # guess: should be working
1042 #test_loadstore1_ifetch_multi()
1043 test_loadstore1_misalign()