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
170 def write_mem2(mem
, addr
, i1
, i2
):
171 mem
[addr
] = i1 | i2
<<32
173 def _test_loadstore1_ifetch_multi(dut
, mem
):
174 mmu
= dut
.submodules
.mmu
175 ldst
= dut
.submodules
.ldst
177 icache
= dut
.submodules
.ldst
.icache
178 assert wbget
.stop
== False
180 print ("set process table")
181 yield from debug(dut
, "set prtble")
182 yield mmu
.rin
.prtbl
.eq(0x1000000) # set process table
189 # TODO fetch instructions from multiple addresses
190 # should cope with some addresses being invalid
191 real_addrs
= [0,4,8,0,8,4,0,0,12]
192 write_mem2(mem
,0,0xF0,0xF4)
193 write_mem2(mem
,8,0xF8,0xFC)
195 yield i_in
.priv_mode
.eq(1)
196 for addr
in real_addrs
:
197 yield from debug(dut
, "real_addr "+hex(addr
))
198 # use the new interface in this test
200 insn
= yield from read_from_addr(icache
, addr
, stall
=False)
201 nia
= yield i_out
.nia
# NO, must use FetchUnitInterface
202 print ("TEST_MULTI: fetched %x from addr %x == %x" % (insn
, nia
,addr
))
203 assert insn
==0xF0+addr
205 yield i_in
.virt_mode
.eq(1)
207 virt_addrs
= [0x10200,0x10204,0x10208,0x10200,
208 0x102008,0x10204,0x10200,0x10200,0x10200C]
210 for addr
in virt_addrs
:
211 yield from debug(dut
, "virt_addr "+hex(addr
))
215 #TODO: use fetch interface here
216 ###################################
218 yield i_in
.nia
.eq(addr
)
220 valid
= yield i_out
.valid
221 failed
= yield i_out
.fetch_failed
222 while not valid
and not failed
and timeout
< 100:
224 valid
= yield i_out
.valid
225 failed
= yield i_out
.fetch_failed
226 timeout
= timeout
+ 1
228 ###################################
229 print("TEST_MULTI: failed=",failed
) # this is reported wrong
236 def _test_loadstore1_ifetch(dut
, mem
):
237 """test_loadstore1_ifetch
239 this is quite a complex multi-step test.
241 * first (just because, as a demo) read in priv mode, non-virtual.
242 just like in experiment/icache.py itself.
244 * second, using the (usual) PTE for these things (which came originally
245 from gem5-experimental experiment/radix_walk_example.txt) do a
246 virtual-memory read through the *instruction* cache.
247 this is expected to FAIL
249 * third: mess about with the MMU, setting "iside" (instruction-side),
250 requesting an MMU RADIX LOOKUP. this triggers an itlb_load
251 (instruction-cache TLB entry-insertion)
253 * fourth and finally: retry the read of the instruction through i-cache.
254 this is now expected to SUCCEED
259 mmu
= dut
.submodules
.mmu
260 ldst
= dut
.submodules
.ldst
262 icache
= dut
.submodules
.ldst
.icache
265 print("=== test loadstore instruction (real) ===")
271 # first virtual memory test
273 print ("set process table")
274 yield from debug(dut
, "set prtble")
275 yield mmu
.rin
.prtbl
.eq(0x1000000) # set process table
278 yield from debug(dut
, "real mem instruction")
279 # set address to zero, update mem[0] to 01234
281 expected_insn
= 0x1234
282 mem
[addr
] = expected_insn
284 yield i_in
.priv_mode
.eq(1)
286 yield i_in
.nia
.eq(addr
)
287 yield i_in
.stop_mark
.eq(0)
288 yield i_m_in
.tlbld
.eq(0)
289 yield i_m_in
.tlbie
.eq(0)
290 yield i_m_in
.addr
.eq(0)
291 yield i_m_in
.pte
.eq(0)
296 # miss, stalls for a bit -- this one is different here
297 ##nia, insn, valid, failed = yield from icache_read(dut,addr,0,0)
302 yield i_in
.nia
.eq(addr
)
304 valid
= yield i_out
.valid
307 valid
= yield i_out
.valid
310 nia
= yield i_out
.nia
311 insn
= yield i_out
.insn
315 print ("fetched %x from addr %x" % (insn
, nia
))
316 assert insn
== expected_insn
318 print("=== test loadstore instruction (virtual) ===")
320 # look up i-cache expecting it to fail
322 yield from debug(dut
, "virtual instr req")
323 # set address to 0x10200, update mem[] to 5678
325 real_addr
= virt_addr
326 expected_insn
= 0x5678
327 mem
[real_addr
] = expected_insn
329 yield i_in
.priv_mode
.eq(0)
330 yield i_in
.virt_mode
.eq(1)
332 yield i_in
.nia
.eq(virt_addr
)
333 yield i_in
.stop_mark
.eq(0)
334 yield i_m_in
.tlbld
.eq(0)
335 yield i_m_in
.tlbie
.eq(0)
336 yield i_m_in
.addr
.eq(0)
337 yield i_m_in
.pte
.eq(0)
342 # miss, stalls for a bit
344 yield i_in
.nia
.eq(virt_addr
)
346 valid
= yield i_out
.valid
347 failed
= yield i_out
.fetch_failed
348 while not valid
and not failed
:
350 valid
= yield i_out
.valid
351 failed
= yield i_out
.fetch_failed
354 print ("failed?", "yes" if failed
else "no")
359 print("=== test loadstore instruction (instruction fault) ===")
361 yield from debug(dut
, "instr fault")
365 yield ldst
.priv_mode
.eq(0)
366 yield ldst
.instr_fault
.eq(1)
367 yield ldst
.maddr
.eq(virt_addr
)
368 # still broken -- investigate
369 # msr = MSRSpec(pr=?, dr=?, sf=0)
370 # ld_data, exctype, exc = yield from pi_ld(pi, virt_addr, 8, msr=msr)
372 yield ldst
.instr_fault
.eq(0)
374 done
= yield (ldst
.done
)
375 exc_info
= yield from get_exception_info(pi
.exc_o
)
376 if done
or exc_info
.happened
:
379 assert exc_info
.happened
== 0 # assert just before doing the fault set zero
380 yield ldst
.instr_fault
.eq(0)
385 print("=== test loadstore instruction (try instruction again) ===")
386 yield from debug(dut
, "instr virt retry")
387 # set address to 0x10200, update mem[] to 5678
389 real_addr
= virt_addr
390 expected_insn
= 0x5678
392 yield i_in
.priv_mode
.eq(0)
393 yield i_in
.virt_mode
.eq(1)
395 yield i_in
.nia
.eq(virt_addr
)
396 yield i_in
.stop_mark
.eq(0)
397 yield i_m_in
.tlbld
.eq(0)
398 yield i_m_in
.tlbie
.eq(0)
399 yield i_m_in
.addr
.eq(0)
400 yield i_m_in
.pte
.eq(0)
405 # miss, stalls for a bit
408 yield i_in.nia.eq(virt_addr)
410 valid = yield i_out.valid
411 failed = yield i_out.fetch_failed
412 while not valid and not failed:
414 valid = yield i_out.valid
415 failed = yield i_out.fetch_failed
417 nia = yield i_out.nia
418 insn = yield i_out.insn
422 nia
, insn
, valid
, failed
= yield from icache_read(dut
,virt_addr
,0,1)
424 yield from debug(dut
, "test done")
428 print ("failed?", "yes" if failed
else "no")
431 print ("fetched %x from addr %x" % (insn
, nia
))
432 assert insn
== expected_insn
437 def _test_loadstore1_invalid(dut
, mem
):
438 mmu
= dut
.submodules
.mmu
439 pi
= dut
.submodules
.ldst
.pi
442 print("=== test invalid ===")
445 msr
= MSRSpec(pr
=1, dr
=0, sf
=0) # set problem-state
446 ld_data
, exctype
, exc
= yield from pi_ld(pi
, addr
, 8, msr
=msr
)
447 print("ld_data", ld_data
, exctype
, exc
)
448 assert (exctype
== "slow")
449 invalid
= exc
.invalid
450 assert (invalid
== 1)
452 print("=== test invalid done ===")
457 def _test_loadstore1(dut
, mem
):
458 mmu
= dut
.submodules
.mmu
459 pi
= dut
.submodules
.ldst
.pi
460 ldst
= dut
.submodules
.ldst
# to get at DAR (NOT part of PortInterface)
463 yield mmu
.rin
.prtbl
.eq(0x1000000) # set process table
467 data
= 0xf553b658ba7e1f51
470 msr
= MSRSpec(pr
=0, dr
=0, sf
=0)
471 yield from pi_st(pi
, addr
, data
, 8, msr
=msr
)
474 ld_data
, exctype
, exc
= yield from pi_ld(pi
, addr
, 8, msr
=msr
)
475 assert ld_data
== 0xf553b658ba7e1f51
476 assert exctype
is None
478 ld_data
, exctype
, exc
= yield from pi_ld(pi
, addr
, 8, msr
=msr
)
479 assert ld_data
== 0xf553b658ba7e1f51
480 assert exctype
is None
482 print("do_dcbz ===============")
483 yield from pi_st(pi
, addr
, data
, 8, msr
=msr
, is_dcbz
=1)
484 print("done_dcbz ===============")
487 ld_data
, exctype
, exc
= yield from pi_ld(pi
, addr
, 8, msr
=msr
)
488 print("ld_data after dcbz")
491 assert exctype
is None
494 print("=== alignment error (ld) ===")
496 ld_data
, exctype
, exc
= yield from pi_ld(pi
, addr
, 8, msr
=msr
)
498 alignment
= exc
.alignment
499 happened
= exc
.happened
500 yield # wait for dsr to update
506 assert (happened
== 1)
507 assert (alignment
== 1)
509 assert (exctype
== "fast")
510 yield from wait_busy(pi
, debug
="pi_ld_E_alignment_error")
511 # wait is only needed in case of in exception here
512 print("=== alignment error test passed (ld) ===")
514 # take some cycles in between so that gtkwave separates out
521 print("=== alignment error (st) ===")
523 exctype
, exc
= yield from pi_st(pi
, addr
,0, 8, msr
=msr
)
525 alignment
= exc
.alignment
526 happened
= exc
.happened
530 assert (happened
== 1)
531 assert (alignment
==1)
533 assert (exctype
== "fast")
534 #???? yield from wait_busy(pi, debug="pi_st_E_alignment_error")
535 # wait is only needed in case of in exception here
536 print("=== alignment error test passed (st) ===")
540 print("=== no alignment error (ld) ===")
542 ld_data
, exctype
, exc
= yield from pi_ld(pi
, addr
, 8, msr
=msr
)
543 print("ld_data", ld_data
, exctype
, exc
)
545 alignment
= exc
.alignment
546 happened
= exc
.happened
550 assert (happened
== 0)
551 assert (alignment
== 0)
552 print("=== no alignment error done (ld) ===")
555 addrs
= [0x456920,0xa7a180,0x299420,0x1d9d60]
558 print("== RANDOM addr ==",hex(addr
))
559 ld_data
, exctype
, exc
= yield from pi_ld(pi
, addr
, 8, msr
=msr
)
560 print("ld_data[RANDOM]",ld_data
,exc
,addr
)
561 assert (exctype
== None)
564 print("== RANDOM addr ==",hex(addr
))
565 exc
= yield from pi_st(pi
, addr
,0xFF*addr
, 8, msr
=msr
)
566 assert (exctype
== None)
568 # readback written data and compare
570 print("== RANDOM addr ==",hex(addr
))
571 ld_data
, exctype
, exc
= yield from pi_ld(pi
, addr
, 8, msr
=msr
)
572 print("ld_data[RANDOM_READBACK]",ld_data
,exc
,addr
)
573 assert (exctype
== None)
574 assert (ld_data
== 0xFF*addr
)
576 print("== RANDOM addr done ==")
581 def _test_loadstore1_ifetch_invalid(dut
, mem
):
582 mmu
= dut
.submodules
.mmu
583 ldst
= dut
.submodules
.ldst
585 icache
= dut
.submodules
.ldst
.icache
588 print("=== test loadstore instruction (invalid) ===")
594 # first virtual memory test
596 print ("set process table")
597 yield from debug(dut
, "set prtbl")
598 yield mmu
.rin
.prtbl
.eq(0x1000000) # set process table
601 yield from debug(dut
, "real mem instruction")
602 # set address to zero, update mem[0] to 01234
604 expected_insn
= 0x1234
605 mem
[addr
] = expected_insn
607 yield i_in
.priv_mode
.eq(1)
609 yield i_in
.nia
.eq(addr
)
610 yield i_in
.stop_mark
.eq(0)
611 yield i_m_in
.tlbld
.eq(0)
612 yield i_m_in
.tlbie
.eq(0)
613 yield i_m_in
.addr
.eq(0)
614 yield i_m_in
.pte
.eq(0)
619 # miss, stalls for a bit
621 yield i_in
.nia
.eq(addr
)
623 valid
= yield i_out
.valid
624 nia
= yield i_out
.nia
627 valid
= yield i_out
.valid
630 nia
= yield i_out
.nia
631 insn
= yield i_out
.insn
636 print ("fetched %x from addr %x" % (insn
, nia
))
637 assert insn
== expected_insn
639 print("=== test loadstore instruction (virtual) ===")
640 yield from debug(dut
, "virtual instr req")
642 # look up i-cache expecting it to fail
644 # set address to 0x10200, update mem[] to 5678
646 real_addr
= virt_addr
647 expected_insn
= 0x5678
648 mem
[real_addr
] = expected_insn
650 yield i_in
.priv_mode
.eq(1)
651 yield i_in
.virt_mode
.eq(1)
653 yield i_in
.nia
.eq(virt_addr
)
654 yield i_in
.stop_mark
.eq(0)
655 yield i_m_in
.tlbld
.eq(0)
656 yield i_m_in
.tlbie
.eq(0)
657 yield i_m_in
.addr
.eq(0)
658 yield i_m_in
.pte
.eq(0)
663 # miss, stalls for a bit
665 yield i_in
.nia
.eq(virt_addr
)
667 valid
= yield i_out
.valid
668 failed
= yield i_out
.fetch_failed
669 while not valid
and not failed
:
671 valid
= yield i_out
.valid
672 failed
= yield i_out
.fetch_failed
675 print ("failed?", "yes" if failed
else "no")
680 print("=== test invalid loadstore instruction (instruction fault) ===")
682 yield from debug(dut
, "instr fault (perm err expected)")
685 yield ldst
.priv_mode
.eq(0)
686 yield ldst
.instr_fault
.eq(1)
687 yield ldst
.maddr
.eq(virt_addr
)
688 #ld_data, exctype, exc = yield from pi_ld(pi, virt_addr, 8, msr=msr)
690 yield ldst
.instr_fault
.eq(0)
692 done
= yield (ldst
.done
)
693 exc_info
= yield from get_exception_info(pi
.exc_o
)
694 if done
or exc_info
.happened
:
697 assert exc_info
.happened
== 1 # different here as expected
699 # TODO: work out what kind of exception occurred and check it's
700 # the right one. we *expect* it to be a permissions error because
701 # the RPTE leaf node in pagetables.test2 is marked as "non-executable"
702 # but we also expect instr_fault to be set because it is an instruction
704 print (" MMU lookup exception type?")
705 for fname
in LDSTExceptionTuple
._fields
:
706 print (" fname %20s %d" % (fname
, getattr(exc_info
, fname
)))
708 # ok now printed them out and visually inspected: check them with asserts
709 assert exc_info
.instr_fault
== 1 # instruction fault (yes!)
710 assert exc_info
.perm_error
== 1 # permissions (yes!)
711 assert exc_info
.rc_error
== 0
712 assert exc_info
.alignment
== 0
713 assert exc_info
.invalid
== 0
714 assert exc_info
.segment_fault
== 0
715 assert exc_info
.rc_error
== 0
717 yield from debug(dut
, "test done")
718 yield ldst
.instr_fault
.eq(0)
726 def test_loadstore1_ifetch_unit_iface():
728 m
, cmpi
= setup_mmu()
730 mem
= pagetables
.test1
732 # set this up before passing to Simulator (which calls elaborate)
733 icache
= m
.submodules
.ldst
.icache
734 icache
.use_fetch_interface() # this is the function which converts
735 # to FetchUnitInterface. *including*
736 # rewiring the Wishbone Bus to ibus
742 sim
.add_sync_process(wrap(_test_loadstore1_ifetch_iface(m
, mem
)))
743 # add two wb_get processes onto the *same* memory dictionary.
744 # this shouuuld work.... cross-fingers...
745 sim
.add_sync_process(wrap(wb_get(cmpi
.wb_bus(), mem
)))
746 sim
.add_sync_process(wrap(wb_get(icache
.ibus
, mem
))) # ibus not bus
747 with sim
.write_vcd('test_loadstore1_ifetch_iface.vcd',
748 traces
=[m
.debug_status
]): # include extra debug
752 def test_loadstore1_ifetch():
754 m
, cmpi
= setup_mmu()
756 mem
= pagetables
.test1
762 icache
= m
.submodules
.ldst
.icache
763 sim
.add_sync_process(wrap(_test_loadstore1_ifetch(m
, mem
)))
764 # add two wb_get processes onto the *same* memory dictionary.
765 # this shouuuld work.... cross-fingers...
766 sim
.add_sync_process(wrap(wb_get(cmpi
.wb_bus(), mem
)))
767 sim
.add_sync_process(wrap(wb_get(icache
.bus
, mem
)))
768 with sim
.write_vcd('test_loadstore1_ifetch.vcd',
769 traces
=[m
.debug_status
]): # include extra debug
773 def test_loadstore1():
775 m
, cmpi
= setup_mmu()
777 mem
= pagetables
.test1
783 sim
.add_sync_process(wrap(_test_loadstore1(m
, mem
)))
784 sim
.add_sync_process(wrap(wb_get(cmpi
.wb_bus(), mem
)))
785 with sim
.write_vcd('test_loadstore1.vcd'):
789 def test_loadstore1_invalid():
791 m
, cmpi
= setup_mmu()
799 sim
.add_sync_process(wrap(_test_loadstore1_invalid(m
, mem
)))
800 sim
.add_sync_process(wrap(wb_get(cmpi
.wb_bus(), mem
)))
801 with sim
.write_vcd('test_loadstore1_invalid.vcd'):
804 def test_loadstore1_ifetch_invalid():
805 m
, cmpi
= setup_mmu()
807 # this is a specially-arranged page table which has the permissions
808 # barred for execute on the leaf node (EAA=0x2 instead of EAA=0x3)
809 mem
= pagetables
.test2
815 icache
= m
.submodules
.ldst
.icache
816 sim
.add_sync_process(wrap(_test_loadstore1_ifetch_invalid(m
, mem
)))
817 # add two wb_get processes onto the *same* memory dictionary.
818 # this shouuuld work.... cross-fingers...
819 sim
.add_sync_process(wrap(wb_get(cmpi
.wb_bus(), mem
)))
820 sim
.add_sync_process(wrap(wb_get(icache
.bus
, mem
)))
821 with sim
.write_vcd('test_loadstore1_ifetch_invalid.vcd',
822 traces
=[m
.debug_status
]): # include extra debug
825 def test_loadstore1_ifetch_multi():
826 m
, cmpi
= setup_mmu()
829 # this is a specially-arranged page table which has the permissions
830 # barred for execute on the leaf node (EAA=0x2 instead of EAA=0x3)
831 mem
= pagetables
.test1
833 # set this up before passing to Simulator (which calls elaborate)
834 icache
= m
.submodules
.ldst
.icache
835 icache
.use_fetch_interface() # this is the function which converts
836 # to FetchUnitInterface. *including*
837 # rewiring the Wishbone Bus to ibus
843 sim
.add_sync_process(wrap(_test_loadstore1_ifetch_multi(m
, mem
)))
844 # add two wb_get processes onto the *same* memory dictionary.
845 # this shouuuld work.... cross-fingers...
846 sim
.add_sync_process(wrap(wb_get(cmpi
.wb_bus(), mem
)))
847 sim
.add_sync_process(wrap(wb_get(icache
.ibus
, mem
))) # ibus not bus
848 with sim
.write_vcd('test_loadstore1_ifetch_multi.vcd',
849 traces
=[m
.debug_status
]): # include extra debug
852 if __name__
== '__main__':
854 test_loadstore1_invalid()
855 test_loadstore1_ifetch() #FIXME
856 test_loadstore1_ifetch_invalid()
857 test_loadstore1_ifetch_unit_iface() # guess: should be working
858 test_loadstore1_ifetch_multi()