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