fix bug in unit test, forgot that wb_get mem dict is 64-bit wide data
[soc.git] / src / soc / experiment / test / test_loadstore1.py
1 from nmigen import (C, Module, Signal, Elaboratable, Mux, Cat, Repl, Signal,
2 Const)
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
10
11 from soc.config.test.test_pi2ls import (pi_ld, pi_st, pi_ldst, wait_busy,
12 get_exception_info)
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
16
17 from soc.fu.ldst.loadstore import LoadStore1
18 from soc.experiment.mmu import MMU
19 from soc.experiment.test import pagetables
20
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
26
27 from soc.config.test.test_fetch import read_from_addr
28
29 def setup_mmu():
30
31 wbget.stop = False
32
33 pspec = TestMemPspec(ldst_ifacetype='mmu_cache_wb',
34 imem_ifacetype='',
35 addr_wid=48,
36 #disable_cache=True, # hmmm...
37 mask_wid=8,
38 reg_wid=64)
39
40 m = Module()
41 comb = m.d.comb
42 cmpi = ConfigMemoryPortInterface(pspec)
43 m.submodules.ldst = ldst = cmpi.pi
44 m.submodules.mmu = mmu = MMU()
45 dcache = ldst.dcache
46 icache = ldst.icache
47
48 l_in, l_out = mmu.l_in, mmu.l_out
49 d_in, d_out = dcache.d_in, dcache.d_out
50 i_in, i_out = icache.i_in, icache.i_out # FetchToICache, ICacheToDecode
51
52 # link mmu, dcache and icache together
53 m.d.comb += dcache.m_in.eq(mmu.d_out) # MMUToDCacheType
54 m.d.comb += icache.m_in.eq(mmu.i_out) # MMUToICacheType
55 m.d.comb += mmu.d_in.eq(dcache.m_out) # DCacheToMMUType
56
57 # link ldst and MMU together
58 comb += l_in.eq(ldst.m_out)
59 comb += ldst.m_in.eq(l_out)
60
61 # add a debug status Signal: use "msg.str = "blah"
62 # then toggle with yield msg.eq(0); yield msg.eq(1)
63 debug_status = Signal(8, decoder=lambda _ : debug_status.str)
64 m.debug_status = debug_status
65 debug_status.str = ''
66
67 return m, cmpi
68
69
70 def icache_read(dut,addr,priv,virt):
71
72 icache = dut.submodules.ldst.icache
73 i_in = icache.i_in
74 i_out = icache.i_out
75
76 yield i_in.priv_mode.eq(priv)
77 yield i_in.virt_mode.eq(virt)
78 yield i_in.req.eq(1)
79 yield i_in.nia.eq(addr)
80 yield i_in.stop_mark.eq(0)
81
82 yield i_in.req.eq(1)
83 yield i_in.nia.eq(addr)
84 yield
85 valid = yield i_out.valid
86 failed = yield i_out.fetch_failed
87 while not valid and not failed:
88 yield
89 valid = yield i_out.valid
90 failed = yield i_out.fetch_failed
91 yield i_in.req.eq(0)
92
93 nia = yield i_out.nia
94 insn = yield i_out.insn
95 yield
96 yield
97
98 return nia, insn, valid, failed
99
100
101 test_exceptions = True
102 test_dcbz = True
103 test_random = True
104
105
106 def debug(dut, msg):
107 print ("set debug message", msg)
108 dut.debug_status.str = msg # set the message
109 yield dut.debug_status.eq(0) # trigger an update
110 yield dut.debug_status.eq(1)
111
112
113 def _test_loadstore1_ifetch_iface(dut, mem):
114 """test_loadstore1_ifetch_iface
115
116 read in priv mode, non-virtual. tests the FetchUnitInterface
117
118 """
119
120 mmu = dut.submodules.mmu
121 ldst = dut.submodules.ldst
122 pi = ldst.pi
123 icache = dut.submodules.ldst.icache
124 wbget.stop = False
125
126 print("=== test loadstore instruction (real) ===")
127
128 i_in = icache.i_in
129 i_out = icache.i_out
130 i_m_in = icache.m_in
131
132 yield from debug(dut, "real mem instruction")
133 # set address to 0x8, update mem[0x8] to 01234 | 0x5678<<32
134 # (have to do 64-bit writes into the dictionary-memory-emulated-thing)
135 addr = 8
136 addr2 = 12
137 expected_insn2 = 0x5678
138 expected_insn = 0x1234
139 mem[addr] = expected_insn | expected_insn2<<32
140
141 yield i_in.priv_mode.eq(1)
142 insn = yield from read_from_addr(icache, addr, stall=False)
143
144 nia = yield i_out.nia # NO, must use FetchUnitInterface
145 print ("fetched %x from addr %x" % (insn, nia))
146 assert insn == expected_insn
147
148 print("=== test loadstore instruction (2nd, real) ===")
149 yield from debug(dut, "real mem 2nd (addr 0xc)")
150
151 insn2 = yield from read_from_addr(icache, addr2, stall=False)
152
153 nia = yield i_out.nia # NO, must use FetchUnitInterface
154 print ("fetched %x from addr2 %x" % (insn2, nia))
155 assert insn2 == expected_insn2
156
157 print("=== test loadstore instruction (done) ===")
158
159 yield from debug(dut, "test done")
160 yield
161 yield
162
163 print ("fetched %x from addr %x" % (insn, nia))
164 assert insn == expected_insn
165
166 wbget.stop = True
167
168 def _test_loadstore1_ifetch_multi(dut, mem):
169 yield from debug(dut, "TODO")
170 yield
171 yield
172 yield
173 # TODO fetch instructions from multiple addresses
174 # should cope with some addresses being invalid
175 addrs = [0x10200,0x10204,10208,10200]
176 for addr in addrs:
177 yield from debug(dut, "TODO_fetch_from "+hex(addr))
178 # use the new interface in this test
179 yield
180 yield
181 yield
182
183 wbget.stop = True
184
185 def _test_loadstore1_ifetch(dut, mem):
186 """test_loadstore1_ifetch
187
188 this is quite a complex multi-step test.
189
190 * first (just because, as a demo) read in priv mode, non-virtual.
191 just like in experiment/icache.py itself.
192
193 * second, using the (usual) PTE for these things (which came originally
194 from gem5-experimental experiment/radix_walk_example.txt) do a
195 virtual-memory read through the *instruction* cache.
196 this is expected to FAIL
197
198 * third: mess about with the MMU, setting "iside" (instruction-side),
199 requesting an MMU RADIX LOOKUP. this triggers an itlb_load
200 (instruction-cache TLB entry-insertion)
201
202 * fourth and finally: retry the read of the instruction through i-cache.
203 this is now expected to SUCCEED
204
205 a lot going on.
206 """
207
208 mmu = dut.submodules.mmu
209 ldst = dut.submodules.ldst
210 pi = ldst.pi
211 icache = dut.submodules.ldst.icache
212 wbget.stop = False
213
214 print("=== test loadstore instruction (real) ===")
215
216 i_in = icache.i_in
217 i_out = icache.i_out
218 i_m_in = icache.m_in
219
220 # first virtual memory test
221
222 print ("set process table")
223 yield from debug(dut, "set prtble")
224 yield mmu.rin.prtbl.eq(0x1000000) # set process table
225 yield
226
227 yield from debug(dut, "real mem instruction")
228 # set address to zero, update mem[0] to 01234
229 addr = 8
230 expected_insn = 0x1234
231 mem[addr] = expected_insn
232
233 yield i_in.priv_mode.eq(1)
234 yield i_in.req.eq(0)
235 yield i_in.nia.eq(addr)
236 yield i_in.stop_mark.eq(0)
237 yield i_m_in.tlbld.eq(0)
238 yield i_m_in.tlbie.eq(0)
239 yield i_m_in.addr.eq(0)
240 yield i_m_in.pte.eq(0)
241 yield
242 yield
243 yield
244
245 # miss, stalls for a bit -- this one is different here
246 ##nia, insn, valid, failed = yield from icache_read(dut,addr,0,0)
247 ##assert(valid==0)
248 ##assert(failed==1)
249
250 yield i_in.req.eq(1)
251 yield i_in.nia.eq(addr)
252 yield
253 valid = yield i_out.valid
254 while not valid:
255 yield
256 valid = yield i_out.valid
257 yield i_in.req.eq(0)
258
259 nia = yield i_out.nia
260 insn = yield i_out.insn
261 yield
262 yield
263
264 print ("fetched %x from addr %x" % (insn, nia))
265 assert insn == expected_insn
266
267 print("=== test loadstore instruction (virtual) ===")
268
269 # look up i-cache expecting it to fail
270
271 yield from debug(dut, "virtual instr req")
272 # set address to 0x10200, update mem[] to 5678
273 virt_addr = 0x10200
274 real_addr = virt_addr
275 expected_insn = 0x5678
276 mem[real_addr] = expected_insn
277
278 yield i_in.priv_mode.eq(0)
279 yield i_in.virt_mode.eq(1)
280 yield i_in.req.eq(0)
281 yield i_in.nia.eq(virt_addr)
282 yield i_in.stop_mark.eq(0)
283 yield i_m_in.tlbld.eq(0)
284 yield i_m_in.tlbie.eq(0)
285 yield i_m_in.addr.eq(0)
286 yield i_m_in.pte.eq(0)
287 yield
288 yield
289 yield
290
291 # miss, stalls for a bit
292 yield i_in.req.eq(1)
293 yield i_in.nia.eq(virt_addr)
294 yield
295 valid = yield i_out.valid
296 failed = yield i_out.fetch_failed
297 while not valid and not failed:
298 yield
299 valid = yield i_out.valid
300 failed = yield i_out.fetch_failed
301 yield i_in.req.eq(0)
302
303 print ("failed?", "yes" if failed else "no")
304 assert failed == 1
305 yield
306 yield
307
308 print("=== test loadstore instruction (instruction fault) ===")
309
310 yield from debug(dut, "instr fault")
311
312 virt_addr = 0x10200
313
314 yield ldst.priv_mode.eq(0)
315 yield ldst.instr_fault.eq(1)
316 yield ldst.maddr.eq(virt_addr)
317 #ld_data, exctype, exc = yield from pi_ld(pi, virt_addr, 8, msr_pr=1)
318 yield
319 yield ldst.instr_fault.eq(0)
320 while True:
321 done = yield (ldst.done)
322 exc_info = yield from get_exception_info(pi.exc_o)
323 if done or exc_info.happened:
324 break
325 yield
326 assert exc_info.happened == 0 # assert just before doing the fault set zero
327 yield ldst.instr_fault.eq(0)
328 yield
329 yield
330 yield
331
332 print("=== test loadstore instruction (try instruction again) ===")
333 yield from debug(dut, "instr virt retry")
334 # set address to 0x10200, update mem[] to 5678
335 virt_addr = 0x10200
336 real_addr = virt_addr
337 expected_insn = 0x5678
338
339 yield i_in.priv_mode.eq(0)
340 yield i_in.virt_mode.eq(1)
341 yield i_in.req.eq(0)
342 yield i_in.nia.eq(virt_addr)
343 yield i_in.stop_mark.eq(0)
344 yield i_m_in.tlbld.eq(0)
345 yield i_m_in.tlbie.eq(0)
346 yield i_m_in.addr.eq(0)
347 yield i_m_in.pte.eq(0)
348 yield
349 yield
350 yield
351
352 # miss, stalls for a bit
353 """
354 yield i_in.req.eq(1)
355 yield i_in.nia.eq(virt_addr)
356 yield
357 valid = yield i_out.valid
358 failed = yield i_out.fetch_failed
359 while not valid and not failed:
360 yield
361 valid = yield i_out.valid
362 failed = yield i_out.fetch_failed
363 yield i_in.req.eq(0)
364 nia = yield i_out.nia
365 insn = yield i_out.insn
366 """
367
368 ## part 4
369 nia, insn, valid, failed = yield from icache_read(dut,virt_addr,0,1)
370
371 yield from debug(dut, "test done")
372 yield
373 yield
374
375 print ("failed?", "yes" if failed else "no")
376 assert failed == 0
377
378 print ("fetched %x from addr %x" % (insn, nia))
379 assert insn == expected_insn
380
381 wbget.stop = True
382
383
384 def _test_loadstore1_invalid(dut, mem):
385 mmu = dut.submodules.mmu
386 pi = dut.submodules.ldst.pi
387 wbget.stop = False
388
389 print("=== test invalid ===")
390
391 addr = 0
392 ld_data, exctype, exc = yield from pi_ld(pi, addr, 8, msr_pr=1)
393 print("ld_data", ld_data, exctype, exc)
394 assert (exctype == "slow")
395 invalid = exc.invalid
396 assert (invalid == 1)
397
398 print("=== test invalid done ===")
399
400 wbget.stop = True
401
402
403 def _test_loadstore1(dut, mem):
404 mmu = dut.submodules.mmu
405 pi = dut.submodules.ldst.pi
406 ldst = dut.submodules.ldst # to get at DAR (NOT part of PortInterface)
407 wbget.stop = False
408
409 yield mmu.rin.prtbl.eq(0x1000000) # set process table
410 yield
411
412 addr = 0x100e0
413 data = 0xf553b658ba7e1f51
414
415 if test_dcbz:
416 yield from pi_st(pi, addr, data, 8, msr_pr=1)
417 yield
418
419 ld_data, exctype, exc = yield from pi_ld(pi, addr, 8, msr_pr=1)
420 assert ld_data == 0xf553b658ba7e1f51
421 assert exctype is None
422
423 ld_data, exctype, exc = yield from pi_ld(pi, addr, 8, msr_pr=1)
424 assert ld_data == 0xf553b658ba7e1f51
425 assert exctype is None
426
427 print("do_dcbz ===============")
428 yield from pi_st(pi, addr, data, 8, msr_pr=1, is_dcbz=1)
429 print("done_dcbz ===============")
430 yield
431
432 ld_data, exctype, exc = yield from pi_ld(pi, addr, 8, msr_pr=1)
433 print("ld_data after dcbz")
434 print(ld_data)
435 assert ld_data == 0
436 assert exctype is None
437
438 if test_exceptions:
439 print("=== alignment error (ld) ===")
440 addr = 0xFF100e0FF
441 ld_data, exctype, exc = yield from pi_ld(pi, addr, 8, msr_pr=1)
442 if exc:
443 alignment = exc.alignment
444 happened = exc.happened
445 yield # wait for dsr to update
446 dar = yield ldst.dar
447 else:
448 alignment = 0
449 happened = 0
450 dar = 0
451 assert (happened == 1)
452 assert (alignment == 1)
453 assert (dar == addr)
454 assert (exctype == "fast")
455 yield from wait_busy(pi, debug="pi_ld_E_alignment_error")
456 # wait is only needed in case of in exception here
457 print("=== alignment error test passed (ld) ===")
458
459 # take some cycles in between so that gtkwave separates out
460 # signals
461 yield
462 yield
463 yield
464 yield
465
466 print("=== alignment error (st) ===")
467 addr = 0xFF100e0FF
468 exctype, exc = yield from pi_st(pi, addr,0, 8, msr_pr=1)
469 if exc:
470 alignment = exc.alignment
471 happened = exc.happened
472 else:
473 alignment = 0
474 happened = 0
475 assert (happened == 1)
476 assert (alignment==1)
477 assert (dar==addr)
478 assert (exctype == "fast")
479 #???? yield from wait_busy(pi, debug="pi_st_E_alignment_error")
480 # wait is only needed in case of in exception here
481 print("=== alignment error test passed (st) ===")
482 yield #FIXME hangs
483
484 if True:
485 print("=== no alignment error (ld) ===")
486 addr = 0x100e0
487 ld_data, exctype, exc = yield from pi_ld(pi, addr, 8, msr_pr=1)
488 print("ld_data", ld_data, exctype, exc)
489 if exc:
490 alignment = exc.alignment
491 happened = exc.happened
492 else:
493 alignment = 0
494 happened = 0
495 assert (happened == 0)
496 assert (alignment == 0)
497 print("=== no alignment error done (ld) ===")
498
499 if test_random:
500 addrs = [0x456920,0xa7a180,0x299420,0x1d9d60]
501
502 for addr in addrs:
503 print("== RANDOM addr ==",hex(addr))
504 ld_data, exctype, exc = yield from pi_ld(pi, addr, 8, msr_pr=1)
505 print("ld_data[RANDOM]",ld_data,exc,addr)
506 assert (exctype == None)
507
508 for addr in addrs:
509 print("== RANDOM addr ==",hex(addr))
510 exc = yield from pi_st(pi, addr,0xFF*addr, 8, msr_pr=1)
511 assert (exctype == None)
512
513 # readback written data and compare
514 for addr in addrs:
515 print("== RANDOM addr ==",hex(addr))
516 ld_data, exctype, exc = yield from pi_ld(pi, addr, 8, msr_pr=1)
517 print("ld_data[RANDOM_READBACK]",ld_data,exc,addr)
518 assert (exctype == None)
519 assert (ld_data == 0xFF*addr)
520
521 print("== RANDOM addr done ==")
522
523 wbget.stop = True
524
525
526 def _test_loadstore1_ifetch_invalid(dut, mem):
527 mmu = dut.submodules.mmu
528 ldst = dut.submodules.ldst
529 pi = ldst.pi
530 icache = dut.submodules.ldst.icache
531 wbget.stop = False
532
533 print("=== test loadstore instruction (invalid) ===")
534
535 i_in = icache.i_in
536 i_out = icache.i_out
537 i_m_in = icache.m_in
538
539 # first virtual memory test
540
541 print ("set process table")
542 yield from debug(dut, "set prtbl")
543 yield mmu.rin.prtbl.eq(0x1000000) # set process table
544 yield
545
546 yield from debug(dut, "real mem instruction")
547 # set address to zero, update mem[0] to 01234
548 addr = 8
549 expected_insn = 0x1234
550 mem[addr] = expected_insn
551
552 yield i_in.priv_mode.eq(1)
553 yield i_in.req.eq(0)
554 yield i_in.nia.eq(addr)
555 yield i_in.stop_mark.eq(0)
556 yield i_m_in.tlbld.eq(0)
557 yield i_m_in.tlbie.eq(0)
558 yield i_m_in.addr.eq(0)
559 yield i_m_in.pte.eq(0)
560 yield
561 yield
562 yield
563
564 # miss, stalls for a bit
565 yield i_in.req.eq(1)
566 yield i_in.nia.eq(addr)
567 yield
568 valid = yield i_out.valid
569 nia = yield i_out.nia
570 while not valid:
571 yield
572 valid = yield i_out.valid
573 yield i_in.req.eq(0)
574
575 nia = yield i_out.nia
576 insn = yield i_out.insn
577
578 yield
579 yield
580
581 print ("fetched %x from addr %x" % (insn, nia))
582 assert insn == expected_insn
583
584 print("=== test loadstore instruction (virtual) ===")
585 yield from debug(dut, "virtual instr req")
586
587 # look up i-cache expecting it to fail
588
589 # set address to 0x10200, update mem[] to 5678
590 virt_addr = 0x10200
591 real_addr = virt_addr
592 expected_insn = 0x5678
593 mem[real_addr] = expected_insn
594
595 yield i_in.priv_mode.eq(1)
596 yield i_in.virt_mode.eq(1)
597 yield i_in.req.eq(0)
598 yield i_in.nia.eq(virt_addr)
599 yield i_in.stop_mark.eq(0)
600 yield i_m_in.tlbld.eq(0)
601 yield i_m_in.tlbie.eq(0)
602 yield i_m_in.addr.eq(0)
603 yield i_m_in.pte.eq(0)
604 yield
605 yield
606 yield
607
608 # miss, stalls for a bit
609 yield i_in.req.eq(1)
610 yield i_in.nia.eq(virt_addr)
611 yield
612 valid = yield i_out.valid
613 failed = yield i_out.fetch_failed
614 while not valid and not failed:
615 yield
616 valid = yield i_out.valid
617 failed = yield i_out.fetch_failed
618 yield i_in.req.eq(0)
619
620 print ("failed?", "yes" if failed else "no")
621 assert failed == 1
622 yield
623 yield
624
625 print("=== test invalid loadstore instruction (instruction fault) ===")
626
627 yield from debug(dut, "instr fault (perm err expected)")
628 virt_addr = 0x10200
629
630 yield ldst.priv_mode.eq(0)
631 yield ldst.instr_fault.eq(1)
632 yield ldst.maddr.eq(virt_addr)
633 #ld_data, exctype, exc = yield from pi_ld(pi, virt_addr, 8, msr_pr=1)
634 yield
635 yield ldst.instr_fault.eq(0)
636 while True:
637 done = yield (ldst.done)
638 exc_info = yield from get_exception_info(pi.exc_o)
639 if done or exc_info.happened:
640 break
641 yield
642 assert exc_info.happened == 1 # different here as expected
643
644 # TODO: work out what kind of exception occurred and check it's
645 # the right one. we *expect* it to be a permissions error because
646 # the RPTE leaf node in pagetables.test2 is marked as "non-executable"
647 # but we also expect instr_fault to be set because it is an instruction
648 # (iside) lookup
649 print (" MMU lookup exception type?")
650 for fname in LDSTExceptionTuple._fields:
651 print (" fname %20s %d" % (fname, getattr(exc_info, fname)))
652
653 # ok now printed them out and visually inspected: check them with asserts
654 assert exc_info.instr_fault == 1 # instruction fault (yes!)
655 assert exc_info.perm_error == 1 # permissions (yes!)
656 assert exc_info.rc_error == 0
657 assert exc_info.alignment == 0
658 assert exc_info.invalid == 0
659 assert exc_info.segment_fault == 0
660 assert exc_info.rc_error == 0
661
662 yield from debug(dut, "test done")
663 yield ldst.instr_fault.eq(0)
664 yield
665 yield
666 yield
667
668 wbget.stop = True
669
670
671 def test_loadstore1_ifetch_unit_iface():
672
673 m, cmpi = setup_mmu()
674
675 mem = pagetables.test1
676
677 # set this up before passing to Simulator (which calls elaborate)
678 icache = m.submodules.ldst.icache
679 icache.use_fetch_interface() # this is the function which converts
680 # to FetchUnitInterface. *including*
681 # rewiring the Wishbone Bus to ibus
682
683 # nmigen Simulation
684 sim = Simulator(m)
685 sim.add_clock(1e-6)
686
687 sim.add_sync_process(wrap(_test_loadstore1_ifetch_iface(m, mem)))
688 # add two wb_get processes onto the *same* memory dictionary.
689 # this shouuuld work.... cross-fingers...
690 sim.add_sync_process(wrap(wb_get(cmpi.wb_bus(), mem)))
691 sim.add_sync_process(wrap(wb_get(icache.ibus, mem))) # ibus not bus
692 with sim.write_vcd('test_loadstore1_ifetch_iface.vcd',
693 traces=[m.debug_status]): # include extra debug
694 sim.run()
695
696
697 def test_loadstore1_ifetch():
698
699 m, cmpi = setup_mmu()
700
701 mem = pagetables.test1
702
703 # nmigen Simulation
704 sim = Simulator(m)
705 sim.add_clock(1e-6)
706
707 icache = m.submodules.ldst.icache
708 sim.add_sync_process(wrap(_test_loadstore1_ifetch(m, mem)))
709 # add two wb_get processes onto the *same* memory dictionary.
710 # this shouuuld work.... cross-fingers...
711 sim.add_sync_process(wrap(wb_get(cmpi.wb_bus(), mem)))
712 sim.add_sync_process(wrap(wb_get(icache.bus, mem)))
713 with sim.write_vcd('test_loadstore1_ifetch.vcd',
714 traces=[m.debug_status]): # include extra debug
715 sim.run()
716
717
718 def test_loadstore1():
719
720 m, cmpi = setup_mmu()
721
722 mem = pagetables.test1
723
724 # nmigen Simulation
725 sim = Simulator(m)
726 sim.add_clock(1e-6)
727
728 sim.add_sync_process(wrap(_test_loadstore1(m, mem)))
729 sim.add_sync_process(wrap(wb_get(cmpi.wb_bus(), mem)))
730 with sim.write_vcd('test_loadstore1.vcd'):
731 sim.run()
732
733
734 def test_loadstore1_invalid():
735
736 m, cmpi = setup_mmu()
737
738 mem = {}
739
740 # nmigen Simulation
741 sim = Simulator(m)
742 sim.add_clock(1e-6)
743
744 sim.add_sync_process(wrap(_test_loadstore1_invalid(m, mem)))
745 sim.add_sync_process(wrap(wb_get(cmpi.wb_bus(), mem)))
746 with sim.write_vcd('test_loadstore1_invalid.vcd'):
747 sim.run()
748
749 def test_loadstore1_ifetch_invalid():
750 m, cmpi = setup_mmu()
751
752 # this is a specially-arranged page table which has the permissions
753 # barred for execute on the leaf node (EAA=0x2 instead of EAA=0x3)
754 mem = pagetables.test2
755
756 # nmigen Simulation
757 sim = Simulator(m)
758 sim.add_clock(1e-6)
759
760 icache = m.submodules.ldst.icache
761 sim.add_sync_process(wrap(_test_loadstore1_ifetch_invalid(m, mem)))
762 # add two wb_get processes onto the *same* memory dictionary.
763 # this shouuuld work.... cross-fingers...
764 sim.add_sync_process(wrap(wb_get(cmpi.wb_bus(), mem)))
765 sim.add_sync_process(wrap(wb_get(icache.bus, mem)))
766 with sim.write_vcd('test_loadstore1_ifetch_invalid.vcd',
767 traces=[m.debug_status]): # include extra debug
768 sim.run()
769
770 def test_loadstore1_ifetch_multi():
771 m, cmpi = setup_mmu()
772
773 # this is a specially-arranged page table which has the permissions
774 # barred for execute on the leaf node (EAA=0x2 instead of EAA=0x3)
775 mem = pagetables.test1
776
777 # nmigen Simulation
778 sim = Simulator(m)
779 sim.add_clock(1e-6)
780
781 icache = m.submodules.ldst.icache
782 sim.add_sync_process(wrap(_test_loadstore1_ifetch_multi(m, mem)))
783 # add two wb_get processes onto the *same* memory dictionary.
784 # this shouuuld work.... cross-fingers...
785 sim.add_sync_process(wrap(wb_get(cmpi.wb_bus(), mem)))
786 sim.add_sync_process(wrap(wb_get(icache.bus, mem)))
787 with sim.write_vcd('test_loadstore1_ifetch_multi.vcd',
788 traces=[m.debug_status]): # include extra debug
789 sim.run()
790
791 if __name__ == '__main__':
792 test_loadstore1()
793 test_loadstore1_invalid()
794 test_loadstore1_ifetch()
795 test_loadstore1_ifetch_invalid()
796 test_loadstore1_ifetch_multi()
797 test_loadstore1_ifetch_unit_iface()