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