should have been using common version of wb_get, not 8 duplicates
[soc.git] / src / soc / experiment / test / test_compldst_multi_mmu.py
1 # test case for LOAD / STORE Computation Unit using MMU
2
3 from nmigen.sim import Simulator, Delay, Settle, Tick
4 from nmigen.cli import verilog, rtlil
5 from nmigen import Module, Signal, Mux, Cat, Elaboratable, Array, Repl
6 from nmigen.hdl.rec import Record, Layout
7
8 from nmutil.latch import SRLatch, latchregister
9 from nmutil.byterev import byte_reverse
10 from nmutil.extend import exts
11 from nmutil.util import wrap
12 from soc.fu.regspec import RegSpecAPI
13
14 from openpower.decoder.power_enums import MicrOp, Function, LDSTMode
15 from soc.fu.ldst.ldst_input_record import CompLDSTOpSubset
16 from openpower.decoder.power_decoder2 import Data
17 from openpower.consts import MSR
18
19 from soc.experiment.compalu_multi import go_record, CompUnitRecord
20 from soc.experiment.l0_cache import PortInterface
21 from soc.experiment.pimem import LDSTException
22 from soc.experiment.compldst_multi import LDSTCompUnit, load, store
23 from soc.config.test.test_loadstore import TestMemPspec
24
25 from soc.experiment.mmu import MMU
26 from nmutil.util import Display
27
28 from soc.config.loadstore import ConfigMemoryPortInterface
29 from soc.experiment.test import pagetables
30 from openpower.test.wb_get import wb_get
31 from openpower.test import wb_get as wbget
32
33
34 ########################################
35
36 def wait_for_debug(sig, reason, wait=True, test1st=False):
37 v = (yield sig)
38 cnt = 0
39 print("wait for", reason, sig, v, wait, test1st)
40 if test1st and bool(v) == wait:
41 return
42 while True:
43 cnt = cnt + 1
44 if cnt > 15:
45 raise(Exception(reason))
46 break
47 yield
48 v = (yield sig)
49 #print("...wait for", sig, v)
50 if bool(v) == wait:
51 break
52
53 def store_debug(dut, src1, src2, src3, imm, imm_ok=True, update=False,
54 byterev=True,dcbz=False):
55 print("cut here ======================================")
56 print("ST", src1, src2, src3, imm, imm_ok, update)
57 if dcbz:
58 yield dut.oper_i.insn_type.eq(MicrOp.OP_DCBZ)
59 else:
60 yield dut.oper_i.insn_type.eq(MicrOp.OP_STORE)
61 yield dut.oper_i.data_len.eq(2) # half-word
62 yield dut.oper_i.byte_reverse.eq(byterev)
63 yield dut.src1_i.eq(src1)
64 yield dut.src2_i.eq(src2)
65 yield dut.src3_i.eq(src3)
66 yield dut.oper_i.imm_data.data.eq(imm)
67 yield dut.oper_i.imm_data.ok.eq(imm_ok)
68 #guess: this one was removed -- yield dut.oper_i.update.eq(update)
69 yield dut.issue_i.eq(1)
70 yield
71 yield dut.issue_i.eq(0)
72
73 if imm_ok:
74 active_rel = 0b101
75 else:
76 active_rel = 0b111
77 if dcbz:
78 active_rel = 0b001 # may be wrong, verify
79
80 # wait for all active rel signals to come up
81 cnt = 0
82 while True:
83 rel = yield dut.rd.rel_o # guess: wrong in dcbz case
84 cnt = cnt + 1
85 print("waitActiveRel",cnt)
86 if cnt > 10:
87 raise(Exception("Error1"))
88 print("rel EQ active_rel ?",rel,active_rel)
89 if rel == active_rel:
90 break
91 yield
92 yield dut.rd.go_i.eq(active_rel)
93 yield
94 yield dut.rd.go_i.eq(0)
95
96 yield from wait_for_debug(dut.adr_rel_o, "addr valid",False, test1st=True)
97 # yield from wait_for(dut.adr_rel_o)
98 # yield dut.ad.go.eq(1)
99 # yield
100 # yield dut.ad.go.eq(0)
101
102 if update:
103 yield from wait_for_debug(dut.wr.rel_o[1],"update")
104 yield dut.wr.go.eq(0b10)
105 yield
106 addr = yield dut.addr_o
107 print("addr", addr)
108 yield dut.wr.go.eq(0)
109 else:
110 addr = None
111 print("not update ===============")
112
113 yield from wait_for_debug(dut.sto_rel_o,"sto_rel_o")
114 yield dut.go_st_i.eq(1)
115 yield
116 yield dut.go_st_i.eq(0)
117 yield from wait_for_debug(dut.busy_o,"not_busy" ,False)
118 ###wait_for(dut.stwd_mem_o)
119 yield
120 return addr
121
122 # same thing as soc/src/soc/experiment/test/test_dcbz_pi.py
123 def ldst_sim(dut):
124 yield dut.mmu.rin.prtbl.eq(0x1000000) # set process table
125 addr = 0x100e0
126 data = 0xFF #just a single byte for this test
127 #data = 0xf553b658ba7e1f51
128
129 yield from store(dut, addr, 0, data, 0)
130 yield
131 ld_data, data_ok, ld_addr = yield from load(dut, addr, 0, 0)
132 print(data,data_ok,ld_addr)
133 assert(ld_data==data)
134 yield
135
136 data = 0
137
138 print("doing dcbz/store with data 0 .....")
139 yield from store_debug(dut, addr, 0, data, 0, dcbz=True) #hangs
140
141 ld_data, data_ok, ld_addr = yield from load(dut, addr, 0, 0)
142 print(data,data_ok,ld_addr)
143 print("ld_data is")
144 print(ld_data)
145 assert(ld_data==data)
146 print("dzbz test passed")
147
148 wbget.stop = True # stop simulation
149
150 ########################################
151 class TestLDSTCompUnitMMU(LDSTCompUnit):
152
153 def __init__(self, rwid, pspec):
154 # use a LoadStore1 here
155 cmpi = ConfigMemoryPortInterface(pspec)
156 self.cmpi = cmpi
157 ldst = cmpi.pi
158 self.l0 = ldst
159
160 self.mmu = MMU()
161 LDSTCompUnit.__init__(self, ldst.pi, rwid, 4)
162
163 def elaborate(self, platform):
164 m = LDSTCompUnit.elaborate(self, platform)
165 m.submodules.l0 = self.l0
166 m.submodules.mmu = self.mmu
167 # link addr-go direct to rel
168 m.d.comb += self.ad.go_i.eq(self.ad.rel_o)
169
170 # link mmu and dcache together
171 dcache = self.l0.dcache
172 mmu = self.mmu
173 m.d.comb += dcache.m_in.eq(mmu.d_out) # MMUToDCacheType
174 m.d.comb += mmu.d_in.eq(dcache.m_out) # DCacheToMMUType
175
176 return m
177
178
179 def test_scoreboard_mmu():
180
181 m = Module()
182
183 units = {}
184 pspec = TestMemPspec(ldst_ifacetype='mmu_cache_wb',
185 imem_ifacetype='bare_wb',
186 addr_wid=48,
187 mask_wid=8,
188 reg_wid=64,
189 units=units)
190
191 dut = TestLDSTCompUnitMMU(16,pspec)
192
193 m.submodules.dut = dut
194
195 sim = Simulator(m)
196 sim.add_clock(1e-6)
197
198 dut.mem = pagetables.test1
199 wbget.stop = False
200
201 sim.add_sync_process(wrap(ldst_sim(dut)))
202 sim.add_sync_process(wrap(wb_get(dut.cmpi.wb_bus(), dut.mem)))
203 with sim.write_vcd('test_scoreboard_mmu.vcd'):
204 sim.run()
205
206 ########################################
207 class TestLDSTCompUnitRegSpecMMU(LDSTCompUnit):
208
209 def __init__(self, pspec):
210 from soc.fu.ldst.pipe_data import LDSTPipeSpec
211 regspec = LDSTPipeSpec.regspec
212
213 # use a LoadStore1 here
214 cmpi = ConfigMemoryPortInterface(pspec)
215 self.cmpi = cmpi
216 ldst = cmpi.pi
217 self.l0 = ldst
218
219 self.mmu = MMU()
220 LDSTCompUnit.__init__(self, ldst.pi, regspec, 4)
221
222 def elaborate(self, platform):
223 m = LDSTCompUnit.elaborate(self, platform)
224 m.submodules.l0 = self.l0
225 m.submodules.mmu = self.mmu
226 # link addr-go direct to rel
227 m.d.comb += self.ad.go_i.eq(self.ad.rel_o)
228
229 # link mmu and dcache together
230 dcache = self.l0.dcache
231 mmu = self.mmu
232 m.d.comb += dcache.m_in.eq(mmu.d_out) # MMUToDCacheType
233 m.d.comb += mmu.d_in.eq(dcache.m_out) # DCacheToMMUType
234
235 return m
236
237 def test_scoreboard_regspec_mmu():
238
239 m = Module()
240
241 units = {}
242 pspec = TestMemPspec(ldst_ifacetype='mmu_cache_wb',
243 imem_ifacetype='bare_wb',
244 addr_wid=48,
245 mask_wid=8,
246 reg_wid=64,
247 units=units)
248
249 dut = TestLDSTCompUnitRegSpecMMU(pspec)
250
251 m.submodules.dut = dut
252
253 sim = Simulator(m)
254 sim.add_clock(1e-6)
255
256 dut.mem = pagetables.test1
257 wbget.stop = False
258
259 sim.add_sync_process(wrap(ldst_sim(dut)))
260 sim.add_sync_process(wrap(wb_get(dut.cmpi.wb_bus(), dut.mem)))
261 with sim.write_vcd('test_scoreboard_regspec_mmu.vcd'):
262 sim.run()
263
264 if __name__ == '__main__':
265 test_scoreboard_regspec_mmu()
266 test_scoreboard_mmu()