6efd8f88b5af3f5beab4b17fc3557ec53ef340f9
[soc.git] / src / soc / experiment / test / test_mmu_dcache.py
1 from nmigen import (C, Module, Signal, Elaboratable, Mux, Cat, Repl, Signal)
2 from nmigen.cli import main
3 from nmigen.cli import rtlil
4 from nmutil.iocontrol import RecordObject
5 from nmutil.byterev import byte_reverse
6 from nmutil.mask import Mask, masked
7 from nmutil.util import Display
8
9 if True:
10 from nmigen.back.pysim import Simulator, Delay, Settle
11 else:
12 from nmigen.sim.cxxsim import Simulator, Delay, Settle
13 from nmutil.util import wrap
14
15 from soc.experiment.mem_types import (LoadStore1ToMMUType,
16 MMUToLoadStore1Type,
17 MMUToDCacheType,
18 DCacheToMMUType,
19 MMUToICacheType)
20
21 from soc.experiment.mmu import MMU
22 from soc.experiment.dcache import DCache
23
24 stop = False
25
26
27 def wb_get(dc):
28 """simulator process for getting memory load requests
29 """
30
31 global stop
32
33 def b(x):
34 return int.from_bytes(x.to_bytes(8, byteorder='little'),
35 byteorder='big', signed=False)
36
37 mem = {0x10000: # PARTITION_TABLE_2
38 # PATB_GR=1 PRTB=0x1000 PRTS=0xb
39 b(0x800000000100000b),
40
41 0x30000: # RADIX_ROOT_PTE
42 # V = 1 L = 0 NLB = 0x400 NLS = 9
43 b(0x8000000000040009),
44
45 0x40000: # RADIX_SECOND_LEVEL
46 # V = 1 L = 1 SW = 0 RPN = 0
47 # R = 1 C = 1 ATT = 0 EAA 0x7
48 b(0xc000000000000187),
49
50 0x1000000: # PROCESS_TABLE_3
51 # RTS1 = 0x2 RPDB = 0x300 RTS2 = 0x5 RPDS = 13
52 b(0x40000000000300ad),
53 }
54
55 while not stop:
56 while True: # wait for dc_valid
57 if stop:
58 return
59 cyc = yield (dc.wb_out.cyc)
60 stb = yield (dc.wb_out.stb)
61 if cyc and stb:
62 break
63 yield
64 addr = (yield dc.wb_out.adr) << 3
65 if addr not in mem:
66 print (" DCACHE LOOKUP FAIL %x" % (addr))
67 stop = True
68 return
69
70 yield
71 data = mem[addr]
72 yield dc.wb_in.data.eq(data)
73 print ("dcache get %x data %x" % (addr, data))
74 yield dc.wb_in.ack.eq(1)
75 yield
76 yield dc.wb_in.ack.eq(0)
77
78
79 def mmu_sim(mmu):
80 global stop
81 yield mmu.rin.prtbl.eq(0x1000000) # set process table
82 yield
83
84 yield mmu.l_in.load.eq(1)
85 yield mmu.l_in.priv.eq(1)
86 yield mmu.l_in.addr.eq(0x10000)
87 yield mmu.l_in.valid.eq(1)
88 while not stop: # wait for dc_valid / err
89 l_done = yield (mmu.l_out.done)
90 l_err = yield (mmu.l_out.err)
91 l_badtree = yield (mmu.l_out.badtree)
92 l_permerr = yield (mmu.l_out.perm_error)
93 l_rc_err = yield (mmu.l_out.rc_error)
94 l_segerr = yield (mmu.l_out.segerr)
95 l_invalid = yield (mmu.l_out.invalid)
96 if (l_done or l_err or l_badtree or
97 l_permerr or l_rc_err or l_segerr or l_invalid):
98 break
99 yield
100 addr = yield mmu.d_out.addr
101 pte = yield mmu.d_out.pte
102 print ("translated done %d err %d badtree %d addr %x pte %x" % \
103 (l_done, l_err, l_badtree, addr, pte))
104
105 stop = True
106
107
108 def test_mmu():
109 mmu = MMU()
110 dcache = DCache()
111 m = Module()
112 m.submodules.mmu = mmu
113 m.submodules.dcache = dcache
114
115 # link mmu and dcache together
116 m.d.comb += dcache.m_in.eq(mmu.d_out)
117 m.d.comb += mmu.d_in.eq(dcache.m_out)
118
119 # nmigen Simulation
120 sim = Simulator(m)
121 sim.add_clock(1e-6)
122
123 sim.add_sync_process(wrap(mmu_sim(mmu)))
124 sim.add_sync_process(wrap(wb_get(dcache)))
125 with sim.write_vcd('test_mmu.vcd'):
126 sim.run()
127
128 if __name__ == '__main__':
129 test_mmu()