6871109ad0eeb4fe7a4ea36621463fbe720e3cb5
[soc.git] / src / soc / experiment / test / test_loadstore1.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.mask import Mask, masked
5 from nmutil.util import Display
6 from random import randint, seed
7 from nmigen.sim import Simulator, Delay, Settle
8 from nmutil.util import wrap
9
10 from soc.config.test.test_pi2ls import pi_ld, pi_st, pi_ldst
11 from soc.config.test.test_loadstore import TestMemPspec
12 from soc.config.loadstore import ConfigMemoryPortInterface
13
14 from soc.fu.ldst.loadstore import LoadStore1
15 from soc.experiment.mmu import MMU
16 from soc.experiment.test import pagetables
17
18 from nmigen.compat.sim import run_simulation
19
20 stop = False
21
22 def wb_get(wb, mem):
23 """simulator process for getting memory load requests
24 """
25
26 global stop
27 assert(stop==False)
28
29 while not stop:
30 while True: # wait for dc_valid
31 if stop:
32 return
33 cyc = yield (wb.cyc)
34 stb = yield (wb.stb)
35 if cyc and stb:
36 break
37 yield
38 addr = (yield wb.adr) << 3
39 if addr not in mem:
40 print (" WB LOOKUP NO entry @ %x, returning zero" % (addr))
41
42 # read or write?
43 we = (yield wb.we)
44 if we:
45 store = (yield wb.dat_w)
46 sel = (yield wb.sel)
47 data = mem.get(addr, 0)
48 # note we assume 8-bit sel, here
49 res = 0
50 for i in range(8):
51 mask = 0xff << (i*8)
52 if sel & (1<<i):
53 res |= store & mask
54 else:
55 res |= data & mask
56 mem[addr] = res
57 print (" DCACHE set %x mask %x data %x" % (addr, sel, res))
58 else:
59 data = mem.get(addr, 0)
60 yield wb.dat_r.eq(data)
61 print (" DCACHE get %x data %x" % (addr, data))
62
63 yield wb.ack.eq(1)
64 yield
65 yield wb.ack.eq(0)
66 yield
67
68 def setup_mmu():
69
70 global stop
71 stop = False
72
73 pspec = TestMemPspec(ldst_ifacetype='mmu_cache_wb',
74 imem_ifacetype='',
75 addr_wid=48,
76 #disable_cache=True, # hmmm...
77 mask_wid=8,
78 reg_wid=64)
79
80 m = Module()
81 comb = m.d.comb
82 cmpi = ConfigMemoryPortInterface(pspec)
83 m.submodules.ldst = ldst = cmpi.pi
84 m.submodules.mmu = mmu = MMU()
85 dcache = ldst.dcache
86
87 l_in, l_out = mmu.l_in, mmu.l_out
88 d_in, d_out = dcache.d_in, dcache.d_out
89 wb_out, wb_in = dcache.wb_out, dcache.wb_in
90
91 # link mmu and dcache together
92 m.d.comb += dcache.m_in.eq(mmu.d_out) # MMUToDCacheType
93 m.d.comb += mmu.d_in.eq(dcache.m_out) # DCacheToMMUType
94
95 # link ldst and MMU together
96 comb += l_in.eq(ldst.m_out)
97 comb += ldst.m_in.eq(l_out)
98
99 return m, cmpi
100
101 def _test_loadstore1(dut, mem):
102 mmu = dut.submodules.mmu
103 pi = dut.submodules.ldst.pi
104 global stop
105 stop = False
106
107 yield mmu.rin.prtbl.eq(0x1000000) # set process table
108 yield
109
110 addr = 0x100e0
111 data = 0xf553b658ba7e1f51
112
113 yield from pi_st(pi, addr, data, 8, msr_pr=1)
114 yield
115
116 ld_data = yield from pi_ld(pi, addr, 8, msr_pr=1)
117 assert ld_data == 0xf553b658ba7e1f51
118 ld_data = yield from pi_ld(pi, addr, 8, msr_pr=1)
119 assert ld_data == 0xf553b658ba7e1f51
120
121 print("do_dcbz ===============")
122 yield from pi_st(pi, addr, data, 8, msr_pr=0, is_dcbz=1)
123 print("done_dcbz ===============")
124 yield
125
126 ld_data = yield from pi_ld(pi, addr, 8, msr_pr=1)
127 print("ld_data after dcbz")
128 print(ld_data)
129 assert ld_data == 0
130
131 print("=== alignment error ===")
132
133 addr = 0xFF100e0FF
134 ld_data = yield from pi_ld(pi, addr, 8, msr_pr=1)
135 # TODO assert dar == addr
136
137 yield
138 stop = True
139
140 def test_loadstore1():
141
142 m, cmpi = setup_mmu()
143
144 mem = pagetables.test1
145
146 # nmigen Simulation
147 sim = Simulator(m)
148 sim.add_clock(1e-6)
149
150 sim.add_sync_process(wrap(_test_loadstore1(m, mem)))
151 sim.add_sync_process(wrap(wb_get(cmpi.wb_bus(), mem)))
152 with sim.write_vcd('test_loadstore1.vcd'):
153 sim.run()
154
155 if __name__ == '__main__':
156 test_loadstore1()